Skip to content

Commit

Permalink
[client] Mark redirected traffic early to match input filters on pre-…
Browse files Browse the repository at this point in the history
…DNAT ports (#3205)
  • Loading branch information
lixmal authored Jan 23, 2025
1 parent 790a9ed commit eb2ac03
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 87 deletions.
48 changes: 32 additions & 16 deletions client/firewall/iptables/acl_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package iptables
import (
"fmt"
"net"
"slices"
"strconv"

"github.com/coreos/go-iptables/iptables"
Expand Down Expand Up @@ -99,6 +100,16 @@ func (m *aclManager) AddPeerFiltering(

ipsetName = transformIPsetName(ipsetName, sPortVal, dPortVal)
specs := filterRuleSpecs(ip, string(protocol), sPortVal, dPortVal, action, ipsetName)

mangleSpecs := slices.Clone(specs)
mangleSpecs = append(mangleSpecs,
"-i", m.wgIface.Name(),
"-m", "addrtype", "--dst-type", "LOCAL",
"-j", "MARK", "--set-xmark", fmt.Sprintf("%#x", nbnet.PreroutingFwmarkRedirected),
)

specs = append(specs, "-j", actionToStr(action))

if ipsetName != "" {
if ipList, ipsetExists := m.ipsetStore.ipset(ipsetName); ipsetExists {
if err := ipset.Add(ipsetName, ip.String()); err != nil {
Expand Down Expand Up @@ -130,24 +141,30 @@ func (m *aclManager) AddPeerFiltering(
m.ipsetStore.addIpList(ipsetName, ipList)
}

ok, err := m.iptablesClient.Exists("filter", chain, specs...)
ok, err := m.iptablesClient.Exists(tableFilter, chain, specs...)
if err != nil {
return nil, fmt.Errorf("failed to check rule: %w", err)
}
if ok {
return nil, fmt.Errorf("rule already exists")
}

if err := m.iptablesClient.Append("filter", chain, specs...); err != nil {
if err := m.iptablesClient.Append(tableFilter, chain, specs...); err != nil {
return nil, err
}

if err := m.iptablesClient.Append(tableMangle, chainRTPRE, mangleSpecs...); err != nil {
log.Errorf("failed to add mangle rule: %v", err)
mangleSpecs = nil
}

rule := &Rule{
ruleID: uuid.New().String(),
specs: specs,
ipsetName: ipsetName,
ip: ip.String(),
chain: chain,
ruleID: uuid.New().String(),
specs: specs,
mangleSpecs: mangleSpecs,
ipsetName: ipsetName,
ip: ip.String(),
chain: chain,
}

m.updateState()
Expand Down Expand Up @@ -190,6 +207,12 @@ func (m *aclManager) DeletePeerRule(rule firewall.Rule) error {
return fmt.Errorf("failed to delete rule: %s, %v: %w", r.chain, r.specs, err)
}

if r.mangleSpecs != nil {
if err := m.iptablesClient.Delete(tableMangle, chainRTPRE, r.mangleSpecs...); err != nil {
log.Errorf("failed to delete mangle rule: %v", err)
}
}

m.updateState()

return nil
Expand Down Expand Up @@ -310,17 +333,10 @@ func (m *aclManager) seedInitialEntries() {
func (m *aclManager) seedInitialOptionalEntries() {
m.optionalEntries["FORWARD"] = []entry{
{
spec: []string{"-m", "mark", "--mark", fmt.Sprintf("%#x", nbnet.PreroutingFwmarkRedirected), "-j", chainNameInputRules},
spec: []string{"-m", "mark", "--mark", fmt.Sprintf("%#x", nbnet.PreroutingFwmarkRedirected), "-j", "ACCEPT"},
position: 2,
},
}

m.optionalEntries["PREROUTING"] = []entry{
{
spec: []string{"-t", "mangle", "-i", m.wgIface.Name(), "-m", "addrtype", "--dst-type", "LOCAL", "-j", "MARK", "--set-mark", fmt.Sprintf("%#x", nbnet.PreroutingFwmarkRedirected)},
position: 1,
},
}
}

func (m *aclManager) appendToEntries(chainName string, spec []string) {
Expand Down Expand Up @@ -377,7 +393,7 @@ func filterRuleSpecs(ip net.IP, protocol, sPort, dPort string, action firewall.A
if dPort != "" {
specs = append(specs, "--dport", dPort)
}
return append(specs, "-j", actionToStr(action))
return specs
}

func actionToStr(action firewall.Action) string {
Expand Down
7 changes: 4 additions & 3 deletions client/firewall/iptables/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ type Rule struct {
ruleID string
ipsetName string

specs []string
ip string
chain string
specs []string
mangleSpecs []string
ip string
chain string
}

// GetRuleID returns the rule id
Expand Down
Loading

0 comments on commit eb2ac03

Please sign in to comment.