Step 6. Configure FirewallD Settings

In CentOS / RedHat 7 iptables firewall was extended with firewalld daemon which is much more user friendly to a novice network admin and still allows for advanced rules in the old iptables style.

The firewalld 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 scripts.

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/sysconfig/network-scripts/ifcfg-ens32 and add the ZONE=external line. The following screenshot shows the edited contents.

../../_images/ifcfg_external.png

Open /etc/sysconfig/network-scripts/ifcfg-ens33 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 06_firewall.sh script 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

# 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 ens33 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 ens33 -p tcp --dport 80 -j REDIRECT --to-ports 3126</rule>
    <rule ipv="ipv4" table="nat" chain="PREROUTING" priority="0">-i ens33 -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