diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..2bb15b07 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,25 @@ +# `dependabot.yml` file + +# Enable version updates for golang +version: 2 +updates: + - package-ecosystem: "gomod" + directory: "/" + schedule: + interval: "daily" + + # Enable version updates for Docker + - package-ecosystem: "docker" + # Look for a `Dockerfile` in the `root` directory + directory: "/" + # Check for updates once a week + schedule: + interval: "weekly" + + # Enable version updates for GitHub Actions + - package-ecosystem: "github-actions" + # Workflow files stored in the default location of `.github/workflows` + # You don't need to specify `/.github/workflows` for `directory`. You can use `directory: "/"`. + directory: "/" + schedule: + interval: "weekly" \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dd172d95..d7ead756 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,7 +15,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setting up Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: "1.21" - name: Building Windows amd64 Version @@ -35,7 +35,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setting up Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: "1.21" - name: Building Windows arm64 Version @@ -55,7 +55,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setting up Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: "1.21" - name: Building Linux amd64 Version @@ -75,7 +75,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setting up Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: "1.21" - name: Building Linux arm64 Version @@ -95,7 +95,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setting up Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: "1.21" - name: Building Linux s390x Version @@ -115,7 +115,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setting up Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: "1.21" - name: Building Darwin amd64 Version @@ -135,7 +135,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setting up Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: "1.21" - name: Building Darwin arm64 Version diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 6fb237f3..20ab68fb 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -15,9 +15,9 @@ jobs: name: lint runs-on: ubuntu-latest steps: - - uses: actions/setup-go@v5 + - uses: actions/setup-go@v6 with: - go-version: '1.21' + go-version: '1.25' - uses: actions/checkout@v4 - name: golangci-lint uses: golangci/golangci-lint-action@v4 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6f5dbb8a..8c6dc08c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,9 +15,9 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setting up Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: - go-version: "1.21" + go-version: "1.25" - name: Install dependencies run: sudo apt install wireguard curl - name: Building wireproxy diff --git a/.github/workflows/wireproxy.yml b/.github/workflows/wireproxy.yml index 17cc1919..e181a960 100644 --- a/.github/workflows/wireproxy.yml +++ b/.github/workflows/wireproxy.yml @@ -28,7 +28,7 @@ jobs: cp ./.github/wireproxy-releaser.yml ${{ env.workdir }}/.goreleaser.yml - name: Set up GoReleaser - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: "1.21" diff --git a/Dockerfile b/Dockerfile index 9906d1c6..43f34b31 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Start by building the application. -FROM docker.io/golang:1.21 as build +FROM docker.io/golang:1.25 as build WORKDIR /usr/src/wireproxy COPY . . diff --git a/README.md b/README.md index 5c774e0e..03c8d524 100644 --- a/README.md +++ b/README.md @@ -50,9 +50,9 @@ with a discount using [this referral link](https://iproyal.com/?r=795836)! 🚀 ``` ```bash -usage: wireproxy [-h|--help] [-c|--config ""] [-s|--silent] - [-d|--daemon] [-i|--info ""] [-v|--version] - [-n|--configtest] +usage: wireproxy [-h|--help] [-c|--config ""] [-s|--silent] + [-v|--verbose] [-d|--daemon] [-i|--info ""] + [-V|--version] [-n|--configtest] Userspace wireguard client for proxying @@ -61,10 +61,11 @@ Arguments: -h --help Print help information -c --config Path of configuration file Default paths: /etc/wireproxy/wireproxy.conf, $HOME/.config/wireproxy.conf - -s --silent Silent mode + -s --silent Logging: Set silent mode + -v --verbose Logging: Set verbose mode -d --daemon Make wireproxy run in background -i --info Specify the address and port for exposing health status - -v --version Print version + -V --version Print version -n --configtest Configtest mode. Only check the configuration file for validity. ``` diff --git a/cmd/wireproxy/main.go b/cmd/wireproxy/main.go index 713943a2..fbf9f96e 100644 --- a/cmd/wireproxy/main.go +++ b/cmd/wireproxy/main.go @@ -3,7 +3,6 @@ package main import ( "context" "fmt" - "github.com/landlock-lsm/go-landlock/landlock" "log" "net" "net/http" @@ -13,6 +12,8 @@ import ( "strconv" "syscall" + "github.com/landlock-lsm/go-landlock/landlock" + "github.com/akamensky/argparse" "github.com/pufferffish/wireproxy" "golang.zx2c4.com/wireguard/device" @@ -23,9 +24,9 @@ import ( const daemonProcess = "daemon-process" // default paths for wireproxy config file -var default_config_paths = []string { - "/etc/wireproxy/wireproxy.conf", - os.Getenv("HOME")+"/.config/wireproxy.conf", +var default_config_paths = []string{ + "/etc/wireproxy/wireproxy.conf", + os.Getenv("HOME") + "/.config/wireproxy.conf", } var version = "1.0.8-dev" @@ -59,12 +60,12 @@ func executablePath() string { // check if default config file paths exist func configFilePath() (string, bool) { - for _, path := range default_config_paths { - if _, err := os.Stat(path); err == nil { - return path, true - } - } - return "", false + for _, path := range default_config_paths { + if _, err := os.Stat(path); err == nil { + return path, true + } + } + return "", false } func lock(stage string) { @@ -175,10 +176,12 @@ func main() { parser := argparse.NewParser("wireproxy", "Userspace wireguard client for proxying") config := parser.String("c", "config", &argparse.Options{Help: "Path of configuration file"}) - silent := parser.Flag("s", "silent", &argparse.Options{Help: "Silent mode"}) + silent := parser.Flag("s", "silent", &argparse.Options{Help: "Logging: Set silent mode"}) + verbose := parser.Flag("v", "verbose", &argparse.Options{Help: "Logging: Set verbose mode"}) + daemon := parser.Flag("d", "daemon", &argparse.Options{Help: "Make wireproxy run in background"}) info := parser.String("i", "info", &argparse.Options{Help: "Specify the address and port for exposing health status"}) - printVerison := parser.Flag("v", "version", &argparse.Options{Help: "Print version"}) + printVerison := parser.Flag("V", "version", &argparse.Options{Help: "Print version"}) configTest := parser.Flag("n", "configtest", &argparse.Options{Help: "Configtest mode. Only check the configuration file for validity."}) err := parser.Parse(args) @@ -193,12 +196,12 @@ func main() { } if *config == "" { - if path, config_exist := configFilePath(); config_exist { - *config = path - } else { - fmt.Println("configuration path is required") - return - } + if path, config_exist := configFilePath(); config_exist { + *config = path + } else { + fmt.Println("configuration path is required") + return + } } if !*daemon { @@ -237,14 +240,18 @@ func main() { // https://github.com/WireGuard/wireguard-go/blob/master/device/logger.go#L39 // so redirect STDOUT to STDERR, we don't want to print anything to STDOUT anyways os.Stdout = os.NewFile(uintptr(syscall.Stderr), "/dev/stderr") - logLevel := device.LogLevelVerbose + logLevel := device.LogLevelError if *silent { logLevel = device.LogLevelSilent + + } else if *verbose { + logLevel = device.LogLevelVerbose } lock("ready") + var errorLogger = device.NewLogger(logLevel, "wireproxy - ") - tun, err := wireproxy.StartWireguard(conf.Device, logLevel) + tun, err := wireproxy.StartWireguard(conf.Device, errorLogger) if err != nil { log.Fatal(err) } diff --git a/config.go b/config.go index 1f6e4e4a..6322793a 100644 --- a/config.go +++ b/config.go @@ -175,7 +175,7 @@ func parseCIDRNetIP(section *ini.Section, keyName string) ([]netip.Addr, error) if len(str) == 0 { continue } - + if addr, err := netip.ParseAddr(str); err == nil { ips = append(ips, addr) } else { @@ -183,7 +183,7 @@ func parseCIDRNetIP(section *ini.Section, keyName string) ([]netip.Addr, error) if err != nil { return nil, err } - + addr := prefix.Addr() ips = append(ips, addr) } diff --git a/config_test.go b/config_test.go index 948fbf83..0e0cdc82 100644 --- a/config_test.go +++ b/config_test.go @@ -1,8 +1,9 @@ package wireproxy import ( - "github.com/go-ini/ini" "testing" + + "github.com/go-ini/ini" ) func loadIniConfig(config string) (*ini.File, error) { diff --git a/go.mod b/go.mod index b022b0ae..558eaeab 100644 --- a/go.mod +++ b/go.mod @@ -1,26 +1,24 @@ module github.com/pufferffish/wireproxy -go 1.21.1 - -toolchain go1.21.6 +go 1.25.0 require ( github.com/MakeNowJust/heredoc/v2 v2.0.1 github.com/akamensky/argparse v1.4.0 github.com/go-ini/ini v1.67.0 - github.com/landlock-lsm/go-landlock v0.0.0-20240216195629-efb66220540a - github.com/things-go/go-socks5 v0.0.5 - golang.org/x/net v0.33.0 + github.com/landlock-lsm/go-landlock v0.0.0-20250303204525-1544bccde3a3 + github.com/things-go/go-socks5 v0.1.0 + golang.org/x/net v0.55.0 golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 - suah.dev/protect v1.2.3 + suah.dev/protect v1.2.4 ) require ( github.com/google/btree v1.1.2 // indirect - golang.org/x/crypto v0.31.0 // indirect - golang.org/x/sys v0.28.0 // indirect + golang.org/x/crypto v0.51.0 // indirect + golang.org/x/sys v0.45.0 // indirect golang.org/x/time v0.5.0 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259 // indirect - kernel.org/pub/linux/libs/security/libcap/psx v1.2.69 // indirect + kernel.org/pub/linux/libs/security/libcap/psx v1.2.70 // indirect ) diff --git a/go.sum b/go.sum index f51522a8..70581cf8 100644 --- a/go.sum +++ b/go.sum @@ -8,21 +8,21 @@ github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/landlock-lsm/go-landlock v0.0.0-20240216195629-efb66220540a h1:dz+a1MiMQksVhejeZwqJuzPawYQBwug74J8PPtkLl9U= -github.com/landlock-lsm/go-landlock v0.0.0-20240216195629-efb66220540a/go.mod h1:1NY/VPO8xm3hXw3f+M65z+PJDLUaZA5cu7OfanxoUzY= +github.com/landlock-lsm/go-landlock v0.0.0-20250303204525-1544bccde3a3 h1:zcMi8R8vP0WrrXlFMNUBpDy/ydo3sTnCcUPowq1XmSc= +github.com/landlock-lsm/go-landlock v0.0.0-20250303204525-1544bccde3a3/go.mod h1:RSub3ourNF8Hf+swvw49Catm3s7HVf4hzdFxDUnEzdA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/things-go/go-socks5 v0.0.5 h1:qvKaGcBkfDrUL33SchHN93srAmYGzb4CxSM2DPYufe8= -github.com/things-go/go-socks5 v0.0.5/go.mod h1:mtzInf8v5xmsBpHZVbIw2YQYhc4K0jRwzfsH64Uh0IQ= -golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= -golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +github.com/stretchr/testify v1.11.0 h1:ib4sjIrwZKxE5u/Japgo/7SJV3PvgjGiRNAvTVGqQl8= +github.com/stretchr/testify v1.11.0/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/things-go/go-socks5 v0.1.0 h1:4f5dz0iMQ6cA4wseFmyLmCHmg3SWJTW92ndrKS6oERg= +github.com/things-go/go-socks5 v0.1.0/go.mod h1:Riabiyu52kLsla0YmJqunt1c1JEl6iXSr4bRd7swFEA= +golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI= +golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8= +golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= +golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= +golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg= @@ -33,7 +33,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259 h1:TbRPT0HtzFP3Cno1zZo7yPzEEnfu8EjLfl6IU9VfqkQ= gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259/go.mod h1:AVgIgHMwK63XvmAzWG9vLQ41YnVHN0du0tEC46fI7yY= -kernel.org/pub/linux/libs/security/libcap/psx v1.2.69 h1:IdrOs1ZgwGw5CI+BH6GgVVlOt+LAXoPyh7enr8lfaXs= -kernel.org/pub/linux/libs/security/libcap/psx v1.2.69/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= -suah.dev/protect v1.2.3 h1:aHeoNwZ9YPp64hrYaN0g0djNE1eRujgH63CrfRrUKdc= -suah.dev/protect v1.2.3/go.mod h1:n1R3XIbsnryKX7C1PO88i5Wgo0v8OTXm9K9FIKt4rfs= +kernel.org/pub/linux/libs/security/libcap/psx v1.2.70 h1:HsB2G/rEQiYyo1bGoQqHZ/Bvd6x1rERQTNdPr1FyWjI= +kernel.org/pub/linux/libs/security/libcap/psx v1.2.70/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= +suah.dev/protect v1.2.4 h1:iVZG/zQB63FKNpITDYM/cXoAeCTIjCiXHuFVByJFDzg= +suah.dev/protect v1.2.4/go.mod h1:vVrquYO3u1Ep9Ez2z8x+6N6/czm+TBmWKZfiXU2tb54= diff --git a/http.go b/http.go index 88a7ef48..1636adbc 100644 --- a/http.go +++ b/http.go @@ -6,7 +6,8 @@ import ( "encoding/base64" "fmt" "io" - "log" + + //"log" "net" "net/http" "strings" @@ -21,6 +22,7 @@ type HTTPServer struct { dial func(network, address string) (net.Conn, error) authRequired bool + vtun *VirtualTun } func (s *HTTPServer) authenticate(req *http.Request) (int, error) { @@ -55,6 +57,7 @@ func (s *HTTPServer) handleConn(req *http.Request, conn net.Conn) (peer net.Conn addr = net.JoinHostPort(addr, port) } + s.vtun.logger.Verbosef("Got HTTP Connect to %s", addr) peer, err = s.dial("tcp", addr) if err != nil { return peer, fmt.Errorf("tun tcp dial failed: %w", err) @@ -76,6 +79,7 @@ func (s *HTTPServer) handle(req *http.Request) (peer net.Conn, err error) { addr = net.JoinHostPort(addr, port) } + s.vtun.logger.Verbosef("Got HTTP GET to %s", addr) peer, err = s.dial("tcp", addr) if err != nil { return peer, fmt.Errorf("tun tcp dial failed: %w", err) @@ -95,7 +99,7 @@ func (s *HTTPServer) serve(conn net.Conn) { var rd = bufio.NewReader(conn) req, err := http.ReadRequest(rd) if err != nil { - log.Printf("read request failed: %s\n", err) + s.vtun.logger.Errorf("read request failed: %s", err) return } @@ -106,7 +110,7 @@ func (s *HTTPServer) serve(conn net.Conn) { resp.Header.Set("Proxy-Authenticate", "Basic realm=\"Proxy\"") } _ = resp.Write(conn) - log.Println(err) + s.vtun.logger.Errorf("authenticate failed: %s", err) return } @@ -118,15 +122,15 @@ func (s *HTTPServer) serve(conn net.Conn) { peer, err = s.handle(req) default: _ = responseWith(req, http.StatusMethodNotAllowed).Write(conn) - log.Printf("unsupported protocol: %s\n", req.Method) + s.vtun.logger.Errorf("unsupported protocol: %s", req.Method) return } if err != nil { - log.Printf("dial proxy failed: %s\n", err) + s.vtun.logger.Errorf("dial proxy failed: %s", err) return } if peer == nil { - log.Println("dial proxy failed: peer nil") + s.vtun.logger.Errorf("dial proxy failed: peer nil") return } @@ -149,7 +153,8 @@ func (s *HTTPServer) serve(conn net.Conn) { func (s *HTTPServer) ListenAndServe(network, addr string) error { server, err := net.Listen(network, addr) if err != nil { - return fmt.Errorf("listen tcp failed: %w", err) + s.vtun.logger.Errorf("listen tcp failed: %w", err) + return err } defer func(server net.Listener) { _ = server.Close() @@ -157,7 +162,8 @@ func (s *HTTPServer) ListenAndServe(network, addr string) error { for { conn, err := server.Accept() if err != nil { - return fmt.Errorf("accept request failed: %w", err) + s.vtun.logger.Errorf("accept request failed: %w", err) + return err } go func(conn net.Conn) { s.serve(conn) diff --git a/routine.go b/routine.go index edfc793b..99536b12 100644 --- a/routine.go +++ b/routine.go @@ -8,10 +8,6 @@ import ( "encoding/binary" "encoding/json" "errors" - "golang.org/x/net/icmp" - "golang.org/x/net/ipv4" - "golang.org/x/net/ipv6" - "golang.zx2c4.com/wireguard/device" "io" "log" "math/rand" @@ -24,6 +20,11 @@ import ( "sync" "time" + "golang.org/x/net/icmp" + "golang.org/x/net/ipv4" + "golang.org/x/net/ipv6" + "golang.zx2c4.com/wireguard/device" + "github.com/things-go/go-socks5" "github.com/things-go/go-socks5/bufferpool" @@ -33,7 +34,7 @@ import ( ) // errorLogger is the logger to print error message -var errorLogger = log.New(os.Stderr, "ERROR: ", log.LstdFlags) +//var errorLogger = log.New(os.Stderr, "ERROR: ", log.LstdFlags) // CredentialValidator stores the authentication data of a socks5 proxy type CredentialValidator struct { @@ -50,6 +51,7 @@ type VirtualTun struct { // PingRecord stores the last time an IP was pinged PingRecord map[string]uint64 PingRecordLock *sync.Mutex + logger *device.Logger } // RoutineSpawner spawns a routine (e.g. socks5, tcp static routes) after the configuration is parsed @@ -110,7 +112,7 @@ func (d VirtualTun) Resolve(ctx context.Context, name string) (context.Context, if err != nil { return nil, nil, err } - + d.logger.Verbosef("Resolved %s to %s\n", name, addr) return ctx, addr.AsSlice(), nil } @@ -169,6 +171,7 @@ func (config *HTTPConfig) SpawnRoutine(vt *VirtualTun) { config: config, dial: vt.Tnet.Dial, auth: CredentialValidator{config.Username, config.Password}, + vtun: vt, } if config.Username != "" || config.Password != "" { server.authRequired = true @@ -188,13 +191,13 @@ func (c CredentialValidator) Valid(username, password string) bool { } // connForward copy data from `from` to `to` -func connForward(from io.ReadWriteCloser, to io.ReadWriteCloser) { +func connForward(from io.ReadWriteCloser, to io.ReadWriteCloser, logger *device.Logger) { defer from.Close() defer to.Close() _, err := io.Copy(to, from) if err != nil { - errorLogger.Printf("Cannot forward traffic: %s\n", err.Error()) + logger.Errorf("Cannot forward traffic: %s\n", err.Error()) } } @@ -202,7 +205,7 @@ func connForward(from io.ReadWriteCloser, to io.ReadWriteCloser) { func tcpClientForward(vt *VirtualTun, raddr *addressPort, conn net.Conn) { target, err := vt.resolveToAddrPort(raddr) if err != nil { - errorLogger.Printf("TCP Server Tunnel to %s: %s\n", target, err.Error()) + vt.logger.Errorf("TCP Server Tunnel to %s: %s\n", target, err.Error()) return } @@ -210,38 +213,38 @@ func tcpClientForward(vt *VirtualTun, raddr *addressPort, conn net.Conn) { sconn, err := vt.Tnet.DialTCP(tcpAddr) if err != nil { - errorLogger.Printf("TCP Client Tunnel to %s: %s\n", target, err.Error()) + vt.logger.Errorf("TCP Client Tunnel to %s: %s\n", target, err.Error()) return } - go connForward(sconn, conn) - go connForward(conn, sconn) + go connForward(sconn, conn, vt.logger) + go connForward(conn, sconn, vt.logger) } // STDIOTcpForward starts a new connection via wireguard and forward traffic from `conn` func STDIOTcpForward(vt *VirtualTun, raddr *addressPort) { target, err := vt.resolveToAddrPort(raddr) if err != nil { - errorLogger.Printf("Name resolution error for %s: %s\n", raddr.address, err.Error()) + vt.logger.Errorf("Name resolution error for %s: %s\n", raddr.address, err.Error()) return } // os.Stdout has previously been remapped to stderr, se we can't use it stdout, err := os.OpenFile("/dev/stdout", os.O_WRONLY, 0) if err != nil { - errorLogger.Printf("Failed to open /dev/stdout: %s\n", err.Error()) + vt.logger.Errorf("Failed to open /dev/stdout: %s\n", err.Error()) return } tcpAddr := TCPAddrFromAddrPort(*target) sconn, err := vt.Tnet.DialTCP(tcpAddr) if err != nil { - errorLogger.Printf("TCP Client Tunnel to %s (%s): %s\n", target, tcpAddr, err.Error()) + vt.logger.Errorf("TCP Client Tunnel to %s (%s): %s\n", target, tcpAddr, err.Error()) return } - go connForward(os.Stdin, sconn) - go connForward(sconn, stdout) + go connForward(os.Stdin, sconn, vt.logger) + go connForward(sconn, stdout, vt.logger) } // SpawnRoutine spawns a local TCP server which acts as a proxy to the specified target @@ -279,7 +282,7 @@ func (conf *STDIOTunnelConfig) SpawnRoutine(vt *VirtualTun) { func tcpServerForward(vt *VirtualTun, raddr *addressPort, conn net.Conn) { target, err := vt.resolveToAddrPort(raddr) if err != nil { - errorLogger.Printf("TCP Server Tunnel to %s: %s\n", target, err.Error()) + vt.logger.Errorf("TCP Server Tunnel to %s: %s\n", target, err.Error()) return } @@ -287,12 +290,12 @@ func tcpServerForward(vt *VirtualTun, raddr *addressPort, conn net.Conn) { sconn, err := net.DialTCP("tcp", nil, tcpAddr) if err != nil { - errorLogger.Printf("TCP Server Tunnel to %s: %s\n", target, err.Error()) + vt.logger.Errorf("TCP Server Tunnel to %s: %s\n", target, err.Error()) return } - go connForward(sconn, conn) - go connForward(conn, sconn) + go connForward(sconn, conn, vt.logger) + go connForward(conn, sconn, vt.logger) } @@ -319,12 +322,12 @@ func (conf *TCPServerTunnelConfig) SpawnRoutine(vt *VirtualTun) { } func (d VirtualTun) ServeHTTP(w http.ResponseWriter, r *http.Request) { - log.Printf("Health metric request: %s\n", r.URL.Path) + d.logger.Verbosef("Health metric request: %s\n", r.URL.Path) switch path.Clean(r.URL.Path) { case "/readyz": body, err := json.Marshal(d.PingRecord) if err != nil { - errorLogger.Printf("Failed to get device metrics: %s\n", err.Error()) + d.logger.Errorf("Failed to get device metrics: %s\n", err.Error()) w.WriteHeader(http.StatusInternalServerError) return } @@ -345,7 +348,7 @@ func (d VirtualTun) ServeHTTP(w http.ResponseWriter, r *http.Request) { case "/metrics": get, err := d.Dev.IpcGet() if err != nil { - errorLogger.Printf("Failed to get device metrics: %s\n", err.Error()) + d.logger.Errorf("Failed to get device metrics: %s\n", err.Error()) w.WriteHeader(http.StatusInternalServerError) return } @@ -376,7 +379,7 @@ func (d VirtualTun) pingIPs() { for _, addr := range d.Conf.CheckAlive { socket, err := d.Tnet.Dial("ping", addr.String()) if err != nil { - errorLogger.Printf("Failed to ping %s: %s\n", addr, err.Error()) + d.logger.Errorf("Failed to ping %s: %s\n", addr, err.Error()) continue } @@ -394,14 +397,14 @@ func (d VirtualTun) pingIPs() { } else if addr.Is6() { icmpBytes, _ = (&icmp.Message{Type: ipv6.ICMPTypeEchoRequest, Code: 0, Body: &requestPing}).Marshal(nil) } else { - errorLogger.Printf("Failed to ping %s: invalid address: %s\n", addr, addr.String()) + d.logger.Errorf("Failed to ping %s: invalid address: %s\n", addr, addr.String()) continue } _ = socket.SetReadDeadline(time.Now().Add(time.Duration(d.Conf.CheckAliveInterval) * time.Second)) _, err = socket.Write(icmpBytes) if err != nil { - errorLogger.Printf("Failed to ping %s: %s\n", addr, err.Error()) + d.logger.Errorf("Failed to ping %s: %s\n", addr, err.Error()) continue } @@ -409,24 +412,24 @@ func (d VirtualTun) pingIPs() { go func() { n, err := socket.Read(icmpBytes[:]) if err != nil { - errorLogger.Printf("Failed to read ping response from %s: %s\n", addr, err.Error()) + d.logger.Errorf("Failed to read ping response from %s: %s\n", addr, err.Error()) return } replyPacket, err := icmp.ParseMessage(1, icmpBytes[:n]) if err != nil { - errorLogger.Printf("Failed to parse ping response from %s: %s\n", addr, err.Error()) + d.logger.Errorf("Failed to parse ping response from %s: %s\n", addr, err.Error()) return } if addr.Is4() { replyPing, ok := replyPacket.Body.(*icmp.Echo) if !ok { - errorLogger.Printf("Failed to parse ping response from %s: invalid reply type: %s\n", addr, replyPacket.Type) + d.logger.Errorf("Failed to parse ping response from %s: invalid reply type: %s\n", addr, replyPacket.Type) return } if !bytes.Equal(replyPing.Data, requestPing.Data) || replyPing.Seq != requestPing.Seq { - errorLogger.Printf("Failed to parse ping response from %s: invalid ping reply: %v\n", addr, replyPing) + d.logger.Errorf("Failed to parse ping response from %s: invalid ping reply: %v\n", addr, replyPing) return } } @@ -434,14 +437,14 @@ func (d VirtualTun) pingIPs() { if addr.Is6() { replyPing, ok := replyPacket.Body.(*icmp.RawBody) if !ok { - errorLogger.Printf("Failed to parse ping response from %s: invalid reply type: %s\n", addr, replyPacket.Type) + d.logger.Errorf("Failed to parse ping response from %s: invalid reply type: %s\n", addr, replyPacket.Type) return } seq := binary.BigEndian.Uint16(replyPing.Data[2:4]) pongBody := replyPing.Data[4:] if !bytes.Equal(pongBody, requestPing.Data) || int(seq) != requestPing.Seq { - errorLogger.Printf("Failed to parse ping response from %s: invalid ping reply: %v\n", addr, replyPing) + d.logger.Errorf("Failed to parse ping response from %s: invalid ping reply: %v\n", addr, replyPing) return } } diff --git a/wireguard.go b/wireguard.go index 71a2960e..de5443bb 100644 --- a/wireguard.go +++ b/wireguard.go @@ -60,7 +60,7 @@ func CreateIPCRequest(conf *DeviceConfig) (*DeviceSetting, error) { } // StartWireguard creates a tun interface on netstack given a configuration -func StartWireguard(conf *DeviceConfig, logLevel int) (*VirtualTun, error) { +func StartWireguard(conf *DeviceConfig, logger *device.Logger) (*VirtualTun, error) { setting, err := CreateIPCRequest(conf) if err != nil { return nil, err @@ -70,7 +70,7 @@ func StartWireguard(conf *DeviceConfig, logLevel int) (*VirtualTun, error) { if err != nil { return nil, err } - dev := device.NewDevice(tun, conn.NewDefaultBind(), device.NewLogger(logLevel, "")) + dev := device.NewDevice(tun, conn.NewDefaultBind(), logger) err = dev.IpcSet(setting.IpcRequest) if err != nil { return nil, err @@ -88,5 +88,6 @@ func StartWireguard(conf *DeviceConfig, logLevel int) (*VirtualTun, error) { SystemDNS: len(setting.DNS) == 0, PingRecord: make(map[string]uint64), PingRecordLock: new(sync.Mutex), + logger: logger, }, nil }