Intra Zone Forwarding
A new feature, intra zone forwarding, is coming to firewalld. This feature allows packets to freely forward between interfaces or sources with in a zone.
Why is it needed?
One axiom of zone based firewalls is that traffic with in a zone can flow from interface (or source) to interface (or source). The zone specifies the trust level of all those interfaces and sources. If they have the same trust level then they can communicate unencumbered. Firewalld has lacked this functionality until now.
What does it look like?
This feature does not bring many CLI additions; only a couple knobs to enable or disable it for the zone.
Let’s say we have our home
zone with two interfaces: dummy1, and
dummy2
# firewall-cmd --zone=home --add-interface=dummy1 --add-interface=dummy2
Now let’s enable intra zone forwarding.
# firewall-cmd --zone=home --add-forward
This results in the following nftables rules being added to the zone.
table inet firewalld {
chain filter_FWDI_home_allow {
oifname "dummy1" accept
oifname "dummy2" accept
}
}
The rules say: if the packet is destined to the any interface in the zone
home
then go ahead and accept it.
If we were to add another interface or source to the home zone then we will see it show up in the ruleset as well.
# firewall-cmd --zone=home --add-source 10.10.10.0/24
And the result:
table inet firewalld {
chain filter_FWDI_home_allow {
oifname "dummy1" accept
oifname "dummy2" accept
ip daddr 10.10.10.0/24 accept
}
}
Doesn’t this already happen?
Some zones use a --set-target
of ACCEPT
. Those zones immediately accept
all forwarded traffic. As such, the new --add-forward
option has no effect
for them.
For all others --set-target
values forwarded traffic is dropped by default.
This includes all stock zones except trusted.
Caveats
When enabled in the default zone, intra zone forwarding can only be applied to the interfaces and sources that have been explicitly added to the current default zone. It can not use a catch-all for all outgoing interfaces as this would allow packets to forward to an interface or source assigned to a different zone.
Default value
By default, all currently shipped zone definitions and user created zones have
forward
disabled. This is done as to not introduce any surprising behavioral
changes.
In the future this may change. It may make sense to enable by default in at least these zones: internal, home, and work.
Contributed By
This feature was initially contributed by github user @danc86 in pull request #586.
firewalld 0.7.4 release
A new release of firewalld, version 0.7.4, is available.
This is a bug fix only release.
However, it does reintroduce the zone drifting bug as a feature. This behavior is disabled by default.
- improvement: build: add an option to disable building documentation
- Typo in firewall-config(1)
- Fix typo in TFTP service description
- doc: README: add note about language translations
- fix: rich: source/dest only matching with mark action
- feat: AllowZoneDrifting config option
- feat: nftables: support AllowZoneDrifting=yes
- feat: ipXtables: support AllowZoneDrifting=yes
- test: verify AllowZoneDrifting=yes
- fix: firewall-offline-cmd: Don’t print warning about AllowZoneDrifting
- fix: add logrotate policy
- fix: tests: regenerate testsuite if …/{cli,python}/*.at changes
- doc: direct: add CAVEATS section
- fix: checkIP6: strip leading/trailing square brackets
- fix: nftables: remove square brackets from IPv6 addresses
- fix: ipXtables: remove square brackets from IPv6 addresses
- fix: nftables: zone dispatch with multidimensional ipsets
- fix: ipset: destroy runtime sets on reload/stop
- fix: port: support querying sub ranges
- fix: source_port: support querying sub ranges
- doc: specify accepted characters for object names
- fix: doc: address copy/paste mistakes in short/description
- fix: configure: atlocal: quote variable values
- fix: nftables: allow set intervals with concatenations
- doc: clarify –set-target values “default” vs “reject”
Source available here:
- Tarball: firewalld-0.7.4.tar.gz
- SHA256: 0d74744e363a72aef1182325dbece54578faf39e7f2d8b377be1be57bb2e242f
- Complete changelog on github: 0.7.3 to 0.7.4
firewalld 0.8.2 release
A new release of firewalld, version 0.8.2, is available.
This is a big fix only release.
However, it does reintroduce the zone drifting bug as a feature. This behavior is disabled by default.
- improvement: build: add an option to disable building documentation
- Typo in firewall-config(1)
- Fix typo in TFTP service description
- doc: README: add note about language translations
- fix: rich: source/dest only matching with mark action
- feat: AllowZoneDrifting config option
- feat: nftables: support AllowZoneDrifting=yes
- feat: ipXtables: support AllowZoneDrifting=yes
- fix: firewall-offline-cmd: Don’t print warning about AllowZoneDrifting
- fix: add logrotate policy
- doc: direct: add CAVEATS section
- fix: checkIP6: strip leading/trailing square brackets
- fix: nftables: remove square brackets from IPv6 addresses
- fix: ipXtables: remove square brackets from IPv6 addresses
- fix: nftables: ipset types using “port”
- fix: nftables: zone dispatch with multidimensional ipsets
- fix: ipset: destroy runtime sets on reload/stop
- fix: port: support querying sub ranges
- fix: source_port: support querying sub ranges
- doc: specify accepted characters for object names
- fix: doc: address copy/paste mistakes in short/description
- fix: configure: atlocal: quote variable values
- fix: nftables: allow set intervals with concatenations
- doc: clarify –set-target values “default” vs “reject”
Source available here:
- Tarball: firewalld-0.8.2.tar.gz
- SHA256: 391a750a2bfb9db1179829a136451daf256660b591d380ce504fd4e896f7d797
- Complete changelog on github: 0.8.1 to 0.8.2
Allowing Zone Drifting
A future release of firewalld will contain a behavioral change that may affect some users. Older version of firewalld had undocumented behavior that has come to be known as zone drifting.
The default value of AllowZoneDrifting
is no. To regain the old, buggy
behavior users can set this to yes.
What is zone drifting?
A user may configure a source-based zoneFoo - a zone to which you’ve added
sources via --add-source
. If zoneFoo uses a --set-target
of default,
then the packets will be allowed to ingress a second interface-based zone. This
includes the catch-all default zone.
This is a result of how previous version of firewalld dispatched packets to zones.
Each dispatch type used to have it’s own dedicated chain.
chain filter_INPUT {
...
jump filter_INPUT_ZONES_SOURCE # The important
jump filter_INPUT_ZONES # parts are here
...
}
chain filter_INPUT_ZONES_SOURCE {
ip6 saddr dead:beef::/54 goto filter_IN_internal
}
chain filter_INPUT_ZONES {
iifname "dummy0" goto filter_IN_trusted
goto filter_IN_public
}
They key bit, as noted by the comment, is that there are two different chains
performing dispatch. One for source-based. One for interface-based. If the
chain filter_IN_internal is non-terminal, as is the case if --set-target
is
default, then packet processing will return to the filter_INPUT chain and
jump to the filter_INPUT_ZONES chain. This means a packet can ingress both
the internal zone and the trusted/public zones.
Why disable it by default?
A tenant of zone based firewalls is that packets ingress one and only one zone. The above is a violation of that. It can cause traffic or services to be allowed unexpectedly.
This can be see by the various bug reports:
For these reasons AllowZoneDrifting
defaults to no.
Slightly different than previous firewalld versions
Even with AllowZoneDrifting
set to yes there is a slight behavioral
difference between previous firewalld versions and current versions. This only
applies to a subset of features; masquerade, forward-port, and helpers. For
these features, zone drifting could occur for any value of --set-target
including ACCEPT, DROP, REJECT even amongst interface-based zones.
This is the cause of the following issues:
It was deemed a security bug by firewalld developers and has no reasonable use
case. As such, it was not carried forward when AllowZoneDrifting
was
featured.
How to re-enable zone drifting?
The firewalld developers strongly discourage enabling zone drifting. It is better to add the necessary services and configuration to the source-based zone.
That being said, if you would like to enable zone drifting it can easily be
done by setting AllowZoneDrifting
to yes in /etc/firewalld/firewalld.conf
and restarting firewalld.
What versions are affected?
The following versions fixed the zone drifting bug and disallowed its occurrence:
- 0.6.5
- 0.7.0
- 0.8.0
AllowZoneDrifting
was introduced in the following versions allowing users to
regain the old behavior.
- 0.7.4
- 0.8.2
- 1.0.0
firewalld 0.7.3 release
A new release of firewalld, version 0.7.3, is available.
This is a bug fix only release.
- fix: src/tests/Makefile: distclean should clean atconfig
- fix: test: use debug output based on autotest variable
- chore: doc: update authors
- fix: tests/functions: canonicalize XML output
- fix: failure to load modules no longer fatal
- fix: don’t probe for available kernel modules
- fix: build: distribute testsuite
- fix: tests: convert nftables fib checks to runtime
- fix: tests: convert probe of nft numeric args to runtime
- fix: tests: convert ip6tables checks to runtime
- fix: tests: convert host ipv6 checks to runtime
- chore: tests: rename IF_IPV6_SUPPORTED to IF_HOST_SUPPORTS_IPV6_RULES
- fix: reload: let NM interface assignments override permanent config
- fix: test: CHECK_NAT_COEXISTENCE: only check for kernel version
- fix: test: direct passthrough: no need to check for dummy module
- fix: test/functions: FWD_END_TEST: improve grep for errors/warnings
- tests: support running in containers, “make check-container”
- tests: add integration tests, e.g. network-manager
Source available here:
- Tarball: firewalld-0.7.3.tar.gz
- SHA256: 414c46202c12334cd5c986214e5e2575d18e743c5531a97ace1c0cd94341c60d
- Complete changelog on github: 0.7.2 to 0.7.3