Skip to content

Commit

Permalink
Revert necessary INPUT rules
Browse files Browse the repository at this point in the history
  • Loading branch information
pappz committed Jan 8, 2024
1 parent fa3c179 commit e60f8fc
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 3 deletions.
6 changes: 4 additions & 2 deletions client/firewall/nftables/acl_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ const (
chainNameInputFilter = "netbird-acl-input-filter"
chainNameOutputFilter = "netbird-acl-output-filter"
chainNameForwardFilter = "netbird-acl-forward-filter"

allowNetbirdInputRuleID = "allow Netbird incoming traffic"
)

var (
Expand Down Expand Up @@ -197,9 +199,9 @@ func (m *AclManager) DeleteRule(rule firewall.Rule) error {
return nil
}

// CreateDefaultAllowRules In case if the USP firewall manager can use the native firewall manager we must to create allow rules for
// createDefaultAllowRules In case if the USP firewall manager can use the native firewall manager we must to create allow rules for
// input and output chains
func (m *AclManager) CreateDefaultAllowRules() error {
func (m *AclManager) createDefaultAllowRules() error {
expIn := []expr.Any{
&expr.Meta{Key: expr.MetaKeyIIFNAME, Register: 1},
&expr.Cmp{
Expand Down
101 changes: 100 additions & 1 deletion client/firewall/nftables/manager_linux.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package nftables

import (
"bytes"
"context"
"fmt"
"net"
"sync"

"github.com/google/nftables"
"github.com/google/nftables/expr"
log "github.com/sirupsen/logrus"

firewall "github.com/netbirdio/netbird/client/firewall/manager"
)
Expand Down Expand Up @@ -111,14 +114,72 @@ func (m *Manager) AllowNetbird() error {
m.mutex.Lock()
defer m.mutex.Unlock()

return m.aclManager.CreateDefaultAllowRules()
chains, err := m.rConn.ListChainsOfTableFamily(nftables.TableFamilyIPv4)
if err != nil {
return fmt.Errorf("list of chains: %w", err)
}

var chain *nftables.Chain
for _, c := range chains {
if c.Table.Name == "filter" && c.Name == "INPUT" {
chain = c
break
}
}

if chain == nil {
log.Debugf("chain INPUT not found. Skipping add allow netbird rule")
return nil
}

rules, err := m.rConn.GetRules(chain.Table, chain)
if err != nil {
return fmt.Errorf("failed to get rules for the INPUT chain: %v", err)
}

if rule := m.detectAllowNetbirdRule(rules); rule != nil {
log.Debugf("allow netbird rule already exists: %v", rule)
return nil
}

m.applyAllowNetbirdRules(chain)

err = m.rConn.Flush()
if err != nil {
return fmt.Errorf("failed to flush allow input netbird rules: %v", err)
}

return m.aclManager.createDefaultAllowRules()
}

// Reset firewall to the default state
func (m *Manager) Reset() error {
m.mutex.Lock()
defer m.mutex.Unlock()

chains, err := m.rConn.ListChains()
if err != nil {
return fmt.Errorf("list of chains: %w", err)
}

for _, c := range chains {
// delete Netbird allow input traffic rule if it exists
if c.Table.Name == "filter" && c.Name == "INPUT" {
rules, err := m.rConn.GetRules(c.Table, c)
if err != nil {
log.Errorf("get rules for chain %q: %v", c.Name, err)
continue
}
for _, r := range rules {
if bytes.Equal(r.UserData, []byte(allowNetbirdInputRuleID)) {
if err := m.rConn.DelRule(r); err != nil {
log.Errorf("delete rule: %v", err)
}
}
}
}
}

m.router.ResetForwardRules()

tables, err := m.rConn.ListTables()
Expand Down Expand Up @@ -161,3 +222,41 @@ func (m *Manager) createWorkTable() (*nftables.Table, error) {
err = m.rConn.Flush()
return table, err
}

func (m *Manager) applyAllowNetbirdRules(chain *nftables.Chain) {
rule := &nftables.Rule{
Table: chain.Table,
Chain: chain,
Exprs: []expr.Any{
&expr.Meta{Key: expr.MetaKeyIIFNAME, Register: 1},
&expr.Cmp{
Op: expr.CmpOpEq,
Register: 1,
Data: ifname(m.wgIface.Name()),
},
&expr.Verdict{
Kind: expr.VerdictAccept,
},
},
UserData: []byte(allowNetbirdInputRuleID),
}
_ = m.rConn.InsertRule(rule)
}

func (m *Manager) detectAllowNetbirdRule(existedRules []*nftables.Rule) *nftables.Rule {
ifName := ifname(m.wgIface.Name())
for _, rule := range existedRules {
if rule.Table.Name == "filter" && rule.Chain.Name == "INPUT" {
if len(rule.Exprs) < 4 {
if e, ok := rule.Exprs[0].(*expr.Meta); !ok || e.Key != expr.MetaKeyIIFNAME {
continue
}
if e, ok := rule.Exprs[1].(*expr.Cmp); !ok || e.Op != expr.CmpOpEq || !bytes.Equal(e.Data, ifName) {
continue
}
return rule
}
}
}
return nil
}

0 comments on commit e60f8fc

Please sign in to comment.