CentOS 7 firewalld NAT router

Datetime:2016-08-22 23:43:13          Topic: Centos           Share

I recently built a simple gateway/router using firewalld and NAT on CentOS 7 and thought I’d share the firewall-cmd commands used. The machine in question was used as a gateway/router for two VMWare virtual networks being used by students to build Windows domains. As their domain controllers were running DHCP servers, their networks had to be isolated from the TAFE (college) network and each other to avoid problems, but the students also needed access to the TAFE network for DNS forwarding and internet access purposes.

The gateway/router had three virtual NICs, one in each of the students’ virtual networks and one in TAFE’s network. Creating a new custom firewall zone for each student network was easy enough:

firewall-cmd --permanent --new-zone=student1
firewall-cmd --permanent --new-zone=student2
firewall-cmd --reload

Note that only one new zone can be added at a time, and that the –permanent option must be used. The presence of the new zones in firewalld’s permanent configuration can be verified by typing:

firewall-cmd --permanent --get-zones

Zones can be removed if necessary by typing:

firewall-cmd --permanent --delete-zone=student1

By default, firewalld assigns all interfaces to the default zone, usually the “public” zone. So, in our case the following command produced the following output (interface names have been simplified):

firewall-cmd --list-all

public (default, active)
interfaces: eth1 eth2 eth3
sources:
services: dhcpv6-client ssh
ports:
masquerade: no
forward-ports:
icmp-blocks:
rich rules:

Here, firewalld knows about three interfaces, eth1 eth2 and eth3, and all are assigned to the “public” zone. We want to assign eth1 to the “student1” zone and eth2 to the “student2” zone, and leave eth3 in the “public” zone which we will use for TAFE’s network.

Initially, we tried using some firewall-cmd options for adding interfaces to zones (and removing them) as follows:

firewall-cmd --permanent --zone=public --remove-interface=eth1
firewall-cmd --permanent --zone=student1 --add-interface=eth1

The problem with this approach was that every time firewalld or the server were restarted, all interfaces were reassigned back to the “public” zone despite the use of the –permanent option in the above commands. It turns out that the only way to permanently assign an interface to a zone is to edit the interface’s configuration (ifcfg) file in the /etc/sysconfig/network-scripts/ directory and add a ZONE option as follows:

ZONE=student1

If this option is missing or empty, the default firewalld zone will always be reassigned to the interface when it is restarted. So, with the ZONE option added to both ifcfg-eth1 and ifcfg-eth2 and networking restarted, we moved on to configuring routing using NAT (network address translation).

The following rules allow machines on the isolated internal networks (eth1 and eth2) to send NATed packets to TAFE’s network (eth3), and also allow responses back. Machines on TAFE’s network cannot initiate communications with student machines on the internal networks:

firewall-cmd --direct --add-rule ipv4 nat POSTROUTING 0 -o eth_ext -j MASQUERADE

firewall-cmd --direct --add-rule ipv4 filter FORWARD 0 -i eth1 -o eth3 -j ACCEPT
firewall-cmd --direct --add-rule ipv4 filter FORWARD 0 -i eth3 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT

firewall-cmd --direct --add-rule ipv4 filter FORWARD 0 -i eth2 -o eth3 -j ACCEPT
firewall-cmd --direct --add-rule ipv4 filter FORWARD 0 -i eth3 -o eth2 -m state --state RELATED,ESTABLISHED -j ACCEPT

Pretty simple really. Note that this gateway/router forwards all traffic regardless of service, port or protocol, and functions more as a dumb router than a firewall. It could be locked down to only allow specific services and ports, but works fine for our purposes.





About List