Creating direct rules in RHEL/CentOS 7 firewalld

As we've seen, any time we do anything with the normal firewall-cmd commands on RHEL/CentOS 7, firewalld automatically translates those commands into iptables rules and inserts them into the proper place (or, it deletes the rules, if you've issued some sort of delete command). However, there are some things that we can't do with the normal firewalld-cmd commands. For example, we can't use normal firewall-cmd commands to place rules in a specific iptables chain or table. To do things like that, we need to use the direct configuration commands.

The firewalld.direct man page and the documentation at the Red Hat site both warn you to only use direct configuration as an absolute last resort when nothing else will work. That's because, unlike the normal firewall-cmd commands, the direct commands won't automatically place your new rules into the proper places so that everything works correctly. With the direct commands, you can break the whole firewall by placing a rule into the wrong spot.

In the example output of the previous section, in the default ruleset, you saw that there's a rule in the filter table's INPUT chain that blocks invalid packets. In the Blocking invalid packets with iptables section, you saw that this rule misses certain types of invalid packets. So, we'd like to add a second rule to block what the first rule misses. We'd also like to place these rules into the PREROUTING chain of the mangle table in order to enhance firewall performance. To do this, we need to create a couple of direct rules. (This isn't hard if you're familiar with normal iptables syntax.) So, let's get to it.

First, let's verify that we don't have any effective direct rules, like so:

sudo firewall-cmd --direct --get-rules ipv4 mangle PREROUTING
sudo firewall-cmd --direct --get-rules ipv6 mangle PREROUTING

You should get no output for either command. Now, let's add our two new rules, for both IPv4 and IPv6, with the following four commands:

sudo firewall-cmd --direct --add-rule ipv4 mangle PREROUTING 0 -m conntrack --ctstate INVALID -j DROP

sudo firewall-cmd --direct --add-rule ipv4 mangle PREROUTING 1 -p tcp ! --syn -m conntrack --ctstate NEW -j DROP

sudo firewall-cmd --direct --add-rule ipv6 mangle PREROUTING 0 -m conntrack --ctstate INVALID -j DROP

sudo firewall-cmd --direct --add-rule ipv6 mangle PREROUTING 1 -p tcp ! --syn -m conntrack --ctstate NEW -j DROP


The direct command syntax is very similar to that of normal iptables commands. So, I won't repeat the explanations that I've already presented in the iptables section. However, I do want to point out the 0 and the 1 that come after PREROUTING in each of the commands. Those represent the priority of the rule. The lower the number, the higher the priority, and the higher up the rule is in the chain. So, the rules with the 0 priority are the first rules in their respective chains, while the rules with the 1 priority are the second rules in their respective chains. If you give the same priority to each rule you create, there's no guarantee that the order will remain the same upon each reboot. So, be sure to assign a different priority to each rule.

Now, let's verify that our rules are in effect:

[donnie@localhost ~]$ sudo firewall-cmd --direct --get-rules ipv4 mangle PREROUTING
0 -m conntrack --ctstate INVALID -j DROP

1 -p tcp '!' --syn -m conntrack --ctstate NEW -j DROP
[donnie@localhost ~]$ sudo firewall-cmd --direct --get-rules ipv6 mangle PREROUTING
0 -m conntrack --ctstate INVALID -j DROP

1 -p tcp '!' --syn -m conntrack --ctstate NEW -j DROP
[donnie@localhost ~]$

We can see that they are. When you use the iptables -t mangle -L command and the ip6tables -t mangle -L command, you'll see that the rules show up in the PREROUTING_direct chain (I'm only showing the output once since it's the same for both commands):

. . .
. . .
Chain PREROUTING_direct (1 references)
target prot opt source destination
DROP all -- anywhere anywhere ctstate INVALID
DROP tcp -- anywhere anywhere tcp flags:!FIN,SYN,RST,ACK/SYN ctstate NEW
. . .
. . .

To show that it works, we can perform some Nmap scans against the virtual machine, just like how I showed you to in the Blocking invalid packets with iptables section. (Don't fret if you don't remember how to do it. You'll see the procedure in the upcoming hands-on lab.) Then, we can use sudo iptables -t mangle -L -v and sudo ip6tables -t mangle -L -v to see the packets and bytes that these two rules blocked.

We didn't use the --permanent option with these commands, so they're not permanent yet. Let's make them permanent now:

[donnie@localhost ~]$ sudo firewall-cmd --runtime-to-permanent
[sudo] password for donnie:
success
[donnie@localhost ~]$

Now, let's take a look in the /etc/firewalld directory. Here, you'll see a direct.xml file that wasn't there before:

[donnie@localhost ~]$ sudo ls -l /etc/firewalld
total 20
-rw-r--r--. 1 root root 532 Aug 26 13:17 direct.xml
. . .
. . .
[donnie@localhost ~]$

Look inside the file; you'll see the new rules:

<?xml version="1.0" encoding="utf-8"?>
<direct>
<rule priority="0" table="mangle" ipv="ipv4" chain="PREROUTING">-m conntrack --ctstate INVALID -j DROP</rule>

<rule priority="1" table="mangle" ipv="ipv4" chain="PREROUTING">-p tcp '!' --syn -m conntrack --ctstate NEW -j DROP</rule>

<rule priority="0" table="mangle" ipv="ipv6" chain="PREROUTING">-m conntrack --ctstate INVALID -j DROP</rule>

<rule priority="1" table="mangle" ipv="ipv6" chain="PREROUTING">-p tcp '!' --syn -m conntrack --ctstate NEW -j DROP</rule>

</direct>

The official Red Hat 7 documentation page does cover direct rules, but only briefly. For more detailed information, see the firewalld.direct man page.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.106.100