Page 1 of 1

CentOS8 firewall config

Posted: 2020/07/28 01:57:52
by Cougar281
Let me start by saying I'm not super proficient with Linux - It could probably be said that I know enough about Linux variants to be dangerous, but my main expertise is in networking, VMWare and Windows Server OSes. If I can find a concise 'how-to' for what I'm wanting to do in Linux, no problem, but getting off something like that gets a little dicey.

In the past, my dealings with Linux firewalls has been essentially nil because I always disable the built-in OS firewalls and use a dedicated external firewall.

That being said, I have a use case where I don't have the ability to have a dedicated external firewall, so as such, I have little choice but to use the built in firewall. From the reading I've done, I've gotten somewhere, but not really where I want to be.

What I want to do is 'fairly simple'. I want to:

Allow all outbound
Allow SMTP from anywhere (Ideally IPV4 & IPV6)
Allow 'TCP Port1' from 'x' IPv4 address
Allow 'TCP Port2' from 'x' IPv4 address
Allow 'TCP Port3' from 'x' IPv4 address
Drop all other traffic as if the IP is dead

The idea being it accepts all inbound mail for my domains, and in the event that my internet connection has gone down or my server has become unreachable for whatever reason, this will spool all inbound mail indefinitely until my server comes back online and then deliver it at that point, and it also serves as an outbound relay point for my mail server, so all mail comes and goes from the same IP.

I did manage to get part way there using the following:

firewall-cmd --permanent --zone=public --add-icmp-block-inversion
firewall-cmd --permanent --zone=public --add-rich-rule 'rule family="ipv4" source address="IPx" port port=Port1 protocol=tcp accept'
firewall-cmd --permanent --zone=public --add-rich-rule 'rule family="ipv4" source address="IPx" port port=Port2 protocol=tcp accept'
firewall-cmd --permanent --zone=public --add-rich-rule 'rule family="ipv4" source address="IPx" port port=Port3 protocol=tcp accept'

The problem with those commands (well, the ICMP one) is when I ping it, I get 'Destination net unreachable.' instead of the expected/desired 'timeout'.

The other three (non-ICMP) are probably exactly as I need/want them. Using the '--permanent' switch, they're persistent across reboots. I'm just not sure if the 'rich rules' are the best way to get where I want to be with them since that's new to me.

SMTP is listed in the 'services' section of 'firewall-cmd --zone=public --list-all' but I'm not sure that's all that's needed as when I start Postfix, it still doesn't respond if I try to telnet to it on port 25.

If this was a pfSense, ASA or Watchguard firewall, it would be a no-brainier.

So What's the best way to do this? The 'FirewallD' portion of WebMin doesn't seem to give any hints that anything like the 'Rich Rules' are possible, and if I make a change using it, it wipes out the Rich Rules I configured.

Is it possible to configure this sort of thing from WebMin's FirewallD section? Or should it be just CLI? Any advice/suggestions?

Re: CentOS8 firewall config

Posted: 2020/07/28 07:39:04
by jlehtone
Disclaimer: I have no idea what "WebMin" is.

Red Hat has documentation: ... networking

No, rich rules are not the primary "firewalld way" for your scenario. Zones are.

If the "IPx" is same for all three ports, then I would create a zone that allows ports Port[1-3] (or even define services that have those ports and add those services to the zone).
Or just modify the original 'public' for this:

Code: Select all

$ firewall-cmd --permanent --zone=public --add-source=IPx
$ firewall-cmd --permanent --zone=public --add-port=Port1/tcp
$ firewall-cmd --permanent --zone=public --add-port=Port2/tcp
$ firewall-cmd --permanent --zone=public --add-port=Port3/tcp
Then take the predefined zone 'drop' which has description:
Unsolicited incoming network packets are dropped. Incoming packets that are related to outgoing network connections are accepted. Outgoing network connections are allowed.
If that does not drop dead incoming packets, then what does?

Allow smtp from both zones:

Code: Select all

$ firewall-cmd --permanent --zone=public --add-service=smtp
$ firewall-cmd --permanent --zone=drop --add-service=smtp
The service 'smtp' allows exactly port 25/tcp

Code: Select all

$ firewall-cmd --info-service=smtp
  ports: 25/tcp
Make 'drop' the primary zone. Firewalld has "default zone" that all connections use by default. It is 'public'. Lets make that 'drop':

Code: Select all

$ firewalld-cmd --set-default-zone=drop
The effect is immediate and permanent.
Each connection can have explicit zone. That can be changed with 'nmcli':

Code: Select all

$ nmcli con mod "System em1" drop
That did modify connection, whose name is 'System em1'. You can see connection names with: nmcli con s
The effect is immediate and permanent.

After you reload firewalld, you should get something like:

Code: Select all

$ firewall-cmd --get-active-zones
  interfaces: em1 em2
  sources: IPx
The effective rules are:

Code: Select all

IF incoming packet has source IPx
  IF zone public has destination port (ssh, smtp, Port1, ...)
  THEN allow
  ELSE reject
  IF zone drop has destination port (i.e. smtp)
  THEN allow
  ELSE drop
Note: if you connect to server remotely (ssh), make and activate these changes, and you are not connecting from "IPx" or make a mistake, then you have locked yourself out and have to go to console.

The firewalld has configuration in two places: files and memory.
It uses in-memory config to manage actual rules in kernel's nftables.
The '--permanent' modifies the config in files. Without, you modify config in memory. The '--reload' reads config from files to memory.

When you modify config in memory, you can use '--timeout' to have new config for a while and then revert to previous state. Handy to test a rule that could throw you out.
All operations do not have the timeout option.

The predefined zone and service files are in /usr/lib/firewalld
Your modifications and additions are in /etc/firewalld
For example, you have modified zone 'public'. You have /etc/firewalld/zones/public.xml that overrides /usr/lib/firewalld/zones/public.xml
You can revert to original in-files configuration of 'public' by deleting /etc/firewalld/zones/public.xml

Red Hat recommends nftables.service for "real work". The firewalld is "simple", but the ruleset it creates is rather bloated. Use of nftables.service allows more compact (but less dynamic) ruleset, if you can write one by hand.

Re: CentOS8 firewall config

Posted: 2020/07/31 20:31:51
by Cougar281
Thank you very much for that - it was very helpful. Following your post, I was able to get it working exactly how I'd like it to work.

By the way, Webmin is a web-based interface for system administration: