nftables forwarding from wlan0 to eth0, but nothing happens
I have a Raspberry Pi that's connected to a wireless router with wlan0, and there's a server that's connected to the eth0. Both these connections work fine.
The eth0 between Pi and the server is statically configured so that Pi's eth0 has IP 192.168.3.23/24 and the server has IP 192.168.3.200/24. Pi's wlan0 has IP of 192.168.1.131/24.
Now, I'm trying to do forwarding so that when connecting Pi's port 88, it forwards to the server behind it. I have forwarding enabled as per sysctl -a | grep forward
:
net.ipv4.conf.all.bc_forwarding = 0
net.ipv4.conf.all.forwarding = 1
net.ipv4.conf.all.mc_forwarding = 0
net.ipv4.conf.default.bc_forwarding = 0
net.ipv4.conf.default.forwarding = 1
net.ipv4.conf.default.mc_forwarding = 0
net.ipv4.conf.eth0.bc_forwarding = 0
net.ipv4.conf.eth0.forwarding = 1
net.ipv4.conf.eth0.mc_forwarding = 0
net.ipv4.conf.lo.bc_forwarding = 0
net.ipv4.conf.lo.forwarding = 1
net.ipv4.conf.lo.mc_forwarding = 0
net.ipv4.conf.wlan0.bc_forwarding = 0
net.ipv4.conf.wlan0.forwarding = 1
net.ipv4.conf.wlan0.mc_forwarding = 0
net.ipv4.ip_forward = 1
net.ipv4.ip_forward_update_priority = 1
net.ipv4.ip_forward_use_pmtu = 0
I also have nftables
configured as such:
table ip nat {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
tcp dport { 88, 443 } dnat to 192.168.3.200
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
}
}
AFAIK this should forward TCP ports 88 and 443 to the server at 192.168.3.200, but nothing happens. If I do curl http://192.168.1.131:88
, the request just hangs indefinitely. The nftables rule is doing something, though, because if I flush the ruleset, the requests are denied immediately.
Am I missing something here?
Your NAT rules fail to specify the interface where packets come in (for DNAT or go out (for SNAT) thus they are applying to all routed traffic in both directions, which is not what you want.
You at least need to specify the incoming interface for DNAT to work properly. For example:
iif wlan0 tcp dport { 88, 443 } dnat to 192.168.3.200
You're missing the outbound masquerade rule entirely from your postrouting
chain. For example:
oif wlan0 masquerade
With destination NAT, only the destination is rewritten. The source is left untouched, so any packages arriving at the server will have a source in 192.168.1.0/24.
Your server probably doesn't have a route to reach 192.168.1.0/24; it only has a route to reach 192.168.3.0/24. So it throws up its hands, and discards the package.
You have two ways to solve this:
- Set the 192.168.3.23 device as default gateway on the server, and apply appropriate firewall settings.
- Use Source NAT as well, and rewrite both source and destination of the packages forwarded.