Configure FirewallD Settings

Warning

Starting from RHEL 9 network configuration is done using Network Manager, see https://www.redhat.com/en/blog/rhel-9-networking-say-goodbye-ifcfg-files-and-hello-keyfiles for more information. This tutorial was adjusted in August 2023 to match new style management in RHEL 9.

First we will need to configure the firewalld daemon. The firewall daemon is built on the idea of zones. We will consider our lan as an internal zone and our public wan as external zone. These predefined names need to be specified in the network configuration.

Note

We are using the predefined zone names to ease NAT-ting as external zone has the masquerade attribute required for successful NAT already configured.

Open /etc/NetworkManager/system-connections/ens160.nmconnection and add the zone=external line. The following screenshot shows the edited contents.

../../_images/ifcfg_external.png

Open /etc/NetworkManager/system-connections/ens192.nmconnection and add the zone=internal line. The following screenshot shows the edited contents.

../../_images/ifcfg_internal.png

Reboot your gateway and after it comes back to life run the following command to see if zones were assigned correctly.

firewall-cmd --get-active-zones

The output should look like:

../../_images/active_zones.png

Run the bash firewall.sh script from our repository https://github.com/diladele/websafety/tree/master/intercept/rhel9 to add required rules for external and internal networks. Contents of this script are shown below. Basically it allows SSH, HTTP and HTTPS access on the internal NIC and add 3126, 3127 and 3128 ports for transparent and explicit HTTP/HTTPS proxy (to be described below).

#!/bin/bash

# firewall setup should be done as root
if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root" 1>&2
   exit 1
fi

# check kernel forwarding is enabled
enabled=`cat /proc/sys/net/ipv4/ip_forward`
if [[ $enabled -ne 1 ]]; then
    echo "Kernel forwarding seems to be disabled, are internal and external zones assigned correctly?" 1>&2
    exit 1
fi

# we will have the following ports open on our gateway for all internal clients
#   22   - sshd for SSH
#   80   - http for HTTP traffic
#   443  - https for HTTPS traffic
#   8000 - for Web Safety UI
#   3126 - for intercepted HTTP traffic for Squid
#   3127 - for intercepted HTTPS traffic for Squid
#   3128 - for normal explicit proxy traffic
#
firewall-cmd --zone=internal --add-service=ssh --permanent
firewall-cmd --zone=internal --add-service=http --permanent
firewall-cmd --zone=internal --add-service=https --permanent
firewall-cmd --zone=internal --add-port=8000/tcp --permanent
firewall-cmd --zone=internal --add-port=3126/tcp --permanent
firewall-cmd --zone=internal --add-port=3127/tcp --permanent
firewall-cmd --zone=internal --add-port=3128/tcp --permanent

# also allow connections to external DNS server as we use it in the tutorial
firewall-cmd --zone=internal --add-port=53/udp --permanent

# and copy the direct xml
cp direct.xml /etc/firewalld/direct.xml

The script also adds two rules to redirect traffic from internal zone targeted at port 80 (HTTP) to port 3126 and 443 (HTTPS) to port 3127 on our gateway. These ports will be used by Squid proxy to listen for redirected traffic flow. Please note - syntax of these rules is advanced and we must use the direct interface of firewalld daemon.

The script creates the file /etc/firewalld/direct.xml and puts the following in it (please note - here we designate the ens192 as our internal NIC, you might need to adjust this according to actual NIC name in your deployment).

<?xml version="1.0" encoding="utf-8"?>
<direct>
    <rule ipv="ipv4" table="nat" chain="PREROUTING" priority="0">-i ens192 -p tcp --dport 80 -j REDIRECT --to-ports 3126</rule>
    <rule ipv="ipv4" table="nat" chain="PREROUTING" priority="0">-i ens192 -p tcp --dport 443 -j REDIRECT --to-ports 3127</rule>
</direct>

Note

Having redirect rules in this file lets it survive reboots as rules added to FirewallD using –direct command line option are not permanent. For more information on direct.xml please see the man 5 firewalld.direct entry.

Now reboot your gateway and test if both normal and advanced firewall rules are stored as expected.

# see the active zones
firewall-cmd --get-active-zones

# see the settings of the internal zone
firewall-cmd --zone=internal --list-all

# see the settings direct rules
firewall-cmd --direct --get-all-rules

The output should look like:

../../_images/all.png