Skip to content

Commit

Permalink
netconfigd: do not hardcode 10.0.0.0/24 netmask for hairpinning
Browse files Browse the repository at this point in the history
related to #53
  • Loading branch information
stapelberg committed Jan 12, 2025
1 parent af27264 commit 07325dd
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 9 deletions.
8 changes: 4 additions & 4 deletions integration/netconfig/netconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,13 @@ func goldenNftablesRules(additionalForwarding bool) string {
add := ""
if additionalForwarding {
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 {
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 != 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 != 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 != 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 != 192.168.42.0/24 fib daddr type 2 udp dport 53 dnat to 192.168.42.99:53
}
chain prerouting {
Expand Down
21 changes: 16 additions & 5 deletions internal/netconfig/netconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ func nfifname(n string) []byte {
//
// Instead, it uses “fib daddr type local” to match all locally-configured IP
// addresses and then excludes the loopback and LAN IP addresses.
func matchUplinkIP() []expr.Any {
func matchUplinkIP(lan0ip net.IP) []expr.Any {
return []expr.Any{
// [ payload load 4b @ network header + 16 => reg 1 ]
&expr.Payload{
Expand Down Expand Up @@ -626,7 +626,9 @@ func matchUplinkIP() []expr.Any {
&expr.Cmp{
Op: expr.CmpOpNeq,
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 ]
Expand All @@ -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
if portMin == portMax {
cmp = []expr.Any{
Expand All @@ -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 ]
&expr.Meta{Key: expr.MetaKeyL4PROTO, Register: 1},
// [ cmp eq reg 1 0x00000006 ]
Expand Down Expand Up @@ -781,6 +783,15 @@ func applyPortForwardings(dir, ifname string, c *nftables.Conn, nat *nftables.Ta
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 _, proto := range strings.Split(fw.Proto, ",") {
var p uint8
Expand All @@ -805,7 +816,7 @@ func applyPortForwardings(dir, ifname string, c *nftables.Conn, nat *nftables.Ta
c.AddRule(&nftables.Rule{
Table: nat,
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),
})
}
}
Expand Down

0 comments on commit 07325dd

Please sign in to comment.