diff --git a/go.mod b/go.mod index b71ac9372..88aab92b3 100644 --- a/go.mod +++ b/go.mod @@ -30,6 +30,7 @@ require ( require ( fyne.io/fyne/v2 v2.1.4 github.com/TheJumpCloud/jcapi-go v3.0.0+incompatible + github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 github.com/c-robinson/iplib v1.0.3 github.com/cilium/ebpf v0.10.0 github.com/coreos/go-iptables v0.7.0 diff --git a/go.sum b/go.sum index 9ad425dfd..8fc30c063 100644 --- a/go.sum +++ b/go.sum @@ -76,6 +76,8 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFI github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/bazelbuild/rules_go v0.30.0/go.mod h1:MC23Dc/wkXEyk3Wpq6lCqz0ZAYOZDw2DR5y3N1q2i7M= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= diff --git a/iface/tun_unix.go b/iface/tun_unix.go index 8a8feea64..f345c0198 100644 --- a/iface/tun_unix.go +++ b/iface/tun_unix.go @@ -4,16 +4,14 @@ package iface import ( "net" - "net/netip" "os" "github.com/pion/transport/v2" "golang.zx2c4.com/wireguard/ipc" - "golang.zx2c4.com/wireguard/tun/netstack" "github.com/netbirdio/netbird/iface/bind" + "github.com/netbirdio/netbird/iface/uspproxy" - log "github.com/sirupsen/logrus" "golang.zx2c4.com/wireguard/device" ) @@ -49,6 +47,7 @@ func (c *tunDevice) WgAddress() WGAddress { } func (t *tunDevice) Device() *device.Device { + // todo: potential nil pointer exception return t.tunDevice } @@ -91,19 +90,14 @@ func (c *tunDevice) Close() error { return err3 } -// createWithUserspace Creates a new Wireguard interface, using wireguard-go userspace implementation func (c *tunDevice) createWithUserspace() (NetInterface, error) { - tunIface, _, err := netstack.CreateNetTUN( - []netip.Addr{netip.MustParseAddr(c.address.IP.String())}, - []netip.Addr{netip.MustParseAddr("8.8.8.8")}, - 1420) + nsTun := uspproxy.NewNetStackTun(c.address.IP.String()) + tunIface, err := nsTun.Create() if err != nil { - log.Debugf("createWithUserspace failed with error: %v", err) return nil, err } c.wrapper = newDeviceWrapper(tunIface) - // We need to create a wireguard-go device and listen to configuration requests tunDev := device.NewDevice( c.wrapper, c.iceBind, @@ -111,7 +105,6 @@ func (c *tunDevice) createWithUserspace() (NetInterface, error) { ) err = tunDev.Up() if err != nil { - log.Debugf("tunDev.Up() failed with error: %v", err) _ = tunIface.Close() return nil, err } diff --git a/iface/uspproxy/proxy.go b/iface/uspproxy/proxy.go new file mode 100644 index 000000000..16b6a3be5 --- /dev/null +++ b/iface/uspproxy/proxy.go @@ -0,0 +1,43 @@ +package uspproxy + +import ( + "context" + "net" + + "github.com/armon/go-socks5" + log "github.com/sirupsen/logrus" +) + +type Dialer interface { + Dial(ctx context.Context, network, addr string) (net.Conn, error) +} + +// Proxy todo close server +type Proxy struct { + server *socks5.Server +} + +func NewSocks5(dialer Dialer) (*Proxy, error) { + conf := &socks5.Config{ + Dial: dialer.Dial, + } + server, err := socks5.New(conf) + if err != nil { + log.Debugf("failed to init socks5 proxy: %s", err) + return nil, err + } + + return &Proxy{ + server: server, + }, nil +} + +func (s *Proxy) ListenAndServe(addr string) error { + go func() { + err := s.server.ListenAndServe("tcp", addr) + if err != nil { + log.Debugf("failed to start socks5 proxy: %s", err) + } + }() + return nil +} diff --git a/iface/uspproxy/tun.go b/iface/uspproxy/tun.go new file mode 100644 index 000000000..17a61ac67 --- /dev/null +++ b/iface/uspproxy/tun.go @@ -0,0 +1,55 @@ +package uspproxy + +import ( + "context" + "net" + "net/netip" + + log "github.com/sirupsen/logrus" + "golang.zx2c4.com/wireguard/tun" + "golang.zx2c4.com/wireguard/tun/netstack" +) + +type NSDialer struct { + net *netstack.Net +} + +func (d *NSDialer) Dial(ctx context.Context, network, addr string) (net.Conn, error) { + conn, err := d.net.Dial(network, addr) + if err != nil { + log.Debugf("failed to deal connection: %s", err) + } + return conn, err +} + +type NetStackTun struct { + address string + + proxy *Proxy +} + +func NewNetStackTun(address string) *NetStackTun { + return &NetStackTun{ + address: address, + } +} + +func (t *NetStackTun) Create() (tun.Device, error) { + nsTunDev, tunNet, err := netstack.CreateNetTUN( + []netip.Addr{netip.MustParseAddr(t.address)}, + []netip.Addr{netip.MustParseAddr("8.8.8.8")}, + 1420) + if err != nil { + return nil, err + } + + dialer := &NSDialer{tunNet} + t.proxy, err = NewSocks5(dialer) + if err != nil { + // close nsTunDev + return nil, err + } + + err = t.proxy.ListenAndServe("127.0.0.1:1234") + return nsTunDev, nil +}