Linux Firewall (Part 1) : Install

Intro

In this post we are going to set up a linux firewall and router. We are going to use Red Hat Enterprise Linux (RHEL) and nftables. If you do not have a subscription for RHEL, you can join the no-cost Red Hat Developer Program to get RHEL license for up to 16 physical or virtual nodes.

I will use Qotom Q355G4 Mini PC, which has four gigabit ethernet ports. We will use one as WAN port (internet), one for DMZ (place our servers here) and one for LAN (place our local devices here).

[!Note]

Even though I use the term DMZ, it’s not DMZ in a true sense, just a different network for separating my personal devices from my severs.

RHEL Install

We are going to use a kickstart file for RHEL install. The kickstart file will contain configuration for automated install of RHEL. We can either create one using text editor or we can use the kickstart generator on RHEL website.

We will let it auto partition the drive, use minimal environment and enable SELinux. We will also set a temporary password for installation and change it later with passwd command. I will set up this firewall using a dynamic IP address for WAN port and static IP addresses for DMZ and LAN. If you have a static IP address for WAN, add that as well.

rhel9-firewall-kickstart.cfg

lang en_US
keyboard --xlayouts='us'
timezone America/Vancouver --utc
rootpw SomePassword
reboot
text
cdrom
bootloader --append="rhgb quiet crashkernel=1G-4G:192M,4G-64G:256M,64G-:512M"
zerombr
clearpart --all --initlabel
autopart
network --device=igb0 --hostname=router --bootproto=dhcp
network --device=igb1 --hostname=router --bootproto=static --ip=10.1.1.1 --netmask=255.255.255.0 --nameserver=10.1.1.1
network --device=igb2 --hostname=router --bootproto=static --ip=10.1.2.1 --netmask=255.255.255.0 --nameserver=10.1.2.1
skipx
firstboot --disable
selinux --enforcing
%packages
@^minimal-environment
kexec-tools
%end

For installation we are going to use Ventoy. Ventoy is an open source tool to create bootable USB drive for ISO files. We can create a Ventory bootable USB drive and then add the RHEL ISO to /linux/rhel folder and the kickstart config file to /autoinstall.

Add the entry for auto install in /ventoy/ventory.json

{
    "auto_install":[
        {
            "parent": "/linux/rhel",
            "template":[
                "/autoinstall/rhel9-firewall-kickstart.cfg"
            ]
        }
    ]
}

Plug in the ethernet cable for WAN in the first ethernet port. We will need the internet to connect to RHEL subscription servers. Boot using the Ventory media and follow prompts to install RHEL.

[!Note]

There are other ways to use the kickstart configuration file. Read about them in RHEL docs

[!Warning]

Don’t forget to change the root password and update the system.

Network

Packet Forwarding

We will need to route traffic between interfaces so the devices on our network can talk to each other and to the internet. For this we will need to enable packet forwarding, which is disabled by default.

Enable forwarding by editing /etc/sysctl.conf

net.ipv4.ip_forward = 1

DMZ and LAN

Since we plugged in the WAN cable in the previous step, RHEL should have automatically set up the first ethernet interface enp1s0 as WAN interface with DHCP client or static IP address depending on our installation. We can also setup DMZ and LAN if not set in kickstart file.

For DMZ, create br_dmz bridge with 10.1.1.1/24 subnet and manual ip assignment

nmcli connection add ifname br_dmz type bridge con-name br_dmz bridge.stp no ipv4.addresses 10.1.1.1/24 ipv4.method manual

Add the second ethernet interface enp2s0 to the DMZ network

nmcli con add type bridge-slave ifname enp2s0 master br_dmz

Do the same for LAN, create br_lan with 10.1.2.1/24 subnet with manual ip assignment

nmcli connection add ifname br_lan type bridge con-name br_lan bridge.stp no ipv4.addresses 10.1.2.1/24 ipv4.method manual

Add the third ethernet interface enp3s0 to the LAN network

nmcli con add type bridge-slave ifname enp3s0 master br_lan

DHCP Server

Now we need to add a DHCP server so the devices on our network can get IP addresses. We will install ISC DHCP server.

[!Warning]

ISC DHCP is EOL. RHEL still supports it so we will use it for now. Read more at https://access.redhat.com/solutions/6990410

Install and enable DHCP server

dnf install dhcp-server
systemctl enable dhcpd

Edit the configuration file for the DHCP server

nano /etc/dhcp/dhcpd.conf

/etc/dhcp/dhcpd.conf

Add internal domain name

option domain-name "example.com";

Set some defaults

default-lease-time 1800;
max-lease-time 3600;
log-facility local7;
one-lease-per-client true;
deny duplicates;
ping-check true;
update-conflict-detection false;
authoritative;

Let’s set up the DMZ network. Add DMZ subnet. The IP address 10.1.1.1 is used by router itself. We can also reserver IPs 2-49 and 201-254 for static assignment. We will add 50-200 for dynamic assignment.

subnet 10.1.1.0 netmask 255.255.255.0 {
    pool {
        range 10.1.1.50 10.1.1.200;
    }

    option routers 10.1.1.1;
    option domain-name-servers 10.1.1.1;
}

Create the static leases for known clients

group {
    option subnet-mask 255.255.255.0;

    host aa_kvm {
        hardware ethernet <MAC ADDRESS>;
        fixed-address 10.1.1.10;
        option host-name "aakvm";
        set hostname-override = config-option host-name;
    }

    host aa_g1 {
        hardware ethernet <MAC ADDRESS>;
        fixed-address 10.1.1.11;
        option host-name "aa";
        set hostname-override = config-option host-name;
    }
}

Do the same thing for our LAN network. Add LAN subnet. The IP address 10.1.2.1 is used by router itself. We can also reserver IPs 2-49 and 201-254 for static assignment. We will add 50-200 for dynamic assignment.

subnet 10.1.2.0 netmask 255.255.255.0 {
    pool {
        range 10.1.2.50 10.1.2.200;
    }

    option routers 10.1.2.1;
    option domain-name-servers 10.1.2.1;
}

Create the static leases for known clients

[!Tip]

We can also connect a wireless access point to our LAN network. Turn off the DHCP server on the wireless access point, so our network the one we installed.


group {
    option subnet-mask 255.255.255.0;

    host ring_doorbell {
        hardware ethernet <MAC ADDRESS>;
        fixed-address 10.1.2.2;
        option host-name "RingDoorbell";
        set hostname-override = config-option host-name;
    }

    host desktop {
        hardware ethernet <MAC ADDRESS>;
        fixed-address 10.1.2.10;
        option host-name "desktop";
        set hostname-override = config-option host-name;
    }

    host wireless_ap {
        hardware ethernet <MAC ADDRESS>;
        fixed-address 10.1.2.254;
        option host-name "wirelessap";
        set hostname-override = config-option host-name;
    }
}

Start the DHCP server

systemctl start dhcpd

Now we can connect network switches to the DMZ and LAN ports and connect devices to them. In the next part we will set up the nftables and firewall rules.

Thank you for reading. Check out the other parts in the series below.