NAT router with 2 interfaces, how to do with firewalld and Centos 9 Stream (original) (raw)

Hello,
I’m trying to migrate C8s to C9s, and I need to recreate a machine with two interfaces, one WAN that does NAT, and one LAN.
WAN (ens192) is in zone “external”, with forward and masquerade set to yes.
LAN (ens224) is in zone “internal”, with forward and masquerade set to no.
I have /proc/sys/net/ipv4/ip_forward set to 1.
I must set target for internal to ACCEPT for packets to be NAT/Forwarded. Otherwise, everything is blocked. But if I do that, then any machine on the internal zone can for example ssh to my gateway.
With Centos8Stream, same parameters (unless I’m mistaken), the internal zone was set to default, and ssh to the machine acting as a NAT/masquerade router was blocked.

barryascott (Barry A Scott) July 3, 2024, 3:15pm 2

Just copy your firewalld config files to the new system.
Provided the interfaces have the same names it should work.

I have been upgrading my Fedora bases firewall across many releases and the firewall continued to work.

as2917 (Paul Rolland) July 3, 2024, 4:45pm 3

Hello Barry,
Thanks for the reply.
When you say “your firewall config files”, are you referring to the ones in /etc/firewalld/ ? I didn’t copy them, I recreate the configuration using firewall-cmd, but I made sure they were having the same content.
Fact is C8s is using firewalld 0.9.4 and C9s is based on 1.3.4, and having the same configuration files doesn’t mean the behavior is the same (some breaking changes are know, such as the forward parameter in zone).

barryascott (Barry A Scott) July 3, 2024, 7:37pm 4

Your comment about requirements and forward parameter suggests you know what you are doing.

Assuming you are an admin isn’t this a simple firewall you need to configure?
I assume this is covered in the docs?

I have not done this from scratch in a long while, but the docs made sense when I did do the setup.

vgaetera (Vladislav Grigoryev) July 8, 2024, 4:20am 5

sudo firewall-cmd --permanent --new-policy=internal-external
sudo firewall-cmd --permanent --policy=internal-external --set-target=ACCEPT
sudo firewall-cmd --permanent --policy=internal-external --add-masquerade
sudo firewall-cmd --permanent --policy=internal-external --add-ingress-zone=internal
sudo firewall-cmd --permanent --policy=internal-external --add-egress-zone=external
sudo firewall-cmd --reload

Policy Objects: Introduction | firewalld

valeube (Valentino Uberti) December 21, 2024, 5:38pm 6

Hi, I tried your solution on RHEL 9 but I can not reach internet from the internal network. This should work but it doesn’t and I don’t know why:

firewall-cmd --zone=external --add-interface=enp2s0 --permanent
firewall-cmd --zone=internal --add-interface=enp3s0 --permanent
firewall-cmd --set-default-zone=external
firewall-cmd --permanent --new-policy=internal-external
firewall-cmd --permanent --policy=internal-external --set-target=ACCEPT
firewall-cmd --permanent --policy=internal-external --add-masquerade
firewall-cmd --permanent --policy=internal-external --add-ingress-zone=internal
firewall-cmd --permanent --policy=internal-external --add-egress-zone=external
firewall-cmd --permanent --policy=internal-external --add-service={http,https,ldap,ldaps,kerberos,dns,kpasswd,ntp,ftp}
firewall-cmd --reload

Could you please help me @vgaetera ?

barryascott (Barry A Scott) December 21, 2024, 8:13pm 7

Check you have ipv4 forwarding set in your .network files.
here is an example from my systemd-networkd router:

more internal-if.network
[Match]
Name=internal

[Network]
Description=internal network
Address=172.17.1.1/24
IPForward=yes
DNS=127.0.0.1

The key is the IPForward=yes.
As I run named-chroot on the router I use 127.0.0.1 as the DNS.

I rename my interface to “internal” and “external” to avoid the default names like this:

more 11-internal.link
[Link]
Description=Set internal ethernet interface name

Name=internal

[Match]
# enp3s0
MACAddress=xx:yy:...

valeube (Valentino Uberti) December 22, 2024, 5:07am 8

Hi Barry, systemd-networkd is not running as I am using NetworkManager. The IPForward is enable on the internal interface:

[root@bastion ~]# firewall-cmd --list-all --zone internal
internal
  target: default
  icmp-block-inversion: no
  interfaces: 
  sources: 
  services: cockpit dhcpv6-client mdns samba-client ssh
  ports: 
  protocols: 
  forward: yes
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

And here the external interface:

external
  target: default
  icmp-block-inversion: no
  interfaces: 
  sources: 
  services: ssh
  ports: 
  protocols: 
  forward: yes
  masquerade: yes
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

Thanks a lot

vgaetera (Vladislav Grigoryev) December 22, 2024, 5:10am 9

Check the output:

# Fedora router
firewall-cmd --get-active-zones
firewall-cmd --get-active-policies

# LAN client
traceroute -n 1.1.1.1
nslookup example.org 1.1.1.1

valeube (Valentino Uberti) December 22, 2024, 6:38am 10

root@bastion:~# firewall-cmd --get-active-zones
external (default)
  interfaces: enp2s0
internal
  interfaces: enp3s0
root@bastion:~# firewall-cmd --get-active-policies
allow-host-ipv6
  ingress-zones: ANY
  egress-zones: HOST
internal-external
  ingress-zones: internal
  egress-zones: external

Thank you

valeube (Valentino Uberti) December 22, 2024, 6:40am 11

Here the simple configuration of the internal nic (enp3s0)

ipv4.method:                            manual
ipv4.dns:                               --
ipv4.dns-search:                        --
ipv4.dns-options:                       --
ipv4.dns-priority:                      0
ipv4.addresses:                         172.22.0.1/24
ipv4.gateway:                           --
ipv4.routes:                            --

Here the policy info:

root@bastion:~# firewall-cmd --info-policy internal-external
internal-external (active)
  priority: -1
  target: ACCEPT
  ingress-zones: internal
  egress-zones: external
  services: dns ftp http https kerberos kpasswd ldap ldaps ntp
  ports: 
  protocols: 
  masquerade: yes
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

valeube (Valentino Uberti) December 22, 2024, 6:56am 13

from the LAN client (172.22.0.2) I’m receiving a communication error to 1.1.1.1

The nic of the LAN client is configured just with the IPv4, without default gateway.
I added the default route to 172.22.0.2

valeube (Valentino Uberti) December 22, 2024, 7:08am 15

Still nothing, even with direct rules (worked on fedora 33)

vgaetera (Vladislav Grigoryev) December 22, 2024, 7:35am 17

sudo nmcli connection show
sudo nmcli connection modify LAN_CONNECTION ipv4.method shared 
sudo nmcli connection up LAN_CONNECTION
sudo firewall-cmd --permanent --zone=internal --add-service=dhcp
sudo firewall-cmd --permanent --zone=internal --add-service=dns
sudo firewall-cmd --permanent --policy=internal-external \
    --add-rich-rule="rule tcp-mss-clamp value=pmtu"
sudo firewall-cmd --reload
sudo tee /etc/NetworkManager/conf.d/99-local.conf << EOF > /dev/null
[main]
firewall-backend=none
EOF
sudo systemctl restart NetworkManager.service

Also make sure the LAN client is configured with DHCP.

valeube (Valentino Uberti) December 22, 2024, 8:06am 18

Thank you! Using DHCP did the trick. Now I’ll investigate the received network connection parameters as I need some static IP configuration for different devices connected to the internal lan. Here the working example:

firewall-cmd --zone=external --add-interface=enp2s0 --permanent
firewall-cmd --zone=internal --add-interface=enp3s0 --permanent
firewall-cmd --set-default-zone=external
firewall-cmd --permanent --new-policy=internal-external
firewall-cmd --permanent --policy=internal-external --set-target=ACCEPT
firewall-cmd --permanent --policy=internal-external --add-masquerade
firewall-cmd --permanent --policy=internal-external --add-ingress-zone=internal
firewall-cmd --permanent --policy=internal-external --add-egress-zone=external
firewall-cmd --permanent --policy=internal-external --add-service={http,https,ldap,ldaps,kerberos,dns,kpasswd,ntp,ftp}
firewall-cmd --permanent --zone=internal --add-service=dhcp --add-service=dns
firewall-cmd --permanent --policy=internal-external --add-rich-rule="rule tcp-mss-clamp value=pmtu"
firewall-cmd --reload