Welcome to configuring Fedora Server 38 as a router tutorial series!

  1. Setup Fedora Server 38 as a NAT Router with Qemu/KVM, Part 1
  2. Setup Fedora Server 38 as a DHCP Server with Qemu/KVM, Part 2
  3. Setup Fedora Server 38 as a DNS Server with Qemu/KVM, Part 3

This is how it will look like the virtual network we are going to build:

configuring Fedora Server 38 as a NAT router
  • enp0s4: WAN interface
  • enp0s5: LAN interface with a ipv4 subnet prefix address 172.16.0.0/24
  • 192.168.0.15: the first IPv4 address of Fedora Server 38 as WAN IPv4 address
  • 172.16.0.1: the second IPv4 address of Fedora Server 38 as LAN IPv4 Gateway
  • 172.16.0.11: the IPv4 address of the first client
  • 172.16.0.12: the IPv4 address of the second client

First, we need to have three qemu images:

  • Fedora Server 38 distro as a router gateway
  • Fedora Desktop 38 distro as a client 1
  • Fedora Desktop 38 distro as a client 2

Then, we need set up a linux bridge (which will act as a layer 2 switch) and three tap interfaces on the host computer to connect three qemu images to each other.

We can create a new tap interface using tunctl command. In order to use tunctl command, you need to install uml-utilities package on Ubuntu:

sudo apt install uml-utilities

Or tunctl package on Fedora:

sudo dnf install tunctl

We need to create a tap interface for each of the virtual machines, then we will need to create three different tap interfaces:

sudo tunctl -u $USER -t tap1
sudo tunctl -u $USER -t tap2
sudo tunctl -u $USER -t tap3

Next, we bring the tap interfaces up:

sudo ip link set dev tap1 up 
sudo ip link set dev tap2 up
sudo ip link set dev tap3 up

Then, we create a network bridge using brctl command:

sudo brctl addbr br0

Bring up the network bridge:

sudo ip link set dev br0 up

Then we attach the tap interfaces to the bridge interface:

sudo brctl addif br0 tap1
sudo brctl addif br0 tap2
sudo brctl addif br0 tap3

Start the Fedora Server 38 virtual machine by specifying two network interfaces (WAN interface and LAN interface) with unique mac addresses:

qemu-system-x86_64 -name "Fedora Server 38 Router" \
-machine type=pc-q35-2.12 -accel kvm \
-m 4G -cpu host \
-display sdl \
-bios /usr/share/ovmf/OVMF.fd \
-device virtio-vga,addr=01.0 \
-drive file=fedorarouter.img,if=none,id=drive0 \
-device nvme,serial=364740043439,addr=02.0,bus=pcie.0,drive=drive0 \
-netdev user,id=net0,ipv4=on,net=192.168.0.0/24,ipv6=on,ipv6-net=fd65:9513:8ed6:5dc7::/64,dns=192.168.0.1,ipv6-dns=fd65:9513:8ed6:5dc7::1 \
-device e1000-82545em,addr=04.0,bus=pcie.0,mac=46:34:84:53:93:78,netdev=net0 \
-netdev tap,id=net1,ifname="tap1",script=no,downscript=no \
-device e1000-82545em,addr=05.0,bus=pcie.0,mac=35:93:59:28:34:55,netdev=net1

List all the available devices/network interfaces using nmcli command:

sudo nmcli device status

The response should look similar to this:

enp0s4  ethernet  connected               enp0s4     
lo      loopback  connected (externally)  lo         
enp0s5  ethernet  disconnected            --

WAN interface enp0s4 sets to DHCP and LAN interface enp0s5 sets to static IP.

Create a LAN interface connection enp0s5:

sudo nmcli connection add type ethernet con-name enp0s5

Attach the enp0s5 device to the connection enp0s5:

sudo nmcli connection modify enp0s5 connection.interface-name enp0s5

Modify the connection enp0s5 to use a static IP.

sudo nmcli connection modify enp0s5 ipv4.addresses 172.16.0.1/24
sudo nmcli connection modify enp0s5 ipv6.addresses fd62:bf06:3a25:7670::1/64
sudo nmcli connection modify enp0s6 ipv4.addresses 172.17.0.1/24 sudo nmcli connection modify enp0s6 ipv6.addresses fdf4:1106:0655:089f::1/64

Then, change the connection addressing method from auto to manual.

sudo nmcli connection modify enp0s5 ipv4.method manual
sudo nmcli connection modify enp0s5 ipv6.method manual

To apply the configuration, run:

sudo systemctl restart NetworkManager

Next, we need to enable IP Masquerading. The purpose of IP Masquerading is to allow machines with private IP addresses on your network to access the Internet through the machine doing the masquerading.

To enable IP Masquerading in firewalld, run:

sudo firewall-cmd --zone=public --permanent --add-masquerade

IP forwarding plays a fundamental role on a router. This is the functionality that allows a router to forward traffic from one network interface to another network interface.

To enable IP forwarding in firewalld, run:

sudo firewall-cmd --zone=public --permanent --add-forward

To apply the configuration, run:

sudo firewall-cmd --reload

Then, we also need to IP forwarding on the Fedora Server system by creating sysctl configuration file 90-override.conf in /etc/sysctl.d/ and add the following line:.

net.ipv4.ip_forward=1

net.ipv6.conf.default.forwarding=1

Next, execute the sysctl command to enable the new settings in the configuration file:

sysctl -p /etc/sysctl.d/90-override.conf

Start the Ubuntu Desktop 22.04 virtual machines by specifying one network interface (only LAN interface) with unique mac addresses:

qemu-system-x86_64 -name "Fedora Desktop 38 Client 1" \
-machine type=pc-q35-2.12 -accel kvm \
-m 4G -cpu host \
-display sdl \
-bios /usr/share/ovmf/OVMF.fd \
-device virtio-vga,addr=01.0 \
-drive file=fedoraclient1.img,if=none,id=drive0 \
-device nvme,serial=364740043439,addr=02.0,bus=pcie.0,drive=drive0 \
-netdev tap,id=net0,ifname="tap2",script=no,downscript=no \
-device e1000-82545em,addr=04.0,bus=pcie.0,mac=68:98:35:90:34:56,netdev=net0
qemu-system-x86_64 -name "Fedora Desktop 38 Client 2" \
-machine type=pc-q35-2.12 -accel kvm \
-m 4G -cpu host \
-display sdl \
-bios /usr/share/ovmf/OVMF.fd \
-device virtio-vga,addr=01.0 \
-drive file=fedoraclient2.img,if=none,id=drive0 \
-device nvme,serial=364740043439,addr=02.0,bus=pcie.0,drive=drive0 \
-netdev tap,id=net0,ifname="tap3",script=no,downscript=no \
-device e1000-82545em,addr=04.0,bus=pcie.0,mac=82:54:65:76:38:28,netdev=net0

List all the available devices/network interfaces using nmcli command:

sudo nmcli device status

The response should look similar to this:

lo      loopback  connected (externally)  lo         
enp0s4  ethernet  disconnected            --

Create a LAN interface connection enp0s4:

sudo nmcli connection add type ethernet con-name enp0s4

Attach the enp0s4 device to the connection enp0s4:

sudo nmcli connection modify enp0s4 connection.interface-name enp0s4

On the first client:

Modify the connection enp0s4 to use a static IP.

sudo nmcli connection modify enp0s4 ipv4.addresses 172.16.0.11/24
sudo nmcli connection modify enp0s4 ipv6.addresses fd62:bf06:3a25:7670::11/64

Configure the default gateway.

sudo nmcli connection modify enp0s4 ipv4.gateway 172.16.0.1
sudo nmcli connection modify enp0s4 ipv6.gateway fd62:bf06:3a25:7670::1

Then, change the connection addressing method from auto to manual.

sudo nmcli connection modify enp0s4 ipv4.method manual
sudo nmcli connection modify enp0s4 ipv6.method manual

To apply the configuration, run:

sudo systemctl restart NetworkManager

On the second client:

Modify the connection enp0s4 to use a static IP.

sudo nmcli connection modify enp0s4 ipv4.addresses 172.16.0.12/24
sudo nmcli connection mod enp0s4 ipv6.addresses fd62:bf06:3a25:7670::12/64

Configure the default gateway.

sudo nmcli connection modify enp0s4 ipv4.gateway 172.16.0.1
sudo nmcli connection mod enp0s4 ipv6.addresses fd62:bf06:3a25:7670::1

Then, change the connection addressing method from auto to manual.

sudo nmcli connection mod enp0s4 ipv4.method manual
sudo nmcli connection mod enp0s4 ipv6.method manual

To apply the configuration, run:

sudo systemctl restart NetworkManager

Configure systemd-resolved to use Google Public DNS so your system can have internet access. Edit /etc/systemd/resolved.conf, uncomment and change the DNS to 8.8.8.8

DNS=8.8.8.8

To apply the configuration, run:

sudo systemctl restart systemd-resolved

Try to ping google.com to check internet connectivity. You should have internet access now.