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 is connected to
enp0s9 is connected to
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
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
The network interfaces that will be used for routing need to have static ip addresses so let’s start with that.
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
do anything. Bring down the interfaces:
$ sudo ip link set enp0s8 down $ sudo ip link set enp0s9 down
dhcpcd is running the static/extra interfaces needs to be
disabled from getting managed by
dhcpcd. This is done by adding the following
This will use DHCP on the ‘management’ interface and not the other interfaces.
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
Create a netctl profile in the file
Interface=enp0s8 Connection=ethernet IP=static Address='10.0.1.1/24'
And for the next interface create the profile:
Interface=enp0s9 Connection=ethernet IP=static Address='10.0.2.1/24'
Now list available netctl profiles
$ netctl list enp0s8 enp0s9
* will indicate interfaces that are up and configured.
$ 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.
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
10.0.1.100 -> 10.0.1.250 on the
10.0.1.0/24 network and
10.0.2.100 -> 10.0.2.250 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
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
10.0.1.50 server1 10.0.1.51 server2
/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
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
$ 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 10.0.2.0/24 network on
enp0s9) will be behind NAT and hidden outside that network. Hosts on
network1 are still accessible individually from
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
network2, i.e. traffic entering
enp0s8 and going out on
$ sudo iptables -I FORWARD -i enp0s8 -o enp0s9 -j REJECT
This will also block responses to traffic going out from
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!