Firewalld

How to Limit Network Access By Firewalld on Enterprise Linux 7

You may have noticed that the service ssh is also added in the public zone (/etc/firewalld/zones/public.xml) by default. This is necessary for initialization. But after that, we don’t need to let ssh widely open to the public.

Let’s see some login failed attemps of one server for example, then you will understand why we should limit access:

[root@test ~]# utmpdump /var/log/btmp | cut -c1-51 | tail
Utmp dump of /var/log/btmp
[6] [34941] [    ] [root    ] [ssh:notty   ] [136.i
[6] [34946] [    ] [simon   ] [ssh:notty   ] [159.2
[6] [34946] [    ] [simon   ] [ssh:notty   ] [159.2
[6] [34950] [    ] [media   ] [ssh:notty   ] [40.11
[6] [34950] [    ] [media   ] [ssh:notty   ] [40.11
[6] [34954] [    ] [michael ] [ssh:notty   ] [40.11
[6] [34954] [    ] [michael ] [ssh:notty   ] [40.11
[6] [34966] [    ] [alex    ] [ssh:notty   ] [159.2
[6] [34966] [    ] [alex    ] [ssh:notty   ] [159.2
[6] [34969] [    ] [root    ] [ssh:notty   ] [136.i

As you can see, some attemps from various ip addresses tried to login the server as root, simon, media, michael, alex, etc. Why would they try to login the server with nonsense usernames? Of course, they have their intentions that could be bad. Once they succeeded, you might have taken the risk of server security.

If we know there’re only fixed sources who will use ssh, we can limit incoming source on firewall to avoid unnecessary risks. For example, we only allow all clients from the intranet to use ssh into this server. So we add a rich rule onto the public zone.

White Listing: Accept connections only from specific IP addresses

[root@test ~]# firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="1.35.0.0/16" service name="ssh" log prefix="ssh" level="info" limit value="5/m" accept"
success
[root@test ~]# firewall-cmd --reload
success
[root@test ~]# firewall-cmd --list-all
public (default, active)
  interfaces: eno16777736
  sources:
  services: dhcpv6-client http https ssh
  ports:
  masquerade: no
  forward-ports:
  icmp-blocks:
  rich rules:
        rule family="ipv4" source address="1.35.0.0/16" service name="ssh" log prefix="ssh" level="info" limit value="5/m" accept

Another way to do white listing is to use invert=”true” which will invert the sense of the source address.

[root@test ~]# firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="1.35.0.0/16" invert="true" service name="ssh" log prefix="ssh" level="info" limit value="5/m" drop"

In the above rule, the firewall will drop all packets except from the specified source addresses.

Black Listing: Drop packets from unwanted visitors

For malicious or spam IP addresses, we drop their packets, no matter what.

[root@test ~]# firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="123.123.0.0/16" drop"
success
[root@test ~]# firewall-cmd --reload
success
[root@test ~]# firewall-cmd --list-all
public (default, active)
  interfaces: eno16777736
  sources:
  services: dhcpv6-client http https ssh
  ports:
  masquerade: no
  forward-ports:
  icmp-blocks:
  rich rules:
        rule family="ipv4" source address="123.123.0.0/16" drop
        rule family="ipv4" source address="1.35.0.0/16" service name="ssh" log prefix="ssh" level="info" limit value="5/m" accept

Let’s see the “public” zone file.

[root@test ~]# cat /etc/firewalld/zones/public.xml
<?xml version="1.0" encoding="utf-8"?>
<zone>
  <short>Public</short>
  <description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
  <service name="dhcpv6-client"/>
  <service name="http"/>
  <service name="ssh"/>
  <service name="https"/>
  <rule family="ipv4">
    <source address="123.123.0.0/16"/>
    <drop/>
  </rule>
  <rule family="ipv4">
    <source address="1.35.0.0/16"/>
    <service name="ssh"/>
    <log prefix="ssh" level="info">
      <limit value="5/m"/>
    </log>
    <accept/>
  </rule>
</zone>

Save Run-time to Permanent

Adding a simple option can save run-time (memory) settings into the permanent zone file.

[root@test ~]# firewall-cmd --runtime-to-permanent
success

Please note that, firewalld processes these rich rules in chain by this order:

  1. log
  2. deny
  3. allow

For more configuration, you may refer to red hat document:
4.5.3. Configuring firewalld

Leave a Reply

Your email address will not be published. Required fields are marked *