Block all WAN access on Wi-Fi interface using DD-WRT

I have a dd-wrt router with two Wi-Fi interfaces (ath0, ath1). I want everything that's on ath0 to not have any kind of WAN access. Only LAN (to and from the device).

How would I do this in the easiest and most robust manner?

Before I've tried this using ath1 aswell by adding a virtual AP, a new bridge for the AP and some advanced routing and firewall settings. This was overly complicated though and I figured it should be a lot easier to just use my, unused anyway, ath0 (5GHz) interface for this purpose.

I am using OpenVPN as a client which makes things a bit more complicated. When using iptables firewall with the old approach I would always have to manually re-set the firewall settings because a file in /etc/ is overwriting my rules (-I at the top) because of the VPN, allowing everything WAN access as long as its over the VPN. Because of squashFS I couldn't find a way to prevent that and always having to manually overwrite it after saving settings/rebooting the router isn't so nice. Also I'm not sure if it won't overwrite it again later.

I don't want ath0 to have VPN access either. I can't use iptables with a source IP because it should be for all clients on that SSID/interface and as soon as they connect, so I won't really know an IP in advance.

I've tried looking this up but I couldn't find anything that'd work for my case except for the overly advanced virtual AP/bridge solution.


Solution 1:

Assuming you have also ebtables (or ebtables-nft) in addition to iptables on the router, and that all the (W)LAN interfaces are bridge slaves to the same master (say named bridge0):

ebtables -I INPUT -i ath0 -j mark --set-mark 0xabcd
iptables -I FORWARD -i bridge0 -m mark --mark 0xabcd -j DROP

(Note that the mark value 0xabcd is arbitrary.)

This causes all traffics that comes into the router from the "LAN side" to "stay within" the broadcast domain. The reason is, ebtables' INPUT does not include traffics that goes from a bridge slave/port to another (i.e. L2 forwarding). And for what targets the router itself (that comes from ath0 and is henced marked), we don't want them to be forwarded on L3 (i.e. to be able to go from "LAN" to "WAN"/VPN/...).

As an alternative, you can do it without relying on iptables or packet marking as well:

ebtables -I INPUT -i ath0 -d Unicast -p ip ! --ip-dst $ROUTER_LAN_IP -j DROP

While not tested, -d Unicast is supposed to keep DHCP and so working. If you also need IPv6 (traffics for the router on L3) to work, you probably need/want an extra chain for more exceptions (which will allow you to allow DHCP with another approach as well), like:

ebtables -N ATH0
ebtables -A ATH0 -p ip --ip-dst $ROUTER_LAN_IP -j ACCEPT # unicast
ebtables -A ATH0 -p ip --ip-dport 67 -j ACCEPT # broadcast
ebtables -A ATH0 -p ip ... -j ACCEPT
...
ebtables -A ATH0 -p ip6 ... -j ACCEPT
...
ebtables -A ATH0 -j DROP
ebtables -I INPUT -i ath0 -j ATH0

But as you can see, the latter approach is much more clumsy.

P.S. I have zero experience with all of the WRTs or alike, so I have no idea how one should make xtables rules persistent on them. (To be fair though, AFAIK it's distro-specific anyway even on "typical" Linux distros.)