Configuring firewalls and packet filters
Managing the firewalld service, the nftables framework, and XDP packet filtering features
Abstract
firewalld service and the nftables framework to filter network traffic and build performance-critical firewalls. You can also use the Express Data Path (XDP) feature of the kernel to process or drop network packets at the network interface at a very high rate.
Providing feedback on Red Hat documentation Copy linkLink copied to clipboard!
We appreciate your feedback on our documentation. Let us know how we can improve it.
Submitting feedback through Jira (account required)
- Log in to the Jira website.
- Click Create in the top navigation bar
- Enter a descriptive title in the Summary field.
- Enter your suggestion for improvement in the Description field. Include links to the relevant parts of the documentation.
- Click Create at the bottom of the dialogue.
Chapter 1. Using and configuring firewalld Copy linkLink copied to clipboard!
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 it through.
firewalld is a firewall service daemon that provides a dynamic, customizable firewall with a D-Bus interface. Being dynamic, it enables creating, changing, and deleting rules without the necessity of restarting the firewall daemon each time the rules are changed.
You can use firewalld to configure packet filtering required by the majority of typical cases. If firewalld does not cover your scenario, or you want to have complete control of rules, use the nftables framework.
firewalld uses the concepts of zones, policies, and services to simplify traffic management. Zones logically separate a network. Network interfaces and sources can be assigned to a zone. Policies are used to deny or allow traffic flowing between zones. 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.
firewalld maintains separate runtime and permanent configurations. This allows runtime-only changes. The runtime configuration does not persist after firewalld reload or restart. At startup, it is populated from the permanent configuration.
Note that firewalld with nftables back end does not support passing custom nftables rules to firewalld, using the --direct option.
1.1. When to use firewalld or nftables Copy linkLink copied to clipboard!
On Red Hat Enterprise Linux, you can use the following packet-filtering utilities depending on your scenario:
-
firewalld: Thefirewalldutility simplifies firewall configuration for common use cases. -
nftables: Use thenftablesutility to set up complex and performance-critical firewalls, such as for a whole network.
To prevent the different firewall-related services (firewalld or nftables) from influencing each other, run only one of them on a RHEL host, and disable the other service.
1.2. Firewall zones Copy linkLink copied to clipboard!
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:
- Traffic ingresses only one zone.
- Traffic egresses only one zone.
- A zone defines a level of trust.
- Intrazone traffic (within the same zone) is allowed by default.
- 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-configutility -
firewall-cmdutility - 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
IPv4and icmp6-adm-prohibited forIPv6. - Accepts: Only network connections initiated from within the system.
-
Suitable for: Any incoming network connections are rejected with an icmp-host-prohibited message for
dmz- Suitable for: Computers in your DMZ that are publicly-accessible with limited access to your internal network.
- Accepts: Only selected incoming connections.
dropSuitable 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.
workSuitable 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.
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.
1.3. Firewall policies Copy linkLink copied to clipboard!
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.
1.4. Firewall rules Copy linkLink copied to clipboard!
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.
1.5. Firewall direct rules Copy linkLink copied to clipboard!
The firewalld service provides multiple ways with which to configure rules, including regular rules and direct rules.
One difference between these is how each method interacts with the underlying backend (iptables or nftables).
The direct rules are advanced, low-level rules that allow direct interaction with iptables. They bypass the structured zone-based management of firewalld to give you more control. You manually define the direct rules with the firewall-cmd command by using the raw iptables syntax. For example, firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -s 198.51.100.1 -j DROP. This command adds an iptables rule to drop traffic from the 198.51.100.1 source IP address.
However, using the direct rules also has its drawbacks. Especially when nftables is your primary firewall backend. For example:
-
The direct rules are harder to maintain and can conflict with
nftablesbasedfirewalldconfigurations. -
The direct rules do not support advanced features that you can find in
nftablessuch as raw expressions and stateful objects. -
Direct rules are not future-proof. The
iptablescomponent is deprecated and will eventually be removed from RHEL.
For the previous reasons, you might consider replacing firewalld direct rules with nftables. Review the knowledgebase solution How to replace firewalld direct rules with nftables? to see more details.
1.6. Predefined firewalld services Copy linkLink copied to clipboard!
Predefined firewalld services offer an abstraction layer for low-level firewall rules. They map common network services, such as SSH or HTTP, to their specific ports and protocols, simplifying firewall management and reducing errors by using a named service instead of manual configuration.
To see available predefined services:
firewall-cmd --get-services
# firewall-cmd --get-services RH-Satellite-6 RH-Satellite-6-capsule afp amanda-client amanda-k5-client amqp amqps apcupsd audit ausweisapp2 bacula bacula-client bareos-director bareos-filedaemon bareos-storage bb bgp bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc bittorrent-lsd ceph ceph-exporter ceph-mon cfengine checkmk-agent cockpit collectd condor-collector cratedb ctdb dds...Copy to Clipboard Copied! Toggle word wrap Toggle overflow To further inspect a particular predefined service:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The example output shows that the
RH-Satellite-6predefined service listens on ports 5000/tcp 5646-5647/tcp 5671/tcp 8000/tcp 8080/tcp 9090/tcp. Additionally,RH-Satellite-6inherits rules from another predefined service. In this caseforeman.
Each predefined service is stored as an XML file with the same name in the /usr/lib/firewalld/services/ directory.
1.7. Working with firewalld zones Copy linkLink copied to clipboard!
Zones represent a concept to manage incoming traffic more transparently. Network interfaces and source addresses are assigned to zones. You manage firewall rules for each zone independently, which enables you to define complex firewall settings and apply them to the traffic.
1.7.1. Customizing firewall settings for a specific zone to enhance security Copy linkLink copied to clipboard!
To strengthen network security, modify the firewalld settings by associating a specific network interface or connection with a particular firewall zone. By defining granular rules for a zone, you can control inbound and outbound traffic according to your security needs.
For example, you can achieve the following benefits:
- Protection of sensitive data
- Prevention of unauthorized access
- Mitigation of potential network threats
Prerequisites
-
The
firewalldservice is running.
Procedure
List the available firewall zones:
firewall-cmd --get-zones
# firewall-cmd --get-zonesCopy to Clipboard Copied! Toggle word wrap Toggle overflow The
firewall-cmd --get-zonescommand 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 thefirewall-cmd --list-all-zonescommand.- Choose the zone you want to use for this configuration.
Modify firewall settings for the chosen zone. For example, to allow the
SSHservice and remove theftpservice:firewall-cmd --add-service=ssh --zone=<your_chosen_zone> firewall-cmd --remove-service=ftp --zone=<same_chosen_zone>
# firewall-cmd --add-service=ssh --zone=<your_chosen_zone> # firewall-cmd --remove-service=ftp --zone=<same_chosen_zone>Copy to Clipboard Copied! Toggle word wrap Toggle overflow Assign a network interface to the firewall zone:
List the available network interfaces:
firewall-cmd --get-active-zones
# firewall-cmd --get-active-zonesCopy to Clipboard Copied! Toggle word wrap Toggle overflow 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.
Assign a network interface to the chosen zone:
firewall-cmd --zone=<your_chosen_zone> --change-interface=<interface_name> --permanent
# firewall-cmd --zone=<your_chosen_zone> --change-interface=<interface_name> --permanentCopy to Clipboard Copied! Toggle word wrap Toggle overflow 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-cmdcommand, when used with the--permanentoption, often involves updating NetworkManager connection profiles to make changes to the firewall configuration permanent. This integration betweenfirewalldand NetworkManager ensures consistent network and firewall settings.
Verification
Display the updated settings for your chosen zone:
firewall-cmd --zone=<your_chosen_zone> --list-all
# firewall-cmd --zone=<your_chosen_zone> --list-allCopy to Clipboard Copied! Toggle word wrap Toggle overflow The command output displays all zone settings including the assigned services, network interface, and network connections (sources).
1.7.2. Changing the default zone Copy linkLink copied to clipboard!
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. 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
firewalldservice is running.
Procedure
Display the current default zone:
firewall-cmd --get-default-zone
# firewall-cmd --get-default-zoneCopy to Clipboard Copied! Toggle word wrap Toggle overflow Set the new default zone:
firewall-cmd --set-default-zone <zone_name>
# firewall-cmd --set-default-zone <zone_name>Copy to Clipboard Copied! Toggle word wrap Toggle overflow NoteFollowing this procedure, the setting is a permanent setting, even without the
--permanentoption.
1.7.3. Assigning a network interface to a zone Copy linkLink copied to clipboard!
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
List the active zones and the interfaces assigned to them:
firewall-cmd --get-active-zones
# firewall-cmd --get-active-zonesCopy to Clipboard Copied! Toggle word wrap Toggle overflow Assign the interface to a different zone:
firewall-cmd --zone=zone_name --change-interface=interface_name --permanent
# firewall-cmd --zone=zone_name --change-interface=interface_name --permanentCopy to Clipboard Copied! Toggle word wrap Toggle overflow
1.7.4. Adding a source Copy linkLink copied to clipboard!
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.
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>
# firewall-cmd --add-source=<source>Copy to Clipboard Copied! Toggle word wrap Toggle overflow To set the source IP address for a specific zone:
firewall-cmd --zone=zone-name --add-source=<source>
# firewall-cmd --zone=zone-name --add-source=<source>Copy to Clipboard Copied! Toggle word wrap Toggle overflow
The following procedure allows all incoming traffic from 192.168.2.15 in the trusted zone:
Procedure
List all available zones:
firewall-cmd --get-zones
# firewall-cmd --get-zonesCopy to Clipboard Copied! Toggle word wrap Toggle overflow Add the source IP to the trusted zone in the permanent mode:
firewall-cmd --zone=trusted --add-source=192.168.2.15
# firewall-cmd --zone=trusted --add-source=192.168.2.15Copy to Clipboard Copied! Toggle word wrap Toggle overflow Make the new settings persistent:
firewall-cmd --runtime-to-permanent
# firewall-cmd --runtime-to-permanentCopy to Clipboard Copied! Toggle word wrap Toggle overflow
1.7.5. Removing a source Copy linkLink copied to clipboard!
When you remove a source from a firewalld zone, its traffic is no longer directed by that source’s rules. Instead, it falls back to the rules of the interface’s zone or the default zone.
Procedure
List allowed sources for the required zone:
firewall-cmd --zone=zone-name --list-sources
# firewall-cmd --zone=zone-name --list-sourcesCopy to Clipboard Copied! Toggle word wrap Toggle overflow Remove the source from the zone permanently:
firewall-cmd --zone=zone-name --remove-source=<source>
# firewall-cmd --zone=zone-name --remove-source=<source>Copy to Clipboard Copied! Toggle word wrap Toggle overflow Make the new settings persistent:
firewall-cmd --runtime-to-permanent
# firewall-cmd --runtime-to-permanentCopy to Clipboard Copied! Toggle word wrap Toggle overflow
1.7.6. Assigning a zone to a connection by using nmcli Copy linkLink copied to clipboard!
You can add a firewalld zone to a NetworkManager connection using the nmcli utility.
Procedure
Assign the zone to the
NetworkManagerconnection profile:nmcli connection modify profile connection.zone zone_name
# nmcli connection modify profile connection.zone zone_nameCopy to Clipboard Copied! Toggle word wrap Toggle overflow Activate the connection:
nmcli connection up profile
# nmcli connection up profileCopy to Clipboard Copied! Toggle word wrap Toggle overflow
1.7.7. Creating a new zone Copy linkLink copied to clipboard!
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
firewalldservice is running.
Procedure
Create a new zone:
firewall-cmd --permanent --new-zone=zone-name
# firewall-cmd --permanent --new-zone=zone-nameCopy to Clipboard Copied! Toggle word wrap Toggle overflow Make the new zone usable:
firewall-cmd --reload
# firewall-cmd --reloadCopy to Clipboard Copied! Toggle word wrap Toggle overflow 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
# firewall-cmd --get-zones --permanentCopy to Clipboard Copied! Toggle word wrap Toggle overflow
1.7.8. Enabling zones by using the web console Copy linkLink copied to clipboard!
You can apply predefined and existing firewall zones on a particular interface or a range of IP addresses through the RHEL web console.
Prerequisites
- You have installed the RHEL 9 web console.
- You have enabled the cockpit service.
Your user account is allowed to log in to the web console.
For instructions, see Installing and enabling the web console.
- You enabled administrative access in the web console.
-
The
firewalldservice is running.
Procedure
Log in to the RHEL 9 web console.
For details, see Logging in to the web console.
- Click Networking.
Click the button.
If you do not see the button, log in to the web console with the administrator privileges.
- In the Firewall section, click Add new zone.
In the Add zone dialog box, select a zone from the Trust level options.
The web console displays all zones predefined in the
firewalldservice.- In the Interfaces part, select an interface or interfaces to which you want to apply the selected zone.
In the Allowed Addresses part, you can select whether the zone is applied to:
- the whole subnet
a range of IP addresses in the following format:
- 192.168.1.0
- 192.168.1.0/24
- 192.168.1.0/24, 192.168.1.0
Click the button.
Verification
Check the configuration in the Firewall section:
1.7.9. Disabling zones by using the web console Copy linkLink copied to clipboard!
You can remove a firewall zone from your firewall configuration by using the web console.
Prerequisites
- You have installed the RHEL 9 web console.
- You have enabled the cockpit service.
Your user account is allowed to log in to the web console.
For instructions, see Installing and enabling the web console.
- You enabled administrative access in the web console.
-
The
firewalldservice is running.
Procedure
Log in to the RHEL 9 web console.
For details, see Logging in to the web console.
- Click Networking.
Click the button.
If you do not see the button, log in to the web console with the administrator privileges.
Click the Options icon at the zone you want to remove.
- Click Delete.
1.7.10. Using zone targets to set default behavior for incoming traffic Copy linkLink copied to clipboard!
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.
-
ACCEPT: Accepts all incoming packets except those disallowed by specific rules. -
REJECT: Rejects all incoming packets except those allowed by specific rules. Whenfirewalldrejects packets, the source machine is informed about the rejection. -
DROP: Drops all incoming packets except those allowed by specific rules. Whenfirewallddrops packets, the source machine is not informed about the packet drop. -
default: Similar behavior as forREJECT, but with special meanings in certain scenarios.
Prerequisites
-
The
firewalldservice is running.
Procedure
List the information for the specific zone to see the default target:
firewall-cmd --zone=zone-name --list-all
# firewall-cmd --zone=zone-name --list-allCopy to Clipboard Copied! Toggle word wrap Toggle overflow Set a new target in the zone:
firewall-cmd --permanent --zone=zone-name --set-target=<default|ACCEPT|REJECT|DROP>
# firewall-cmd --permanent --zone=zone-name --set-target=<default|ACCEPT|REJECT|DROP>Copy to Clipboard Copied! Toggle word wrap Toggle overflow
1.7.11. Configuring dynamic updates for allowlisting with IP sets Copy linkLink copied to clipboard!
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
firewalldservice is running.
Procedure
Create an IP set with a meaningful name:
firewall-cmd --permanent --new-ipset=allowlist --type=hash:ip
# firewall-cmd --permanent --new-ipset=allowlist --type=hash:ipCopy to Clipboard Copied! Toggle word wrap Toggle overflow The new IP set called
allowlistcontains IP addresses that you want your firewall to allow.Add a dynamic update to the IP set:
firewall-cmd --permanent --ipset=allowlist --add-entry=198.51.100.10
# firewall-cmd --permanent --ipset=allowlist --add-entry=198.51.100.10Copy to Clipboard Copied! Toggle word wrap Toggle overflow This configuration updates the
allowlistIP set with a newly added IP address that is allowed to pass network traffic by your firewall.Create a firewall rule that references the previously created IP set:
firewall-cmd --permanent --zone=public --add-source=ipset:allowlist
# firewall-cmd --permanent --zone=public --add-source=ipset:allowlistCopy to Clipboard Copied! Toggle word wrap Toggle overflow Without this rule, the IP set would not have any impact on network traffic. The default firewall policy would prevail.
Reload the firewall configuration to apply the changes:
firewall-cmd --reload
# firewall-cmd --reloadCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
List all IP sets:
firewall-cmd --get-ipsets
# firewall-cmd --get-ipsets allowlistCopy to Clipboard Copied! Toggle word wrap Toggle overflow List the active rules:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The
sourcessection 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 theallowlistIP set are allowed to pass traffic through the firewall for thepubliczone.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>
# cat /etc/firewalld/ipsets/allowlist.xml <?xml version="1.0" encoding="utf-8"?> <ipset type="hash:ip"> <entry>198.51.100.10</entry> </ipset>Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Next steps
-
Use a script or a security utility to fetch your threat intelligence feeds and update
allowlistaccordingly in an automated fashion.
1.8. Controlling network traffic using firewalld Copy linkLink copied to clipboard!
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.
1.8.1. Controlling traffic with predefined services using the CLI Copy linkLink copied to clipboard!
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
firewalldservice is running.
Procedure
Check that the service in
firewalldis not already allowed:firewall-cmd --list-services
# firewall-cmd --list-services ssh dhcpv6-clientCopy to Clipboard Copied! Toggle word wrap Toggle overflow The command lists the services that are enabled in the default zone.
List all predefined services in
firewalld:firewall-cmd --get-services
# 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 ...Copy to Clipboard Copied! Toggle word wrap Toggle overflow The command displays a list of available services for the default zone.
Add the service to the list of services that
firewalldallows:firewall-cmd --add-service=<service_name>
# firewall-cmd --add-service=<service_name>Copy to Clipboard Copied! Toggle word wrap Toggle overflow The command adds the specified service to the default zone.
Make the new settings persistent:
firewall-cmd --runtime-to-permanent
# firewall-cmd --runtime-to-permanentCopy to Clipboard Copied! Toggle word wrap Toggle overflow 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
List all permanent firewall rules:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The command displays complete configuration with the permanent firewall rules of the default firewall zone (
public).Check the validity of the permanent configuration of the
firewalldservice.firewall-cmd --check-config
# firewall-cmd --check-config successCopy to Clipboard Copied! Toggle word wrap Toggle overflow If the permanent configuration is invalid, the command returns an error with further details:
firewall-cmd --check-config
# firewall-cmd --check-config Error: INVALID_PROTOCOL: 'public.xml': 'tcpx' not from {'tcp'|'udp'|'sctp'|'dccp'}Copy to Clipboard Copied! Toggle word wrap Toggle overflow 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.
1.8.2. Enabling services on the firewall by using the web console Copy linkLink copied to clipboard!
By default, services are added to the default firewall zone. If you use more firewall zones on more network interfaces, you must select a zone first and then add the service with port.
The RHEL web console displays predefined firewalld services and you can add them to active firewall zones.
The RHEL 9 web console configures the firewalld service.
The web console does not allow generic firewalld rules that are not listed in the web console.
Prerequisites
- You have installed the RHEL 9 web console.
- You have enabled the cockpit service.
Your user account is allowed to log in to the web console.
For instructions, see Installing and enabling the web console.
- You enabled administrative access in the web console.
-
The
firewalldservice is running.
Procedure
Log in to the RHEL 9 web console.
For details, see Logging in to the web console.
- Click Networking.
Click the button.
If you do not see the button, log in to the web console with the administrator privileges.
In the Firewall section, select a zone for which you want to add the service and click Add Services.
- In the Add Services dialog box, find the service you want to enable in the firewall.
Enable services according to your scenario:
- Click Add Services.
1.8.3. Configuring custom ports by using the web console Copy linkLink copied to clipboard!
You can add custom ports for services through the RHEL web console.
Prerequisites
- You have installed the RHEL 9 web console.
- You have enabled the cockpit service.
Your user account is allowed to log in to the web console.
For instructions, see Installing and enabling the web console.
-
The
firewalldservice is running.
Procedure
Log in to the RHEL 9 web console.
For details, see Logging in to the web console.
- Click Networking.
Click the button.
If you do not see the button, log in to the web console with the administrative privileges.
In the Firewall section, select a zone for which you want to configure a custom port and click Add Services.
- In the Add services dialog box, click the radio button.
In the TCP and UDP fields, add ports according to examples. You can add ports in the following formats:
- Port numbers such as 22
- Range of port numbers such as 5900-5910
- Aliases such as nfs, rsync
NoteYou can add multiple values into each field. You must separate values with a comma and without a space, for example: 8080,8081,http
After adding the port number in the TCP field, the UDP field, or both, verify the service name in the Name field.
The Name field displays the name of the service for which this port is reserved. You can rewrite the name if you are sure that this port is free to use and no server requires it to communicate on this port.
- In the Name field, add a name for the service including defined ports.
Click the button.
Verification
To verify the settings, go to the Firewall page and find the service in the list of zone’s Services.
1.9. Filtering forwarded traffic between zones Copy linkLink copied to clipboard!
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.
1.9.1. The relationship between policy objects and zones Copy linkLink copied to clipboard!
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
# 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
HOSTsymbolic zone allows policies for the traffic originating from or has a destination to the host running firewalld. -
The
ANYsymbolic zone applies policy to all the current and future zones.ANYsymbolic zone acts as a wildcard for all zones.
1.9.2. Using priorities to sort policies Copy linkLink copied to clipboard!
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
# 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.
1.9.3. Using policy objects to filter traffic between locally hosted containers and a network physically connected to the host Copy linkLink copied to clipboard!
The policy objects feature enables users to filter traffic between Podman and firewalld zones.
Red Hat recommends blocking all traffic by default and opening the selective services needed for the Podman utility.
Procedure
Create a new firewall policy:
firewall-cmd --permanent --new-policy podmanToAny
# firewall-cmd --permanent --new-policy podmanToAnyCopy to Clipboard Copied! Toggle word wrap Toggle overflow 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
# 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 httpsCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create a new Podman zone:
firewall-cmd --permanent --new-zone=podman
# firewall-cmd --permanent --new-zone=podmanCopy to Clipboard Copied! Toggle word wrap Toggle overflow Define the ingress zone for the policy:
firewall-cmd --permanent --policy podmanToHost --add-ingress-zone podman
# firewall-cmd --permanent --policy podmanToHost --add-ingress-zone podmanCopy to Clipboard Copied! Toggle word wrap Toggle overflow Define the egress zone for all other zones:
firewall-cmd --permanent --policy podmanToHost --add-egress-zone ANY
# firewall-cmd --permanent --policy podmanToHost --add-egress-zone ANYCopy to Clipboard Copied! Toggle word wrap Toggle overflow 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.
Restart the firewalld service:
systemctl restart firewalld
# systemctl restart firewalldCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Verify the Podman firewall policy to other zones:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
1.9.4. Setting the default target of policy objects Copy linkLink copied to clipboard!
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.
Procedure
Set the default target:
firewall-cmd --permanent --policy mypolicy --set-target CONTINUE
# firewall-cmd --permanent --policy mypolicy --set-target CONTINUECopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Verify information about the policy
firewall-cmd --info-policy mypolicy
# firewall-cmd --info-policy mypolicyCopy to Clipboard Copied! Toggle word wrap Toggle overflow
1.10. Configuring NAT by using firewalld Copy linkLink copied to clipboard!
With firewalld, you can configure the masquerading, destination NAT (DNAT), and redirect NAT types. With NAT, you can modify the source or destination IP address.
1.10.1. Network address translation types Copy linkLink copied to clipboard!
If you require network address translation (NAT) in your network, it is important to understand the NAT types.
These are the different NAT types:
- Masquerading
Use this NAT type 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.
1.10.2. Configuring IP address masquerading Copy linkLink copied to clipboard!
You can enable IP masquerading on your system. IP masquerading hides individual machines behind a gateway when accessing the internet.
Procedure
To check if IP masquerading is enabled (for example, for the
externalzone), enter the following command asroot:firewall-cmd --zone=external --query-masquerade
# firewall-cmd --zone=external --query-masqueradeCopy to Clipboard Copied! Toggle word wrap Toggle overflow The command prints
yeswith exit status0if enabled. It printsnowith exit status1otherwise. Ifzoneis omitted, the default zone will be used.To enable IP masquerading, enter the following command as
root:firewall-cmd --zone=external --add-masquerade
# firewall-cmd --zone=external --add-masqueradeCopy to Clipboard Copied! Toggle word wrap Toggle overflow -
To make this setting persistent, pass the
--permanentoption to the command. To disable IP masquerading, enter the following command as
root:firewall-cmd --zone=external --remove-masquerade
# firewall-cmd --zone=external --remove-masqueradeCopy to Clipboard Copied! Toggle word wrap Toggle overflow To make this setting permanent, pass the
--permanentoption to the command.
1.10.3. Using DNAT to forward incoming HTTP traffic Copy linkLink copied to clipboard!
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
firewalldservice is running.
Procedure
Forward incoming HTTP traffic:
firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:toaddr=198.51.100.10:toport=8080 --permanent
# firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:toaddr=198.51.100.10:toport=8080 --permanentCopy to Clipboard Copied! Toggle word wrap Toggle overflow 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.
-
Reload the firewall configuration to apply the changes:
firewall-cmd --reload
# firewall-cmd --reloadCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Verify the DNAT rule for the firewall zone that you used:
firewall-cmd --list-forward-ports --zone=public
# firewall-cmd --list-forward-ports --zone=public port=80:proto=tcp:toport=8080:toaddr=198.51.100.10Copy to Clipboard Copied! Toggle word wrap Toggle overflow Alternatively, view the corresponding XML configuration file:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
1.10.4. Redirecting traffic from a non-standard port to make the web service accessible on a standard port Copy linkLink copied to clipboard!
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.
If you use redirect, the URLs are simpler and provide better browsing experience, while a non-standard port is still used internally or for specific requirements.
Prerequisites
-
The
firewalldservice is running.
Procedure
Create the NAT redirect rule:
firewall-cmd --zone=public --add-forward-port=port=<standard_port>:proto=tcp:toport=<non_standard_port> --permanent
# firewall-cmd --zone=public --add-forward-port=port=<standard_port>:proto=tcp:toport=<non_standard_port> --permanentCopy to Clipboard Copied! Toggle word wrap Toggle overflow 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.
-
Reload the firewall configuration to apply the changes:
firewall-cmd --reload
# firewall-cmd --reloadCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Verify the redirect rule for the firewall zone that you used:
firewall-cmd --list-forward-ports
# firewall-cmd --list-forward-ports port=8080:proto=tcp:toport=80:toaddr=Copy to Clipboard Copied! Toggle word wrap Toggle overflow Alternatively, view the corresponding XML configuration file:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
1.11. Prioritizing rich rules Copy linkLink copied to clipboard!
Rich rules provide a more advanced and flexible way to define firewall rules. Rich rules are particularly useful where services, ports, and so on are not enough to express complex firewall rules.
Concepts behind rich rules:
- granularity and flexibility
- You can define detailed conditions for network traffic based on more specific criteria.
- rule structure
A rich rule consists of a family (IPv4 or IPv6), followed by conditions and actions.
rule family="ipv4|ipv6" [conditions] [actions]
rule family="ipv4|ipv6" [conditions] [actions]Copy to Clipboard Copied! Toggle word wrap Toggle overflow - conditions
- They allow rich rules to apply only when certain criteria are met.
- actions
- You can define what happens to network traffic that matches the conditions.
- combining multiple conditions
- You can create more specific and complex filtering.
- hierarchical control and reusability
- You can combine rich rules with other firewall mechanisms such as zones or services.
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.
1.11.1. How the priority parameter organizes rules into different chains Copy linkLink copied to clipboard!
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
_presuffix. -
Priority higher than 0: the rule is redirected into a chain with the
_postsuffix. -
Priority equals 0: based on the action, the rule is redirected into a chain with the
_log,_deny, or_allowthe action.
Inside these sub-chains, firewalld sorts the rules based on their priority value.
1.11.2. Setting the priority of a rich rule Copy linkLink copied to clipboard!
You can use the priority parameter to log all traffic that is not allowed or denied by other rules. For example, you can use this feature 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"'
# firewall-cmd --add-rich-rule='rule priority=32767 log prefix="UNEXPECTED: " limit value="5/m"'Copy to Clipboard Copied! Toggle word wrap Toggle overflow The command additionally limits the number of log entries to
5per minute.
Verification
Display the
nftablesrule that the command in the previous step created:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
1.12. Enabling traffic forwarding between different interfaces or sources within a firewalld zone Copy linkLink copied to clipboard!
Intra-zone forwarding is a firewalld feature that enables traffic forwarding between interfaces or sources within a firewalld zone.
1.12.1. The difference between intra-zone forwarding and zones with the default target set to ACCEPT Copy linkLink copied to clipboard!
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.
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.
1.12.2. Using intra-zone forwarding to forward traffic between an Ethernet and Wi-Fi network Copy linkLink copied to clipboard!
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
enp1s0and a Wi-Fi network connected towlp0s20) - 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
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
# echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf # sysctl -p /etc/sysctl.d/95-IPv4-forwarding.confCopy to Clipboard Copied! Toggle word wrap Toggle overflow Ensure that interfaces between which you want to enable intra-zone forwarding are assigned only to the
internalzone:firewall-cmd --get-active-zones
# firewall-cmd --get-active-zonesCopy to Clipboard Copied! Toggle word wrap Toggle overflow If the interface is currently assigned to a zone other than
internal, reassign it:firewall-cmd --zone=internal --change-interface=interface_name --permanent
# firewall-cmd --zone=internal --change-interface=interface_name --permanentCopy to Clipboard Copied! Toggle word wrap Toggle overflow Add the
enp1s0andwlp0s20interfaces to theinternalzone:firewall-cmd --zone=internal --add-interface=enp1s0 --add-interface=wlp0s20
# firewall-cmd --zone=internal --add-interface=enp1s0 --add-interface=wlp0s20Copy to Clipboard Copied! Toggle word wrap Toggle overflow Enable intra-zone forwarding:
firewall-cmd --zone=internal --add-forward
# firewall-cmd --zone=internal --add-forwardCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
-
Log in to a host that is on the same network as the
enp1s0interface of the host on which you enabled zone forwarding. Start an echo service with
ncatto test connectivity:ncat -e /usr/bin/cat -l 12345
# ncat -e /usr/bin/cat -l 12345Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
Log in to a host that is in the same network as the
wlp0s20interface. Connect to the echo server running on the host that is in the same network as the
enp1s0:ncat <other_host> 12345
# ncat <other_host> 12345Copy to Clipboard Copied! Toggle word wrap Toggle overflow - Type something and press . Verify the text is sent back.
1.13. Configuring firewalld by using RHEL system roles Copy linkLink copied to clipboard!
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 at once.
The rhel-system-roles package contains the rhel-system-roles.firewall RHEL system role. This role was introduced for automated configurations of the firewalld service.
With the firewall RHEL system 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
1.13.1. Resetting the firewalld settings by using the firewall RHEL system role Copy linkLink copied to clipboard!
The firewall RHEL system role supports automating a reset of firewalld settings to their defaults. This efficiently removes insecure or unintentional firewall rules and simplifies management.
Prerequisites
- You have prepared the control node and the managed nodes.
-
The account you use to connect to the managed nodes has
sudopermissions for these nodes.
Procedure
Create a playbook file, for example,
~/playbook.yml, with the following content:Copy to Clipboard Copied! Toggle word wrap Toggle overflow The settings specified in the example playbook include the following:
previous: replacedRemoves all existing user-defined settings and resets the
firewalldsettings to defaults. If you combine theprevious:replacedparameter with other settings, thefirewallrole removes all existing settings before applying new ones.For details about all variables used in the playbook, see the
/usr/share/ansible/roles/rhel-system-roles.firewall/README.mdfile on the control node.
Validate the playbook syntax:
ansible-playbook --syntax-check ~/playbook.yml
$ ansible-playbook --syntax-check ~/playbook.ymlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Note that this command only validates the syntax and does not protect against a wrong but valid configuration.
Run the playbook:
ansible-playbook ~/playbook.yml
$ ansible-playbook ~/playbook.ymlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Run this command on the control node to remotely check that all firewall configuration on your managed node was reset to its default values:
ansible managed-node-01.example.com -m ansible.builtin.command -a 'firewall-cmd --list-all-zones'
# ansible managed-node-01.example.com -m ansible.builtin.command -a 'firewall-cmd --list-all-zones'Copy to Clipboard Copied! Toggle word wrap Toggle overflow
1.13.2. Forwarding incoming traffic in firewalld from one local port to a different local port by using the firewall RHEL system role Copy linkLink copied to clipboard!
You can use the firewall RHEL system role to remotely configure forwarding of incoming traffic from one local port to a different local port.
For example, if you have an environment where multiple services co-exist on the same machine and need the same default port, there are likely to become port conflicts. These conflicts can disrupt services and cause downtime. With the firewall RHEL system role, you can efficiently forward traffic to alternative ports to ensure that your services can run simultaneously without modification to their configuration.
Prerequisites
- You have prepared the control node and the managed nodes.
-
The account you use to connect to the managed nodes has
sudopermissions for these nodes.
Procedure
Create a playbook file, for example,
~/playbook.yml, with the following content:Copy to Clipboard Copied! Toggle word wrap Toggle overflow The settings specified in the example playbook include the following:
forward_port: 8080/tcp;443- Traffic coming to the local port 8080 using the TCP protocol is forwarded to port 443.
runtime: trueEnables changes in the runtime configuration. The default is set to
true.For details about all variables used in the playbook, see the
/usr/share/ansible/roles/rhel-system-roles.firewall/README.mdfile on the control node.
Validate the playbook syntax:
ansible-playbook --syntax-check ~/playbook.yml
$ ansible-playbook --syntax-check ~/playbook.ymlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Note that this command only validates the syntax and does not protect against a wrong but valid configuration.
Run the playbook:
ansible-playbook ~/playbook.yml
$ ansible-playbook ~/playbook.ymlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
On the control node, run the following command to remotely check the forwarded-ports on your managed node:
ansible managed-node-01.example.com -m ansible.builtin.command -a 'firewall-cmd --list-forward-ports'
# ansible managed-node-01.example.com -m ansible.builtin.command -a 'firewall-cmd --list-forward-ports' managed-node-01.example.com | CHANGED | rc=0 >> port=8080:proto=tcp:toport=443:toaddr=Copy to Clipboard Copied! Toggle word wrap Toggle overflow
1.13.3. Configuring a firewalld DMZ zone by using the firewall RHEL system role Copy linkLink copied to clipboard!
You can use the firewall RHEL system role to configure a zone to allow certain traffic. For example, you can configure that the dmz zone with the enp1s0 interface allows HTTPS traffic to enable external users to access your web servers.
Prerequisites
- You have prepared the control node and the managed nodes.
-
The account you use to connect to the managed nodes has
sudopermissions for these nodes.
Procedure
Create a playbook file, for example,
~/playbook.yml, with the following content:Copy to Clipboard Copied! Toggle word wrap Toggle overflow For details about all variables used in the playbook, see the
/usr/share/ansible/roles/rhel-system-roles.firewall/README.mdfile on the control node.Validate the playbook syntax:
ansible-playbook --syntax-check ~/playbook.yml
$ ansible-playbook --syntax-check ~/playbook.ymlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Note that this command only validates the syntax and does not protect against a wrong but valid configuration.
Run the playbook:
ansible-playbook ~/playbook.yml
$ ansible-playbook ~/playbook.ymlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
On the control node, run the following command to remotely check the information about the
dmzzone on your managed node:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
1.13.4. Creating a custom firewalld service by using the firewall RHEL system role Copy linkLink copied to clipboard!
In firewalld, a service is a named collection of rules that permit traffic for specific applications. Instead of manually managing individual ports and protocols, administrators can open up traffic by using a service name.
You can use the firewall RHEL system role to automate the creation of custom service files, making your firewall configurations simpler and more reusable.
Prerequisites
- You have prepared the control node and the managed nodes.
-
The account you use to connect to the managed nodes has
sudopermissions for these nodes.
Procedure
Create a playbook file, for example
~/playbook.yml, with the following content:Copy to Clipboard Copied! Toggle word wrap Toggle overflow The settings specified in the example playbook include the following:
service: <service_name>- Sets the name of the service.
short: <short_description>- Sets a short description for the service.
description: <description>- Sets a long description for the service.
port: <port>/<protocol>- Defines the ports and protocols the service file should allow. To define multiple entries, use a YAML list.
includes: <services>-
Optional: Defines other
firewalldservice files the service you want to create should include. state: present- Adds the service. If the service already exists, the role modifies it as defined.
permanent: trueEnables changes in the permanent configuration of
firewalld.For details about all variables used in the playbook, see the
/usr/share/ansible/roles/rhel-system-roles.firewall/README.mdfile on the control node.
Validate the playbook syntax:
ansible-playbook --syntax-check ~/playbook.yml
$ ansible-playbook --syntax-check ~/playbook.ymlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Note that this command only validates the syntax and does not protect against a wrong but valid configuration.
Run the playbook:
ansible-playbook ~/playbook.yml
$ ansible-playbook ~/playbook.ymlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Display the service definition you created:
ansible managed-node-01.example.com -m ansible.builtin.command -a 'firewall-cmd --info-service=custom_service'
# ansible managed-node-01.example.com -m ansible.builtin.command -a 'firewall-cmd --info-service=custom_service'Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Chapter 2. Getting started with nftables Copy linkLink copied to clipboard!
If your scenario does not fall under typical packet-filtering cases covered by firewalld, or you want to have complete control of rules, you can use the nftables framework.
The nftables framework classifies packets, and it is the successor to the iptables, ip6tables, arptables, ebtables, and ipset utilities. It offers numerous improvements in convenience, features, and performance over previous packet-filtering tools, most notably:
- Built-in lookup tables instead of linear processing
-
A single framework for both the
IPv4andIPv6protocols - Updating the kernel rule set in place through transactions instead of fetching, updating, and storing the entire rule set
-
Support for debugging and tracing in the rule set (
nftrace) and monitoring trace events (in thenfttool) - More consistent and compact syntax, no protocol-specific extensions
- A Netlink API for third-party applications
The nftables framework uses tables to store chains. The chains contain individual rules for performing actions. The nft utility replaces all tools from the previous packet-filtering frameworks. You can use the libnftables library for low-level interaction with nftables Netlink API through the libnftnl library.
To display the effect of rule set changes, use the nft list ruleset command. To clear the kernel rule set, use the nft flush ruleset command. Note that this may also affect the rule set installed by the iptables-nft command, as it utilizes the same kernel infrastructure.
2.1. Creating and managing nftables tables, chains, and rules Copy linkLink copied to clipboard!
You can display nftables rule sets and manage them.
2.1.1. Basics of nftables tables Copy linkLink copied to clipboard!
A table in nftables is a namespace that contains a collection of chains, rules, sets, and other objects.
Each table must have an address family assigned. The address family defines the packet types that this table processes. You can set one of the following address families when you create a table:
-
ip: Matches only IPv4 packets. This is the default if you do not specify an address family. -
ip6: Matches only IPv6 packets. -
inet: Matches both IPv4 and IPv6 packets. -
arp: Matches IPv4 address resolution protocol (ARP) packets. -
bridge: Matches packets that pass through a bridge device. -
netdev: Matches packets from ingress.
If you want to add a table, the format to use depends on your firewall script:
In scripts in native syntax, use:
table <table_address_family> <table_name> { }table <table_address_family> <table_name> { }Copy to Clipboard Copied! Toggle word wrap Toggle overflow In shell scripts, use:
nft add table <table_address_family> <table_name>
nft add table <table_address_family> <table_name>Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.1.2. Basics of nftables chains Copy linkLink copied to clipboard!
Tables consist of chains which in turn are containers for rules. The following two rule types exists:
- Base chain: You can use base chains as an entry point for packets from the networking stack.
-
Regular chain: You can use regular chains as a
jumptarget to better organize rules.
If you want to add a base chain to a table, the format to use depends on your firewall script:
In scripts in native syntax, use:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow In shell scripts, use:
nft add chain <table_address_family> <table_name> <chain_name> { type <type> hook <hook> priority <priority> \; policy <policy> \; }nft add chain <table_address_family> <table_name> <chain_name> { type <type> hook <hook> priority <priority> \; policy <policy> \; }Copy to Clipboard Copied! Toggle word wrap Toggle overflow To avoid that the shell interprets the semicolons as the end of the command, place the
\escape character in front of the semicolons.
Both examples create base chains. To create a regular chain, do not set any parameters in the curly brackets.
Chain types:
The following are the chain types and an overview with which address families and hooks you can use them:
| Type | Address families | Hooks | Description |
|---|---|---|---|
|
| all | all | Standard chain type |
|
|
|
| Chains of this type perform native address translation based on connection tracking entries. Only the first packet traverses this chain type. |
|
|
|
| Accepted packets that traverse this chain type cause a new route lookup if relevant parts of the IP header have changed. |
Chain priorities:
The priority parameter specifies the order in which packets traverse chains with the same hook value. You can set this parameter to an integer value or use a standard priority name.
The following matrix is an overview of the standard priority names and their numeric values, and with which address families and hooks you can use them:
| Textual value | Numeric value | Address families | Hooks |
|---|---|---|---|
|
|
|
| all |
|
|
|
| all |
|
|
|
|
|
|
|
|
| |
|
|
|
| all |
|
|
| all | |
|
|
|
| all |
|
|
|
|
|
|
|
|
| |
|
|
|
|
|
Chain policies:
The chain policy defines whether nftables should accept or drop packets if rules in this chain do not specify any action. You can set one of the following policies in a chain:
-
accept(default) -
drop
2.1.3. Basics of nftables rules Copy linkLink copied to clipboard!
Rules define actions to perform on packets that pass a chain that contains this rule. If the rule also contains matching expressions, nftables performs the actions only if all previous expressions apply.
If you want to add a rule to a chain, the format to use depends on your firewall script:
In scripts in native syntax, use:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow In shell scripts, use:
nft add rule <table_address_family> <table_name> <chain_name> <rule>
nft add rule <table_address_family> <table_name> <chain_name> <rule>Copy to Clipboard Copied! Toggle word wrap Toggle overflow This shell command appends the new rule at the end of the chain. If you prefer to add a rule at the beginning of the chain, use the
nft insertcommand instead ofnft add.
2.1.4. Managing tables, chains, and rules by using nft commands Copy linkLink copied to clipboard!
To manage an nftables firewall on the command line or in shell scripts, use the nft utility.
The commands in this procedure do not represent a typical workflow and are not optimized. This procedure only demonstrates how to use nft commands to manage tables, chains, and rules in general.
Procedure
Create a table named
nftables_svcwith theinetaddress family so that the table can process both IPv4 and IPv6 packets:nft add table inet nftables_svc
# nft add table inet nftables_svcCopy to Clipboard Copied! Toggle word wrap Toggle overflow Add a base chain named
INPUT, that processes incoming network traffic, to theinet nftables_svctable:nft add chain inet nftables_svc INPUT { type filter hook input priority filter \; policy accept \; }# nft add chain inet nftables_svc INPUT { type filter hook input priority filter \; policy accept \; }Copy to Clipboard Copied! Toggle word wrap Toggle overflow To avoid that the shell interprets the semicolons as the end of the command, escape the semicolons using the
\character.Add rules to the
INPUTchain. For example, allow incoming TCP traffic on port 22 and 443, and, as the last rule of theINPUTchain, reject other incoming traffic with an Internet Control Message Protocol (ICMP) port unreachable message:nft add rule inet nftables_svc INPUT tcp dport 22 accept nft add rule inet nftables_svc INPUT tcp dport 443 accept nft add rule inet nftables_svc INPUT reject with icmpx type port-unreachable
# nft add rule inet nftables_svc INPUT tcp dport 22 accept # nft add rule inet nftables_svc INPUT tcp dport 443 accept # nft add rule inet nftables_svc INPUT reject with icmpx type port-unreachableCopy to Clipboard Copied! Toggle word wrap Toggle overflow If you enter the
nft add rulecommands as shown,nftadds the rules in the same order to the chain as you run the commands.Display the current rule set including handles:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Insert a rule before the existing rule with handle 3. For example, to insert a rule that allows TCP traffic on port 636, enter:
nft insert rule inet nftables_svc INPUT position 3 tcp dport 636 accept
# nft insert rule inet nftables_svc INPUT position 3 tcp dport 636 acceptCopy to Clipboard Copied! Toggle word wrap Toggle overflow Append a rule after the existing rule with handle 3. For example, to insert a rule that allows TCP traffic on port 80, enter:
nft add rule inet nftables_svc INPUT position 3 tcp dport 80 accept
# nft add rule inet nftables_svc INPUT position 3 tcp dport 80 acceptCopy to Clipboard Copied! Toggle word wrap Toggle overflow Display the rule set again with handles. Verify that the later added rules have been added to the specified positions:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Remove the rule with handle 6:
nft delete rule inet nftables_svc INPUT handle 6
# nft delete rule inet nftables_svc INPUT handle 6Copy to Clipboard Copied! Toggle word wrap Toggle overflow To remove a rule, you must specify the handle.
Display the rule set, and verify that the removed rule is no longer present:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Remove all remaining rules from the
INPUTchain:nft flush chain inet nftables_svc INPUT
# nft flush chain inet nftables_svc INPUTCopy to Clipboard Copied! Toggle word wrap Toggle overflow Display the rule set, and verify that the
INPUTchain is empty:Copy to Clipboard Copied! Toggle word wrap Toggle overflow Delete the
INPUTchain:nft delete chain inet nftables_svc INPUT
# nft delete chain inet nftables_svc INPUTCopy to Clipboard Copied! Toggle word wrap Toggle overflow You can also use this command to delete chains that still contain rules.
Display the rule set, and verify that the
INPUTchain has been deleted:nft list table inet nftables_svc
# nft list table inet nftables_svc table inet nftables_svc { }Copy to Clipboard Copied! Toggle word wrap Toggle overflow Delete the
nftables_svctable:nft delete table inet nftables_svc
# nft delete table inet nftables_svcCopy to Clipboard Copied! Toggle word wrap Toggle overflow You can also use this command to delete tables that still contain chains.
NoteTo delete the entire rule set, use the
nft flush rulesetcommand instead of manually deleting all rules, chains, and tables in separate commands.
2.2. Migrating from iptables to nftables Copy linkLink copied to clipboard!
If your firewall configuration still uses iptables rules, you can migrate your iptables rules to nftables.
The ipset and iptables-nft packages have been deprecated in Red Hat Enterprise Linux 9. This includes deprecation of nft-variants such as iptables, ip6tables, arptables, and ebtables utilities. If you are using any of these tools, for example, because you upgraded from an earlier RHEL version, Red Hat recommends migrating to the nft command line tool provided by the nftables package.
2.2.1. When to use firewalld or nftables Copy linkLink copied to clipboard!
On Red Hat Enterprise Linux, you can use the following packet-filtering utilities depending on your scenario:
-
firewalld: Thefirewalldutility simplifies firewall configuration for common use cases. -
nftables: Use thenftablesutility to set up complex and performance-critical firewalls, such as for a whole network.
To prevent the different firewall-related services (firewalld or nftables) from influencing each other, run only one of them on a RHEL host, and disable the other service.
2.2.2. Concepts in the nftables framework Copy linkLink copied to clipboard!
The nftables framework is a modern, efficient, and flexible alternative to iptables. It simplifies rule management and enhances performance, making it a better choice for complex, high-performance network environments.
- Tables and namespaces
-
In
nftables, tables represent organizational units or namespaces that group together related firewall chains, sets, flowtables, and other objects. Innftables, tables provide a more flexible way to structure firewall rules and related components. While iniptables, the tables were more rigidly defined with specific purposes. - Table families
-
Each table in
nftablesis associated with a specific family (ip,ip6,inet,arp,bridge, ornetdev). This association determines which packets the table can process. For example, a table in theipfamily handles only IPv4 packets. On the other hand,inetis a special case of table family. It offers a unified approach across protocols, because it can process both IPv4 and IPv6 packets. Another case of a special table family isnetdev, because it is used for rules that apply directly to network devices, enabling filtering at the device level. - Base chains
Base chains in
nftablesare highly configurable entry-points in the packet processing pipeline that enable users to specify the following:- Type of chain, for example, "filter"
- The hook point in the packet processing path, for example, "input", "output", "forward"
- Priority of the chain
This flexibility enables precise control over when and how the rules are applied to packets as they pass through the network stack. A special case of a chain is the
routechain, which is used to influence the routing decisions made by the kernel, based on packet headers.- Virtual machine for rule processing
The
nftablesframework uses an internal virtual machine to process rules. This virtual machine executes instructions that are similar to assembly language operations (loading data into registers, performing comparisons, and so on). Such a mechanism allows for highly flexible and efficient rule processing.Enhancements in
nftablescan be introduced as new instructions for that virtual machine. This typically requires a new kernel module and updates to thelibnftnllibrary and thenftcommand-line utility.Alternatively, you can introduce new features by combining existing instructions in innovative ways without a need for kernel modifications. The syntax of
nftablesrules reflects the flexibility of the underlying virtual machine. For example, the rulemeta mark set tcp dport map { 22: 1, 80: 2 }sets a packet’s firewall mark to 1 if the TCP destination port is 22, and to 2 if the port is 80. This demonstrates how complex logic can be expressed concisely.- Complex filtering and verdict maps
The
nftablesframework integrates and extends the functionality of theipsetutility, which is used iniptablesfor bulk matching on IP addresses, ports, other data types and, most importantly, combinations thereof. This integration makes it easier to manage large and dynamic sets of data directly withinnftables. Next,nftablesnatively supports matching packets based on multiple values or ranges for any data type, which enhances its capability to handle complex filtering requirements. Withnftablesyou can manipulate any field within a packet.In
nftables, sets can be either named or anonymous. The named sets can be referenced by multiple rules and modified dynamically. The anonymous sets are defined inline within a rule and are immutable. Sets can contain elements that are combinations of different types, for example IP address and port number pairs. This feature provides greater flexibility in matching complex criteria. To manage sets, the kernel can select the most appropriate backend based on the specific requirements (performance, memory efficiency, and others). Sets can also function as maps with key-value pairs. The value part can be used as data points (values to write into packet headers), or as verdicts or chains to jump to. This enables complex and dynamic rule behaviors, known as "verdict maps".- Flexible rule format
The structure of
nftablesrules is straightforward. The conditions and actions are applied sequentially from left to right. This intuitive format simplifies rule creating and troubleshooting.Conditions in a rule are logically connected (with the AND operator) together, which means that all conditions must be evaluated as "true" for the rule to match. If any condition fails, the evaluation moves to the next rule.
Actions in
nftablescan be final, such asdroporaccept, which stop further rule processing for the packet. Non-terminal actions, such ascounter log meta mark set 0x3, perform specific tasks (counting packets, logging, setting a mark, and others), but allow subsequent rules to be evaluated.
2.2.3. Concepts in the deprecated iptables framework Copy linkLink copied to clipboard!
Similar to the actively-maintained nftables framework, the deprecated iptables framework enables you to perform a variety of packet filtering tasks, logging and auditing, NAT-related configuration tasks, and more.
The iptables framework is structured into multiple tables, where each table is designed for a specific purpose:
filter- The default table, ensures general packet filtering
nat- For Network Address Translation (NAT), includes altering the source and destination addresses of packets
mangle- For specific packet alteration, enables you to do modification of packet headers for advanced routing decisions
raw- For configurations that need to happen before connection tracking
These tables are implemented as separate kernel modules, where each table offers a fixed set of builtin chains such as INPUT, OUTPUT, and FORWARD. A chain is a sequence of rules that packets are evaluated against. These chains hook into specific points in the packet processing flow in the kernel. The chains have the same names across different tables, however their order of execution is determined by their respective hook priorities. The priorities are managed internally by the kernel to make sure that the rules are applied in the correct sequence.
Originally, iptables was designed to process IPv4 traffic. However, with the inception of the IPv6 protocol, the ip6tables utility needed to be introduced to provide comparable functionality (as iptables) and enable users to create and manage firewall rules for IPv6 packets. With the same logic, the arptables utility was created to process Address Resolution Protocol (ARP) and the ebtables utility was developed to handle Ethernet bridging frames. These tools ensure that you can apply the packet filtering abilities of iptables across various network protocols and provide comprehensive network coverage.
To enhance the functionality of iptables, the extensions started to be developed. The functionality extensions are typically implemented as kernel modules that are paired with user-space dynamic shared objects (DSOs). The extensions introduce "matches" and "targets" that you can use in firewall rules to perform more sophisticated operations. Extensions can enable complex matches and targets. For instance you can match on, or manipulate specific layer 4 protocol header values, perform rate-limiting, enforce quotas, and so on. Some extensions are designed to address limitations in the default iptables syntax, for example the "multiport" match extension. This extension allows a single rule to match multiple, non-consecutive ports to simplify rule definitions, and thereby reducing the number of individual rules required.
An ipset is a special kind of functionality extension to iptables. It is a kernel-level data structure that is used together with iptables to create collections of IP addresses, port numbers, and other network-related elements that you can match against packets. These sets significantly streamline, optimize, and accelerate the process of writing and managing firewall rules.
2.2.4. Converting iptables and ip6tables rule sets to nftables Copy linkLink copied to clipboard!
Use the iptables-restore-translate and ip6tables-restore-translate utilities to translate iptables and ip6tables rule sets to nftables.
Prerequisites
-
The
nftablesandiptablespackages are installed. -
The system has
iptablesandip6tablesrules configured.
Procedure
Write the
iptablesandip6tablesrules to a file:iptables-save >/root/iptables.dump ip6tables-save >/root/ip6tables.dump
# iptables-save >/root/iptables.dump # ip6tables-save >/root/ip6tables.dumpCopy to Clipboard Copied! Toggle word wrap Toggle overflow Convert the dump files to
nftablesinstructions:iptables-restore-translate -f /root/iptables.dump > /etc/nftables/ruleset-migrated-from-iptables.nft ip6tables-restore-translate -f /root/ip6tables.dump > /etc/nftables/ruleset-migrated-from-ip6tables.nft
# iptables-restore-translate -f /root/iptables.dump > /etc/nftables/ruleset-migrated-from-iptables.nft # ip6tables-restore-translate -f /root/ip6tables.dump > /etc/nftables/ruleset-migrated-from-ip6tables.nftCopy to Clipboard Copied! Toggle word wrap Toggle overflow -
Review and, if needed, manually update the generated
nftablesrules. To enable the
nftablesservice to load the generated files, add the following to the/etc/sysconfig/nftables.conffile:include "/etc/nftables/ruleset-migrated-from-iptables.nft" include "/etc/nftables/ruleset-migrated-from-ip6tables.nft"
include "/etc/nftables/ruleset-migrated-from-iptables.nft" include "/etc/nftables/ruleset-migrated-from-ip6tables.nft"Copy to Clipboard Copied! Toggle word wrap Toggle overflow Stop and disable the
iptablesservice:systemctl disable --now iptables
# systemctl disable --now iptablesCopy to Clipboard Copied! Toggle word wrap Toggle overflow If you used a custom script to load the
iptablesrules, ensure that the script no longer starts automatically and reboot to flush all tables.Enable and start the
nftablesservice:systemctl enable --now nftables
# systemctl enable --now nftablesCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Display the
nftablesrule set:nft list ruleset
# nft list rulesetCopy to Clipboard Copied! Toggle word wrap Toggle overflow
2.2.5. Converting single iptables and ip6tables rules to nftables Copy linkLink copied to clipboard!
Red Hat Enterprise Linux provides the iptables-translate and ip6tables-translate utilities to convert an iptables or ip6tables rule into the equivalent one for nftables.
Prerequisites
-
The
nftablespackage is installed.
Procedure
Use the
iptables-translateorip6tables-translateutility instead ofiptablesorip6tablesto display the correspondingnftablesrule, for example:iptables-translate -A INPUT -s 192.0.2.0/24 -j ACCEPT
# iptables-translate -A INPUT -s 192.0.2.0/24 -j ACCEPT nft add rule ip filter INPUT ip saddr 192.0.2.0/24 counter acceptCopy to Clipboard Copied! Toggle word wrap Toggle overflow Note that some extensions lack translation support. In these cases, the utility prints the untranslated rule prefixed with the
#sign, for example:iptables-translate -A INPUT -j CHECKSUM --checksum-fill
# iptables-translate -A INPUT -j CHECKSUM --checksum-fill nft # -A INPUT -j CHECKSUM --checksum-fillCopy to Clipboard Copied! Toggle word wrap Toggle overflow
2.2.6. Comparison of common iptables and nftables commands Copy linkLink copied to clipboard!
The following is a comparison of common iptables and nftables commands.
Listing all rules:
Expand iptables nftables iptables-savenft list rulesetListing a certain table and chain:
Expand iptables nftables iptables -Lnft list table ip filteriptables -L INPUTnft list chain ip filter INPUTiptables -t nat -L PREROUTINGnft list chain ip nat PREROUTINGThe
nftcommand does not pre-create tables and chains. They exist only if a user created them manually.Listing rules generated by firewalld:
nft list table inet firewalld nft list table ip firewalld nft list table ip6 firewalld
# nft list table inet firewalld # nft list table ip firewalld # nft list table ip6 firewalldCopy to Clipboard Copied! Toggle word wrap Toggle overflow
2.3. Configuring NAT using nftables Copy linkLink copied to clipboard!
With nftables, you can configure the masquerading, source (SNAT), destination NAT (DNAT), and redirect types. With NAT, you can modify the source or destination IP address.
You can only use real interface names in iifname and oifname parameters, and alternative names (altname) are not supported.
2.3.1. NAT types Copy linkLink copied to clipboard!
The nftables framework supports different network address translation (NAT) types.
- Masquerading and source NAT (SNAT)
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 and SNAT are very similar to one another. The differences are:
- Masquerading automatically uses the IP address of the outgoing interface. Therefore, use masquerading if the outgoing interface uses a dynamic IP address.
- SNAT sets the source IP address of packets to a specified IP and does not dynamically look up the IP of the outgoing interface. Therefore, SNAT is faster than masquerading. Use SNAT if the outgoing interface uses a fixed 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 the local machine depending on the chain hook. 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.
2.3.2. Configuring masquerading using nftables Copy linkLink copied to clipboard!
Masquerading enables a router to dynamically change the source IP of packets sent through an interface to the IP address of the interface. This means that if the interface gets a new IP assigned, nftables automatically uses the new IP when replacing the source IP.
Replace the source IP of packets leaving the host through the ens3 interface to the IP set on ens3.
Procedure
Create a table:
nft add table nat
# nft add table natCopy to Clipboard Copied! Toggle word wrap Toggle overflow Add the
preroutingandpostroutingchains to the table:nft add chain nat postrouting { type nat hook postrouting priority 100 \; }# nft add chain nat postrouting { type nat hook postrouting priority 100 \; }Copy to Clipboard Copied! Toggle word wrap Toggle overflow ImportantEven if you do not add a rule to the
preroutingchain, thenftablesframework requires this chain to match incoming packet replies.Note that you must pass the
--option to thenftcommand to prevent the shell from interpreting the negative priority value as an option of thenftcommand.Add a rule to the
postroutingchain that matches outgoing packets on theens3interface:nft add rule nat postrouting oifname "ens3" masquerade
# nft add rule nat postrouting oifname "ens3" masqueradeCopy to Clipboard Copied! Toggle word wrap Toggle overflow
2.3.3. Configuring source NAT using nftables Copy linkLink copied to clipboard!
On a router, Source NAT (SNAT) enables you to change the IP of packets sent through an interface to a specific IP address. The router then replaces the source IP of outgoing packets.
Procedure
Create a table:
nft add table nat
# nft add table natCopy to Clipboard Copied! Toggle word wrap Toggle overflow Add the
preroutingandpostroutingchains to the table:nft add chain nat postrouting { type nat hook postrouting priority 100 \; }# nft add chain nat postrouting { type nat hook postrouting priority 100 \; }Copy to Clipboard Copied! Toggle word wrap Toggle overflow ImportantEven if you do not add a rule to the
postroutingchain, thenftablesframework requires this chain to match outgoing packet replies.Note that you must pass the
--option to thenftcommand to prevent the shell from interpreting the negative priority value as an option of thenftcommand.Add a rule to the
postroutingchain that replaces the source IP of outgoing packets throughens3with192.0.2.1:nft add rule nat postrouting oifname "ens3" snat to 192.0.2.1
# nft add rule nat postrouting oifname "ens3" snat to 192.0.2.1Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.3.4. Configuring destination NAT using nftables Copy linkLink copied to clipboard!
Destination NAT (DNAT) enables you to redirect traffic on a router to a host that is not directly accessible from the internet.
For example, with DNAT the router redirects incoming traffic sent to port 80 and 443 to a web server with the IP address 192.0.2.1.
Procedure
Create a table:
nft add table nat
# nft add table natCopy to Clipboard Copied! Toggle word wrap Toggle overflow Add the
preroutingandpostroutingchains to the table:nft -- add chain nat prerouting { type nat hook prerouting priority -100 \; } nft add chain nat postrouting { type nat hook postrouting priority 100 \; }# nft -- add chain nat prerouting { type nat hook prerouting priority -100 \; } # nft add chain nat postrouting { type nat hook postrouting priority 100 \; }Copy to Clipboard Copied! Toggle word wrap Toggle overflow ImportantEven if you do not add a rule to the
postroutingchain, thenftablesframework requires this chain to match outgoing packet replies.Note that you must pass the
--option to thenftcommand to prevent the shell from interpreting the negative priority value as an option of thenftcommand.Add a rule to the
preroutingchain that redirects incoming traffic to port80and443on theens3interface of the router to the web server with the IP address192.0.2.1:nft add rule nat prerouting iifname ens3 tcp dport { 80, 443 } dnat to 192.0.2.1# nft add rule nat prerouting iifname ens3 tcp dport { 80, 443 } dnat to 192.0.2.1Copy to Clipboard Copied! Toggle word wrap Toggle overflow Depending on your environment, add either a SNAT or masquerading rule to change the source address for packets returning from the web server to the sender:
If the
ens3interface uses a dynamic IP addresses, add a masquerading rule:nft add rule nat postrouting oifname "ens3" masquerade
# nft add rule nat postrouting oifname "ens3" masqueradeCopy to Clipboard Copied! Toggle word wrap Toggle overflow If the
ens3interface uses a static IP address, add a SNAT rule. For example, if theens3uses the198.51.100.1IP address:nft add rule nat postrouting oifname "ens3" snat to 198.51.100.1
# nft add rule nat postrouting oifname "ens3" snat to 198.51.100.1Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Enable packet forwarding:
echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf
# echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf # sysctl -p /etc/sysctl.d/95-IPv4-forwarding.confCopy to Clipboard Copied! Toggle word wrap Toggle overflow
2.3.5. Configuring a redirect using nftables Copy linkLink copied to clipboard!
The redirect feature is a special case of destination network address translation (DNAT) that redirects packets to the local machine depending on the chain hook.
For example, you can redirect incoming and forwarded traffic sent to port 22 of the local host to port 2222.
Procedure
Create a table:
nft add table nat
# nft add table natCopy to Clipboard Copied! Toggle word wrap Toggle overflow Add the
preroutingchain to the table:nft -- add chain nat prerouting { type nat hook prerouting priority -100 \; }# nft -- add chain nat prerouting { type nat hook prerouting priority -100 \; }Copy to Clipboard Copied! Toggle word wrap Toggle overflow Note that you must pass the
--option to thenftcommand to prevent the shell from interpreting the negative priority value as an option of thenftcommand.Add a rule to the
preroutingchain that redirects incoming traffic on port22to port2222:nft add rule nat prerouting tcp dport 22 redirect to 2222
# nft add rule nat prerouting tcp dport 22 redirect to 2222Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.4. Writing and executing nftables scripts Copy linkLink copied to clipboard!
The major benefit of using the nftables framework is that the execution of scripts is atomic. This means that the system either applies the whole script or prevents the execution if an error occurs. This guarantees that the firewall is always in a consistent state.
Additionally, with the nftables script environment, you can:
- Add comments
- Define variables
- Include other rule-set files
When you install the nftables package, Red Hat Enterprise Linux automatically creates *.nft scripts in the /etc/nftables/ directory. These scripts contain commands that create tables and empty chains for different purposes.
2.4.1. Supported nftables script formats Copy linkLink copied to clipboard!
The nftables framework supports scripts in different formats.
You can use the following formats:
The same format as the
nft list rulesetcommand displays the rule set:Copy to Clipboard Copied! Toggle word wrap Toggle overflow The same syntax as for
nftcommands:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.4.2. Running nftables scripts Copy linkLink copied to clipboard!
You can run an nftables script either by passing it to the nft utility or by executing the script directly.
Procedure
To run an
nftablesscript by passing it to thenftutility, enter:nft -f /etc/nftables/<example_firewall_script>.nft
# nft -f /etc/nftables/<example_firewall_script>.nftCopy to Clipboard Copied! Toggle word wrap Toggle overflow To run an
nftablesscript directly:For the single time that you perform this:
Ensure that the script starts with the following shebang sequence:
#!/usr/sbin/nft -f
#!/usr/sbin/nft -fCopy to Clipboard Copied! Toggle word wrap Toggle overflow ImportantIf you omit the
-fparameter, thenftutility does not read the script and displays:Error: syntax error, unexpected newline, expecting string.Optional: Set the owner of the script to
root:chown root /etc/nftables/<example_firewall_script>.nft
# chown root /etc/nftables/<example_firewall_script>.nftCopy to Clipboard Copied! Toggle word wrap Toggle overflow Make the script executable for the owner:
chmod u+x /etc/nftables/<example_firewall_script>.nft
# chmod u+x /etc/nftables/<example_firewall_script>.nftCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Run the script:
/etc/nftables/<example_firewall_script>.nft
# /etc/nftables/<example_firewall_script>.nftCopy to Clipboard Copied! Toggle word wrap Toggle overflow If no output is displayed, the system executed the script successfully.
ImportantEven if
nftexecutes the script successfully, incorrectly placed rules, missing parameters, or other problems in the script can cause that the firewall behaves not as expected.
2.4.3. Using comments in nftables scripts Copy linkLink copied to clipboard!
The nftables scripting environment interprets everything to the right of a # character to the end of a line as a comment.
Comments can start at the beginning of a line, or next to a command:
2.4.4. Using variables in nftables script Copy linkLink copied to clipboard!
To define a variable in an nftables script, use the define keyword. You can store single values and anonymous sets in a variable. For more complex scenarios, use sets or verdict maps.
- Variables with a single value
The following example defines a variable named
INET_DEVwith the valueenp1s0:define INET_DEV = enp1s0
define INET_DEV = enp1s0Copy to Clipboard Copied! Toggle word wrap Toggle overflow You can use the variable in the script by entering the
$sign followed by the variable name:... add rule inet example_table example_chain iifname $INET_DEV tcp dport ssh accept ...
... add rule inet example_table example_chain iifname $INET_DEV tcp dport ssh accept ...Copy to Clipboard Copied! Toggle word wrap Toggle overflow - Variables that contain an anonymous set
The following example defines a variable that contains an anonymous set:
define DNS_SERVERS = { 192.0.2.1, 192.0.2.2 }define DNS_SERVERS = { 192.0.2.1, 192.0.2.2 }Copy to Clipboard Copied! Toggle word wrap Toggle overflow You can use the variable in the script by writing the
$sign followed by the variable name:add rule inet example_table example_chain ip daddr $DNS_SERVERS accept
add rule inet example_table example_chain ip daddr $DNS_SERVERS acceptCopy to Clipboard Copied! Toggle word wrap Toggle overflow NoteCurly braces have special semantics when you use them in a rule because they indicate that the variable represents a set.
2.4.5. Including files in nftables scripts Copy linkLink copied to clipboard!
In the nftables scripting environment, you can include other scripts by using the include statement.
If you specify only a file name without an absolute or relative path, nftables includes files from the default search path, which is set to /etc on Red Hat Enterprise Linux.
Example 2.1. Including files from the default search directory
To include a file from the default search directory:
include "example.nft"
include "example.nft"
Example 2.2. Including all *.nft files from a directory
To include all files ending with *.nft that are stored in the /etc/nftables/rulesets/ directory:
include "/etc/nftables/rulesets/*.nft"
include "/etc/nftables/rulesets/*.nft"
Note that the include statement does not match files beginning with a dot.
2.4.6. Automatically loading nftables rules when the system boots Copy linkLink copied to clipboard!
The nftables systemd service loads firewall scripts that are included in the /etc/sysconfig/nftables.conf file.
Prerequisites
-
The
nftablesscripts are stored in the/etc/nftables/directory.
Procedure
Edit the
/etc/sysconfig/nftables.conffile.-
If you modified the
*.nftscripts that were created in/etc/nftables/with the installation of thenftablespackage, uncomment theincludestatement for these scripts. If you wrote new scripts, add
includestatements to include these scripts. For example, to load the/etc/nftables/example.nftscript when thenftablesservice starts, add:include "/etc/nftables/_example_.nft"
include "/etc/nftables/_example_.nft"Copy to Clipboard Copied! Toggle word wrap Toggle overflow
-
If you modified the
Optional: Start the
nftablesservice to load the firewall rules without rebooting the system:systemctl start nftables
# systemctl start nftablesCopy to Clipboard Copied! Toggle word wrap Toggle overflow Enable the
nftablesservice.systemctl enable nftables
# systemctl enable nftablesCopy to Clipboard Copied! Toggle word wrap Toggle overflow
2.5. Using sets in nftables commands Copy linkLink copied to clipboard!
The nftables framework natively supports sets. You can use sets, for example, if a rule should match multiple IP addresses, port numbers, interfaces, or any other match criteria.
2.5.1. Using anonymous sets in nftables Copy linkLink copied to clipboard!
An anonymous set contains comma-separated values enclosed in curly brackets, such as { 22, 80, 443 }, that you use directly in a rule. You can use anonymous sets also for IP addresses and any other match criteria.
The drawback of anonymous sets is that if you want to change the set, you must replace the rule. For a dynamic solution, use named sets as described in Using named sets in nftables.
Prerequisites
-
The
example_chainchain and theexample_tabletable in theinetfamily exist.
Procedure
For example, to add a rule to
example_chaininexample_tablethat allows incoming traffic to port22,80, and443:nft add rule inet example_table example_chain tcp dport { 22, 80, 443 } accept# nft add rule inet example_table example_chain tcp dport { 22, 80, 443 } acceptCopy to Clipboard Copied! Toggle word wrap Toggle overflow Optional: Display all chains and their rules in
example_table:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.5.2. Using named sets in nftables Copy linkLink copied to clipboard!
The nftables framework supports mutable named sets. A named set is a list of ranges that you can use in multiple rules within a table. Another benefit over anonymous sets is that you can update a named set without replacing the rules that use the set.
When you create a named set, you must specify the type of elements the set contains. You can set the following types:
-
ipv4_addrfor a set that contains IPv4 addresses or ranges, such as192.0.2.1or192.0.2.0/24. -
ipv6_addrfor a set that contains IPv6 addresses or ranges, such as2001:db8:1::1or2001:db8:1::1/64. -
ether_addrfor a set that contains a list of media access control (MAC) addresses, such as52:54:00:6b:66:42. -
inet_protofor a set that contains a list of internet protocol types, such astcp. -
inet_servicefor a set that contains a list of internet services, such asssh. -
markfor a set that contains a list of packet marks. Packet marks can be any positive 32-bit integer value (0to2147483647).
Prerequisites
-
The
example_chainchain and theexample_tabletable exists.
Procedure
Create an empty set. The following examples create a set for IPv4 addresses:
To create a set that can store multiple individual IPv4 addresses:
nft add set inet example_table example_set { type ipv4_addr \; }# nft add set inet example_table example_set { type ipv4_addr \; }Copy to Clipboard Copied! Toggle word wrap Toggle overflow To create a set that can store IPv4 address ranges:
nft add set inet example_table example_set { type ipv4_addr \; flags interval \; }# nft add set inet example_table example_set { type ipv4_addr \; flags interval \; }Copy to Clipboard Copied! Toggle word wrap Toggle overflow
ImportantTo prevent the shell from interpreting the semicolons as the end of the command, you must escape the semicolons with a backslash.
Optional: Create rules that use the set. For example, the following command adds a rule to the
example_chainin theexample_tablethat will drop all packets from IPv4 addresses inexample_set.nft add rule inet example_table example_chain ip saddr @example_set drop
# nft add rule inet example_table example_chain ip saddr @example_set dropCopy to Clipboard Copied! Toggle word wrap Toggle overflow Because
example_setis still empty, the rule has currently no effect.Add IPv4 addresses to
example_set:If you create a set that stores individual IPv4 addresses, enter:
nft add element inet example_table example_set { 192.0.2.1, 192.0.2.2 }# nft add element inet example_table example_set { 192.0.2.1, 192.0.2.2 }Copy to Clipboard Copied! Toggle word wrap Toggle overflow If you create a set that stores IPv4 ranges, enter:
nft add element inet example_table example_set { 192.0.2.0-192.0.2.255 }# nft add element inet example_table example_set { 192.0.2.0-192.0.2.255 }Copy to Clipboard Copied! Toggle word wrap Toggle overflow When you specify an IP address range, you can alternatively use the Classless Inter-Domain Routing (CIDR) notation, such as
192.0.2.0/24in the above example.
2.5.3. Using dynamic sets to add entries from the packet path Copy linkLink copied to clipboard!
Dynamic sets in nftables automatically add elements, such as IP addresses, ports, and MAC addresses from packet data. This enables real-time collection of data to create dynamic deny or ban lists, instantly reacting to security threats.
Prerequisites
-
The
example_chainchain and theexample_tabletable in theinetfamily exist.
Procedure
Create an empty set. The following examples create a set for IPv4 addresses:
To create a set that can store multiple individual IPv4 addresses:
nft add set inet example_table example_set { type ipv4_addr \; }# nft add set inet example_table example_set { type ipv4_addr \; }Copy to Clipboard Copied! Toggle word wrap Toggle overflow To create a set that can store IPv4 address ranges:
nft add set inet example_table example_set { type ipv4_addr \; flags interval \; }# nft add set inet example_table example_set { type ipv4_addr \; flags interval \; }Copy to Clipboard Copied! Toggle word wrap Toggle overflow ImportantTo prevent the shell from interpreting the semicolons as the end of the command, you must escape the semicolons with a backslash.
Create a rule for dynamically adding the source IPv4 addresses of incoming packets to the
example_setset:nft add rule inet example_table example_chain set add ip saddr @example_set
# nft add rule inet example_table example_chain set add ip saddr @example_setCopy to Clipboard Copied! Toggle word wrap Toggle overflow The command creates a new rule within the
example_chainrule chain and theexample_tableto dynamically add the source IPv4 address of the packet to theexample_set.
Verification
Ensure the rule was added:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The command displays the entire ruleset currently loaded in
nftables. It shows that IPs are actively triggering the rule, andexample_setis being updated with the relevant addresses.
Next steps
Once you have a dynamic set of IPs, you can use it for various security, filtering, and traffic control purposes. For example:
- block, limit, or log network traffic
- combine with allow-listing to avoid banning trusted users
- use automatic timeouts to prevent over-blocking
2.6. Using verdict maps in nftables commands Copy linkLink copied to clipboard!
Verdict maps, which are also known as dictionaries, enable nft to perform an action based on packet information by mapping match criteria to an action.
2.6.1. Using anonymous maps in nftables Copy linkLink copied to clipboard!
An anonymous map is a { match_criteria : action } statement that you use directly in a rule. The statement can contain multiple comma-separated mappings.
The drawback of an anonymous map is that if you want to change the map, you must replace the rule. For a dynamic solution, use named maps as described in Using named maps in nftables.
For example, you can use an anonymous map to route both TCP and UDP packets of the IPv4 and IPv6 protocol to different chains to count incoming TCP and UDP packets separately.
Procedure
Create a new table:
nft add table inet example_table
# nft add table inet example_tableCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create the
tcp_packetschain inexample_table:nft add chain inet example_table tcp_packets
# nft add chain inet example_table tcp_packetsCopy to Clipboard Copied! Toggle word wrap Toggle overflow Add a rule to
tcp_packetsthat counts the traffic in this chain:nft add rule inet example_table tcp_packets counter
# nft add rule inet example_table tcp_packets counterCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create the
udp_packetschain inexample_tablenft add chain inet example_table udp_packets
# nft add chain inet example_table udp_packetsCopy to Clipboard Copied! Toggle word wrap Toggle overflow Add a rule to
udp_packetsthat counts the traffic in this chain:nft add rule inet example_table udp_packets counter
# nft add rule inet example_table udp_packets counterCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create a chain for incoming traffic. For example, to create a chain named
incoming_trafficinexample_tablethat filters incoming traffic:nft add chain inet example_table incoming_traffic { type filter hook input priority 0 \; }# nft add chain inet example_table incoming_traffic { type filter hook input priority 0 \; }Copy to Clipboard Copied! Toggle word wrap Toggle overflow Add a rule with an anonymous map to
incoming_traffic:nft add rule inet example_table incoming_traffic ip protocol vmap { tcp : jump tcp_packets, udp : jump udp_packets }# nft add rule inet example_table incoming_traffic ip protocol vmap { tcp : jump tcp_packets, udp : jump udp_packets }Copy to Clipboard Copied! Toggle word wrap Toggle overflow The anonymous map distinguishes the packets and sends them to the different counter chains based on their protocol.
To list the traffic counters, display
example_table:Copy to Clipboard Copied! Toggle word wrap Toggle overflow The counters in the
tcp_packetsandudp_packetschain display both the number of received packets and bytes.
2.6.2. Using named maps in nftables Copy linkLink copied to clipboard!
The nftables framework supports named maps. You can use these maps in multiple rules within a table. Another benefit over anonymous maps is that you can update a named map without replacing the rules that use it.
When you create a named map, you must specify the type of elements:
-
ipv4_addrfor a map whose match part contains an IPv4 address, such as192.0.2.1. -
ipv6_addrfor a map whose match part contains an IPv6 address, such as2001:db8:1::1. -
ether_addrfor a map whose match part contains a media access control (MAC) address, such as52:54:00:6b:66:42. -
inet_protofor a map whose match part contains an internet protocol type, such astcp. -
inet_servicefor a map whose match part contains an internet services name port number, such assshor22. -
markfor a map whose match part contains a packet mark. A packet mark can be any positive 32-bit integer value (0to2147483647). -
counterfor a map whose match part contains a counter value. The counter value can be any positive 64-bit integer value. -
quotafor a map whose match part contains a quota value. The quota value can be any positive 64-bit integer value.
For example, you can allow or drop incoming packets based on their source IP address. Using a named map, you require only a single rule to configure this scenario while the IP addresses and actions are dynamically stored in the map.
Procedure
Create a table. For example, to create a table named
example_tablethat processes IPv4 packets:nft add table ip example_table
# nft add table ip example_tableCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create a chain. For example, to create a chain named
example_chaininexample_table:nft add chain ip example_table example_chain { type filter hook input priority 0 \; }# nft add chain ip example_table example_chain { type filter hook input priority 0 \; }Copy to Clipboard Copied! Toggle word wrap Toggle overflow ImportantTo prevent the shell from interpreting the semicolons as the end of the command, you must escape the semicolons with a backslash.
Create an empty map. For example, to create a map for IPv4 addresses:
nft add map ip example_table example_map { type ipv4_addr : verdict \; }# nft add map ip example_table example_map { type ipv4_addr : verdict \; }Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create rules that use the map. For example, the following command adds a rule to
example_chaininexample_tablethat applies actions to IPv4 addresses which are both defined inexample_map:nft add rule example_table example_chain ip saddr vmap @example_map
# nft add rule example_table example_chain ip saddr vmap @example_mapCopy to Clipboard Copied! Toggle word wrap Toggle overflow Add IPv4 addresses and corresponding actions to
example_map:nft add element ip example_table example_map { 192.0.2.1 : accept, 192.0.2.2 : drop }# nft add element ip example_table example_map { 192.0.2.1 : accept, 192.0.2.2 : drop }Copy to Clipboard Copied! Toggle word wrap Toggle overflow This example defines the mappings of IPv4 addresses to actions. In combination with the rule created above, the firewall accepts packets from
192.0.2.1and drops packets from192.0.2.2.Optional: Enhance the map by adding another IP address and action statement:
nft add element ip example_table example_map { 192.0.2.3 : accept }# nft add element ip example_table example_map { 192.0.2.3 : accept }Copy to Clipboard Copied! Toggle word wrap Toggle overflow Optional: Remove an entry from the map:
nft delete element ip example_table example_map { 192.0.2.1 }# nft delete element ip example_table example_map { 192.0.2.1 }Copy to Clipboard Copied! Toggle word wrap Toggle overflow Optional: Display the rule set:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.7. Example: Protecting a LAN and DMZ using an nftables script Copy linkLink copied to clipboard!
Use the nftables framework on a RHEL router to write and install a firewall script that protects the network clients in an internal LAN and a web server in a DMZ from unauthorized access from the internet and from other networks.
This example is only for demonstration purposes and describes a scenario with specific requirements.
Firewall scripts highly depend on the network infrastructure and security requirements. Use this example to learn the concepts of nftables firewalls when you write scripts for your own environment.
2.7.1. Network conditions Copy linkLink copied to clipboard!
The network in this example has the following conditions.
The router is connected to the following networks:
-
The internet through interface
enp1s0 -
The internal LAN through interface
enp7s0 -
The DMZ through
enp8s0
-
The internet through interface
-
The internet interface of the router has both a static IPv4 address (
203.0.113.1) and IPv6 address (2001:db8:a::1) assigned. -
The clients in the internal LAN use only private IPv4 addresses from the range
10.0.0.0/24. Consequently, traffic from the LAN to the internet requires source network address translation (SNAT). -
The administrator PCs in the internal LAN use the IP addresses
10.0.0.100and10.0.0.200. -
The DMZ uses public IP addresses from the ranges
198.51.100.0/24and2001:db8:b::/56. -
The web server in the DMZ uses the IP addresses
198.51.100.5and2001:db8:b::5. - The router acts as a caching DNS server for hosts in the LAN and DMZ.
2.7.2. Security requirements to the firewall script Copy linkLink copied to clipboard!
The following are the requirements to the nftables firewall in the example network.
The router must be able to:
- Recursively resolve DNS queries.
- Perform all connections on the loopback interface.
Clients in the internal LAN must be able to:
- Query the caching DNS server running on the router.
- Access the HTTPS server in the DMZ.
- Access any HTTPS server on the internet.
- The PCs of the administrators must be able to access the router and every server in the DMZ using SSH.
The web server in the DMZ must be able to:
- Query the caching DNS server running on the router.
- Access HTTPS servers on the internet to download updates.
Hosts on the internet must be able to:
- Access the HTTPS servers in the DMZ.
Additionally, the following security requirements exists:
- Connection attempts that are not explicitly allowed should be dropped.
- Dropped packets should be logged.
2.7.3. Configuring logging of dropped packets to a file Copy linkLink copied to clipboard!
By default, systemd logs kernel messages, such as for dropped packets, to the journal. Additionally, you can configure the rsyslog service to log such entries to a separate file. To ensure that the log file does not grow infinitely, configure a rotation policy.
Prerequisites
-
The
rsyslogpackage is installed. -
The
rsyslogservice is running.
Procedure
Create the
/etc/rsyslog.d/nftables.conffile with the following content::msg, startswith, "nft drop" -/var/log/nftables.log & stop
:msg, startswith, "nft drop" -/var/log/nftables.log & stopCopy to Clipboard Copied! Toggle word wrap Toggle overflow Using this configuration, the
rsyslogservice logs dropped packets to the/var/log/nftables.logfile instead of/var/log/messages.Restart the
rsyslogservice:systemctl restart rsyslog
# systemctl restart rsyslogCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create the
/etc/logrotate.d/nftablesfile with the following content to rotate/var/log/nftables.logif the size exceeds 10 MB:Copy to Clipboard Copied! Toggle word wrap Toggle overflow The
maxage 30setting defines thatlogrotateremoves rotated logs older than 30 days during the next rotation operation.
2.7.4. Writing and activating the nftables script Copy linkLink copied to clipboard!
This example is an nftables firewall script that runs on a RHEL router and protects the clients in an internal LAN and a web server in a DMZ.
For details about the network and the requirements for the firewall used in the example, see Network conditions and Security requirements to the firewall script.
This nftables firewall script is only for demonstration purposes. Do not use it without adapting it to your environments and security requirements.
Prerequisites
- The network is configured as described in Network conditions.
Procedure
Create the
/etc/nftables/firewall.nftscript with the following content:Copy to Clipboard Copied! Toggle word wrap Toggle overflow Include the
/etc/nftables/firewall.nftscript in the/etc/sysconfig/nftables.conffile:include "/etc/nftables/firewall.nft"
include "/etc/nftables/firewall.nft"Copy to Clipboard Copied! Toggle word wrap Toggle overflow Enable IPv4 forwarding:
echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf
# echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf # sysctl -p /etc/sysctl.d/95-IPv4-forwarding.confCopy to Clipboard Copied! Toggle word wrap Toggle overflow Enable and start the
nftablesservice:systemctl enable --now nftables
# systemctl enable --now nftablesCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Optional: Verify the
nftablesrule set:nft list ruleset
# nft list ruleset ...Copy to Clipboard Copied! Toggle word wrap Toggle overflow Try to perform an access that the firewall prevents. For example, try to access the router using SSH from the DMZ:
ssh router.example.com
# ssh router.example.com ssh: connect to host router.example.com port 22: Network is unreachableCopy to Clipboard Copied! Toggle word wrap Toggle overflow Depending on your logging settings, search:
The
systemdjournal for the blocked packets:journalctl -k -g "nft drop"
# journalctl -k -g "nft drop" Oct 14 17:27:18 router kernel: nft drop IN : IN=enp8s0 OUT= MAC=... SRC=198.51.100.5 DST=198.51.100.1 ... PROTO=TCP SPT=40464 DPT=22 ... SYN ...Copy to Clipboard Copied! Toggle word wrap Toggle overflow The
/var/log/nftables.logfile for the blocked packets:Oct 14 17:27:18 router kernel: nft drop IN : IN=enp8s0 OUT= MAC=... SRC=198.51.100.5 DST=198.51.100.1 ... PROTO=TCP SPT=40464 DPT=22 ... SYN ...
Oct 14 17:27:18 router kernel: nft drop IN : IN=enp8s0 OUT= MAC=... SRC=198.51.100.5 DST=198.51.100.1 ... PROTO=TCP SPT=40464 DPT=22 ... SYN ...Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.8. Using nftables to limit the amount of connections Copy linkLink copied to clipboard!
You can use nftables to limit the number of connections or to block IP addresses that attempt to establish a given amount of connections to prevent them from using too many system resources.
2.8.1. Limiting the number of connections by using nftables Copy linkLink copied to clipboard!
By using the ct count parameter of the nft utility, you can limit the number of simultaneous connections per IP address. For example, you can use this feature to configure that each source IP address can only establish two parallel SSH connections to a host.
Procedure
Create the
filtertable with theinetaddress family:nft add table inet filter
# nft add table inet filterCopy to Clipboard Copied! Toggle word wrap Toggle overflow Add the
inputchain to theinet filtertable:nft add chain inet filter input { type filter hook input priority 0 \; }# nft add chain inet filter input { type filter hook input priority 0 \; }Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create a dynamic set for IPv4 addresses:
nft add set inet filter limit-ssh { type ipv4_addr\; flags dynamic \;}# nft add set inet filter limit-ssh { type ipv4_addr\; flags dynamic \;}Copy to Clipboard Copied! Toggle word wrap Toggle overflow Add a rule to the
inputchain that allows only two simultaneous incoming connections to the SSH port (22) from an IPv4 address and rejects all further connections from the same IP:nft add rule inet filter input tcp dport ssh ct state new add @limit-ssh { ip saddr ct count over 2 } counter reject# nft add rule inet filter input tcp dport ssh ct state new add @limit-ssh { ip saddr ct count over 2 } counter rejectCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
- Establish more than two new simultaneous SSH connections from the same IP address to the host. Nftables refuses connections to the SSH port if two connections are already established.
Display the
limit-sshdynamic set:Copy to Clipboard Copied! Toggle word wrap Toggle overflow The
elementsentry displays addresses that currently match the rule. In this example,elementslists IP addresses that have active connections to the SSH port. Note that the output does not display the number of active connections or if connections were rejected.
2.8.2. Blocking IP addresses that attempt more than ten new incoming TCP connections within one minute Copy linkLink copied to clipboard!
You can temporarily block hosts that are establishing more than ten IPv4 TCP connections within one minute.
Procedure
Create the
filtertable with theipaddress family:nft add table ip filter
# nft add table ip filterCopy to Clipboard Copied! Toggle word wrap Toggle overflow Add the
inputchain to thefiltertable:nft add chain ip filter input { type filter hook input priority 0 \; }# nft add chain ip filter input { type filter hook input priority 0 \; }Copy to Clipboard Copied! Toggle word wrap Toggle overflow Add a set named
denylistto thefiltertable:nft add set ip filter denylist { type ipv4_addr \; flags dynamic, timeout \; timeout 5m \; }# nft add set ip filter denylist { type ipv4_addr \; flags dynamic, timeout \; timeout 5m \; }Copy to Clipboard Copied! Toggle word wrap Toggle overflow This command creates a dynamic set for IPv4 addresses. The
timeout 5mparameter defines thatnftablesautomatically removes entries after five minutes to prevent that the set fills up with stale entries.Add a rule that automatically adds the source IP address of hosts that attempt to establish more than ten new TCP connections within one minute to the
denylistset:nft add rule ip filter input ip protocol tcp ct state new, untracked add @denylist { ip saddr limit rate over 10/minute } drop# nft add rule ip filter input ip protocol tcp ct state new, untracked add @denylist { ip saddr limit rate over 10/minute } dropCopy to Clipboard Copied! Toggle word wrap Toggle overflow
2.9. Debugging nftables rules Copy linkLink copied to clipboard!
The nftables framework provides different options for administrators to debug rules and if packets match them.
2.9.1. Creating a rule with a counter Copy linkLink copied to clipboard!
To identify if a rule is matched, you can use a counter.
Prerequisites
- The chain to which you want to add the rule exists.
Procedure
Add a new rule with the
counterparameter to the chain. The following example adds a rule with a counter that allows TCP traffic on port 22 and counts the packets and traffic that match this rule:nft add rule inet example_table example_chain tcp dport 22 counter accept
# nft add rule inet example_table example_chain tcp dport 22 counter acceptCopy to Clipboard Copied! Toggle word wrap Toggle overflow To display the counter values:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.9.2. Adding a counter to an existing rule Copy linkLink copied to clipboard!
To identify if a rule is matched, you can use a counter.
Prerequisites
- The rule to which you want to add the counter exists.
Procedure
Display the rules in the chain including their handles:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Add the counter by replacing the rule but with the
counterparameter. The following example replaces the rule displayed in the previous step and adds a counter:nft replace rule inet example_table example_chain handle 4 tcp dport 22 counter accept
# nft replace rule inet example_table example_chain handle 4 tcp dport 22 counter acceptCopy to Clipboard Copied! Toggle word wrap Toggle overflow To display the counter values:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.9.3. Monitoring packets that match an existing rule Copy linkLink copied to clipboard!
The tracing feature in nftables in combination with the nft monitor command enables administrators to display packets that match a rule. You can enable tracing for a rule and use it to monitor packets that match this rule.
Prerequisites
- The rule to which you want to add the counter exists.
Procedure
Display the rules in the chain including their handles:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Add the tracing feature by replacing the rule but with the
meta nftrace set 1parameters. The following example replaces the rule displayed in the previous step and enables tracing:nft replace rule inet example_table example_chain handle 4 tcp dport 22 meta nftrace set 1 accept
# nft replace rule inet example_table example_chain handle 4 tcp dport 22 meta nftrace set 1 acceptCopy to Clipboard Copied! Toggle word wrap Toggle overflow Use the
nft monitorcommand to display the tracing. The following example filters the output of the command to display only entries that containinet example_table example_chain:nft monitor | grep "inet example_table example_chain"
# nft monitor | grep "inet example_table example_chain" trace id 3c5eb15e inet example_table example_chain packet: iif "enp1s0" ether saddr 52:54:00:17:ff:e4 ether daddr 52:54:00:72:2f:6e ip saddr 192.0.2.1 ip daddr 192.0.2.2 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 49710 ip protocol tcp ip length 60 tcp sport 56728 tcp dport ssh tcp flags == syn tcp window 64240 trace id 3c5eb15e inet example_table example_chain rule tcp dport ssh nftrace set 1 accept (verdict accept) ...Copy to Clipboard Copied! Toggle word wrap Toggle overflow WarningDepending on the number of rules with tracing enabled and the amount of matching traffic, the
nft monitorcommand can display a lot of output. Usegrepor other utilities to filter the output.
2.10. Backing up and restoring the nftables rule set Copy linkLink copied to clipboard!
You can backup nftables rules to a file and later restoring them. Also, administrators can use a file with the rules to, for example, transfer the rules to a different server.
2.10.1. Backing up the nftables rule set to a file Copy linkLink copied to clipboard!
You can use the nft utility to back up the nftables rule set to a file.
Procedure
To backup
nftablesrules:In a format produced by
nft list rulesetformat:nft list ruleset > file.nft
# nft list ruleset > file.nftCopy to Clipboard Copied! Toggle word wrap Toggle overflow In JSON format:
nft -j list ruleset > file.json
# nft -j list ruleset > file.jsonCopy to Clipboard Copied! Toggle word wrap Toggle overflow
2.10.2. Restoring the nftables rule set from a file Copy linkLink copied to clipboard!
You can restore the nftables rule set from a file.
Procedure
To restore
nftablesrules:If the file to restore is in the format produced by
nft list rulesetor containsnftcommands directly:nft -f file.nft
# nft -f file.nftCopy to Clipboard Copied! Toggle word wrap Toggle overflow If the file to restore is in JSON format:
nft -j -f file.json
# nft -j -f file.jsonCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Chapter 3. Using xdp-filter for high-performance traffic filtering to prevent DDoS attacks Copy linkLink copied to clipboard!
The xdp-filter utility uses XDP to drop packets directly at the network interface, making it faster than filters, such as nftables. It helps block traffic quickly during DDoS attacks and you can filter by IP, MAC address, or port.
For example, during testing, Red Hat dropped 26 million network packets per second on a single core, which is significantly higher than the drop rate of nftables on the same hardware.
The xdp-filter utility allows or drops incoming network packets using XDP. You can create rules to filter traffic to or from specific:
- IP addresses
- MAC addresses
- Ports
Note that, even if xdp-filter has a significantly higher packet-processing rate, it does not have the same capabilities as, for example, nftables. Consider xdp-filter a conceptual utility to demonstrate packet filtering using XDP. Additionally, you can use the code of the utility for a better understanding of how to write your own XDP applications.
On other architectures than AMD and Intel 64-bit, the xdp-filter utility is provided as a Technology Preview only. Technology Preview features are not supported with Red Hat production Service Level Agreements (SLAs), might not be functionally complete, and Red Hat does not recommend using them for production. These previews provide early access to upcoming product features, enabling customers to test functionality and provide feedback during the development process.
See Technology Preview Features Support Scope on the Red Hat Customer Portal for information about the support scope for Technology Preview features.
3.1. Dropping network packets that match an xdp-filter rule Copy linkLink copied to clipboard!
The xdp-filter utility can use an allow policy that allows all traffic except packets that match specific rules, such as those from a particular source IP address, source MAC address, or to a specific destination port.
If you are a developer and interested in the code of xdp-filter, download and install the corresponding source RPM (SRPM) from the Red Hat Customer Portal.
Prerequisites
-
The
xdp-toolspackage is installed. - A network driver that supports XDP programs.
Procedure
Load
xdp-filterto process incoming packets on a certain interface, such asenp1s0:xdp-filter load enp1s0
# xdp-filter load enp1s0Copy to Clipboard Copied! Toggle word wrap Toggle overflow By default,
xdp-filteruses theallowpolicy, and the utility drops only traffic that matches any rule.Optional: Use the
-f featureoption to enable only particular features, such astcp,ipv4, orethernet. Loading only the required features instead of all of them increases the speed of packet processing. To enable multiple features, separate them with a comma.If the command fails with an error, the network driver does not support XDP programs.
Add rules to drop packets that match them. For example:
To drop incoming packets to port
22, enter:xdp-filter port 22
# xdp-filter port 22Copy to Clipboard Copied! Toggle word wrap Toggle overflow This command adds a rule that matches TCP and UDP traffic. To match only a particular protocol, use the
-p protocoloption.To drop incoming packets from
192.0.2.1, enter:xdp-filter ip 192.0.2.1 -m src
# xdp-filter ip 192.0.2.1 -m srcCopy to Clipboard Copied! Toggle word wrap Toggle overflow Note that
xdp-filterdoes not support IP ranges.To drop incoming packets from MAC address
00:53:00:AA:07:BE, enter:xdp-filter ether 00:53:00:AA:07:BE -m src
# xdp-filter ether 00:53:00:AA:07:BE -m srcCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Use the following command to display statistics about dropped and allowed packets:
xdp-filter status
# xdp-filter statusCopy to Clipboard Copied! Toggle word wrap Toggle overflow
3.2. Dropping all network packets except the ones that match an xdp-filter rule Copy linkLink copied to clipboard!
The xdp-filter utility can use a deny policy that drops all traffic except packets that match specific rules, such as those from a particular source IP address, source MAC address, or to a specific destination port.
If you set the default policy to deny when you load xdp-filter on an interface, the kernel immediately drops all packets from this interface until you create rules that allow certain traffic. To avoid being locked out from the system, enter the commands locally or connect through a different network interface to the host.
If you are a developer and you are interested in the code of xdp-filter, download and install the corresponding source RPM (SRPM) from the Red Hat Customer Portal.
Prerequisites
-
The
xdp-toolspackage is installed. - You are logged in to the host either locally or using a network interface for which you do not plan to filter the traffic.
- A network driver that supports XDP programs.
Procedure
Load
xdp-filterto process packets on a certain interface, such asenp1s0:xdp-filter load enp1s0 -p deny
# xdp-filter load enp1s0 -p denyCopy to Clipboard Copied! Toggle word wrap Toggle overflow Optional: Use the
-f featureoption to enable only particular features, such astcp,ipv4, orethernet. Loading only the required features instead of all of them increases the speed of packet processing. To enable multiple features, separate them with a comma.If the command fails with an error, the network driver does not support XDP programs.
Add rules to allow packets that match them. For example:
To allow packets to port
22, enter:xdp-filter port 22
# xdp-filter port 22Copy to Clipboard Copied! Toggle word wrap Toggle overflow This command adds a rule that matches TCP and UDP traffic. To match only a particular protocol, pass the
-p protocoloption to the command.To allow packets to
192.0.2.1, enter:xdp-filter ip 192.0.2.1
# xdp-filter ip 192.0.2.1Copy to Clipboard Copied! Toggle word wrap Toggle overflow Note that
xdp-filterdoes not support IP ranges.To allow packets to MAC address
00:53:00:AA:07:BE, enter:xdp-filter ether 00:53:00:AA:07:BE
# xdp-filter ether 00:53:00:AA:07:BECopy to Clipboard Copied! Toggle word wrap Toggle overflow
ImportantThe
xdp-filterutility does not support stateful packet inspection. This requires that you either do not set a mode using the-m modeoption or you add explicit rules to allow incoming traffic that the machine receives in reply to outgoing traffic.
Verification
Use the following command to display statistics about dropped and allowed packets:
xdp-filter status
# xdp-filter statusCopy to Clipboard Copied! Toggle word wrap Toggle overflow