netconfigd: do not hardcode 10.0.0.0/24 netmask for hairpinning

related to https://github.com/rtr7/router7/issues/53
This commit is contained in:
Michael Stapelberg 2025-01-12 10:29:42 +01:00
parent af27264a03
commit 07325dde93
2 changed files with 20 additions and 9 deletions

View File

@ -148,13 +148,13 @@ func goldenNftablesRules(additionalForwarding bool) string {
add := "" add := ""
if additionalForwarding { if additionalForwarding {
add = ` add = `
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 != 192.168.42.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 router7-portforwardings { chain router7-portforwardings {
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 != 192.168.42.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 != 192.168.42.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 != 192.168.42.0/24 fib daddr type 2 udp dport 53 dnat to 192.168.42.99:53
} }
chain prerouting { chain prerouting {

View File

@ -583,7 +583,7 @@ func nfifname(n string) []byte {
// //
// Instead, it uses “fib daddr type local” to match all locally-configured IP // Instead, it uses “fib daddr type local” to match all locally-configured IP
// addresses and then excludes the loopback and LAN IP addresses. // addresses and then excludes the loopback and LAN IP addresses.
func matchUplinkIP() []expr.Any { func matchUplinkIP(lan0ip net.IP) []expr.Any {
return []expr.Any{ return []expr.Any{
// [ payload load 4b @ network header + 16 => reg 1 ] // [ payload load 4b @ network header + 16 => reg 1 ]
&expr.Payload{ &expr.Payload{
@ -626,7 +626,9 @@ func matchUplinkIP() []expr.Any {
&expr.Cmp{ &expr.Cmp{
Op: expr.CmpOpNeq, Op: expr.CmpOpNeq,
Register: 1, Register: 1,
Data: []byte{0x0a, 0x00, 0x00, 0x00}, // Turn the lan0 IP address (e.g. 192.168.42.1)
// into a netmask like 192.168.42.0/24.
Data: []byte{lan0ip[0], lan0ip[1], lan0ip[2], 0},
}, },
// [ fib daddr type => reg 1 ] // [ fib daddr type => reg 1 ]
@ -644,7 +646,7 @@ func matchUplinkIP() []expr.Any {
} }
} }
func portForwardExpr(ifname string, proto uint8, portMin, portMax uint16, dest net.IP, dportMin, dportMax uint16) []expr.Any { func portForwardExpr(lan0ip net.IP, proto uint8, portMin, portMax uint16, dest net.IP, dportMin, dportMax uint16) []expr.Any {
var cmp []expr.Any var cmp []expr.Any
if portMin == portMax { if portMin == portMax {
cmp = []expr.Any{ cmp = []expr.Any{
@ -671,7 +673,7 @@ func portForwardExpr(ifname string, proto uint8, portMin, portMax uint16, dest n
}, },
} }
} }
ex := append(matchUplinkIP(), ex := append(matchUplinkIP(lan0ip),
// [ meta load l4proto => reg 1 ] // [ meta load l4proto => reg 1 ]
&expr.Meta{Key: expr.MetaKeyL4PROTO, Register: 1}, &expr.Meta{Key: expr.MetaKeyL4PROTO, Register: 1},
// [ cmp eq reg 1 0x00000006 ] // [ cmp eq reg 1 0x00000006 ]
@ -781,6 +783,15 @@ func applyPortForwardings(dir, ifname string, c *nftables.Conn, nat *nftables.Ta
return err return err
} }
lan0ip, err := LinkAddress(dir, "lan0")
if err != nil {
return err
}
lan0ip = lan0ip.To4()
if got, want := len(lan0ip), net.IPv4len; got != want {
return fmt.Errorf("lan0 does not have an IPv4 address configured: len %d != %d", got, want)
}
for _, fw := range cfg.Forwardings { for _, fw := range cfg.Forwardings {
for _, proto := range strings.Split(fw.Proto, ",") { for _, proto := range strings.Split(fw.Proto, ",") {
var p uint8 var p uint8
@ -805,7 +816,7 @@ func applyPortForwardings(dir, ifname string, c *nftables.Conn, nat *nftables.Ta
c.AddRule(&nftables.Rule{ c.AddRule(&nftables.Rule{
Table: nat, Table: nat,
Chain: prerouting, Chain: prerouting,
Exprs: portForwardExpr(ifname, p, min, max, net.ParseIP(fw.DestAddr), dmin, dmax), Exprs: portForwardExpr(lan0ip, p, min, max, net.ParseIP(fw.DestAddr), dmin, dmax),
}) })
} }
} }