Securing Network Ports with Firewalld


Firewalld provides dynamic monitoring and management of firewalls in RHEL 7. It supports firewall networks or zones that define the trust level of network settings and interfaces. Highly manageable and configurable, it also provides support for IPv4 and IPv6 firewall settings.

Firewalld is the default method for managing host level firewalls in Red Hat Enterprise Linux 7 (RHEL 7). It started off from the firewall.service system service, and now manages the Linux kernel netfilter sub-system using low-level iptables, ip6tables, and ebtables commands.

Firewalld separates all incoming traffic into zones, with each zone having its own set of rules. To check which zone to use for an incoming connection, firewalld uses its own logic, using which the first rule that matches wins:

  • If the source address of an incoming packet matches a source rule setup for a zone, that packet will be routed through that zone.
  • If the incoming interface for a packet matches a filter setup for a zone, that zone will be used.
  • Otherwise, the default zone will be used. The default zone is not a separate zone; instead, it points to one of the other zones defined on the system.

Unless overridden by an administrator or a NetworkManager configuration, the default zone for any new network interface will be set to the public zone.


A number of predefined zones are shipped with firewalld, each with its own specified use.

Default configurations for firewalld zones

  • Trusted: Allows all incoming traffic.
  • Home: Rejects incoming traffic unless related to outgoing traffic or matching the ssh, mdns, ipp-client, samba-client or dhcpv6-client predefined services.
  • Internal: Rejects incoming traffic unless related to outgoing traffic or matching the ssh or dhcpv6-client predefined services; this is the default zone for newly added network interfaces.
  • External: Rejects incoming traffic unless related to outgoing traffic or matching the ssh predefined service. Outgoing IPv4 traffic forwarded through this zone is masqueraded to look like it or that it originated from the IPv4 address of the network outgoing interface.
  • Dmz: Rejects incoming traffic unless it is related to outgoing traffic or matches the ssh predefined service.
  • Block: Rejects all incoming traffic unless related to outgoing traffic.
  • Drop: Drops all incoming traffic unless related to outgoing traffic.

Managing firewalld

Firewalld can be managed in three ways.

  • Using the command line tool: firewall-cmd
  • Using the graphical tool: firewall-confi
  • Using the configuration files in /etc/firewalld

In most cases, editing the configuration files directly is not recommended, but it can be useful to copy information when using configuration management tools.

Configuring firewall settings with firewall-cmd

Firewall-cmd is installed as a part of the firewalld package, and can perform the same action as firewall-config.

The list below gives a number of frequently used firewall-cmd commands, along with explanations. Note that almost all commands will work on runtime configuration unless the –permanent option is specified. Many of the commands listed take the –zone=<ZONE> option to determine which zone they affect. If the –zone option is omitted from these commands, the default zone is used.

While configuring a firewall, an administrator normally applies all the changes permanently by using firewall-cmd — permanent –add service=service name and then activates those changes with firewall-cmd –reload. While testing out new and possibly dangerous rules, an administrator can choose to work on the runtime configuration by omitting the –permanent option. In those cases, an extra option —timeout=<TIMEINSECONDS> can be used to automatically remove a rule after a certain amount of time, preventing an administrator from accidentally locking out a system.

Commands with examples

  • –get-default-zone: Queries the current default zone.
  • –set-default-zone=<ZONE>: Sets the default zone. This changes both the runtime and the permanent configuration.
  • –get-zones: Lists all available zones.
  • –get-services: Lists all predefined services.
  • –get-active-zones: Lists all zones currently in use (and have an interface tied to them) along with their interface and source information.
  • –add-source=<CIDR> [–zone=<ZONE>]: Routes all traffic coming from the IP address or network/netmask <CIDR> from the specified zone. If no –zone= option is provided, then the default zone will be used.
  • –remove-source=<CIDR>[–zone=<ZONE>]: Removes the rule routing all traffic coming from the IP address or network/netmask <CIDR> from the specified zone. If no –zone= option is provided, the default zone will be used.
  • –add-interface=<INTERFACE> [–zone=<ZONE>]: Routes all traffic coming from <INTERFACE> to the specified zone. If no –zone= option is provided, the default zone will be used.
  • –change-interface=<INTERFACE>[–zone=<ZONE>]: Associates the interface with <ZONE> instead of its current zone. If no –zone= option is provided, the default zone will be used.
  • –list-all-zones: Retrieves all information for all zones (interfaces, sources, ports, services, etc).
  • –add-service=<SERVICE>: Allows traffic to <SERVICE>. If no –zone= option is provided, the default zone will be used.
  • –add-port=<PORT/PROTOCOL>: Allows traffic to the <PORT/PROTOCOL> ports. If no –zone= option is provided, the default zone will be used.
  • –remove-service=<SERVICE>: Removes <SERVICE> from the allowed list for the zone. If no –zone= option is provided, the default zone will be used.
  • –remove-port=<PORT/PROTOCOL>: Removes the <PORT/PROTOCOL> ports from the allowed list for the zone. If no –zone= option is provided, the default zone will be used.
  • –reload: Drops the runtime configuration and applies the persistent configuration.

Firewall-cmd shows the default zone being set to dmz, all traffic coming from the network being assigned to the internal zone, and network ports for MySQL being opened on the internal zone.

Firewalld configuration files

Firewalld configuration files are stored in two places — /etc/firewalld and /usr/lib/firewalld. If a configuration file with the same name is stored in both locations, the version from /etc/firewalld will be wiped out by a package update.

Managing rich rules

Apart from regular zones and the services syntax that firewalld offers, administrators have two other options for adding firewall rules — direct rules and rich rules.

Direct rules: Direct rules allow an administrator to insert hand-coded {ip, ip6, eb} tables rules into the zones managed by firewalld. While being powerful and exposing features of the kernel net filter sub-system that are not exposed through other means, these rules can be hard to manage. Direct rules also offer less flexibility than standard and rich rules. Unless explicitly inserted into a zone managed by firewalld, direct rules will be parsed before any firewalld rules are.

Shown below is an example of adding some direct rules to blacklist an IP range:

# firewall-cmd –direct --permanent –add-chain ipv4 raw blacklist

# firewall-cmd –direct –permanent –add-rule ipv4 raw PREROUTING 0 –s –j blacklist

#firewall-cmd –direct –permanent –add-rule ipv4 raw blacklist 0 –m limit --limit 1/min –j LOG –log-prefix “blacklisted”

# firewall-cmd –direct –permanent –add-rule ipv4 raw blacklist 1 –j DROP

Rich rules: Firewalld rich rules give administrators an expressive language with which to express custom firewall rules that are not covered by basic firewalld syntax — for example, to only allow connections to a service from a single IP address instead of all IP addresses routed through a zone.

Rich rules can be used to express basic allow/deny rules, and can also be used to configure logging to rsyslog and auditd as well as port forwards, masquerading and rate limiting.

The basic syntax of a rich rule can be expressed by the following block:

Almost every single element of a rule can take additional arguments in the form of option=value.

Note: For the full syntax of rich rules, consult the firewalld.richlanguage man page in Red Hat Enterprise Linux 7.

Rule ordering

Once multiple rules have been added to a zone (or the firewall, in general), the ordering of rules can have a big effect on how the firewall behaves.

The basic ordering of rules inside a zone is the same for all zones:

  • Port forwarding and masquerading rules set for that zone.
  • Logging rules set for that zone.
  • Allow rules set for that zone
  • Deny rules set for that zone.

In all cases, the first match will win. If a packet has not been matched by any rule in a zone, it is typically denied, but zones might have different defaults — for example, the trusted zone will accept any unmatched packet. Also, after matching a logging rule, a packet will continue to be processed as normal.

Direct rules are an exception. Most direct rules are parsed before any other processing is done by firewalld, but the direct syntax allows an administrator to insert any desired rule anywhere in any zone.

Testing and debugging

To make testing and debugging easier, almost all rules can be added to the runtime configuration with a timeout. The moment the rule with a timeout is added to the firewall, the timer starts counting down for that rule. Once the timer for that rule reaches zero seconds, that rule is removed from the runtime configuration.

Using timeouts can be an incredibly useful tool while working on remote firewalls, especially when testing more complicated rule sets. If a rule works, the administrator can add it again but with the –permanent option (or at least with a timeout). If the rule does not work as intended, maybe even locking the administrator out of the system, it will be removed automatically, allowing the administrator to continue his or her work.

A timeout is added to a runtime rule by adding the option –timeout=<TIMEINSECONDS> to the end of firewall-cmd that enables the rule.

Working with rich rules

Firewall-cmd has four options for working with rich rules. All of these options can be used in combination with the regular –permanent or –zone=<ZONE> options.

Some options with explanations are given below.

  • -add-rich-rule=‘<RULE>’: Adds <RULE> to the specified zone, or the default zone if no zone is specified.
  • –remove-rich-rule=‘<RULE>’: Removes <RULE> from the specified zone, or the default zone if no zone is specified.
  • –query-rich-rule=‘<RULE>’: Queries if <RULE>has been added to a specified zone, or the default zone if no zone is specified. Returns 0 if the rule is present, otherwise returns 1.
  • –list-rich-rules: Outputs all rich rules for the specified zone or the default zone if no zone is specified.

All configured rich rules are also shown in the output from firewall-cmd –list-all and firewall-cmd –list-all-zones.

Rich rule examples

Shown below are some examples of rich rules.

  • # firewall-cmd –permanent –zone=classroom –add-rich-rule=‘rulefamily=ipv4 source address= reject’

This rule is to reject all traffic from the IP address in the classroom zone.

When using the source or destination with an address option, the family=option rule must be set to either IPv4 or IPv6.

  • # firewall-cmd –add-rich-rule=‘rule service name=ftp limit value=2/m accept’

This rule is to allow two new connections to ftp per minute in the default zone. This change is only made in runtime configuration.

  • #firewall-cmd –permanent –add-rich-rule=‘rule protocol value=espdrop’

This drops all incoming IPsec esp protocol packets from anywhere in the default zone.

Note: The difference between the reject rule and drop rule is that the former will send back an ICMP packet detailing why a connection was rejected. A drop rule just drops the packet and does nothing else. Normally, an administrator will want to use a reject rule for friendly and neutral networks, and a drop rule only for hostile networks.

  • Firewall-cmd –permanent –zone=vnc –add-rich-rule=‘rulefamily=ipv4 source address= port port=7900-7905 protocol=tcp accept’

This accepts all tcp packets on Ports 7900, up to and including Port 7095, in the vnc zone for the subnet.

Logging with rich rules

When debugging or monitoring a firewall, it can be useful to have a log of accepted or rejected connections. Firewalld can accomplish this in two ways — by logging to syslog, or by sending messages to the kernel audit sub-system, managed by auditd.

In both cases, logging can be rate limited, which ensures that system log files do not fill up with messages at a rate at which the system cannot keep up or fills all its disk space.

The basic syntax for logging to syslog using rich rules is:

Log [prefix=”PREFIXTEXT>” [level=<LOGLEVEL>] [limit value=”<RATE/DURATION>”]

…where <LOGLEVEL> is one of emerg, alert, crit, error, warning, notice, info, or debugging.

<DURATION> can be of ‘s’ for seconds, ‘m’ for minutes, ‘h’ for hours, or ‘d’ for days. For example, the limit value=3/m will limit the log messages to a maximum of three per minute.

The basic system for logging the audit sub-system is:

Audit [limit value=”<RATE/DURATION>”]

The rate limiting is configured in the same way as for syslog logging.

Logging examples

Some examples of logging using rich rules are shown below:

# firewall-cmd --permanent –zone=work –add-rich-rule=’rule servicename=”ssh” log prefix =”ssh” level=”notice” limit value =”3/m” accept

The above code indicates that you can accept new connections to ssh from the work zone, and log new connections to syslog at the notice level with a maximum of three messages per minute.

#firewall-cmd –add-rich-rule=’rule family=ipv6 source address=”2001:db8::/64” service name=”dns” audit limit value=”1/h” reject’ –timeout=300

The code given above states that new IPv6 connections from the subnet 2001:db8::/64 in the default zone to DNS are rejected for the next five minutes, and rejected connections are logged to the audit system with a maximum of one message per hour.



Please enter your comment!
Please enter your name here