'(Firewalld Best Practices)
Audience: sysadmins
Firewalld is the replacement for iptables in RedHat-family distros. Like it or not, you’ll probably end up having to wrestle with it at some point. I’ve read several articles describing it with an overview, but most miss out on important subtleties of a tool that’s in production but maybe not friendly enough for prime time. Here you’ll find my guide to getting the most out of Firewalld and avoiding its gotchas.
The commands get long, long, and very long to type frequently. What’s worse is
that it seems you usually need to repeat them with a --permanent
option, which
is painful and easy to forget.
Command line completion
There appears to be a bash completer. I haven’t tried it since I’m fully in Zsh land these days for all activities. It’s not any RH repo I’m aware of anyway, so let’s forget it.
Firewalld supports a poor man’s version of completion. Instead of typing
--zone
, you can just type --zo
or even --z
. You’d have to memorize how
much of each option is unambiguous. So you still have to type --list-all-z
to
get --list-all-zones
.
So aliases are the way to go.
I did write a Zsh completer here, if you want to use it.
Ansible support
TLDR: don’t bother with Ansible for Firewalld. Even if you do, you’ll likely
need to experiment with firewall-cmd
to get your rules right.
Ansible’s new version 2 purports to support most of the full set of options,
including --source
, which I use frequently. Unfortunately, I’ve found this
bleeding edge Ansible to be way too buggy to use. However, you can actually copy
the newest firewalld add-on python module into Ansible v1.9. However, I don’t
think it actually words, whatever version of the module your get.
Really understanding “zones”
You can actually create your own new zone:
Creating a services file
It should look like this:
<?xml version="1.0" encoding="utf-8"?> <service> <short>Some Service</short> <description>Something very descriptive</description> <port port="1234" protocol="tcp"/> <source ip="10.1.10.10" /> </service>
Put it into /usr/lib/firewalld/services
and run fwr
.
Needed aliases
alias fw='firewall-cmd' alias fwz='fw --zone' alias fwp='fw --permanent' alias fwr='fw --runtime-to-permanent' alias fwpz='fw --permanent --zone' alias fwl='fw --list-all-zones'
Gotchas
Sometimes you want to specify a source and port. But it’s not at all obvious
when it’s an AND or OR specification. No one seems to mention this. But I
did find this gem in the firewalld.zone
man page:
The default target is {chain}_ZONE_{zone} and will be used if the target is not specified. If other than the default target is used, all settings except interface and source are ignored, because the first rule created in firewall for this zone is 'jump to target'.
To discover all the man pages, in Zsh do man firewalld«tab»
firewalld firewalld.lockdown-whitelist firewalld.conf firewalld.richlanguage firewalld.dbus firewalld.service firewalld.direct firewalld.zone firewalld.icmptype firewalld.zones