Introduction: FirewallD vs IPtables
Instead of playing around with IPtables (too complex at times), as an alternative you can use firewalld, a very useful (wellknown) firewall management tool for Linux OS. It basically acts as a front-end for the Linux kernel’s netfilter framework / iptables.
Compared to iptables, firewalld offers a somewhat simplifed syntax (using names, removing dependance on the order of statements).
Further on, comparing it to Uncomplicated Firewall (ufw), they both come with pre-defined rules for common services/protocols. They’re using independed formats that are not interoperable with each other. FirewallD uses XML, while ufw saves its rules to plain text files. Both are relatively straight-forward but inexperienced users or the ones who don’t want to configure a firewall but need one, might prefer ufw over firewalld due to shorter and self-explanatory syntax (if nothing else).
FirewallD Features:
- Complete D-Bus API
- IPv4, IPv6, bridge and ipset support
- IPv4 and IPv6 NAT support
- Firewall zones
- Predefined list of zones, services and icmptypes
- Simple service, port, protocol, source port, masquerading, port forwarding, icmp filter, rich rule, interface and source address handlig in zones
- Simple service definition with ports, protocols, source ports, modules (netfilter helpers) and destination address handling
- Simple log of denied packets
- Rich Language for more flexible and complex rules in zones
- Timed firewall rules in zones
- Direct interface
- Lockdown: Whitelisting of applications that may modify the firewall
- Automatic loading of Linux kernel modules
- Integration with Puppet
- Command line clints for online and offline configuration
- Graphical configuration tool using gtk3
- Applet using Qt4
FirewallD Install
Textbook/Straightforward Install:
$ apt install firewalld
Start it, enable on boot, check the firewalld state and status:
$ sudo systemctl start firewalld
$ sudo systemctl enable firewalld
$ sudo firewall-cmd --state
$ sudo systemctl status firewalld
To stop it and disable it:
$ sudo systemctl stop firewalld
$ sudo systemctl disable firewalld
Firewall-cmd is the primary command line tool for firewalld. It offers a vast number of options (see complete list with firewall-cmd --help
).
Configuration files:
/usr/lib/firewalld/
: default configuration/etc/firewalld/
: system configuration (these overwrite a default conf)
Firewalld Zones
A lot of talk on groups of rules called “zones”. They’re basicaly rulesets for various trust levels, and they can be tied to a different network interfaces (by default, interface is attached to a default zone). It’s a good and flexible solution. For instance, you could have a strict rules in place for public WiFi, but more lax for home environment. As mentioned here, the list of available zones (from untrusted to trusted):
drop
: Any incoming network packets are dropped, there is no reply. Only outgoing network connections are possible.block
: Any incoming network connections are rejected with an icmp-host-prohibited message for IPv4 and icmp6-adm-prohibited for IPv6. Only network connections initiated within this system are possible.public
: For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.external
: For use on external networks with masquerading enabled especially for routers. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.dmz
: For computers in your demilitarized zone that are publicly-accessible with limited access to your internal network. Only selected incoming connections are accepted.work
: For use in work areas. You mostly trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.home
: For use in home areas. You mostly trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.internal
: For use on internal networks. You mostly trust the other computers on the networks to not harm your computer. Only selected incoming connections are accepted.trusted
:- All network connections are accepted.
You have a freedom to alter existing rules or create new zones.
Basic FirewallD commands
Check current rules:
$ sudo firewall-cmd --list-all
public (default)
interfaces:
sources:
services: ssh
ports:
protocols:
masquerade: no
forward-ports:
icmp-blocks:
rich rules:
--permanent
: persist rules against server reboots--reload
: reload the rules. Even after enabling certain port/service, this step might be required.
Firewalld Zones (Basic Commands)
Check/manage zones:
$ sudo firewall-cmd --get-default-zone
$ sudo firewall-cmd --set-default-zone=work
$ sudo firewall-cmd --get-active-zones
Check specific zone (--zone
):
$ sudo firewall-cmd --zone=work --list-all
Change zone (--change-interace
):
$ sudo firewall-cmd --zone=work --change-interface=eth1
To define your own zone, you have to add it permanently to firewall conf (don’t forget to --reload
):
$ sudo firewall-cmd --permanent --new-zone=CustomZone
Check if it’s present in your configuration:
$ sudo firewall-cmd --permanent --get-zones
As a result, you’re probably going to see something like:
block dmz drop external home internal public trusted work CustomZone
Next, you need to add services to that zone or change interface:
$ sudo firewall-cmd --zone=CustomZone --add-service={ssh,http...} --permanent
$ sudo firewall-cmd --zone=CustomZone --change-interface=eth0 --permanent
Not sure if always necessary, but you could restart both network
and firewalld
services (systemctl).
Firewalld Services
You can add certain services to zones. To get a list:
$ sudo firewall-cmd --get-services
amanda-client amanda-k5-client bacula bacula-client ceph ceph-mon dhcp dhcpv6 dhcpv6-client dns docker-registry dropbox-lansync freeipa-ldap freeipa-ldaps freeipa-replication ftp high-availability http https imap imaps ipp ipp-client ipsec iscsi-target kadmin kerberos kpasswd ldap ldaps libvirt libvirt-tls mdns mosh mountd ms-wbt mysql nfs ntp openvpn pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy proxy-dhcp ptp pulseaudio puppetmaster radius rpc-bind rsyncd samba samba-client sane smtp smtps snmp snmptrap squid ssh synergy syslog syslog-tls telnet tftp tftp-client tinc tor-socks transmission-client vdsm vnc-server wbem-https xmpp-bosh xmpp-client xmpp-local xmpp-server
For more details on services check /usr/lib/firewalld/services
Enable service(s) permanently (--permanent
):
$ sudo firewall-cmd --add-service=http --permanent
$ sudo firewall-cmd --add-service={http, https} --permanent
To define your own service, use the structure from some of the already existing services (copy and adjust, from /usr/lib/firewalld/services
to /etc/firewalld/services
). Sample http.xml
:
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>WWW (HTTP)</short>
<description>HTTP is the protocol used to serve Web pages. If you plan to make your Web server publicly available, enable this option. This option is not required for viewing pages locally or developing Web pages.</description>
<port protocol="tcp" port="80"/>
</service>
For instance, for a custom “proxy” service we would convert that http.xml
to cproxy.xml
and adjust the content:
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>Proxy(Type1)</short>
<description>Custom proxy type</description>
<port protocol="tcp" port="68000"/>
</service>
Reload the service to get access to it ( firewall-cmd --reload
)
Custom Firewalld Configuration
Add a custom TCP port:
$ sudo firewall-cmd --add-port=8080/tcp --permanent
$ sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent
$ sudo firewall-cmd --list-all
public (default)
interfaces:
sources:
services: http https ssh
ports: 8080/tcp
protocols:
masquerade: no
forward-ports:
icmp-blocks:
rich rules:
Enable port on a specific zone:
sudo firewall-cmd --zone=custom_zone --add-port=8080/tcp --permanent
Work with specific interface:
sudo firewall-cmd --get-zone-of-interface=eth0
sudo firewall-cmd --zone= --add-interface=eth0 --permanent
Firewalld Rich Rules
For more details check man firewalld.richlanguage
in your terminal.
Allow all IPv4 traffic from host 192.168.1.100:
$ sudo firewall-cmd --zone=public --add-rich-rule 'rule family="ipv4" source address=192.168.1.100 accept'
Deny IPv4 traffic (tcp) from host 192.168.1.100 (port 22):
$ sudo firewall-cmd --zone=public --add-rich-rule 'rule family="ipv4" source address="192.168.1.100" port port=22 protocol=tcp reject'
Allow access to a port from specific subnet:
$ sudo firewall-cmd --add-rich-rule 'rule family="ipv4" service name="ssh" source address="192.168.1.100/32" accept' --permanent
List rich rules:
$ firewall-cmd --list-rich-rules
FirewallD Port forwarding
To forward port to a different server, active masquerade:
$ sudo firewall-cmd --add-masquerade --permanent
Port forward to a different port within same server ( 22 > 2022):
$ sudo firewall-cmd --add-forward-port=port=22:proto=tcp:toport=2022 --permanent
Forward to the same port on a different server (local:22 > 192.168.1.66:22):
$ sudo firewall-cmd --add-forward-port=port=22:proto=tcp:toaddr=192.168.2.66 --permanent
Forwarding to a different port on a different server (local:6800 > 10.1.1.32:7100)
$ sudo firewall-cmd --add-forward-port=port=6800:proto=tcp:toport=70100:toaddr=10.1.1.32 --permanent
To remove rules:
$ sudo firewall-cmd --zone-public --remove-masquerade
Conclusion
FirewallD and accompanying utility firewall-cmd is a neat tool to have in your SysAdmin toolset. There were situations in which admins (especially new ones) by accident locked themselves out of the system (ssh), due to IPTables being too complex. FirewallD can make someone’s life a bit easier. To avoid making a mess, people generaly agree not to use iptables in combination with firewalld, so choose either one.