The Upcoming v1.0.0
Introduction and Motivations
Firewalld is about to have its first major version bump. This signifies that there are non-compatible (breaking) changes being introduced. There are many motivations for these changes. Each of which will be outlined in this post.
Many of these changes are about strengthening the zone
concept in firewalld.
There were many cases were zones almost, but not quite behaved as expected.
The end result is that features enabled in a zone
now apply almost
exclusively to traffic that is destined to the host running firewalld. For
anything else, e.g. forward filtering, a
policy should be
used.
Dropped python2 support
Python2 is no longer supported. This support has been dropped everywhere: source code, documentation, build, CI, packaging, etc. Python2 went EOL as of January 1, 2020.
Dropping python2 allows us to take advantage of some python3 only features:
- static type checking (PEP 484) via mypy
- IP address normalization
- preserve user comments in configuration files
Most distributions were already building firewalld for use with python3.
Reduced dependencies
These are the new set of dependencies:
- ebtables (optional)
- ipset (optional)
- iptables (optional)
- linux >= 5.3
- python3-dbus
- python3-gobject
- python3-nftables >= 0.9.4
Note that ebtables, ipset, and iptables are now optional. firewalld builds and runs without their existence. If iptables is not present then the iptables backend and direct interface will not be usable.
Additionally, the following dependencies have been removed:
Intra-zone forwarding by default
Intra-zone forwarding
has been around since v0.9.0. However, it was disabled by default. In v1.0.0
it will be enabled by default for all shipped and newly created zones. This
includes zones: public
, block
, trusted
, internal
, etc.
This change aligns firewalld with one of the axioms of zone based firewalls. That is, the zone defines the trust level and packets can freely move between interfaces and sources with in the same zone.
This feature can be disabled on a per zone basis.
# firewall-cmd --permanent --zone public --remove-forward
NAT rules moved to inet family
Prior to v1.0.0, firewalld had to duplicate NAT rules in both the ip
and
ip6
families. Enabled by a bump in the minimal Linux requirement, 5.3+,
these have been combined into the inet
family.
There is no longer rule duplication.
This is very significant for ipsets. Prior to this change each ipset and ipset entry had to be duplicated three times. Now there is a single copy. This improves both rule application and execution times.
Note: This change only affects the nftables backend. The iptables backend continues to have rule duplication, but does not have set duplication.
Default target is now similar to reject
In the past users have been
confused about the
differences between default
and reject
values for the --set-target
zone
option. This option defines a catch-all rule for packets at the end of the
zone’s rule set. default
was subtly different and caused all kinds of
unexpected
behavior like zone
drifting. It also caused
some zones to be unexpectedly publicly
accessible.
Now default
is identical to reject
with one caveat: default
allows ICMP
packets.
If you desire the old behavior in which the trusted
zone is publicly
accessible it can be reintroduced via policies.
# firewall-cmd --permanent --new-policy allowForward
# firewall-cmd --permanent --policy allowForward --set-target ACCEPT
# firewall-cmd --permanent --policy allowForward --add-ingress-zone public
# firewall-cmd --permanent --policy allowForward --add-egress-zone trusted
# firewall-cmd --reload
See the commit, f2896e43, for further details.
Policies with positive priority values
Prior to v1.0.0, policies with a positive priority value would apply if and
only if the relevant zones used a --set-target
of default
. With the above
change of “Default target is now similar to reject” these policies are no
longer reachable due to the zone’s chains being terminal. Rule execution no
longer returns to the top-level chains, e.g. forward
.
As such, policies with a positive value have been moved. They now execute
immediately before a zone’s --set-target
catch-all rule. Or said
differently, they are the last thing before the catch-all drop
, reject
, or
accept
rule.
This also has the benefit that policies with a positive priority value are
effective for zones with a --set-target
of drop
, reject
, or accept
.
Prior to v1.0.0 they were not.
ICMP blocks and block inversion only apply to input, not forward
ICMP blocks and ICMP block inversion were a bit odd in that they applied to traffic destined to the host (input) and to any other zone (forward). This is violation of zone concepts. Features added the zone should affect the zone and only the zone. It should not allow packets to propagate to other zones.
Now the following behavior applies:
- ICMP blocks only block ICMP packets destined to the host
- ICMP block inversion only applies to packet destined to the host
ICMP blocks can be applied to forward traffic by using a policy.
# firewall-cmd --permanent --new-policy blockICMP
# firewall-cmd --permanent --policy blockICMP --add-ingress-zone public
# firewall-cmd --permanent --policy blockICMP --add-egress-zone internal
# firewall-cmd --permanent --policy blockICMP --add-icmp-block echo-request
# firewall-cmd --reload
ICMP block inversion can be simulated for forward traffic with a policy as well.
# firewall-cmd --permanent --new-policy blockInversion
# firewall-cmd --permanent --policy blockInversion --add-ingress-zone public
# firewall-cmd --permanent --policy blockInversion --add-egress-zone internal
# firewall-cmd --permanent --policy blockInversion --add-rich-rule='rule priority=100 icmp-type echo-request allow'
# firewall-cmd --permanent --policy blockInversion --add-rich-rule='rule priority=32000 protocol value=icmp drop'
# firewall-cmd --reload
tftp-client service has been removed
Firewalld has support for connection tracker helpers. Helpers are designed to handle protocols that may, as part of the protocol, result in traffic on ports different than the original flow of traffic. Without helpers this traffic would look like a completely new and independent flow of traffic. A canonical example of this is TFTP.
Unfortunately the tftp-client
service never actually worked due to the
connection tracker helper assignment occurring in the wrong place. The
solution is to use the non-client service definition in combination with a
policy for outbound traffic. Then the outbound filtering will assign the
connection tracker helper and TFTP will work as expected.
# firewall-cmd --permanent --new-policy hostTftpTraffic
# firewall-cmd --permanent --policy hostTftpTraffic --add-ingress-zone HOST
# firewall-cmd --permanent --policy hostTftpTraffic --add-egress-zone ANY
# firewall-cmd --permanent --policy hostTftpTraffic --add-service tftp
# firewall-cmd --reload
Due to the fact that it never worked and can never work, the tftp-client
service has been removed. The above should be used instead.
iptables backend is deprecated
Firewalld has had nftables support since v0.6.0. nftables is the actively developed Linux firewall implementation. iptables is stable, but does not receive new features. For this reason the iptables backend has been marked deprecated.
Don’t fret. Deprecation is not removal. iptables support won’t be removed for a long time. It just means the iptables backend is not the primary focus.
Direct interface is deprecated
Policy objects have largely made the direct interface obsolete. The direct interface was mainly used because firewalld lacked forward and output filtering. Since v0.9.0 firewalld has native support for those using a familiar interface. As such the direct interface has limited usefulness.
If the firewalld is lacking features that force you to use the direct interface then please file an issue. Many things can be added with minimal effort via rich rules.
Don’t fret. Deprecation is not removal. The direct interface will not be removed for a long time. It just means its use is discouraged because in most cases policy objects are a better choice.
CleanupModulesOnExit defaults to no
A new configuration option CleanupModulesOnExit
was introduced to avoid
unloading kernel modules when firewalld shuts down. This was done to avoid
issues caused by the
module unloading.
Because CleanupModulesOnExit
defaults to no
it is considered a breaking
change. To get the old behavior it can be set to yes
.
The Exceptions
In the introduction it was mentioned that many of these changes were strengthening the zone concept in firewalld. This section is about the exceptions to the effort. These are are largely in order to maintain compatibility with long standing expectations of other software that integrates with firewalld. For example, libvirt and podman.
With the exception of the following all features added to a zone apply to traffic destined to the host (input).
--set-target
valueaccept
allows forwarding to other zones- zones like
trusted
will allow traffic to be forwarded to other zones - libvirt and podman rely upon this to give virtual machines and containers access to the internet
- zones like
forward-port
- may affect traffic that ingresses a given zone, but is destined for a machine in a different zone. That is, traffic that would be forwarded.
- forward ports are a type of DNAT. They occur in the NAT table during prerouting. At this point in packet processing it’s undetermined if the packet is destined to the host or any other zone. As such the DNAT action may apply to both types of traffic.
masquerade
- affects traffic egressing a given zone
- this is the only feature that when added to a zone applies to the traffic leaving via the zone
- rich rule
mark
andtcp-mss-clamp
actions- similar to forward ports these occur on zone ingress and apply to traffic destined to the host or any other zone.
It’s suggested that new configurations use policies to make use of these features. Using a policy makes it explicit to what kind of traffic the feature is applied.
For example:
# firewall-cmd --permanent --new-policy pppTcpClamp
# firewall-cmd --permanent --policy pppTcpClamp --add-ingress-zone internal
# firewall-cmd --permanent --policy pppTcpClamp --add-egress-zone external
# firewall-cmd --permanent --policy pppTcpClamp --add-rich-rule='rule tcp-mss-clamp'
# firewall-cmd --reload
Conclusion
The firewalld developers are confident that the above changes are necessary to improve the predictability and reliability of firewalld. None of the breaking changes were made lightly. Many are years in the making.