Block luci access from all zones except one

Hi,

I'm using OpenWRT 19.07 on my WR1043nd v1, I have multiple firewall zones configured( WAN , LAN, Guests, IoT devices, etc..). Now I want to block my router administration from all zones but my trusted LAN.

I tried the following rules but got blocked everywhere with them, so I need some help.

config rule
        option name 'Admin'
        option target 'ACCEPT'
        option proto 'tcp'
        option dest_port '22 80 443'
        option src 'lan'

config rule
        option src '*'
        option name 'Admin'
        option proto 'tcp'
        option target 'REJECT'
        option dest_port '22 80 443'

Thank you

Well, found the problem I think.
Iptables rules generated from firewall config file are not in the correct order. They are being generated like this:

iptables -A INPUT -p tcp -m tcp --dport 22-m comment --comment "!fw3: Admin" -j reject
iptables -A INPUT -p tcp -m tcp --dport 80 -m comment --comment "!fw3: Admin" -j reject
iptables -A INPUT -p tcp -m tcp --dport 443 -m comment --comment "!fw3: Admin" -j reject
iptables -A zone_lan_input -p tcp -m tcp --dport 22-m comment --comment "!fw3: Admin" -j ACCEPT
iptables -A zone_lan_input -p tcp -m tcp --dport 80 -m comment --comment "!fw3: Admin" -j ACCEPT
iptables -A zone_lan_input -p tcp -m tcp --dport 443 -m comment --comment "!fw3: Admin" -j ACCEPT

There is an easier way. In your zone definition, set input to reject (or drop). That will block all access to the router from that zone. You’ll probably want to add accept dhcp and dns - those are traffic rules applied to your non trusted networks.

Here's an example:

config zone
	option network 'Guest'
	option forward 'REJECT'
	option name 'guest'
	option output 'ACCEPT'
	option input 'REJECT'

config forwarding
	option dest 'wan'
	option src 'guest'

config rule
	option dest_port '67-68'
	option src 'guest'
	option name 'Guest DHCP'
	option target 'ACCEPT'
	option proto 'tcp udp'

config rule
	option dest_port '53'
	option src 'guest'
	option name 'Guest DNS'
	option target 'ACCEPT'
	option proto 'tcp udp'

As far as I see this doesn't 'block all zones except one'.
I have a similar setup with at least three zones (IoT, guests, dmz) I want to have only limited access to the router.
I thought of having

  • a rule that blocks all access (like a reject but placeble in the middle of the rules chain)
  • a (or two) rule that opens only the necessary ports (dhcp, dns, ntp) for IPv4 and IPv6

With that I would reject all access (except for explicitely allowed traffic) on the WAN and vpn connections from outside.
I would then allow with rule two necessary acces on all interfaces
And then set reject on all connection from 'unsecure' zones (wan, vpn, dmz).

Would that work or would that be overkill?

You are right, my example only blocks one zone. You'd have to make the 'reject' changes to each zone, and possibly create a set of rules for each zone that allow the specified services. I have never tried to build a firewall rule like this with multiple source zones, but if I get a moment, I may experiment to see if it is allowed by LuCI/UCI.

The reason I suggested this particular arrangement, though, is because it inherently blocks all access to the router except what is explicitly allowed. Assuming that the goal is to require explicit allowances on the untrusted networks, the advantage here is that the rules don't have to be updated to block any additional services that might be added (say you added a file sharing service, VPN, or other local services) -- they would be blocked by default unless you make a rule to allow it. Further, it avoids order-dependent rules since the default action of reject is always the last rule would match only when no corresponding accept rules are established. This should make it more secure and less prone to error. (This is not to say that method in the first post is wrong or undesirable -- provided the instantiation order works properly, it is a valid approach; I just prefer the default reject method).

EDIT: I tested applying multiple zones to a given rule -- no dice. However, for 'universal' services like DHCP and dns, you could just use "any zone" to achieve the same result for all networks and zones. Then, if necessary, create zone-specific rules where appropriate.

You need to swap the rules. First REJECT, then ACCEPT.

1 Like

Hi, thanks for your suggestions.
Sorry if I dont write much, English is not my primary language.

Ended up with this for each zone

config zone
        option name 'dmz'
        option network 'dmz'
        option output 'ACCEPT'
        option forward 'REJECT'
        option input 'DROP'

config forwarding
        option dest 'wan'
        option src 'dmz

config rule
        option dest_port '53 67 68'
        option src 'dmz'
        option target 'ACCEPT'
        option proto 'tcp udp'
        option name 'Allow DHCP DNS'

After some testing it looks it's doing what I want.

1 Like

First of all, don't use drop on input for internal zones (makes finding errors realy difficult). Shouldn't use it either for external interfaces. It's no advantage over reject.

This now works for dmz. If I now would like to have this rule for more than one zone?

If I use 'any zone', wouldn't that include WAN zone?

I have roughly four kind of zones:

  • a wan zone (DHCP4, DHCP6 (disabled), 6on4 tunnel)
  • a (secure) LAN zone
  • three vpn connection as incomming zones
  • other insecure local zones (DMZ, IoT, MAIL, GUEST)

Using REJECT as default on WAN zone and VPN zones works well. Only explicitely opened forwards shall be possible and no input to the router itself.

For the internal zones and the one VPN zone that is the incoming connection for my mobile devices I need access to the router for ntp, DNS, DHCP (ipv4 and IPv6) and the control stuff with ping, RA, etc ... So I would like to have a rule for this (or two seperate for IPv4 and IPv6 due to different ports for RA, etc). As it wouldn't be a problem to 'open' these ports also on the secure zones (LAN), I would need that rule for all zones except WAN and two of the VPN zones.

Having 5 zones with IPv4 and IPv6 I end up with 10 traffic rules? No easier way?

You could declare a rule with src '*' (any zone) and then restrict the possible subnets:

list src_ip 10.0.0.0/8
list src_ip 192.168.0.0/16
list src_ip fc00::/7

Seems to be the only way.
Hope that works with changing public prefix (not listing this one in the rule).

Yes, that is true. But DHCP server and DNS are theoretically disabled on those interfaces, so those ports should be dead-end. I think that @jow's advice is good if you do want to do the src '*' option.

Personally, though, creating the relevant per-zone traffic rules doesn't seem overly cumbersome to me, and that is the way I have done it in the past.

I'll have a look on doing it per zone. Looking on what iptables rules are created form the firewall traffic rules defined with usi, it might even reduce the lenght of chains pakets are going trough if I create rules per zone. Using src places it in the input chain before all zone rules ...