2023-04-17 11:15:37 +02:00
|
|
|
//go:build !android
|
|
|
|
|
2022-09-05 09:06:35 +02:00
|
|
|
package routemanager
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
2023-04-17 11:15:37 +02:00
|
|
|
|
2022-09-05 09:06:35 +02:00
|
|
|
"github.com/coreos/go-iptables/iptables"
|
2023-04-17 11:15:37 +02:00
|
|
|
"github.com/google/nftables"
|
2022-09-05 09:06:35 +02:00
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2022-09-30 11:39:15 +02:00
|
|
|
ipv6Forwarding = "netbird-rt-ipv6-forwarding"
|
|
|
|
ipv4Forwarding = "netbird-rt-ipv4-forwarding"
|
|
|
|
ipv6Nat = "netbird-rt-ipv6-nat"
|
|
|
|
ipv4Nat = "netbird-rt-ipv4-nat"
|
|
|
|
natFormat = "netbird-nat-%s"
|
|
|
|
forwardingFormat = "netbird-fwd-%s"
|
|
|
|
inNatFormat = "netbird-nat-in-%s"
|
|
|
|
inForwardingFormat = "netbird-fwd-in-%s"
|
|
|
|
ipv6 = "ipv6"
|
|
|
|
ipv4 = "ipv4"
|
2022-09-05 09:06:35 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
func genKey(format string, input string) string {
|
|
|
|
return fmt.Sprintf(format, input)
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewFirewall if supported, returns an iptables manager, otherwise returns a nftables manager
|
|
|
|
func NewFirewall(parentCTX context.Context) firewallManager {
|
|
|
|
ctx, cancel := context.WithCancel(parentCTX)
|
|
|
|
|
|
|
|
if isIptablesSupported() {
|
|
|
|
log.Debugf("iptables is supported")
|
|
|
|
ipv4Client, _ := iptables.NewWithProtocol(iptables.ProtocolIPv4)
|
2023-07-14 20:44:35 +02:00
|
|
|
if !isIptablesClientAvailable(ipv4Client) {
|
|
|
|
log.Infof("iptables is missing for ipv4")
|
|
|
|
ipv4Client = nil
|
|
|
|
}
|
2022-09-05 09:06:35 +02:00
|
|
|
ipv6Client, _ := iptables.NewWithProtocol(iptables.ProtocolIPv6)
|
2023-07-14 20:44:35 +02:00
|
|
|
if !isIptablesClientAvailable(ipv6Client) {
|
|
|
|
log.Infof("iptables is missing for ipv6")
|
|
|
|
ipv6Client = nil
|
|
|
|
}
|
2022-09-05 09:06:35 +02:00
|
|
|
|
|
|
|
return &iptablesManager{
|
|
|
|
ctx: ctx,
|
|
|
|
stop: cancel,
|
|
|
|
ipv4Client: ipv4Client,
|
|
|
|
ipv6Client: ipv6Client,
|
|
|
|
rules: make(map[string]map[string][]string),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Debugf("iptables is not supported, using nftables")
|
|
|
|
|
|
|
|
manager := &nftablesManager{
|
|
|
|
ctx: ctx,
|
|
|
|
stop: cancel,
|
|
|
|
conn: &nftables.Conn{},
|
|
|
|
chains: make(map[string]map[string]*nftables.Chain),
|
|
|
|
rules: make(map[string]*nftables.Rule),
|
|
|
|
}
|
|
|
|
|
|
|
|
return manager
|
|
|
|
}
|
2022-09-30 11:39:15 +02:00
|
|
|
|
2023-07-14 20:44:35 +02:00
|
|
|
func isIptablesClientAvailable(client *iptables.IPTables) bool {
|
|
|
|
_, err := client.ListChains("filter")
|
|
|
|
return err == nil
|
|
|
|
}
|
|
|
|
|
2022-09-30 11:39:15 +02:00
|
|
|
func getInPair(pair routerPair) routerPair {
|
|
|
|
return routerPair{
|
|
|
|
ID: pair.ID,
|
|
|
|
// invert source/destination
|
|
|
|
source: pair.destination,
|
|
|
|
destination: pair.source,
|
|
|
|
masquerade: pair.masquerade,
|
|
|
|
}
|
|
|
|
}
|