mirror of
https://github.com/netbirdio/netbird.git
synced 2025-08-09 15:25:20 +02:00
32
client/iface/netstack/dialer.go
Normal file
32
client/iface/netstack/dialer.go
Normal file
@ -0,0 +1,32 @@
|
||||
package netstack
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.zx2c4.com/wireguard/tun/netstack"
|
||||
)
|
||||
|
||||
type Dialer interface {
|
||||
Dial(ctx context.Context, network, addr string) (net.Conn, error)
|
||||
}
|
||||
|
||||
type NSDialer struct {
|
||||
net *netstack.Net
|
||||
}
|
||||
|
||||
func NewNSDialer(net *netstack.Net) *NSDialer {
|
||||
return &NSDialer{
|
||||
net: net,
|
||||
}
|
||||
}
|
||||
|
||||
func (d *NSDialer) Dial(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
log.Debugf("dialing %s %s", network, addr)
|
||||
conn, err := d.net.Dial(network, addr)
|
||||
if err != nil {
|
||||
log.Debugf("failed to deal connection: %s", err)
|
||||
}
|
||||
return conn, err
|
||||
}
|
33
client/iface/netstack/env.go
Normal file
33
client/iface/netstack/env.go
Normal file
@ -0,0 +1,33 @@
|
||||
package netstack
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// IsEnabled todo: move these function to cmd layer
|
||||
func IsEnabled() bool {
|
||||
return os.Getenv("NB_USE_NETSTACK_MODE") == "true"
|
||||
}
|
||||
|
||||
func ListenAddr() string {
|
||||
sPort := os.Getenv("NB_SOCKS5_LISTENER_PORT")
|
||||
port, err := strconv.Atoi(sPort)
|
||||
if err != nil {
|
||||
log.Warnf("invalid socks5 listener port, unable to convert it to int, falling back to default: %d", DefaultSocks5Port)
|
||||
return listenAddr(DefaultSocks5Port)
|
||||
}
|
||||
if port < 1 || port > 65535 {
|
||||
log.Warnf("invalid socks5 listener port, it should be in the range 1-65535, falling back to default: %d", DefaultSocks5Port)
|
||||
return listenAddr(DefaultSocks5Port)
|
||||
}
|
||||
|
||||
return listenAddr(port)
|
||||
}
|
||||
|
||||
func listenAddr(port int) string {
|
||||
return fmt.Sprintf("0.0.0.0:%d", port)
|
||||
}
|
65
client/iface/netstack/proxy.go
Normal file
65
client/iface/netstack/proxy.go
Normal file
@ -0,0 +1,65 @@
|
||||
package netstack
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/things-go/go-socks5"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultSocks5Port = 1080
|
||||
)
|
||||
|
||||
// Proxy todo close server
|
||||
type Proxy struct {
|
||||
server *socks5.Server
|
||||
|
||||
listener net.Listener
|
||||
closed bool
|
||||
}
|
||||
|
||||
func NewSocks5(dialer Dialer) (*Proxy, error) {
|
||||
server := socks5.NewServer(
|
||||
socks5.WithDial(dialer.Dial),
|
||||
)
|
||||
|
||||
return &Proxy{
|
||||
server: server,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Proxy) ListenAndServe(addr string) error {
|
||||
listener, err := net.Listen("tcp", addr)
|
||||
if err != nil {
|
||||
log.Errorf("failed to create listener for socks5 proxy: %s", err)
|
||||
return err
|
||||
}
|
||||
s.listener = listener
|
||||
|
||||
for {
|
||||
conn, err := listener.Accept()
|
||||
if err != nil {
|
||||
if s.closed {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
go func() {
|
||||
if err := s.server.ServeConn(conn); err != nil {
|
||||
log.Errorf("failed to serve a connection: %s", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Proxy) Close() error {
|
||||
if s.listener == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
s.closed = true
|
||||
return s.listener.Close()
|
||||
}
|
74
client/iface/netstack/tun.go
Normal file
74
client/iface/netstack/tun.go
Normal file
@ -0,0 +1,74 @@
|
||||
package netstack
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.zx2c4.com/wireguard/tun"
|
||||
"golang.zx2c4.com/wireguard/tun/netstack"
|
||||
)
|
||||
|
||||
type NetStackTun struct { //nolint:revive
|
||||
address string
|
||||
mtu int
|
||||
listenAddress string
|
||||
|
||||
proxy *Proxy
|
||||
tundev tun.Device
|
||||
}
|
||||
|
||||
func NewNetStackTun(listenAddress string, address string, mtu int) *NetStackTun {
|
||||
return &NetStackTun{
|
||||
address: address,
|
||||
mtu: mtu,
|
||||
listenAddress: listenAddress,
|
||||
}
|
||||
}
|
||||
|
||||
func (t *NetStackTun) Create() (tun.Device, error) {
|
||||
nsTunDev, tunNet, err := netstack.CreateNetTUN(
|
||||
[]netip.Addr{netip.MustParseAddr(t.address)},
|
||||
[]netip.Addr{},
|
||||
t.mtu)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t.tundev = nsTunDev
|
||||
|
||||
dialer := NewNSDialer(tunNet)
|
||||
t.proxy, err = NewSocks5(dialer)
|
||||
if err != nil {
|
||||
_ = t.tundev.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
go func() {
|
||||
err := t.proxy.ListenAndServe(t.listenAddress)
|
||||
if err != nil {
|
||||
log.Errorf("error in socks5 proxy serving: %s", err)
|
||||
}
|
||||
}()
|
||||
|
||||
return nsTunDev, nil
|
||||
}
|
||||
|
||||
func (t *NetStackTun) Close() error {
|
||||
var err error
|
||||
if t.proxy != nil {
|
||||
pErr := t.proxy.Close()
|
||||
if pErr != nil {
|
||||
log.Errorf("failed to close socks5 proxy: %s", pErr)
|
||||
err = pErr
|
||||
}
|
||||
}
|
||||
|
||||
if t.tundev != nil {
|
||||
dErr := t.tundev.Close()
|
||||
if dErr != nil {
|
||||
log.Errorf("failed to close netstack tun device: %s", dErr)
|
||||
err = dErr
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
Reference in New Issue
Block a user