Firewalld config questions

Support for security such as Firewalls and securing linux
Post Reply
markmcn
Posts: 5
Joined: 2016/01/02 23:44:51

Firewalld config questions

Post by markmcn » 2018/05/25 22:36:39

Hi All,
I'm currently working on moving toward firewalld and away from iptables as the front end for managing netfilter on some hosts including hosts which act as routers which are performing NAT.
This work & study has prompted some questions which I'm not sure about the answers.
The questions will be based on the following test setup.
CentOS 7.x host with the following interfaces
eth0(1.1.1.1) in the zone public.
br0 (192.168.10.1/24) in the zone internal
There are virtual hosts which are running in KVM which are also in the 192.168.10.0/24 space and use 192.168.10.1 as their default gateway.
My questions are as follows.
Assuming I wish to enable source nat / masquerade from the private subnet 192.168.10.0 to the general internet the packet flows from the internal zone to the public zone.
On the redhat docs at section 5.3.1.9 it says
To translate IPv4 addresses to a single external address, start the firewall-config tool and select the network zone whose addresses are to be translated. Select the Masquerading tab and select the check box to enable the translation of IPv4 addresses to a single address.
I'm using the cli tool rather than gui however I understand this to mean that you enable masquerade on for the zone which is internal in this example. This has not worked for me, However when I enable masquerade on the outbound zone (public) it works fine I can ping out etc etc.
My main reason for seeking clarification on this is i'm starting to prepare for RHCSA and I want to make sure my understanding of this topic is correct.

Secondly with IPtables I was able to configure the following destination nat config which I have not managed to replicate in firewalld yet.
Table:NAT Chain:Prerouting destination-address:1.1.1.1 protocol tcp destination port 80 action:dnat to 192.168.10.14 (Say an internal webserver)
Table:Filter Chain:Forwarding source-address:2.2.2.2 destination-address:1.1.1.1 protocol tcp destination port 80 action:drop (I want to block this one ip)
Table:Filter Chain:Forwarding destination-address:1.1.1.1 protocol tcp destination port 80 action:accept (allow everyone else)
Here I can see the packet flow from the nat table to the filter table and apply different rules at different stages.
In firewalld I've been able to get the port-forwarding working correction without any issue but I thought I'd be able to apply some rules as the packet flowed from the public zone to the internal zone however when I setup deny rules to test on the internal zone it appears they don't get hit.
I know this could be done with direct rules which effectively allow me to use iptables rules within firewalld's interface however before I go down that path I want to make sure it's not that I need to change the way I look at the firewall operation.
does a packet flow from one zone to another so I know the rules are based on the source so i'd infer that means as it enters a zone, Does this mean in a destination nat example it get's examined on the entering the public zone from the interface and then again on the ingress to the internal zone as it leaves the public zone after being nat'd

I hope I've managed to explain my questions clearly.
Many thanks in advance to anyone who takes the time to read this.
Cheers
Mark

User avatar
jlehtone
Posts: 2018
Joined: 2007/12/11 08:17:33
Location: Finland

Re: Firewalld config questions

Post by jlehtone » 2018/05/27 20:13:13

markmcn wrote:I'm using the cli tool rather than gui however I understand this to mean that you enable masquerade on for the zone which is internal in this example. This has not worked for me, However when I enable masquerade on the outbound zone (public) it works fine I can ping out etc etc.
When your VM talks "to internet", the packet is routed through the host.
The packet will travel the table nat chain POSTROUTING just before it leaves through the eth0.
This is where SNAT shall be applied. Rather than having a packet header (From:192.168.0.7, To: 8.8.8.8)
you want header (From:1.1.1.1, To: 8.8.8.8). That way the reply will find its wat back to your host (that then forwards it to the 192.168.0.7).

In other words: if you want to masquerade everything that goes out via interface X, then you must masquerade on the zone, where the interface X is. In your case it is the public.

Have you noticed an another predefined zone, 'external'? I believe that it has masquerade on by default.


When one adds a "port forwarding", aka DNAT, with firewall-cmd, there are actually three netfilter rules added:
1. table mangle marks all packets that match your criteria (to tcp/80 in zone public)
2. table nat applies the DNAT to marked packets
3. table filter forwarding chain (was it "in from public" subchain?) allow passage of marked packets

The criteria probably cannot be (to tcp/80 and not from 2.2.2.2). I would check rich rules next before resorting to direct rules.

markmcn
Posts: 5
Joined: 2016/01/02 23:44:51

Re: Firewalld config questions

Post by markmcn » 2018/05/27 20:30:35

Hi jlehtone,
Many thanks for the reply and clarifying where masquerade should be applied.
I've been happily using IPTables for a long time and really like the flexibility it provides.
I initially thought that maybe I needed to look at things differently to get similar flexibility from firewalld but your feedback along with my own digging and testing really has convinced my that firewalld just isn't ready to replace iptables unless you are using direct rules. I've also spotted the initial flaw in the way I was thinking that a packet would from between zones which I can see now doesn't really happen.
Thanks again for taking the time to help
Cheers
Mark

User avatar
jlehtone
Posts: 2018
Joined: 2007/12/11 08:17:33
Location: Finland

Re: Firewalld config questions

Post by jlehtone » 2018/05/28 10:11:45

Single rich rule:

Code: Select all

firewall-cmd --zone=public --add-rich-rule=
  'rule family="ipv4" source not address="2.2.2.2" destination address="1.1.1.1" forward-port to-addr="192.168.10.14" port="80" protocol="tcp"'
generates:

Code: Select all

-t mangle -A PRE_public_allow ! -s 2.2.2.2/32 -d 1.1.1.1/32 -p tcp -m tcp --dport 80 -j MARK --set-xmark 0x64/0xffffffff
-t nat -A PRE_public_allow -p tcp -m mark --mark 0x64 -j DNAT --to-destination 192.168.10.14
-t filter -A FWDI_public_allow -m conntrack --ctstate NEW -m mark --mark 0x64 -j ACCEPT
More options than --add-forward-port, yet no need to go direct.

Since -s 2.2.2.2 won't be marked, it won't be forwarded and will therefore meet the

Code: Select all

-t filter -A INPUT -j REJECT --reject-with icmp-host-prohibited
Ok, that is not as harsh as the drop. However, one can add the explicit drop:

Code: Select all

firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="2.2.2.2" destination address="1.1.1.1" drop'

Post Reply