This is a description on how to set up a server based on ArchLunix to route network traffic between two interfaces. As an extension I also add some common router functions such as DHCP/DNS and NAT/firewall.

For configuring a server as described here at least two network interfaces are needed. In my setup I used a virtual machine with 3 network interfaces, 1 management interface called enp0s3 and two interfaces for routing between two networks, they are called enp0s8 and enp0s9.

The interface enp0s8 is connected to network1 and enp0s9 is connected to network2.


Routing is enabled by turning on forwarding in the kernel

# sysctl net.ipv4.conf.all.forwarding=1

This will turn on forwaring on all interfaces and set the ip_forward flag. Note that it is only temporary, it will not be persistent accross a reboot. To make forwarding persistent add a sysctl conf file:

# echo "net.ipv4.conf.all.forwarding=1"  | sudo tee /etc/sysctl.d/routing.conf

Configure IP addresses with netctl

The network interfaces that will be used for routing need to have static ip addresses so let’s start with that.

On ArchLinux netctl can be used for handling network interfaces. In order to use netctl the interfaces need to be down otherwise interfaces are considered to already be managed by some other service and netctldoes not do anything. Bring down the interfaces:

$ sudo ip link set enp0s8 down
$ sudo ip link set enp0s9 down

If dhcpcd is running the static/extra interfaces needs to be disabled from getting managed by dhcpcd. This is done by adding the following line to /etc/dhcpcd.conf:

allowinterfaces enp0s3

This will use DHCP on the ‘management’ interface and not the other interfaces.


Interface enp0s8 and enp0s9 are connected to two different networks.

Assigning ip address can be done with ip addr but for making it persistent I’ll do it the netctl way.

Create a netctl profile in the file /etc/netctl/enp0s8 containing:


And for the next interface create the profile: /etc/netctl/enp0s9 containing:


Now list available netctl profiles

$ netctl list

A * will indicate interfaces that are up and configured.

Start profiles:

$ sudo netctl start enp0s8
$ sudo netctl start enp0s9

To make this configuration persistent:

$ sudo netctl enable enp0s8
$ sudo netctl enable enp0s9

Then set up a DHCP server to assign addresses to hosts on the two networks.

DHCP server

A simple choice for running a DHCP server is dnsmasq. Install dnsmasq

$ sudo pacman -S dnsmasq

Configure dnsmaq in /etc/dnsmasq.conf, the file contains a lot of config lines that are commented out and one just have to find the needed config option and enable it with the wanted parameters.

First specify the interfaces to listen to


there are other options here, for example you can list interface not to listen to instead, or the address to listen on etc.

Then configure ranges on which to hand out adresses


This will hand out addresses in the range -> on the network and -> on that network. The last number on the line is the DHCP lease time.

For debugging purposes it can be nice to turn on logging in dnsmasq. This is done by editing dnsmasq service script. Open /usr/lib/systemd/system/dnsmasq.service and add the --log-facility argument:

ExecStart=/usr/bin/dnsmasq -k --enable-dbus --user=dnsmasq --pid-file --log-facility=/var/log/dnsmasq.log


dnsmasq also serves as a DNS server. It’ll use /etc/hosts to resolve hostnames. Start by specifying name and ip in /etc/hosts   server1   server2

Use dhcp-host in /etc/dnsmasq.conf to make the dhcp server hand out the ip above to a server that identifies itself as the host name.


A server with host name server1 on network1 will now get the ip and other servers can access server1 by host name and will have the name resolved to the same ip.

Start and enable dnsmasq service:

$ sudo systemctl start dnsmasq.service
$ sudo systemctl enable dnsmasq.service


The linux kernel firewall iptables is used to prevent access to hosts on the two networks. In this example hosts on network2 (the network on enp0s9) will be behind NAT and hidden outside that network. Hosts on network1 are still accessible individually from network2.

Add a rule to the nat table to replace the source address for hosts on network2 for traffic that leaves to the other network

$ sudo iptables -t nat -A POSTROUTING -o enp0s8 -j MASQUERADE

It is also possible to use SNAT instead of MASQUERADE here since the ip address is static, perhaps also perferable for performace reasons.

Then add a rule to the filtering table to block traffic from network1 to network2, i.e. traffic entering enp0s8 and going out on enp0s9.

$ sudo iptables -I FORWARD -i enp0s8 -o enp0s9 -j REJECT

This will also block responses to traffic going out from network2 to network1. That is fixed by adding a filtering rule to allow packets that are part of an already established connection.

$ sudo iptables -I FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

Make the firewall rules persistent by saving current config to a config file

$ sudo iptables-save | sudo tee /etc/iptables/iptables.rules
$ sudo iptables-save -t nat | sudo tee -a /etc/iptables/iptables.rules

Then enable the service

$ sudo systemctl enable iptables.service


As seen here it’s really simple to create a Linux router. Of course there is a lot more that can be done that will make things more complicated. Anyway, I had a lot of fun exploring this!


ArchLinux Router



NAT with iptables