How to configure the default deny rules in iptables, firewalld & nftables in RHEL?

Solution Verified - Updated -

Environment

  • Red Hat Enterprise Linux 7
  • Red Hat Enterprise Linux 8
  • Red Hat Enterprise Linux 9
  • iptables, firewalld, nftables

Issue

  • How to configure the default deny rules in iptables, firewalld & nftables in RHEL?

Resolution

Configuring default deny rules using iptables, firewalld, and nftables in RHEL involves creating a set of rules that deny all incoming and outgoing traffic by default and then selectively allowing specific traffic based on your requirements. Below are examples for each firewall management tool in the RHEL.

Configuring default deny rules can lock you out of the system. Ensure you have alternative access methods (console) before applying these changes.

Note: Make sure that only one firewall service runs on a RHEL host and disable the other services to prevent the different firewall services from influencing each other.

Follow the below step to configure default deny iptables rules on RHEL:

you can configure iptables to implement a default deny policy by setting the default policies for the filter table's INPUT, OUTPUT, and FORWARD chains to "DROP". This means that unless an explicit rule allows traffic, it will be dropped by default.

  • Install the iptables-services package on the RHEL.
# yum install iptables-services -y
  • Stop the firewalld service if it's running.
# systemctl disable firewalld
# systemctl stop firewalld
# systemctl mask firewalld
  • Start the iptables service.
# systemctl start iptables.service
# systemctl enable iptables.service
  • Flush the iptables rules
# iptables -F
  • Ensure the loopback traffic is configured.
# iptables -A INPUT -i lo -j ACCEPT
# iptables -A OUTPUT -o lo -j ACCEPT
# iptables -A INPUT -s 127.0.0.0/8 -j DROP
  • Run the below command to allow outbound and established connections to be configured with TCP/UDP protocol.
# iptables -A OUTPUT -p tcp -m state --state NEW,ESTABLISHED -j ACCEPT
# iptables -A OUTPUT -p udp -m state --state NEW,ESTABLISHED -j ACCEPT
# iptables -A OUTPUT -p icmp -m state --state NEW,ESTABLISHED -j ACCEPT
# iptables -A INPUT -p tcp -m state --state ESTABLISHED -j ACCEPT
# iptables -A INPUT -p udp -m state --state ESTABLISHED -j ACCEPT
# iptables -A INPUT -p icmp -m state --state ESTABLISHED -j ACCEPT
  • To be safe allow the inbound SSH connection(Default Port-22).
# iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT

Note: You can use the same above command to add the other application port for example: HTTP-80.

  • To set the default policies to DROP for the INPUT, OUTPUT, and FORWARD chains, use the following commands:
# iptables -P INPUT DROP
# iptables -P OUTPUT DROP
# iptables -P FORWARD DROP

These commands set the default policy for incoming, outgoing, and forwarded traffic to DROP.

  • To ensure that the changes persist after a system reboot, you need to save the iptables rules.
#iptables-save > /etc/sysconfig/iptables

This command saves the rules to the /etc/sysconfig/iptables file.

  • To Validate the default deny Rules run the below command. you’ll notice that it says policy DROP next to all three chains.
# iptables -L 
Chain INPUT (policy DROP)      <<----
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere            
DROP       all  --  127.0.0.0/8          anywhere            
ACCEPT     tcp  --  anywhere             anywhere             state ESTABLISHED
ACCEPT     udp  --  anywhere             anywhere             state ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere             state ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh state NEW
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http state NEW

Chain FORWARD (policy DROP)  <<----
target     prot opt source               destination         

Chain OUTPUT (policy DROP)  <<---- 
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     tcp  --  anywhere             anywhere             state NEW,ESTABLISHED
ACCEPT     udp  --  anywhere             anywhere             state NEW,ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere             state NEW,ESTABLISHED

Follow the below step to configure default deny firewalld rules on RHEL:

Configuring default deny rules in firewalld on Linux involves setting up a default zone that drops all incoming and outgoing traffic and then selectively allows specific traffic.

  • First Check the default Zone:
# firewall-cmd --get-default-zone
public
  • Now set drop to the default zone:
# firewall-cmd --set-default-zone=drop
success
  • Reload the firewalld to apply the changes:
# firewall-cmd --reload
success
  • Run the below command to check if the default zone is set to drop:
# firewall-cmd --get-default-zone
drop
  • To Allow the SSH connection add the default ssh service or port:
#firewall-cmd --permanent --zone=drop --add-service=ssh
  • You can add specific rules to allow incoming traffic on specific services/ports:
# firewall-cmd --permanent --zone=drop --add-service=http
success
# firewall-cmd --permanent --zone=drop --add-port=8080/tcp
success
  • Reload the firewalld to apply the above changes:
# firewall-cmd --reload
success
  • Verify the active configuration
[root@client04 ~]# firewall-cmd --list-all
drop (active)         <<---
  target: DROP        <<---
  icmp-block-inversion: no
  interfaces: enp1s0
  sources: 
  services: http ssh  <<---
  ports: 8080/tcp     <<---
  protocols: 
  forward: no
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

Follow the below step to configure default deny nftables rules on RHEL:

Configure the default Deny rules in nftables You can write scripts in the nftables in the following formats which easily get configured without any disconnect.

  • The nftables scripts are stored in the /etc/nftables/ directory.
# pwd
/etc/nftables
  • Create the .nft file as below. You can give script file names as per your suitable.
# vim default-drop-rules.nft
  • Add the below rules in the .nft file.
# cat default-drop-rules.nft
#!/usr/sbin/nft -f

# flush the rule set
flush ruleset

# create tables
add table inet drop_table

# Create a chain for incoming packets that drops all  packets
add chain inet drop_table drop_chain { type filter hook input priority 0 ; policy drop ; }

# allow the remote access connection on port 22 for `ssh`
add rule inet  drop_table drop_chain tcp dport ssh accept

Note: Ensure that the script starts with the shebang #!/usr/sbin/nft -f sequence.

  • To run an nftables script by passing it to the nft utility
# nft -f /etc/nftables/default-drop-rules.nft
  • Check whether the rules apply or not using the below command.
# nft list ruleset
table inet drop_table {
        chain drop_chain {
                type filter hook input priority filter; policy drop;
                tcp dport 22 accept
        }
}
#
  • To make this nftables script drop Rules persist after boot then .nft file should be included in the config file as below.
# vim /etc/sysconfig/nftables.conf

include "/etc/nftables/default-drop-rules.nft"  <<---
  • Restart the nftables service to load the rules without system reboot.
# systemctl restart nftables

Note: We can configure the default deny rules with nft command in nftables but after adding the default deny rules in nftables it disconnects immediately before allowing the SSH Rules which causes the system to unreachable. If you want to configure the default deny rules with nft command then the best method apply all commands mentioned in the script using the console.

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.

Comments