mirror of
https://github.com/netbirdio/netbird.git
synced 2024-11-23 16:43:29 +01:00
2475473227
All routes are now installed in a custom netbird routing table. Management and wireguard traffic is now marked with a custom fwmark. When the mark is present the traffic is routed via the main routing table, bypassing the VPN. When the mark is absent the traffic is routed via the netbird routing table, if: - there's no match in the main routing table - it would match the default route in the routing table IPv6 traffic is blocked when a default route IPv4 route is configured to avoid leakage.
109 lines
2.1 KiB
Go
109 lines
2.1 KiB
Go
package wgproxy
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
nbnet "github.com/netbirdio/netbird/util/net"
|
|
)
|
|
|
|
// WGUserSpaceProxy proxies
|
|
type WGUserSpaceProxy struct {
|
|
localWGListenPort int
|
|
ctx context.Context
|
|
cancel context.CancelFunc
|
|
|
|
remoteConn net.Conn
|
|
localConn net.Conn
|
|
}
|
|
|
|
// NewWGUserSpaceProxy instantiate a user space WireGuard proxy
|
|
func NewWGUserSpaceProxy(wgPort int) *WGUserSpaceProxy {
|
|
log.Debugf("instantiate new userspace proxy")
|
|
p := &WGUserSpaceProxy{
|
|
localWGListenPort: wgPort,
|
|
}
|
|
p.ctx, p.cancel = context.WithCancel(context.Background())
|
|
return p
|
|
}
|
|
|
|
// AddTurnConn start the proxy with the given remote conn
|
|
func (p *WGUserSpaceProxy) AddTurnConn(remoteConn net.Conn) (net.Addr, error) {
|
|
p.remoteConn = remoteConn
|
|
|
|
var err error
|
|
p.localConn, err = nbnet.NewDialer().Dial("udp", fmt.Sprintf(":%d", p.localWGListenPort))
|
|
if err != nil {
|
|
log.Errorf("failed dialing to local Wireguard port %s", err)
|
|
return nil, err
|
|
}
|
|
|
|
go p.proxyToRemote()
|
|
go p.proxyToLocal()
|
|
|
|
return p.localConn.LocalAddr(), err
|
|
}
|
|
|
|
// CloseConn close the localConn
|
|
func (p *WGUserSpaceProxy) CloseConn() error {
|
|
p.cancel()
|
|
if p.localConn == nil {
|
|
return nil
|
|
}
|
|
return p.localConn.Close()
|
|
}
|
|
|
|
// Free doing nothing because this implementation of proxy does not have global state
|
|
func (p *WGUserSpaceProxy) Free() error {
|
|
return nil
|
|
}
|
|
|
|
// proxyToRemote proxies everything from Wireguard to the RemoteKey peer
|
|
// blocks
|
|
func (p *WGUserSpaceProxy) proxyToRemote() {
|
|
|
|
buf := make([]byte, 1500)
|
|
for {
|
|
select {
|
|
case <-p.ctx.Done():
|
|
return
|
|
default:
|
|
n, err := p.localConn.Read(buf)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
_, err = p.remoteConn.Write(buf[:n])
|
|
if err != nil {
|
|
continue
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// proxyToLocal proxies everything from the RemoteKey peer to local Wireguard
|
|
// blocks
|
|
func (p *WGUserSpaceProxy) proxyToLocal() {
|
|
|
|
buf := make([]byte, 1500)
|
|
for {
|
|
select {
|
|
case <-p.ctx.Done():
|
|
return
|
|
default:
|
|
n, err := p.remoteConn.Read(buf)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
_, err = p.localConn.Write(buf[:n])
|
|
if err != nil {
|
|
continue
|
|
}
|
|
}
|
|
}
|
|
}
|