Wednesday, June 10, 2015

RHEL7 - Introduction to firewalld


Firewalld is the new userland interface in RHEL 7. It replaces the iptables interface and connects to the netfilter kernel code. It mainly improves the security rules management by allowing configuration changes without stopping the current connections.
To know if Firewalld is running, type:
# systemctl status firewalld
firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled)
   Active: active (running) since Tue 2014-06-17 11:14:49 CEST; 5 days ago
or alternatively:
# firewall-cmd --state
Note: If Firewalld is not running, the command displays not running.
If you’ve got several network interfaces in IPv4, you will have to activate ip forwarding.
To do that, paste the following line in the /etc/sysctl.conf file:
Then, activate the configuration:
# sysctl -p
Although Firewalld is the RHEL 7 way to deal with firewalls and provides many improvements,iptables can still be used (but both shouldn’t run at the same time).
You can also look at the iptables rules created by Firewalld with the iptables-save command.

Zone management

Also, a new concept of zone appears: all network interfaces can be located in the same default zone or divided into different ones according to the levels of trust defined. In the latter case, this allows to restrict traffic based on origin zone.
Note: Without any configuration, everything is done by default in the public zone. If you’ve got more than one network interface or use sources (see Source management section below), you will be able to restrict traffic between zones.
To get the default zone, type:
# firewall-cmd --get-default-zone
To get the list of zones where you’ve got network interfaces or sources assigned to, type:
# firewall-cmd --get-active-zones
interfaces: eth0
To get the list of all the available zones, type:
# firewall-cmd --get-zones
block dmz drop external home internal public trusted work
To change the default zone to home permanently, type:
# firewall-cmd --set-default-zone=home
Network interfaces can be assigned to a zone in a temporary (until the next reboot or reload) or in a permanent way. Either way, you don’t need to reload the firewall configuration.
To assign the eth0 network interface temporarily to the internal zone, type:
# firewall-cmd --zone=internal --change-interface=eth0
To assign the eth0 network interface permanently to the internal zone (a file called internal.xmlis created in the /etc/firewalld/zones directory), type:
# firewall-cmd --permanent --zone=internal --change-interface=eth0
To know which zone is associated with the eth0 interface, type:
# firewall-cmd --get-zone-of-interface=eth0
To get the current configuration of the public zone, type:
# firewall-cmd --zone=public --list-all
public (default, active)
  interfaces: eth0
  services: dhcpv6-client ssh
  masquerade: no
  rich rules: 
Note: The previous command displays the current configuration, ie the permanent settings and the temporary ones. To only get the permanent settings, use the –permanent option.
It is also possible to create new zones. To create a new zone (here test), type:
# firewall-cmd --permanent --new-zone=test
# firewall-cmd --reload
Note: Only permanent zones can be created.

Source management

A zone can be bound to a network interface (see above) and/or to a network addressing (called here a source).
Any network packet entering in the network stack is associated with a zone.
The association is done according to the following pattern:
– is the packet coming from a source already bound to a zone? (if yes, it is associated with this zone),
– if not, is the packet coming from a network interface already bound to a zone? (if yes, it is associated with this zone),
– if not, the packet is associated with the default zone.
This way, multiple zones can be defined even on a server with only one network interface!
Caution: To get this feature, Firewalld relies on NetworkManager. This means that if you plan to stop NetworkManager for any reason (for example when building a KVM host), you will have tostop Firewalld and use Iptables instead!
To add a source (here to a zone (here trustedpermanently, type:
# firewall-cmd --permanent --zone=trusted --add-source=
# firewall-cmd --reload
Note1: Use the –remove-source option to delete a previous assigned source.
Note2: Use the –change-source option to move the source to the new specified zone.
Note3: If you want to temporarily add a source to a zone, don’t use the –permanent option and don’t reload the firewall configuration. If you reload the firewall configuration, this will cancel all the operation.
To get the list of the sources currently bound to a zone (here trusted), type:
# firewall-cmd --zone=trusted --list-sources
Note: Add the –permanent option if you only want to display permanent settings.
To keep track of your configuration (active zones are zones that have a binding to an interface or source), type:
# firewall-cmd --get-active-zones
  interfaces: eth0

Service management

After assigning each network interface to a zone, it is now possible to add services to each zone.
To allow the http service permanently in the internal zone, type:
# firewall-cmd --permanent --zone=internal --add-service=http
# firewall-cmd --reload
Note1: Type –remove-service=http to deny the http service.
Note2: The firewall-cmd –reload command is necessary to activate the change. Contrary to the–complete-reload option, current connections are not stopped.
Note3: If you only want to temporarily add a service, don’t use the –permanent option and don’treload the firewall configuration. If you reload the firewall configuration, you cancel all the operation.
To get the list of services in the default zone, type:
# firewall-cmd --list-services
dhcpv6-client ssh
Note: To get the list of the services in a particular zone, add the –zone= option.

Service firewall configuration

With the Firewalld package, the firewall configuration of the main services (ftp, httpd, etc) comes in the /usr/lib/firewalld/services directory. But it is still possible to add new ones in the/etc/firewalld/services directory. Also, if files exist at both locations for the same service, the file in the /etc/firewalld/services directory takes precedence.
For example, it is the case of the HAProxy service. There is no firewall configuration associated.
Create the /etc/firewalld/services/haproxy.xml and paste the following lines:
<?xml version="1.0" encoding="utf-8"?>
 <description>HAProxy load-balancer</description>
 <port protocol="tcp" port="80"/>
Note: You can use the firewall-cmd –permanent –new-service=haproxy command to quickly create a configuration file skeleton.
Assign the correct SELinux context and file permissions to the haproxy.xml file:
# cd /etc/firewalld/services
# restorecon haproxy.xml
# chmod 640 haproxy.xml
Add the HAProxy service to the default zone permanently and reload the firewall configuration:
# firewall-cmd --permanent --add-service=haproxy
# firewall-cmd --reload

Port management

Port management follows the same model as service management.
To allow the 443/tcp port temporarily in the internal zone, type:
# firewall-cmd --zone=internal --add-port=443/tcp
Note1: To make the configuration permanent, add the –permanent option and reload the firewall configuration.
Note2: Type –remove-port=443/tcp to deny the port.
To get the list of ports currently open in the internal zone, type:
# firewall-cmd --zone=internal --list-ports
Note: To only get the list of ports permanently open, add the –permanent option. Here, you will not get anything.


If your firewall is your network gateway and you don’t want everybody to know your internal addresses, you can set up two zones, one called internal, the other external, and configuremasquerading on the external zone. This way, all packets will get your firewall ip address as source address.
To set up masquerading on the external zone in a temporary way, type:
# firewall-cmd --zone=external --add-masquerade
Note1: To remove masquerading, use the –remove-masquerade option.
Note2: To know if masquerading is active in a zone, use the –query-masquerade option.
Note3: To get the configuration permanent, add the –permanent option and reload the firewall configuration.

Port forwarding

In addition to the masquerading, you can want to use port forwarding.
If you want all packets intended for port 22 to be now forwarded to port tcp 3753 temporarily, type:
# firewall-cmd --zone=external --add-forward-port=port=22:proto=tcp:toport=3753
Note1: To remove port forwarding, use the –remove-forward-port option.
Note2: To know if port forwarding is active in a zone, use the –query-forward-port option.
Note3: If you want to make the configuration permanent, add the –permanent option and reload the firewall configuration.
Also, if you want to define the destination ip address, this time in a permanent way, type:
# firewall-cmd --permanent --zone=external --add-forward-port=port=22:proto=tcp:toport=3753:toaddr=
# firewall-cmd --reload

Direct rules

It is still possible to set specific rules by using the direct mode (here to open the tcp port 9000) that by-passes the Firewalld interface:
# firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -p tcp --dport 9000 -j ACCEPT
Note1: This example has been borrowed from Khosro Taraghi’s blog.
Note2: Use the same command with the –remove-rule instead of –add-rule to delete the rule.
Note3: The configuration is temporary except if you add the –permanent option.
Note4: It is not necessary to reload the firewall configuration, all commands are directlyactivated.
To display all the direct rules added, type:
# firewall-cmd --direct --get-all-rules

Offline configuration

In some cases (installations through Anaconda or Kickstart for example), you need to set up firewall rules when Firewalld is not running. The firewall-offline-cmd command has just been created for this purpose.
For instance, to open the tcp port 22, you would type in the /etc/sysconfig/iptables file:
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
Instead, you can now execute the following command:
# firewall-offline-cmd --direct --add-rule ipv4 filter INPUT 0 -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT

Additional resources

Please check the original article at

No comments:

Post a Comment