FirewallD is a dynamically managed firewall that provides support for IPv4 and IPv6 firewall rules and firewall zones that is available on RHEL 7 based servers. It is a direct replacement for iptables
and works with the kernel’s netfilter
code.
In this article will take a brief look at managing the firewall on CentOS 7 using the firewall-cmd
command.
Checking if FirewallD is running
The first step is to check whether FirewallD is installed and running. This can be done via systemd
by running the following:
$ systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2016-03-10 15:07:00 UTC; 1min 30s ago
...
Alternatively, you can check using the firewall-cmd
tool:
$ firewall-cmd --state
running
Managing zones
FirewallD operates using the concept of zones
where a zone defined the level of trust used for a connection. You can split different network interfaces into different zones in order to apply specific firewall rules per interface or you can use one zone for all interfaces.
Out of the box, everything is done on the default public
zone, but there are several other pre-configured zones that can be applied too.
Listing all available zones
You may need to get a list of all of the available zones, of which there are several out of the box. Again, this can be done using firewall-cmd
:
$ firewall-cmd --get-zones
block dmz drop external home internal public trusted work
Checking the default zone
You can discover the default zone that’s currently configured using firewall-cmd
:
$ firewall-cmd --get-default-zone
public
If you wish to change the default zone (for example, to home
), this can be done by running:
$ firewall-cmd --set-default-zone=home
success
This information will be reflected in the main configuration file, /etc/firewalld/firewalld.conf
. However, it’s recommended that you don’t manually modify this file and instead use firewall-cmd
.
Checking the currently assigned zones
You can get a list of the zones that you’ve got interfaces assigned to by running:
$ firewall-cmd --get-active-zones
public
interfaces: eth0
You can also check the zone of a single interface (eth0
in this case) by running:
$ firewall-cmd --get-zone-of-interface=eth0
public
Creating zones
If the default pre-configured zones don’t quite suit your needs, the easiest way to create a new zone (zone1
) is again via firewall-cmd
:
$ firewall-cmd --permanent --new-zone=zone1
success
After creation, you need to reload:
$ firewall-cmd --reload
success
Applying a zone to an interface
In order to permanently assign a network interface to a zone, you can use firewall-cmd
though remember to include the --permanent
flag to persist the change. If using NetworkManager
, you should also be sure to use nmcli
to set the connection zone.
$ firewall-cmd --permanent --zone=internal --change-interface=eth1`
success
Getting the permanent configuration of a zone
In order to check the permanent configuration of a zone (public
in this case) including the assigned interfaces, allowed services, port settings and more, run:
$ firewall-cmd --permanent --zone=public --list-all
public (default)
interfaces:
sources:
services: dhcpv6-client ssh
ports:
masquerade: no
forward-ports:
icmp-blocks:
rich rules:
Managing services
Once you have assigned and configured your required zones, you can start adding services to zones. Services describe the protocols and ports that can be accessed for a zone.
Listing existing services
A number of common services are pre-configured within firewalld. These can be listed:
$ firewall-cmd --get-services
RH-Satellite-6 amanda-client bacula bacula-client dhcp dhcpv6 dhcpv6-client dns freeipa-ldap freeipa-ldaps freeipa-replication ftp high-availability http https imaps ipp ipp-client ipsec iscsi-target kerberos kpasswd ldap ldaps libvirt libvirt-tls mdns mountd ms-wbt mysql nfs ntp openvpn pmcd pmproxy pmwebapi pmwebapis pop3s postgresql proxy-dhcp radius rpc-bind rsyncd samba samba-client smtp ssh telnet tftp tftp-client transmission-client vdsm vnc-server wbem-https
You can also get a list of the services enabled for the default zone:
$ firewall-cmd --list-services
dhcpv6-client ssh
Adding a service to a zone
You can enable a given service for a zone (public
) permanently using the --add-service
flag:
$ firewall-cmd --permanent --zone=public --add-service=http
success
And then reload the current firewall session:
$ firewall-cmd --reload
success
Then, to verify it was added:
$ firewall-cmd --zone=public --list-services
dhcpv6-client http ssh
Removing a service from a zone
You can remove a given service for a zone (public
) permanently using the --remove-service
flag:
$ firewall-cmd --permanent --zone=public --remove-service=http
success
And then reload the current firewall session:
$ firewall-cmd --reload
success
Then, to verify it was added:
$ firewall-cmd --zone=public --list-services
dhcpv6-client ssh
Adding/removing multiple services from a zone
You can add or remove multiple services (for example, http
and https
) from a zone either one at a time, or all at once by wrapping the desired service names in curly braces ({
, }
):
$ firewall-cmd --permanent --zone=public --add-service=
success
$ firewall-cmd --permanent --zone=public --list-services
dhcpv6-client http https ssh
Creating new services
Sometimes you may need to add new custom services – for example if you’ve changed the port for the SSH daemon. Services are defined using trivial XML files, with the default files being found in /usr/lib/firewalld/services
:
$ tree /usr/lib/firewalld/services
/usr/lib/firewalld/services
├── amanda-client.xml
├── bacula-client.xml
├── bacula.xml
├── dhcpv6-client.xml
├── dhcpv6.xml
├── dhcp.xml
├── dns.xml
├── freeipa-ldaps.xml
├── freeipa-ldap.xml
├── freeipa-replication.xml
├── ftp.xml
├── high-availability.xml
├── https.xml
├── http.xml
...
The easiest way to create a new service is to copy one of these existing service files and modifying it. Custom services should reside in /etc/firewalld/services
. For example, to customize the SSH service:
$ cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/ssh-custom.xml
The contents of this copied file should look like:
$ cat /etc/firewalld/services/ssh-custom.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>SSH</short>
<description>Secure Shell (SSH) is a protocol for logging into and executing commands on remote machines. It provides secure encrypted communications. If you plan on accessing your machine remotely via SSH over a firewalled interface, enable this option. You need the openssh-server package installed for this option to be useful.</description>
<port protocol="tcp" port="22"/>
</service>
In order to change the port, you should change the short name for the service, and the port. You could also change the description if you desire, but this is just extra metadata that could be used by a user interface or another application. In this example, I’m changing the port to 1234:
$ nano /etc/firewalld/services/ssh-custom.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>SSH-Custom</short>
<description>Secure Shell (SSH) is a protocol for logging into and executing commands on remote machines. It provides secure encrypted communications. If you plan on accessing your machine remotely via SSH over a firewalled interface, enable this option. You need the openssh-server package installed for this option to be useful.</description>
<port protocol="tcp" port="1234"/>
</service>
Once saved, you will need to reload the firewall and then you can apply your rule to your zone:
$ firewall-cmd --reload
success
$ firewall-cmd --permanent --zone=public --add-service=ssh-custom
success
Port management
In addition to using services, you can also manually allow ports by protocol. To allow the TCP port 7777
for the public
zone:
$ firewall-cmd --permanent --zone=public --add-port=7777/tcp
success
You can also add a port range:
$ firewall-cmd --permanent --zone=public --add-port=7000-8000/tcp
success
To remove (and thus deny) TCP port 7777
for the public
zone:
$ firewall-cmd --permanent --zone=public --remove-port=7777/tcp
success
You can also list the currently allowed ports for a given zone (public
) after reloading the current firewall session:
$ firewall-cmd --zone=public --list-ports
7000-8000/tcp
Enabling FirewallD
Once you’ve configured the firewall to your liking, you should be sure to enable it via systemd in order to ensure it starts at startup:
$ systemctl enable firewalld
Conclusion
There are a great deal many more settings and options within FirewallD, such as port forwarding, masquerading and communicating with the firewall via D-Bus. Hopefully this guide has helped you grasp the basics however and has given you the tools to get started with firewalling off your server. Some additional reading below will help you get the most out of your firewall.
- Using Fail2ban with FirewallD – Fedora Wiki
- FirewallD – Fedora Wiki
- Introduction to FirewallD – RedHat 7 Security Guide
Want to contribute?
You could earn up to $300 by adding new articles
Suggest an update
Request an article