Support client default routes for Linux (#1667)

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.
This commit is contained in:
Viktor Liu
2024-03-21 16:49:28 +01:00
committed by GitHub
parent 846871913d
commit 2475473227
41 changed files with 1656 additions and 376 deletions
+18
View File
@@ -23,6 +23,24 @@ func parseWGAddress(address string) (WGAddress, error) {
}, nil
}
// Masked returns the WGAddress with the IP address part masked according to its network mask.
func (addr WGAddress) Masked() WGAddress {
ip := addr.IP.To4()
if ip == nil {
ip = addr.IP.To16()
}
maskedIP := make(net.IP, len(ip))
for i := range ip {
maskedIP[i] = ip[i] & addr.Network.Mask[i]
}
return WGAddress{
IP: maskedIP,
Network: addr.Network,
}
}
func (addr WGAddress) String() string {
maskSize, _ := addr.Network.Mask.Size()
return fmt.Sprintf("%s/%d", addr.IP.String(), maskSize)
+3 -1
View File
@@ -10,6 +10,8 @@ import (
log "github.com/sirupsen/logrus"
"golang.zx2c4.com/wireguard/wgctrl"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
nbnet "github.com/netbirdio/netbird/util/net"
)
type wgKernelConfigurer struct {
@@ -29,7 +31,7 @@ func (c *wgKernelConfigurer) configureInterface(privateKey string, port int) err
if err != nil {
return err
}
fwmark := 0
fwmark := nbnet.NetbirdFwmark
config := wgtypes.Config{
PrivateKey: &key,
ReplacePeers: true,
+10 -1
View File
@@ -13,6 +13,8 @@ import (
log "github.com/sirupsen/logrus"
"golang.zx2c4.com/wireguard/device"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
nbnet "github.com/netbirdio/netbird/util/net"
)
type wgUSPConfigurer struct {
@@ -37,7 +39,7 @@ func (c *wgUSPConfigurer) configureInterface(privateKey string, port int) error
if err != nil {
return err
}
fwmark := 0
fwmark := getFwmark()
config := wgtypes.Config{
PrivateKey: &key,
ReplacePeers: true,
@@ -345,3 +347,10 @@ func toWgUserspaceString(wgCfg wgtypes.Config) string {
}
return sb.String()
}
func getFwmark() int {
if runtime.GOOS == "linux" {
return nbnet.NetbirdFwmark
}
return 0
}