Red Hat Training

A Red Hat training course is available for RHEL 8

Chapter 45. Using and configuring firewalld

A firewall is a way to protect machines from any unwanted traffic from outside. It enables users to control incoming network traffic on host machines by defining a set of firewall rules. These rules are used to sort the incoming traffic and either block it or allow through.

firewalld is a firewall service daemon that provides a dynamic customizable host-based firewall with a D-Bus interface. Being dynamic, it enables creating, changing, and deleting the rules without the necessity to restart the firewall daemon each time the rules are changed.

firewalld uses the concepts of zones and services, that simplify the traffic management. Zones are predefined sets of rules. Network interfaces and sources can be assigned to a zone. The traffic allowed depends on the network your computer is connected to and the security level this network is assigned. Firewall services are predefined rules that cover all necessary settings to allow incoming traffic for a specific service and they apply within a zone.

Services use one or more ports or addresses for network communication. Firewalls filter communication based on ports. To allow network traffic for a service, its ports must be open. firewalld blocks all traffic on ports that are not explicitly set as open. Some zones, such as trusted, allow all traffic by default.

Note that firewalld with nftables backend does not support passing custom nftables rules to firewalld, using the --direct option.

45.1. When to use firewalld, nftables, or iptables

The following is a brief overview in which scenario you should use one of the following utilities:

  • firewalld: Use the firewalld utility for simple firewall use cases. The utility is easy to use and covers the typical use cases for these scenarios.
  • nftables: Use the nftables utility to set up complex and performance-critical firewalls, such as for a whole network.
  • iptables: The iptables utility on Red Hat Enterprise Linux uses the nf_tables kernel API instead of the legacy back end. The nf_tables API provides backward compatibility so that scripts that use iptables commands still work on Red Hat Enterprise Linux. For new firewall scripts, Red Hat recommends to use nftables.
Important

To prevent the different firewall-related services (firewalld, nftables, or iptables) from influencing each other, run only one of them on a RHEL host, and disable the other services.

45.2. Firewall zones

You can use the ⁠firewalld utility to separate networks into different zones according to the level of trust that you have with the interfaces and traffic within that network. A connection can only be part of one zone, but you can use that zone for many network connections.

firewalld follows strict principles in regards to zones:

  1. Traffic ingresses only one zone.
  2. Traffic egresses only one zone.
  3. A zone defines a level of trust.
  4. Intrazone traffic (within the same zone) is allowed by default.
  5. Interzone traffic (from zone to zone) is denied by default.

Principles 4 and 5 are a consequence of principle 3.

Principle 4 is configurable through the zone option --remove-forward. Principle 5 is configurable by adding new policies.

NetworkManager notifies firewalld of the zone of an interface. You can assign zones to interfaces with the following utilities:

  • NetworkManager
  • firewall-config utility
  • firewall-cmd utility
  • The RHEL web console

The RHEL web console, firewall-config, and firewall-cmd can only edit the appropriate NetworkManager configuration files. If you change the zone of the interface using the web console, firewall-cmd, or firewall-config, the request is forwarded to NetworkManager and is not handled by ⁠firewalld.

The /usr/lib/firewalld/zones/ directory stores the predefined zones, and you can instantly apply them to any available network interface. These files are copied to the /etc/firewalld/zones/ directory only after they are modified. The default settings of the predefined zones are as follows:

block
  • Suitable for: Any incoming network connections are rejected with an icmp-host-prohibited message for IPv4 and icmp6-adm-prohibited for IPv6.
  • Accepts: Only network connections initiated from within the system.
dmz
  • Suitable for: Computers in your DMZ that are publicly-accessible with limited access to your internal network.
  • Accepts: Only selected incoming connections.
drop
Suitable for: Any incoming network packets are dropped without any notification.

**Accepts: Only outgoing network connections.

external
  • Suitable for: External networks with masquerading enabled, especially for routers. Situations when you do not trust the other computers on the network.
  • Accepts: Only selected incoming connections.
home
  • Suitable for: Home environment where you mostly trust the other computers on the network.
  • Accepts: Only selected incoming connections.
internal
  • Suitable for: Internal networks where you mostly trust the other computers on the network.
  • Accepts: Only selected incoming connections.
public
  • Suitable for: Public areas where you do not trust other computers on the network.
  • Accepts: Only selected incoming connections.
trusted
  • Accepts: All network connections.
work

Suitable for: Work environment where you mostly trust the other computers on the network.

  • Accepts: Only selected incoming connections.

One of these zones is set as the default zone. When interface connections are added to NetworkManager, they are assigned to the default zone. On installation, the default zone in firewalld is the public zone. You can change the default zone.

Note

Make network zone names self-explanatory to help users understand them quickly.

To avoid any security problems, review the default zone configuration and disable any unnecessary services according to your needs and risk assessments.

Additional resources

  • The firewalld.zone(5) man page.

45.3. Firewall policies

The firewall policies specify the desired security state of your network. They outline rules and actions to take for different types of traffic. Typically, the policies contain rules for the following types of traffic:

  • Incoming traffic
  • Outgoing traffic
  • Forward traffic
  • Specific services and applications
  • Network address translations (NAT)

Firewall policies use the concept of firewall zones. Each zone is associated with a specific set of firewall rules that determine the traffic allowed. Policies apply firewall rules in a stateful, unidirectional manner. This means you only consider one direction of the traffic. The traffic return path is implicitly allowed due to stateful filtering of firewalld.

Policies are associated with an ingress zone and an egress zone. The ingress zone is where the traffic originated (received). The egress zone is where the traffic leaves (sent).

The firewall rules defined in a policy can reference the firewall zones to apply consistent configurations across multiple network interfaces.

45.4. Firewall rules

You can use the firewall rules to implement specific configurations for allowing or blocking network traffic. As a result, you can control the flow of network traffic to protect your system from security threats.

Firewall rules typically define certain criteria based on various attributes. The attributes can be as:

  • Source IP addresses
  • Destination IP addresses
  • Transfer Protocols (TCP, UDP, …​)
  • Ports
  • Network interfaces

The firewalld utility organizes the firewall rules into zones (such as public, internal, and others) and policies. Each zone has its own set of rules that determine the level of traffic freedom for network interfaces associated with a particular zone.

45.5. Zone configuration files

A firewalld zone configuration file contains the information for a zone. These are the zone description, services, ports, protocols, icmp-blocks, masquerade, forward-ports and rich language rules in an XML file format. The file name has to be zone-name.xml where the length of zone-name is currently limited to 17 chars. The zone configuration files are located in the /usr/lib/firewalld/zones/ and /etc/firewalld/zones/ directories.

The following example shows a configuration that allows one service (SSH) and one port range, for both the TCP and UDP protocols:

<?xml version="1.0" encoding="utf-8"?>
<zone>
  <short>My Zone</short>
  <description>Here you can describe the characteristic features of the zone.</description>
  <service name="ssh"/>
  <port protocol="udp" port="1025-65535"/>
  <port protocol="tcp" port="1025-65535"/>
</zone>

Additional resources

  • firewalld.zone manual page

45.6. Predefined firewalld services

The firewalld service is a predefined set of firewall rules that define access to a specific application or network service. Each service represents a combination of the following elements:

  • Local port
  • Network protocol
  • Associated firewall rules
  • Source ports and destinations
  • Firewall helper modules that load automatically if a service is enabled

A service simplifies packet filtering and saves you time because it achieves several tasks at once. For example, firewalld can perform the following tasks at once:

  • Open a port
  • Define network protocol
  • Enable packet forwarding

Service configuration options and generic file information are described in the firewalld.service(5) man page. The services are specified by means of individual XML configuration files, which are named in the following format: service-name.xml. Protocol names are preferred over service or application names in firewalld.

You can configure firewalld in the following ways:

  • Use utilities:

    • firewall-config - graphical utility
    • firewall-cmd - command-line utility
    • firewall-offline-cmd - command-line utility
  • Edit the XML files in the /etc/firewalld/services/ directory.

    If you do not add or change the service, no corresponding XML file exists in /etc/firewalld/services/. You can use the files in /usr/lib/firewalld/services/ as templates.

Additional resources

  • The firewalld.service(5) man page

45.7. Working with firewalld zones

Zones represent a concept to manage incoming traffic more transparently. The zones are connected to networking interfaces or assigned a range of source addresses. You manage firewall rules for each zone independently, which enables you to define complex firewall settings and apply them to the traffic.

45.7.1. Customizing firewall settings for a specific zone to enhance security

You can strengthen your network security by modifying the firewall settings and associating a specific network interface or connection with a particular firewall zone. By defining granular rules and restrictions for a zone, you can control inbound and outbound traffic based on your intended security levels.

For example, you can achieve the following benefits:

  • Protection of sensitive data
  • Prevention of unauthorized access
  • Mitigation of potential network threats

Prerequisites

  • The firewalld service is running.

Procedure

  1. List the available firewall zones:

    # firewall-cmd --get-zones

    The firewall-cmd --get-zones command displays all zones that are available on the system, but it does not show any details for particular zones. To see more detailed information for all zones, use the firewall-cmd --list-all-zones command.

  2. Choose the zone you want to use for this configuration.
  3. Modify firewall settings for the chosen zone. For example, to allow the SSH service and remove the ftp service:

    # firewall-cmd --add-service=ssh --zone=<your_chosen_zone>
    # firewall-cmd --remove-service=ftp --zone=<same_chosen_zone>
  4. Assign a network interface to the firewall zone:

    1. List the available network interfaces:

      # firewall-cmd --get-active-zones

      Activity of a zone is determined by the presence of network interfaces or source address ranges that match its configuration. The default zone is active for unclassified traffic but is not always active if no traffic matches its rules.

    2. Assign a network interface to the chosen zone:

      # firewall-cmd --zone=<your_chosen_zone> --change-interface=<interface_name> --permanent

      Assigning a network interface to a zone is more suitable for applying consistent firewall settings to all traffic on a particular interface (physical or virtual).

      The firewall-cmd command, when used with the --permanent option, often involves updating NetworkManager connection profiles to make changes to the firewall configuration permanent. This integration between firewalld and NetworkManager ensures consistent network and firewall settings.

Verification

  1. Display the updated settings for your chosen zone:

    # firewall-cmd --zone=<your_chosen_zone> --list-all

    The command output displays all zone settings including the assigned services, network interface, and network connections (sources).

45.7.2. Changing the default zone

System administrators assign a zone to a networking interface in its configuration files. If an interface is not assigned to a specific zone, it is assigned to the default zone. After each restart of the firewalld service, firewalld loads the settings for the default zone and makes it active. Note that settings for all other zones are preserved and ready to be used.

Typically, zones are assigned to interfaces by NetworkManager according to the connection.zone setting in NetworkManager connection profiles. Also, after a reboot NetworkManager manages assignments for "activating" those zones.

Prerequisites

  • The firewalld service is running.

Procedure

To set up the default zone:

  1. Display the current default zone:

    # firewall-cmd --get-default-zone
  2. Set the new default zone:

    # firewall-cmd --set-default-zone <zone_name>
    Note

    Following this procedure, the setting is a permanent setting, even without the --permanent option.

45.7.3. Assigning a network interface to a zone

It is possible to define different sets of rules for different zones and then change the settings quickly by changing the zone for the interface that is being used. With multiple interfaces, a specific zone can be set for each of them to distinguish traffic that is coming through them.

Procedure

To assign the zone to a specific interface:

  1. List the active zones and the interfaces assigned to them:

    # firewall-cmd --get-active-zones
  2. Assign the interface to a different zone:

    # firewall-cmd --zone=zone_name --change-interface=interface_name --permanent

45.7.4. Assigning a zone to a connection using nmcli

You can add a firewalld zone to a NetworkManager connection using the nmcli utility.

Procedure

  1. Assign the zone to the NetworkManager connection profile:

    # nmcli connection modify profile connection.zone zone_name
  2. Activate the connection:

    # nmcli connection up profile

45.7.5. Manually assigning a zone to a network connection in a connection profile file

If you cannot use the nmcli utility to modify a connection profile, you can manually edit the corresponding file of the profile to assign a firewalld zone.

Note

Modifying the connection profile with the nmcli utility to assign a firewalld zone is more efficient. For details, see Assigning a network interface to a zone.

Procedure

  1. Determine the path to the connection profile and its format:

    # nmcli -f NAME,FILENAME connection
    NAME    FILENAME
    enp1s0  /etc/NetworkManager/system-connections/enp1s0.nmconnection
    enp7s0  /etc/sysconfig/network-scripts/ifcfg-enp7s0

    NetworkManager uses separate directories and file names for the different connection profile formats:

    • Profiles in /etc/NetworkManager/system-connections/<connection_name>.nmconnection files use the keyfile format.
    • Profiles in /etc/sysconfig/network-scripts/ifcfg-<interface_name> files use the ifcfg format.
  2. Depending on the format, update the corresponding file:

    • If the file uses the keyfile format, append zone=<name> to the [connection] section of the /etc/NetworkManager/system-connections/<connection_name>.nmconnection file:

      [connection]
      ...
      zone=internal
    • If the file uses the ifcfg format, append ZONE=<name> to the /etc/sysconfig/network-scripts/ifcfg-<interface_name> file:

      ZONE=internal
  3. Reload the connection profiles:

    # nmcli connection reload
  4. Reactivate the connection profiles

    # nmcli connection up <profile_name>

Verification

  • Display the zone of the interface, for example:

    # firewall-cmd --get-zone-of-interface enp1s0
    internal

45.7.6. Manually assigning a zone to a network connection in an ifcfg file

When the connection is managed by NetworkManager, it must be aware of a zone that it uses. For every network connection profile, a zone can be specified, which provides the flexibility of various firewall settings according to the location of the computer with portable devices. Thus, zones and settings can be specified for different locations, such as company or home.

Procedure

  • To set a zone for a connection, edit the /etc/sysconfig/network-scripts/ifcfg-connection_name file and add a line that assigns a zone to this connection:

    ZONE=zone_name

45.7.7. Creating a new zone

To use custom zones, create a new zone and use it just like a predefined zone. New zones require the --permanent option, otherwise the command does not work.

Prerequisites

  • The firewalld service is running.

Procedure

  1. Create a new zone:

    # firewall-cmd --permanent --new-zone=zone-name
  2. Make the new zone usable:

    # firewall-cmd --reload

    The command applies recent changes to the firewall configuration without interrupting network services that are already running.

Verification

  • Check if the new zone is added to your permanent settings:

    # firewall-cmd --get-zones --permanent

45.7.8. Using zone targets to set default behavior for incoming traffic

For every zone, you can set a default behavior that handles incoming traffic that is not further specified. Such behavior is defined by setting the target of the zone. There are four options:

  • ACCEPT: Accepts all incoming packets except those disallowed by specific rules.
  • REJECT: Rejects all incoming packets except those allowed by specific rules. When firewalld rejects packets, the source machine is informed about the rejection.
  • DROP: Drops all incoming packets except those allowed by specific rules. When firewalld drops packets, the source machine is not informed about the packet drop.
  • default: Similar behavior as for REJECT, but with special meanings in certain scenarios.

Prerequisites

  • The firewalld service is running.

Procedure

To set a target for a zone:

  1. List the information for the specific zone to see the default target:

    # firewall-cmd --zone=zone-name --list-all
  2. Set a new target in the zone:

    # firewall-cmd --permanent --zone=zone-name --set-target=<default|ACCEPT|REJECT|DROP>

Additional resources

  • firewall-cmd(1) man page

45.8. Controlling network traffic using firewalld

The firewalld package installs a large number of predefined service files and you can add more or customize them. You can then use these service definitions to open or close ports for services without knowing the protocol and port numbers they use.

45.8.1. Controlling traffic with predefined services using the CLI

The most straightforward method to control traffic is to add a predefined service to firewalld. This opens all necessary ports and modifies other settings according to the service definition file.

Prerequisites

  • The firewalld service is running.

Procedure

  1. Check that the service in firewalld is not already allowed:

    # firewall-cmd --list-services
    ssh dhcpv6-client

    The command lists the services that are enabled in the default zone.

  2. List all predefined services in firewalld:

    # firewall-cmd --get-services
    RH-Satellite-6 amanda-client amanda-k5-client bacula bacula-client bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc ceph ceph-mon cfengine condor-collector ctdb dhcp dhcpv6 dhcpv6-client dns docker-registry ...

    The command displays a list of available services for the default zone.

  3. Add the service to the list of services that firewalld allows:

    # firewall-cmd --add-service=<service_name>

    The command adds the specified service to the default zone.

  4. Make the new settings persistent:

    # firewall-cmd --runtime-to-permanent

    The command applies these runtime changes to the permanent configuration of the firewall. By default, it applies these changes to the configuration of the default zone.

Verification

  1. List all permanent firewall rules:

    # firewall-cmd --list-all --permanent
    public
      target: default
      icmp-block-inversion: no
      interfaces:
      sources:
      services: cockpit dhcpv6-client ssh
      ports:
      protocols:
      forward: no
      masquerade: no
      forward-ports:
      source-ports:
      icmp-blocks:
      rich rules:

    The command displays complete configuration with the permanent firewall rules of the default firewall zone (public).

  2. Check the validity of the permanent configuration of the firewalld service.

    # firewall-cmd --check-config
    success

    If the permanent configuration is invalid, the command returns an error with further details:

    # firewall-cmd --check-config
    Error: INVALID_PROTOCOL: 'public.xml': 'tcpx' not from {'tcp'|'udp'|'sctp'|'dccp'}

    You can also manually inspect the permanent configuration files to verify the settings. The main configuration file is /etc/firewalld/firewalld.conf. The zone-specific configuration files are in the /etc/firewalld/zones/ directory and the policies are in the /etc/firewalld/policies/ directory.

45.8.2. Controlling traffic with predefined services using the GUI

You can control the network traffic with predefined services using a graphical user interface. The Firewall Configuration application provides an accessible and user-friendly alternative to the command-line utilities.

Prerequisites

  • You installed the firewall-config package.
  • The firewalld service is running.

Procedure

  1. To enable or disable a predefined or custom service:

    1. Start the firewall-config utility and select the network zone whose services are to be configured.
    2. Select the Zones tab and then the Services tab below.
    3. Select the checkbox for each type of service you want to trust or clear the checkbox to block a service in the selected zone.
  2. To edit a service:

    1. Start the firewall-config utility.
    2. Select Permanent from the menu labeled Configuration. Additional icons and menu buttons appear at the bottom of the Services window.
    3. Select the service you want to configure.

The Ports, Protocols, and Source Port tabs enable adding, changing, and removing of ports, protocols, and source port for the selected service. The modules tab is for configuring Netfilter helper modules. The Destination tab enables limiting traffic to a particular destination address and Internet Protocol (IPv4 or IPv6).

Note

It is not possible to alter service settings in the Runtime mode.

Verification

  • Press the Super key to enter the Activities overview.
  • Select the Firewall Configuration utility.

    • You can also start the graphical firewall configuration utility using the command-line, by entering the firewall-config command.
  • View the list of configurations of your firewall:

    firewall configuration

The Firewall Configuration window opens. Note that this command can be run as a normal user, but you are prompted for an administrator password occasionally.

45.8.3. Configuring firewalld to allow hosting a secure web server

Ports are logical services that enable an operating system to receive and distinguish network traffic and forward it to system services. The system services are represented by a daemon that listens on the port and waits for any traffic coming to this port.

Normally, system services listen on standard ports that are reserved for them. The httpd daemon, for example, listens on port 80. However, system administrators can directly specify the port number instead of the service name.

You can use the firewalld service to configure access to a secure web server for hosting your data.

Prerequisites

  • The firewalld service is running.

Procedure

  1. Check the currently active firewall zone:

    # firewall-cmd --get-active-zones
  2. Add the HTTPS service to the appropriate zone:

    # firewall-cmd --zone=<zone_name> --add-service=https --permanent
  3. Reload the firewall configuration:

    # firewall-cmd --reload

Verification

  1. Check if the port is open in firewalld:

    • If you opened the port by specifying the port number, enter:

      # firewall-cmd --zone=<zone_name> --list-all
    • If you opened the port by specifying a service definition, enter:

      # firewall-cmd --zone=<zone_name> --list-services

45.8.4. Closing unused or unnecessary ports to enhance network security

When an open port is no longer needed, you can use the firewalld utility to close it.

Important

Close all unnecessary ports to reduce the potential attack surface and minimize the risk of unauthorized access or exploitation of vulnerabilities.

Procedure

  1. List all allowed ports:

    # firewall-cmd --list-ports

    By default, this command lists the ports that are enabled in the default zone.

    Note

    This command will only give you a list of ports that are opened as ports. You will not be able to see any open ports that are opened as a service. For that case, consider using the --list-all option instead of --list-ports.

  2. Remove the port from the list of allowed ports to close it for the incoming traffic:

    # firewall-cmd --remove-port=port-number/port-type

    This command removes a port from a zone. If you do not specify a zone, it will remove the port from the default zone.

  3. Make the new settings persistent:

    # firewall-cmd --runtime-to-permanent

    Without specifying a zone, this command applies runtime changes to the permanent configuration of the default zone.

Verification

  1. List the active zones and choose the zone you want to inspect:

    # firewall-cmd --get-active-zones
  2. List the currently open ports in the selected zone to check if the unused or unnecessary ports are closed:

    # firewall-cmd --zone=<zone_to_inspect> --list-ports

45.8.5. Controlling traffic through the CLI

You can use the firewall-cmd command to:

  • disable networking traffic
  • enable networking traffic

As a result, you can for example enhance your system defenses, ensure data privacy or optimize network resources.

Important

Enabling panic mode stops all networking traffic. For this reason, it should be used only when you have the physical access to the machine or if you are logged in using a serial console.

Procedure

  1. To immediately disable networking traffic, switch panic mode on:

    # firewall-cmd --panic-on
  2. Switching off panic mode reverts the firewall to its permanent settings. To switch panic mode off, enter:

    # firewall-cmd --panic-off

Verification

  • To see whether panic mode is switched on or off, use:

    # firewall-cmd --query-panic

45.8.6. Controlling traffic with protocols using GUI

To permit traffic through the firewall using a certain protocol, you can use the GUI.

Prerequisites

  • You installed the firewall-config package

Procedure

  1. Start the firewall-config tool and select the network zone whose settings you want to change.
  2. Select the Protocols tab and click the Add button on the right-hand side. The Protocol window opens.
  3. Either select a protocol from the list or select the Other Protocol check box and enter the protocol in the field.

45.9. Using zones to manage incoming traffic depending on a source

You can use zones to manage incoming traffic based on its source. Incoming traffic in this context is any data that is destined for your system, or passes through the host running firewalld. The source typically refers to the IP address or network range from which the traffic originates. As a result, you can sort incoming traffic and assign it to different zones to allow or disallow services that can be reached by that traffic.

Matching by source address takes precedence over matching by interface name. When you add a source to a zone, the firewall will prioritize the source-based rules for incoming traffic over interface-based rules. This means that if incoming traffic matches a source address specified for a particular zone, the zone associated with that source address will determine how the traffic is handled, regardless of the interface through which it arrives. On the other hand, interface-based rules are generally a fallback for traffic that does not match specific source-based rules. These rules apply to traffic, for which the source is not explicitly associated with a zone. This allows you to define a default behavior for traffic that does not have a specific source-defined zone.

45.9.1. Adding a source

To route incoming traffic into a specific zone, add the source to that zone. The source can be an IP address or an IP mask in the classless inter-domain routing (CIDR) notation.

Note

In case you add multiple zones with an overlapping network range, they are ordered alphanumerically by zone name and only the first one is considered.

  • To set the source in the current zone:

    # firewall-cmd --add-source=<source>
  • To set the source IP address for a specific zone:

    # firewall-cmd --zone=zone-name --add-source=<source>

The following procedure allows all incoming traffic from 192.168.2.15 in the trusted zone:

Procedure

  1. List all available zones:

    # firewall-cmd --get-zones
  2. Add the source IP to the trusted zone in the permanent mode:

    # firewall-cmd --zone=trusted --add-source=192.168.2.15
  3. Make the new settings persistent:

    # firewall-cmd --runtime-to-permanent

45.9.2. Removing a source

When you remove a source from a zone, the traffic which originates from the source is no longer directed through the rules specified for that source. Instead, the traffic falls back to the rules and settings of the zone associated with the interface from which it originates, or goes to the default zone.

Procedure

  1. List allowed sources for the required zone:

    # firewall-cmd --zone=zone-name --list-sources
  2. Remove the source from the zone permanently:

    # firewall-cmd --zone=zone-name --remove-source=<source>
  3. Make the new settings persistent:

    # firewall-cmd --runtime-to-permanent

45.9.3. Removing a source port

By removing a source port you disable sorting the traffic based on a port of origin.

Procedure

  • To remove a source port:

    # firewall-cmd --zone=zone-name --remove-source-port=<port-name>/<tcp|udp|sctp|dccp>

45.9.4. Using zones and sources to allow a service for only a specific domain

To allow traffic from a specific network to use a service on a machine, use zones and source. The following procedure allows only HTTP traffic from the 192.0.2.0/24 network while any other traffic is blocked.

Warning

When you configure this scenario, use a zone that has the default target. Using a zone that has the target set to ACCEPT is a security risk, because for traffic from 192.0.2.0/24, all network connections would be accepted.

Procedure

  1. List all available zones:

    # firewall-cmd --get-zones
    block dmz drop external home internal public trusted work
  2. Add the IP range to the internal zone to route the traffic originating from the source through the zone:

    # firewall-cmd --zone=internal --add-source=192.0.2.0/24
  3. Add the http service to the internal zone:

    # firewall-cmd --zone=internal --add-service=http
  4. Make the new settings persistent:

    # firewall-cmd --runtime-to-permanent

Verification

  • Check that the internal zone is active and that the service is allowed in it:

    # firewall-cmd --zone=internal --list-all
    internal (active)
      target: default
      icmp-block-inversion: no
      interfaces:
      sources: 192.0.2.0/24
      services: cockpit dhcpv6-client mdns samba-client ssh http
      ...

Additional resources

  • firewalld.zones(5) man page

45.10. Filtering forwarded traffic between zones

firewalld enables you to control the flow of network data between different firewalld zones. By defining rules and policies, you can manage how traffic is allowed or blocked when it moves between these zones.

The policy objects feature provides forward and output filtering in firewalld. You can use firewalld to filter traffic between different zones to allow access to locally hosted VMs to connect the host.

45.10.1. The relationship between policy objects and zones

Policy objects allow the user to attach firewalld’s primitives such as services, ports, and rich rules to the policy. You can apply the policy objects to traffic that passes between zones in a stateful and unidirectional manner.

# firewall-cmd --permanent --new-policy myOutputPolicy

# firewall-cmd --permanent --policy myOutputPolicy --add-ingress-zone HOST

# firewall-cmd --permanent --policy myOutputPolicy --add-egress-zone ANY

HOST and ANY are the symbolic zones used in the ingress and egress zone lists.

  • The HOST symbolic zone allows policies for the traffic originating from or has a destination to the host running firewalld.
  • The ANY symbolic zone applies policy to all the current and future zones. ANY symbolic zone acts as a wildcard for all zones.

45.10.2. Using priorities to sort policies

Multiple policies can apply to the same set of traffic, therefore, priorities should be used to create an order of precedence for the policies that may be applied.

To set a priority to sort the policies:

# firewall-cmd --permanent --policy mypolicy --set-priority -500

In the above example -500 is a lower priority value but has higher precedence. Thus, -500 will execute before -100.

Lower numerical priority values have higher precedence and are applied first.

45.10.3. Using policy objects to filter traffic between locally hosted containers and a network physically connected to the host

The policy objects feature allows users to filter traffic between Podman and firewalld zones.

Note

Red Hat recommends blocking all traffic by default and opening the selective services needed for the Podman utility.

Procedure

  1. Create a new firewall policy:

    # firewall-cmd --permanent --new-policy podmanToAny
  2. Block all traffic from Podman to other zones and allow only necessary services on Podman:

    # firewall-cmd --permanent --policy podmanToAny --set-target REJECT
    # firewall-cmd --permanent --policy podmanToAny --add-service dhcp
    # firewall-cmd --permanent --policy podmanToAny --add-service dns
    # firewall-cmd --permanent --policy podmanToAny --add-service https
  3. Create a new Podman zone:

    # firewall-cmd --permanent --new-zone=podman
  4. Define the ingress zone for the policy:

    # firewall-cmd --permanent --policy podmanToHost --add-ingress-zone podman
  5. Define the egress zone for all other zones:

    # firewall-cmd --permanent --policy podmanToHost --add-egress-zone ANY

    Setting the egress zone to ANY means that you filter from Podman to other zones. If you want to filter to the host, then set the egress zone to HOST.

  6. Restart the firewalld service:

    # systemctl restart firewalld

Verification

  • Verify the Podman firewall policy to other zones:

    # firewall-cmd --info-policy podmanToAny
    podmanToAny (active)
      ...
      target: REJECT
      ingress-zones: podman
      egress-zones: ANY
      services: dhcp dns https
      ...

45.10.4. Setting the default target of policy objects

You can specify --set-target options for policies. The following targets are available:

  • ACCEPT - accepts the packet
  • DROP - drops the unwanted packets
  • REJECT - rejects unwanted packets with an ICMP reply
  • CONTINUE (default) - packets will be subject to rules in following policies and zones.

    # firewall-cmd --permanent --policy mypolicy --set-target CONTINUE

Verification

  • Verify information about the policy

    # firewall-cmd --info-policy mypolicy

45.10.5. Using DNAT to forward HTTPS traffic to a different host

If your web server runs in a DMZ with private IP addresses, you can configure destination network address translation (DNAT) to enable clients on the internet to connect to this web server. In this case, the host name of the web server resolves to the public IP address of the router. When a client establishes a connection to a defined port on the router, the router forwards the packets to the internal web server.

Prerequisites

  • The DNS server resolves the host name of the web server to the router’s IP address.
  • You know the following settings:

    • The private IP address and port number that you want to forward
    • The IP protocol to be used
    • The destination IP address and port of the web server where you want to redirect the packets

Procedure

  1. Create a firewall policy:

    # firewall-cmd --permanent --new-policy <example_policy>

    The policies, as opposed to zones, allow packet filtering for input, output, and forwarded traffic. This is important, because forwarding traffic to endpoints on locally run web servers, containers, or virtual machines requires such capability.

  2. Configure symbolic zones for the ingress and egress traffic to also enable the router itself to connect to its local IP address and forward this traffic:

    # firewall-cmd --permanent --policy=<example_policy> --add-ingress-zone=HOST
    # firewall-cmd --permanent --policy=<example_policy> --add-egress-zone=ANY

    The --add-ingress-zone=HOST option refers to packets generated locally and transmitted out of the local host. The --add-egress-zone=ANY option refers to traffic moving to any zone.

  3. Add a rich rule that forwards traffic to the web server:

    # firewall-cmd --permanent --policy=<example_policy> --add-rich-rule='rule family="ipv4" destination address="192.0.2.1" forward-port port="443" protocol="tcp" to-port="443" to-addr="192.51.100.20"'

    The rich rule forwards TCP traffic from port 443 on the IP address of the router (192.0.2.1) to port 443 of the IP address of the web server (192.51.100.20).

  4. Reload the firewall configuration files:

    # firewall-cmd --reload
    success
  5. Activate routing of 127.0.0.0/8 in the kernel:

    • For persistent changes, run:

      # echo "net.ipv4.conf.all.route_localnet=1" > /etc/sysctl.d/90-enable-route-localnet.conf

      The command persistently configures the route_localnet kernel parameter and ensures that the setting is preserved after the system reboots.

    • For applying the settings immediately without a system reboot, run:

      # sysctl -p /etc/sysctl.d/90-enable-route-localnet.conf

      The sysctl command is useful for applying on-the-fly changes, however the configuration will not persist across system reboots.

Verification

  1. Connect to the IP address of the router and to the port that you have forwarded to the web server:

    # curl https://192.0.2.1:443
  2. Optional: Verify that the net.ipv4.conf.all.route_localnet kernel parameter is active:

    # sysctl net.ipv4.conf.all.route_localnet
    net.ipv4.conf.all.route_localnet = 1
  3. Verify that <example_policy> is active and contains the settings you need, especially the source IP address and port, protocol to be used, and the destination IP address and port:

    # firewall-cmd --info-policy=<example_policy>
    example_policy (active)
      priority: -1
      target: CONTINUE
      ingress-zones: HOST
      egress-zones: ANY
      services:
      ports:
      protocols:
      masquerade: no
      forward-ports:
      source-ports:
      icmp-blocks:
      rich rules:
    	rule family="ipv4" destination address="192.0.2.1" forward-port port="443" protocol="tcp" to-port="443" to-addr="192.51.100.20"

Additional resources

45.11. Configuring NAT using firewalld

With firewalld, you can configure the following network address translation (NAT) types:

  • Masquerading
  • Destination NAT (DNAT)
  • Redirect

45.11.1. Network address translation types

These are the different network address translation (NAT) types:

Masquerading

Use one of these NAT types to change the source IP address of packets. For example, Internet Service Providers (ISPs) do not route private IP ranges, such as 10.0.0.0/8. If you use private IP ranges in your network and users should be able to reach servers on the internet, map the source IP address of packets from these ranges to a public IP address.

Masquerading automatically uses the IP address of the outgoing interface. Therefore, use masquerading if the outgoing interface uses a dynamic IP address.

Destination NAT (DNAT)
Use this NAT type to rewrite the destination address and port of incoming packets. For example, if your web server uses an IP address from a private IP range and is, therefore, not directly accessible from the internet, you can set a DNAT rule on the router to redirect incoming traffic to this server.
Redirect
This type is a special case of DNAT that redirects packets to a different port on the local machine. For example, if a service runs on a different port than its standard port, you can redirect incoming traffic from the standard port to this specific port.

45.11.2. Configuring IP address masquerading

You can enable IP masquerading on your system. IP masquerading hides individual machines behind a gateway when accessing the internet.

Procedure

  1. To check if IP masquerading is enabled (for example, for the external zone), enter the following command as root:

    # firewall-cmd --zone=external --query-masquerade

    The command prints yes with exit status 0 if enabled. It prints no with exit status 1 otherwise. If zone is omitted, the default zone will be used.

  2. To enable IP masquerading, enter the following command as root:

    # firewall-cmd --zone=external --add-masquerade
  3. To make this setting persistent, pass the --permanent option to the command.
  4. To disable IP masquerading, enter the following command as root:

    # firewall-cmd --zone=external --remove-masquerade

    To make this setting permanent, pass the --permanent option to the command.

45.11.3. Using DNAT to forward incoming HTTP traffic

You can use destination network address translation (DNAT) to direct incoming traffic from one destination address and port to another. Typically, this is useful for redirecting incoming requests from an external network interface to specific internal servers or services.

Prerequisites

  • The firewalld service is running.

Procedure

  1. Create the /etc/sysctl.d/90-enable-IP-forwarding.conf file with the following content:

    net.ipv4.ip_forward=1

    This setting enables IP forwarding in the kernel. It makes the internal RHEL server act as a router and forward packets from network to network.

  2. Load the setting from the /etc/sysctl.d/90-enable-IP-forwarding.conf file:

    # sysctl -p /etc/sysctl.d/90-enable-IP-forwarding.conf
  3. Forward incoming HTTP traffic:

    # firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:toaddr=198.51.100.10:toport=8080 --permanent

    The previous command defines a DNAT rule with the following settings:

    • --zone=public - The firewall zone for which you configure the DNAT rule. You can adjust this to whatever zone you need.
    • --add-forward-port - The option that indicates you are adding a port-forwarding rule.
    • port=80 - The external destination port.
    • proto=tcp - The protocol indicating that you forward TCP traffic.
    • toaddr=198.51.100.10 - The destination IP address.
    • toport=8080 - The destination port of the internal server.
    • --permanent - The option that makes the DNAT rule persistent across reboots.
  4. Reload the firewall configuration to apply the changes:

    # firewall-cmd --reload

Verification

  • Verify the DNAT rule for the firewall zone that you used:

    # firewall-cmd --list-forward-ports --zone=public
    port=80:proto=tcp:toport=8080:toaddr=198.51.100.10

    Alternatively, view the corresponding XML configuration file:

    # cat /etc/firewalld/zones/public.xml
    <?xml version="1.0" encoding="utf-8"?>
    <zone>
      <short>Public</short>
      <description>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.</description>
      <service name="ssh"/>
      <service name="dhcpv6-client"/>
      <service name="cockpit"/>
      <forward-port port="80" protocol="tcp" to-port="8080" to-addr="198.51.100.10"/>
      <forward/>
    </zone>

Additional resources

45.11.4. Redirecting traffic from a non-standard port to make the web service accessible on a standard port

You can use the redirect mechanism to make the web service that internally runs on a non-standard port accessible without requiring users to specify the port in the URL. As a result, the URLs are simpler and provide better browsing experience, while a non-standard port is still used internally or for specific requirements.

Prerequisites

  • The firewalld service is running.

Procedure

  1. Create the /etc/sysctl.d/90-enable-IP-forwarding.conf file with the following content:

    net.ipv4.ip_forward=1

    This setting enables IP forwarding in the kernel.

  2. Load the setting from the /etc/sysctl.d/90-enable-IP-forwarding.conf file:

    # sysctl -p /etc/sysctl.d/90-enable-IP-forwarding.conf
  3. Create the NAT redirect rule:

    # firewall-cmd --zone=public --add-forward-port=port=<standard_port>:proto=tcp:toport=<non_standard_port> --permanent

    The previous command defines the NAT redirect rule with the following settings:

    • --zone=public - The firewall zone, for which you configure the rule. You can adjust this to whatever zone you need.
    • --add-forward-port=port=<non_standard_port> - The option that indicates you are adding a port-forwarding (redirecting) rule with source port on which you initially receive the incoming traffic.
    • proto=tcp - The protocol indicating that you redirect TCP traffic.
    • toport=<standard_port> - The destination port, to which the incoming traffic should be redirected after being received on the source port.
    • --permanent - The option that makes the rule persist across reboots.
  4. Reload the firewall configuration to apply the changes:

    # firewall-cmd --reload

Verification

  • Verify the redirect rule for the firewall zone that you used:

    # firewall-cmd --list-forward-ports
    port=8080:proto=tcp:toport=80:toaddr=

    Alternatively, view the corresponding XML configuration file:

    # cat /etc/firewalld/zones/public.xml
    <?xml version="1.0" encoding="utf-8"?>
    <zone>
      <short>Public</short>
      <description>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.</description>
      <service name="ssh"/>
      <service name="dhcpv6-client"/>
      <service name="cockpit"/>
      <forward-port port="8080" protocol="tcp" to-port="80"/>
      <forward/>
    </zone>

Additional resources

45.12. Managing ICMP requests

The Internet Control Message Protocol (ICMP) is a supporting protocol that is used by various network devices for testing, troubleshooting, and diagnostics. ICMP differs from transport protocols such as TCP and UDP because it is not used to exchange data between systems.

You can use the ICMP messages, especially echo-request and echo-reply, to reveal information about a network and misuse such information for various kinds of fraudulent activities. Therefore, firewalld enables controlling the ICMP requests to protect your network information.

45.12.1. Configuring ICMP filtering

You can use ICMP filtering to define which ICMP types and codes you want the firewall to permit or deny from reaching your system. ICMP types and codes are specific categories and subcategories of ICMP messages.

ICMP filtering helps, for example, in the following areas:

  • Security enhancement - Block potentially harmful ICMP types and codes to reduce your attack surface.
  • Network performance - Permit only necessary ICMP types to optimize network performance and prevent potential network congestion caused by excessive ICMP traffic.
  • Troubleshooting control - Maintain essential ICMP functionality for network troubleshooting and block ICMP types that represent potential security risk.

Prerequisites

  • The firewalld service is running.

Procedure

  1. List available ICMP types and codes:

    # firewall-cmd --get-icmptypes
    address-unreachable bad-header beyond-scope communication-prohibited destination-unreachable echo-reply echo-request failed-policy fragmentation-needed host-precedence-violation host-prohibited host-redirect host-unknown host-unreachable
    ...

    From this predefined list, select which ICMP types and codes to allow or block.

  2. Filter specific ICMP types by:

    • Allowing ICMP types:

      # firewall-cmd --zone=<target-zone> --remove-icmp-block=echo-request --permanent

      The command removes any existing blocking rules for the echo requests ICMP type.

    • Blocking ICMP types:

      # firewall-cmd --zone=<target-zone> --add-icmp-block=redirect --permanent

      The command ensures that the redirect messages ICMP type is blocked by the firewall.

  3. Reload the firewall configuration to apply the changes:

    # firewall-cmd --reload

Verification

  • Verify your filtering rules are in effect:

    # firewall-cmd --list-icmp-blocks
    redirect

    The command output displays the ICMP types and codes that you allowed or blocked.

Additional resources

  • firewall-cmd(1) manual page

45.13. Setting and controlling IP sets using firewalld

IP sets are a RHEL feature for grouping of IP addresses and networks into sets to achieve more flexible and efficient firewall rule management.

The IP sets are valuable in scenarios when you need to for example:

  • Handle large lists of IP addresses
  • Implement dynamic updates to those large lists of IP addresses
  • Create custom IP-based policies to enhance network security and control
Warning

Red Hat recommends using the firewall-cmd command to create and manage IP sets.

45.13.1. Configuring dynamic updates for allowlisting with IP sets

You can make near real-time updates to flexibly allow specific IP addresses or ranges in the IP sets even in unpredictable conditions. These updates can be triggered by various events, such as detection of security threats or changes in the network behavior. Typically, such a solution leverages automation to reduce manual effort and improve security by responding quickly to the situation.

Prerequisites

  • The firewalld service is running.

Procedure

  1. Create an IP set with a meaningful name:

    # firewall-cmd --permanent --new-ipset=allowlist --type=hash:ip

    The new IP set called allowlist contains IP addresses that you want your firewall to allow.

  2. Add a dynamic update to the IP set:

    # firewall-cmd --permanent --ipset=allowlist --add-entry=198.51.100.10

    This configuration updates the allowlist IP set with a newly added IP address that is allowed to pass network traffic by your firewall.

  3. Create a firewall rule that references the previously created IP set:

    # firewall-cmd --permanent --zone=public --add-source=ipset:allowlist

    Without this rule, the IP set would not have any impact on network traffic. The default firewall policy would prevail.

  4. Reload the firewall configuration to apply the changes:

    # firewall-cmd --reload

Verification

  1. List all IP sets:

    # firewall-cmd --get-ipsets
    allowlist
  2. List the active rules:

    # firewall-cmd --list-all
    public (active)
      target: default
      icmp-block-inversion: no
      interfaces: enp0s1
      sources: ipset:allowlist
      services: cockpit dhcpv6-client ssh
      ports:
      protocols:
      ...

    The sources section of the command-line output provides insights to what origins of traffic (hostnames, interfaces, IP sets, subnets, and others) are permitted or denied access to a particular firewall zone. In this case, the IP addresses contained in the allowlist IP set are allowed to pass traffic through the firewall for the public zone.

  3. Explore the contents of your IP set:

    # cat /etc/firewalld/ipsets/allowlist.xml
    <?xml version="1.0" encoding="utf-8"?>
    <ipset type="hash:ip">
      <entry>198.51.100.10</entry>
    </ipset>

Next steps

  • Use a script or a security utility to fetch your threat intelligence feeds and update allowlist accordingly in an automated fashion.

Additional resources

  • firewall-cmd(1) manual page

45.14. Prioritizing rich rules

By default, rich rules are organized based on their rule action. For example, deny rules have precedence over allow rules. The priority parameter in rich rules provides administrators fine-grained control over rich rules and their execution order. When using the priority parameter, rules are sorted first by their priority values in ascending order. When more rules have the same priority, their order is determined by the rule action, and if the action is also the same, the order may be undefined.

45.14.1. How the priority parameter organizes rules into different chains

You can set the priority parameter in a rich rule to any number between -32768 and 32767, and lower numerical values have higher precedence.

The firewalld service organizes rules based on their priority value into different chains:

  • Priority lower than 0: the rule is redirected into a chain with the _pre suffix.
  • Priority higher than 0: the rule is redirected into a chain with the _post suffix.
  • Priority equals 0: based on the action, the rule is redirected into a chain with the _log, _deny, or _allow the action.

Inside these sub-chains, firewalld sorts the rules based on their priority value.

45.14.2. Setting the priority of a rich rule

The following is an example of how to create a rich rule that uses the priority parameter to log all traffic that is not allowed or denied by other rules. You can use this rule to flag unexpected traffic.

Procedure

  • Add a rich rule with a very low precedence to log all traffic that has not been matched by other rules:

    # firewall-cmd --add-rich-rule='rule priority=32767 log prefix="UNEXPECTED: " limit value="5/m"'

    The command additionally limits the number of log entries to 5 per minute.

Verification

  • Display the nftables rule that the command in the previous step created:

    # nft list chain inet firewalld filter_IN_public_post
    table inet firewalld {
      chain filter_IN_public_post {
        log prefix "UNEXPECTED: " limit rate 5/minute
      }
    }

45.15. Configuring firewall lockdown

Local applications or services are able to change the firewall configuration if they are running as root (for example, libvirt). With this feature, the administrator can lock the firewall configuration so that either no applications or only applications that are added to the lockdown allow list are able to request firewall changes. The lockdown settings default to disabled. If enabled, the user can be sure that there are no unwanted configuration changes made to the firewall by local applications or services.

45.15.1. Configuring lockdown using CLI

You can enable or disable the lockdown feature using the command line.

Procedure

  1. To query whether lockdown is enabled:

    # firewall-cmd --query-lockdown
  2. Manage lockdown configuration by either:

    • Enabling lockdown:

      # firewall-cmd --lockdown-on
    • Disabling lockdown:

      # firewall-cmd --lockdown-off

45.15.2. Overview of lockdown allowlist configuration files

The default allowlist configuration file contains the NetworkManager context and the default context of libvirt. The user ID 0 is also on the list.

The allowlist configuration files are stored in the /etc/firewalld/ directory.

<?xml version="1.0" encoding="utf-8"?>
	<whitelist>
		<command name="/usr/bin/python3 -s /usr/bin/firewall-config"/>
	  <selinux context="system_u:system_r:NetworkManager_t:s0"/>
	  <selinux context="system_u:system_r:virtd_t:s0-s0:c0.c1023"/>
	  <user id="0"/>
	</whitelist>

Following is an example allowlist configuration file enabling all commands for the firewall-cmd utility, for a user called user whose user ID is 815:

<?xml version="1.0" encoding="utf-8"?>
	<whitelist>
	  <command name="/usr/libexec/platform-python -s /bin/firewall-cmd*"/>
	  <selinux context="system_u:system_r:NetworkManager_t:s0"/>
	  <user id="815"/>
	  <user name="user"/>
	</whitelist>

This example shows both user id and user name, but only one option is required. Python is the interpreter and is prepended to the command line.

In Red Hat Enterprise Linux, all utilities are placed in the /usr/bin/ directory and the /bin/ directory is sym-linked to the /usr/bin/ directory. In other words, although the path for firewall-cmd when entered as root might resolve to /bin/firewall-cmd, /usr/bin/firewall-cmd can now be used. All new scripts should use the new location. But be aware that if scripts that run as root are written to use the /bin/firewall-cmd path, then that command path must be added in the allowlist in addition to the /usr/bin/firewall-cmd path traditionally used only for non-root users.

The * at the end of the name attribute of a command means that all commands that start with this string match. If the * is not there then the absolute command including arguments must match.

45.16. Enabling traffic forwarding between different interfaces or sources within a firewalld zone

Intra-zone forwarding is a firewalld feature that enables traffic forwarding between interfaces or sources within a firewalld zone.

45.16.1. The difference between intra-zone forwarding and zones with the default target set to ACCEPT

With intra-zone forwarding enabled, the traffic within a single firewalld zone can flow from one interface or source to another interface or source. The zone specifies the trust level of interfaces and sources. If the trust level is the same, the traffic stays inside the same zone.

Note

Enabling intra-zone forwarding in the default zone of firewalld, applies only to the interfaces and sources added to the current default zone.

firewalld uses different zones to manage incoming and outgoing traffic. Each zone has its own set of rules and behaviors. For example, the trusted zone, allows all forwarded traffic by default.

Other zones can have different default behaviors. In standard zones, forwarded traffic is typically dropped by default when the target of the zone is set to default.

To control how the traffic is forwarded between different interfaces or sources within a zone, make sure you understand and configure the target of the zone accordingly.

45.16.2. Using intra-zone forwarding to forward traffic between an Ethernet and Wi-Fi network

You can use intra-zone forwarding to forward traffic between interfaces and sources within the same firewalld zone. This feature brings the following benefits:

  • Seamless connectivity between wired and wireless devices (you can forward traffic between an Ethernet network connected to enp1s0 and a Wi-Fi network connected to wlp0s20)
  • Support for flexible work environments
  • Shared resources that are accessible and used by multiple devices or users within a network (such as printers, databases, network-attached storage, and others)
  • Efficient internal networking (such as smooth communication, reduced latency, resource accessibility, and others)

You can enable this functionality for individual firewalld zones.

Procedure

  1. Enable packet forwarding in the kernel:

    # echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf
    # sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf
  2. Ensure that interfaces between which you want to enable intra-zone forwarding are assigned only to the internal zone:

    # firewall-cmd --get-active-zones
  3. If the interface is currently assigned to a zone other than internal, reassign it:

    # firewall-cmd --zone=internal --change-interface=interface_name --permanent
  4. Add the enp1s0 and wlp0s20 interfaces to the internal zone:

    # firewall-cmd --zone=internal --add-interface=enp1s0 --add-interface=wlp0s20
  5. Enable intra-zone forwarding:

    # firewall-cmd --zone=internal --add-forward

Verification

The following verification steps require that the nmap-ncat package is installed on both hosts.

  1. Log in to a host that is on the same network as the enp1s0 interface of the host on which you enabled zone forwarding.
  2. Start an echo service with ncat to test connectivity:

    # ncat -e /usr/bin/cat -l 12345
  3. Log in to a host that is in the same network as the wlp0s20 interface.
  4. Connect to the echo server running on the host that is in the same network as the enp1s0:

    # ncat <other_host> 12345
  5. Type something and press Enter. Verify the text is sent back.

Additional resources

  • firewalld.zones(5) man page

45.17. Configuring firewalld by using RHEL System Roles

You can use the firewall System Role to configure settings of the firewalld service on multiple clients at once. This solution:

  • Provides an interface with efficient input settings.
  • Keeps all intended firewalld parameters in one place.

After you run the firewall role on the control node, the System Role applies the firewalld parameters to the managed node immediately and makes them persistent across reboots.

45.17.1. Introduction to the firewall RHEL System Role

RHEL System Roles is a set of contents for the Ansible automation utility. This content together with the Ansible automation utility provides a consistent configuration interface to remotely manage multiple systems.

The rhel-system-roles.firewall role from the RHEL System Roles was introduced for automated configurations of the firewalld service. The rhel-system-roles package contains this System Role, and also the reference documentation.

To apply the firewalld parameters on one or more systems in an automated fashion, use the firewall System Role variable in a playbook. A playbook is a list of one or more plays that is written in the text-based YAML format.

You can use an inventory file to define a set of systems that you want Ansible to configure.

With the firewall role you can configure many different firewalld parameters, for example:

  • Zones.
  • The services for which packets should be allowed.
  • Granting, rejection, or dropping of traffic access to ports.
  • Forwarding of ports or port ranges for a zone.

Additional resources

45.17.2. Resetting the firewalld settings by using a RHEL System Role

With the firewall RHEL system role, you can reset the firewalld settings to their default state. If you add the previous:replaced parameter to the variable list, the System Role removes all existing user-defined settings and resets firewalld to the defaults. If you combine the previous:replaced parameter with other settings, the firewall role removes all existing settings before applying new ones.

Perform this procedure on the Ansible control node.

Prerequisites

  • You have prepared the control node and the managed nodes
  • You are logged in to the control node as a user who can run playbooks on the managed nodes.
  • The account you use to connect to the managed nodes has sudo permissions on the them.
  • The managed nodes or groups of managed nodes on which you want to run this playbook are listed in the Ansible inventory file.

Procedure

  1. Create a playbook file, for example ~/reset-firewalld.yml, with the following content:

    ---
    - name: Reset firewalld example
      hosts: managed-node-01.example.com
      tasks:
      - name: Reset firewalld
        include_role:
          name: rhel-system-roles.firewall
    
        vars:
          firewall:
            - previous: replaced
  2. Validate the playbook syntax:

    # ansible-playbook ~/configure-ethernet-device-with-ethtoolcoalesce-settings.yml --syntax-check

    Note that this command only validates the syntax and does not protect against a wrong but valid configuration.

  3. Run the playbook:

    # ansible-playbook ~/reset-firewalld.yml

Verification

  • Run this command as root on the managed node to check all the zones:

    # firewall-cmd --list-all-zones

Additional resources

  • /usr/share/ansible/roles/rhel-system-roles.firewall/README.md

45.17.3. Forwarding incoming traffic in firewalld from one local port to a different local port by using a RHEL System Role

With the firewall role you can remotely configure firewalld parameters with persisting effect on multiple managed hosts.

Perform this procedure on the Ansible control node.

Prerequisites

  • You have prepared the control node and the managed nodes
  • You are logged in to the control node as a user who can run playbooks on the managed nodes.
  • The account you use to connect to the managed nodes has sudo permissions on the them.
  • The managed nodes or groups of managed nodes on which you want to run this playbook are listed in the Ansible inventory file.

Procedure

  1. Create a playbook file, for example ~/port_forwarding.yml, with the following content:

    ---
    - name: Configure firewalld
      hosts: managed-node-01.example.com
      tasks:
      - name: Forward incoming traffic on port 8080 to 443
        include_role:
          name: rhel-system-roles.firewall
    
        vars:
          firewall:
            - { forward_port: 8080/tcp;443;, state: enabled, runtime: true, permanent: true }
  2. Validate the playbook syntax:

    # ansible-playbook ~/port_forwarding.yml --syntax-check

    Note that this command only validates the syntax and does not protect against a wrong but valid configuration.

  3. Run the playbook:

    # ansible-playbook ~/port_forwarding.yml

Verification

  • On the managed host, display the firewalld settings:

    # firewall-cmd --list-forward-ports

Additional resources

  • /usr/share/ansible/roles/rhel-system-roles.firewall/README.md

45.17.4. Managing ports in firewalld by using a RHEL System Role

You can use the RHEL firewall System Role to open or close ports in the local firewall for incoming traffic and make the new configuration persist across reboots. For example you can configure the default zone to permit incoming traffic for the HTTPS service.

Perform this procedure on the Ansible control node.

Prerequisites

  • You have prepared the control node and the managed nodes
  • You are logged in to the control node as a user who can run playbooks on the managed nodes.
  • The account you use to connect to the managed nodes has sudo permissions on the them.
  • The managed nodes or groups of managed nodes on which you want to run this playbook are listed in the Ansible inventory file.

Procedure

  1. Create a playbook file, for example ~/opening-a-port.yml, with the following content:

    ---
    - name: Configure firewalld
      hosts: managed-node-01.example.com
      tasks:
      - name: Allow incoming HTTPS traffic to the local host
        include_role:
          name: rhel-system-roles.firewall
    
        vars:
          firewall:
            - port: 443/tcp
              service: http
              state: enabled
              runtime: true
              permanent: true

    The permanent: true option makes the new settings persistent across reboots.

  2. Validate the playbook syntax:

    # ansible-playbook ~/opening-a-port.yml --syntax-check

    Note that this command only validates the syntax and does not protect against a wrong but valid configuration.

  3. Run the playbook:

    # ansible-playbook ~/opening-a-port.yml

Verification

  • On the managed node, verify that the 443/tcp port associated with the HTTPS service is open:

    # firewall-cmd --list-ports
    443/tcp

Additional resources

  • /usr/share/ansible/roles/rhel-system-roles.firewall/README.md

45.17.5. Configuring a firewalld DMZ zone by using a RHEL System Role

As a system administrator, you can use the firewall System Role to configure a dmz zone on the enp1s0 interface to permit HTTPS traffic to the zone. In this way, you enable external users to access your web servers.

Perform this procedure on the Ansible control node.

Prerequisites

  • You have prepared the control node and the managed nodes
  • You are logged in to the control node as a user who can run playbooks on the managed nodes.
  • The account you use to connect to the managed nodes has sudo permissions on the them.
  • The managed nodes or groups of managed nodes on which you want to run this playbook are listed in the Ansible inventory file.

Procedure

  1. Create a playbook file, for example ~/configuring-a-dmz.yml, with the following content:

    ---
    - name: Configure firewalld
      hosts: managed-node-01.example.com
      tasks:
      - name: Creating a DMZ with access to HTTPS port and masquerading for hosts in DMZ
        include_role:
          name: rhel-system-roles.firewall
    
        vars:
          firewall:
            - zone: dmz
              interface: enp1s0
              service: https
              state: enabled
              runtime: true
              permanent: true
  2. Validate the playbook syntax:

    # ansible-playbook ~/configuring-a-dmz.yml --syntax-check

    Note that this command only validates the syntax and does not protect against a wrong but valid configuration.

  3. Run the playbook:

    # ansible-playbook ~/configuring-a-dmz.yml

Verification

  • On the managed node, view detailed information about the dmz zone:

    # firewall-cmd --zone=dmz --list-all
    dmz (active)
      target: default
      icmp-block-inversion: no
      interfaces: enp1s0
      sources:
      services: https ssh
      ports:
      protocols:
      forward: no
      masquerade: no
      forward-ports:
      source-ports:
      icmp-blocks:

Additional resources

  • /usr/share/ansible/roles/rhel-system-roles.firewall/README.md