Skip to content

Commit

Permalink
Enhance firewall manager checks to detect unsupported iptables (#2038)
Browse files Browse the repository at this point in the history
Our nftables firewall manager may cause issues when rules are created using older iptable versions
  • Loading branch information
mlsmaycon committed May 23, 2024
1 parent 9d3db68 commit 6b01b00
Showing 1 changed file with 46 additions and 7 deletions.
53 changes: 46 additions & 7 deletions client/firewall/create_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 +85,55 @@ func NewFirewall(context context.Context, iface IFaceMapper) (firewall.Manager,

// check returns the firewall type based on common lib checks. It returns UNKNOWN if no firewall is found.
func check() FWType {
nf := nftables.Conn{}
if _, err := nf.ListChains(); err == nil && os.Getenv(SKIP_NFTABLES_ENV) != "true" {
return NFTABLES
useIPTABLES := false
testingChain := "netbird-testing"
ip, err := iptables.NewWithProtocol(iptables.ProtocolIPv4)
if err == nil && isIptablesClientAvailable(ip) {
major, minor, _ := ip.GetIptablesVersion()
// use iptables when its version is lower than 1.8.0 which doesn't work well with our nftables manager
if major < 1 || (major == 1 && minor < 8) {
return IPTABLES
}

useIPTABLES = true

// create a testing chain to check if iptables is working and to validate if nftables can be used
err = ip.NewChain("filter", testingChain)
if err != nil {
useIPTABLES = false
}
}

ip, err := iptables.NewWithProtocol(iptables.ProtocolIPv4)
if err != nil {
return UNKNOWN
defer func() {
if !useIPTABLES {
return
}
err = ip.ClearChain("filter", testingChain)
if err != nil {
log.Errorf("failed to clear netbird-testing chain: %v", err)
}
err = ip.DeleteChain("filter", testingChain)
if err != nil {
log.Errorf("failed to delete netbird-testing chain: %v", err)
}
}()

nf := nftables.Conn{}
if chains, err := nf.ListChains(); err == nil && os.Getenv(SKIP_NFTABLES_ENV) != "true" {
if !useIPTABLES {
return NFTABLES
}
// search for the testing chain created by iptables client
// failing to find it means that nftables can be used but the system is using a version of iptables
// that doesn't work well with our nftables manager
for _, chain := range chains {
if chain.Name == testingChain {
return NFTABLES
}
}
}
if isIptablesClientAvailable(ip) {

if useIPTABLES {
return IPTABLES
}

Expand Down

0 comments on commit 6b01b00

Please sign in to comment.