netconfig: do not re-create nftables ruleset from scratch
The current behavior stomps on the rules that programs like podman or tailscale set up for port forwarding. With this change, we split port forwardings into a separate chain, which allows us to create the ruleset once at startup and then only update the port forwardings specifically (the only dynamic part of router7’s nftables ruleset).
This commit is contained in:
parent
ac71701d8c
commit
f835cdf1d6
@ -151,13 +151,17 @@ func goldenNftablesRules(additionalForwarding bool) string {
|
|||||||
ip daddr != 127.0.0.0/8 ip daddr != 10.0.0.0/24 fib daddr type 2 tcp dport 8045 dnat to 192.168.42.22:8045`
|
ip daddr != 127.0.0.0/8 ip daddr != 10.0.0.0/24 fib daddr type 2 tcp dport 8045 dnat to 192.168.42.22:8045`
|
||||||
}
|
}
|
||||||
return `table ip nat {
|
return `table ip nat {
|
||||||
chain prerouting {
|
chain router7-portforwardings {
|
||||||
type nat hook prerouting priority 0; policy accept;
|
|
||||||
ip daddr != 127.0.0.0/8 ip daddr != 10.0.0.0/24 fib daddr type 2 tcp dport 8080 dnat to 192.168.42.23:9999` + add + `
|
ip daddr != 127.0.0.0/8 ip daddr != 10.0.0.0/24 fib daddr type 2 tcp dport 8080 dnat to 192.168.42.23:9999` + add + `
|
||||||
ip daddr != 127.0.0.0/8 ip daddr != 10.0.0.0/24 fib daddr type 2 tcp dport 8040-8060 dnat to 192.168.42.99:8040-8060
|
ip daddr != 127.0.0.0/8 ip daddr != 10.0.0.0/24 fib daddr type 2 tcp dport 8040-8060 dnat to 192.168.42.99:8040-8060
|
||||||
ip daddr != 127.0.0.0/8 ip daddr != 10.0.0.0/24 fib daddr type 2 udp dport 53 dnat to 192.168.42.99:53
|
ip daddr != 127.0.0.0/8 ip daddr != 10.0.0.0/24 fib daddr type 2 udp dport 53 dnat to 192.168.42.99:53
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chain prerouting {
|
||||||
|
type nat hook prerouting priority 0; policy accept;
|
||||||
|
jump router7-portforwardings
|
||||||
|
}
|
||||||
|
|
||||||
chain postrouting {
|
chain postrouting {
|
||||||
type nat hook postrouting priority 100; policy accept;
|
type nat hook postrouting priority 100; policy accept;
|
||||||
oifname "uplink0" masquerade
|
oifname "uplink0" masquerade
|
||||||
|
@ -876,9 +876,42 @@ func hairpinDNAT() []expr.Any {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const pfChain = "router7-portforwardings"
|
||||||
|
|
||||||
|
// Only update port forwarding if there are existing rules.
|
||||||
|
// This is required to not stomp over podman port forwarding, for example.
|
||||||
|
func updatePortforwardingsOnly(dir, ifname string) error {
|
||||||
|
c := &nftables.Conn{}
|
||||||
|
|
||||||
|
nat, err := c.ListTable("nat")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
chain, err := c.ListChain(nat, pfChain)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("rules already configured, only updating port forwardings")
|
||||||
|
|
||||||
|
c.FlushChain(chain)
|
||||||
|
if err := applyPortForwardings(dir, ifname, c, nat, chain); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
func applyFirewall(dir, ifname string) error {
|
func applyFirewall(dir, ifname string) error {
|
||||||
c := &nftables.Conn{}
|
c := &nftables.Conn{}
|
||||||
|
|
||||||
|
if err := updatePortforwardingsOnly(dir, ifname); err != nil {
|
||||||
|
log.Printf("could not update port forwardings (%v), creating ruleset from scratch", err)
|
||||||
|
} else {
|
||||||
|
return nil // keep existing ruleset
|
||||||
|
}
|
||||||
|
|
||||||
c.FlushRuleset()
|
c.FlushRuleset()
|
||||||
|
|
||||||
nat := c.AddTable(&nftables.Table{
|
nat := c.AddTable(&nftables.Table{
|
||||||
@ -886,6 +919,12 @@ func applyFirewall(dir, ifname string) error {
|
|||||||
Name: "nat",
|
Name: "nat",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
pf := c.AddChain(&nftables.Chain{
|
||||||
|
Name: pfChain,
|
||||||
|
Table: nat,
|
||||||
|
Type: nftables.ChainTypeNAT,
|
||||||
|
})
|
||||||
|
|
||||||
prerouting := c.AddChain(&nftables.Chain{
|
prerouting := c.AddChain(&nftables.Chain{
|
||||||
Name: "prerouting",
|
Name: "prerouting",
|
||||||
Hooknum: nftables.ChainHookPrerouting,
|
Hooknum: nftables.ChainHookPrerouting,
|
||||||
@ -894,6 +933,17 @@ func applyFirewall(dir, ifname string) error {
|
|||||||
Type: nftables.ChainTypeNAT,
|
Type: nftables.ChainTypeNAT,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
c.AddRule(&nftables.Rule{
|
||||||
|
Table: nat,
|
||||||
|
Chain: prerouting,
|
||||||
|
Exprs: []expr.Any{
|
||||||
|
&expr.Verdict{
|
||||||
|
Kind: expr.VerdictJump,
|
||||||
|
Chain: pfChain,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
postrouting := c.AddChain(&nftables.Chain{
|
postrouting := c.AddChain(&nftables.Chain{
|
||||||
Name: "postrouting",
|
Name: "postrouting",
|
||||||
Hooknum: nftables.ChainHookPostrouting,
|
Hooknum: nftables.ChainHookPostrouting,
|
||||||
@ -925,7 +975,7 @@ func applyFirewall(dir, ifname string) error {
|
|||||||
Exprs: hairpinDNAT(),
|
Exprs: hairpinDNAT(),
|
||||||
})
|
})
|
||||||
|
|
||||||
if err := applyPortForwardings(dir, ifname, c, nat, prerouting); err != nil {
|
if err := applyPortForwardings(dir, ifname, c, nat, pf); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user