OpenWrt Forum Archive

Topic: The meaning of Firewall > Zone > Forward option (bug?)

The content of this topic has been archived on 30 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

Let's assume I have 3 zones: lan, wan and other. For -t filter -A FORWARD, LuCI creates iptables rules which roughly look like this:

-A delegate_forward -i lanif -j zone_lan_forward
-A delegate_forward -i wanif -j zone_wan_forward
-A delegate_forward -i otherif -j zone_other_forward
-A delegate_forward -j GLOBAL_POLICY

...with each -A zone_..._forward being like this:

-A zone_x_forward -j zone_x_dest_POLICY

POLICY corresponds to the value of the Format option in the LuCI for the corresponding zone (x).

zone_x_dest_POLICY itself looks like this:

-A zone_x_dest_POLICY -o xif -j POLICY

So if we merge all this we get essentially these rules:

-A delegate_forward -i lanif -o lanif -j POLICY_for_lan
-A delegate_forward -i wanif -o wanif -j POLICY_for_wan
-A delegate_forward -i otherif -o otherif -j POLICY_for_other
-A delegate_forward -j GLOBAL_POLICY

The question is: does zone policy affect anything? Can there be a packet that is forwarded from a given interface to the same interface? My understanding is that iptables forwarding always have different input/output interfaces but these rules have -i = -o so they must never match.

(This is what the wiki suggests too: "FORWARD rules for a zone describe what happens to traffic passing between different interfaces in that zone.". wiki.openwrt.org/doc/uci/firewall)

If I am correct then it means the zone's policy will never be applied and the global policy will be in effect instead. I think zone_x_forward is supposed to never return but if its final -j zone_x_dest_POLICY doesn't match then zone_x_forward returns (since it's a user chain) and GLOBAL_POLICY is used instead. This may well be undesired.

Should I post this to the bug tracker?

CHAOS CALMER (15.05, r46767)

(Last edited by hofferen on 27 Feb 2017, 16:56)

...and GLOBAL_POLICY is used instead. This may well be undesired.

I have confirmed this by doing the following: assume there are two different setups: in setup A we forward lan to wan, in setup B we have lan and wan separate.

Setup A:

config defaults
        option input 'REJECT'
        option output 'REJECT'
        option forward 'ACCEPT'

config zone
        option name 'lan'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option network 'lan'
        option forward 'REJECT'

config zone
        option forward 'REJECT'
        option input 'DROP'
        option name 'wan'
        option masq '1'
        option network 'wan wan6'
        option output 'REJECT'

config forwarding
        option dest 'wan'
        option src 'lan'

Setup B is the same except for added conntrack and removed config forwarding:

config defaults
        option input 'REJECT'
        option output 'REJECT'
        option forward 'ACCEPT'

config zone
        option name 'lan'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option network 'lan'
        option forward 'REJECT'
        option conntrack '1'

config zone
        option forward 'REJECT'
        option input 'DROP'
        option name 'wan'
        option masq '1'
        option network 'wan wan6'
        option output 'REJECT'

In my view, forward of lan must override forward of defaults, disabling all fowards for packets originating from lan (because -i = Name  of an interface via which a packet was received - iptables(8)). However, in reality lan still forwards to wan (in fact, this happens for all zones with conntrack) even though there is no forwarding rule.

In other words, because of config defaults > forward = ACCEPT both setups forward lan's traffic to wan no matter what forwarding settings are specified for individual zones.

Surely this is not the intended behaviour?

I believe zone_x_dest_POLICY must be zone_x_src_POLICY - then it will work as expected (apply POLICY at the end of the zone's chain, always).

-A zone_x_forward -j zone_x_src_POLICY

Until this is fixed global policy must never be set to be more permissive than any zone's Forward policy. Or don't use conntrack (but this is easy to break/forget).

(Last edited by hofferen on 27 Feb 2017, 17:33)

Yes, it is interesting. I should pay your attention to option masq, that is also critical in making NAT.

hofferen wrote:

The question is: does zone policy affect anything? Can there be a packet that is forwarded from a given interface to the same interface?

Yes, it does. Yes, it can. That will happen if a host in LAN has the router's IP addr set as default gateway but is assuming a wrong netmask and is trying to talk to someone that is on the same link, bouncing through the router. Unusual, but it can happen and the router will likely issue icmp redirect messages to tell the sender that the destination has a direct route on the link.

Routing from and to the same iface will also happen in NAT loopback connections. IPv6 configuration by the way has many odd possibilities, including clearing a flag in Router Advertisement messages that will tell every host on LAN to always talk to other hosts through the router, even if they are physically on the same link.

But the most frequent scenario where you will be forwarding from and to the same ZONE is when this zone has multiple associated interfaces (e.g. you could have several LAN segments segregated by VLAN configs but associated to the same zone named LAN and you want to allow routing between them, so LAN zone to LAN zone forwarding is what you need).

In my understanding, the general policy setting is applied to ifaces that have not been declared in /etc/config/network. For instance, you may have installed some VPN program that created a tun0 iface but tun0 is not explicitly linked to any virtual interface in OpenWrt and consequently will not be linked to any zone name. In this case, the general policy setting will be applied.

(Last edited by AndreL on 27 Feb 2017, 23:06)

AndreL, his statement is also in the fact, that forwarding from lan to wan is executed even there is no explicit forwarding rule. How?

AndreL, thanks for the examines. I'd say they are all exotic (except maybe for the LAN segments). UCI's firewall framework is supposed to suit most common use cases (think I've read this on the wiki). And for such cases current behaviour is counter-intuitive because as you say:

In my understanding, the general policy setting is applied to ifaces that have not been declared in /etc/config/network.

Exactly, and that's how it doesn't work right now - last rule in the zone chain is only applied in those specific cases you have given examines of, and not applied in most other, common cases (because typically in/out interfaces are different) falling through to the remainder of delegate_... rules.

Hi hofferen and ulmwind,

I see the problem now, where there is no "default deny" rule for zone_xxx_forward chains. So the global policy is being applied to routing between different zones.

I suggest that default policy should be always set to DROP forward and can't think on a scenario where someone wants to accept forwarding from unknown ifaces, except for testing incomplete configurations.

I suggest that default policy should be always set to DROP forward and can't think on a scenario where someone wants to accept forwarding from unknown ifaces, except for testing incomplete configurations.

This is correct and personally I have this global set, too. However, it doesn't entirely fix the problem since a zone's forward policy won't be applied in all cases (it will be applied only in rare cases). So in addition to enforcing global forward's policy (or at least hiding from the LuUI or showing a warning liking to this thread) I suggest fixing each zone's forward's chain catch-all rule (zone_x_src_POLICY instead of zone_x_dest_POLICY) to make it really catch-all.

Also, it's unclear why forwarding works without explicit config forwarding entry (simply enabling conntrack is enough). I haven't dug into it but perhaps there's another bug. Or is it intended behaviour?

(Last edited by hofferen on 28 Feb 2017, 08:53)

So, uh, I'd like some input on this problem. Is this a bug? A misdocumentation? Should I report to the bug tracker? Or it's a "feature"?

...I suggest fixing each zone's forward's chain catch-all rule (zone_x_src_POLICY instead of zone_x_dest_POLICY) to make it really catch-all. ...

It is looks like the forwarding policy was source bound and it had it's own problems. The following commit changed it to be destination bound:

zones: make forward policy destination bound

The zone forwarding policy was installed source bound which resulted
in zones with forward accept policy to allow traffic anywhere while
only traffic between the zones network is supposed to be allowed in this
case.

hxxps://git.lede-project.org/?p=project/firewall3.git;a=commit;h=91953d6a6e90df988f442f53097bd208784a295d

(Last edited by mcsim on 28 Sep 2017, 15:15)

The discussion might have continued from here.