Loading...
 

Ubuntu - Basic routing using systemd-networkd

This page shows how to enable router functionality on Ubuntu 16.04 using systemd-networkd. Similarly to instructions given in Ubuntu - initial network configuration, the kernel (we used kernel version 4.4.52) has to be compiled with several NETFILTER/IPTABLES/NAT features. Make sure that the toolchain and the toolchain path are set up as shown in Build from source - Toolchain.

Building the kernel


First head to where you have downloaded your kernel when following Build from source - Kernel and fetch & rebase your repository to make sure you have the latest updates. Now set the necessary environment variables and create a default .config file using the default values from arch/$ARCH/configs/${PLATFORM}_defconfig (in this case from arch/arm64/configs/mvebu_v8_lsp_defconfig):

espressobin@buildserver:~/kernel/4.4.52$ export ARCH=arm64
espressobin@buildserver:~/kernel/4.4.52$ export CROSS_COMPILE=aarch64-linux-gnu-
espressobin@buildserver:~/kernel/4.4.52$ make mvebu_v8_lsp_defconfig


There are two methods of enabling NETFILTER/IPTABLES/NAT options.

Downloading pre-configured .config file


.config file is located in the top of your kernel source tree and it contains kernel configuration. This file can be configured manually or via menuconfig, make xconfig, make XXX defconfig, make oldconfig and similar make XXXconfig targets in the Linux kernel.

The quickest method of achieving a .config file with afore-mentioned options enabled is to replace the file with a .config that has all these options already enabled. The .config files with NETFILTER/IPTABLES/NAT features enabled can be downloaded here:

Make sure to backup your existing .config file with:

espressobin@buildserver:~/kernel/4.4.52$ cp .config .config_old


before replacing it with the .config you have downloaded on the link above:

espressobin@buildserver:~/kernel/4.4.52$ cp /path_to_downloaded_config/ubuntu_systemd-networkd.config .config

 
If using this method, skip to Starting the build & transferring files section.

Manually selecting the options via menuconfig


Instead of replacing .config files you can also launch make menuconfig where you will manually need to select needed options:

espressobin@buildserver:~/kernel/4.4.52$ make menuconfig


Here we will search for (open search prompt by typing / and search string under Symbol) and select the following options:

  • 1) NETFILTER
Symbol: NETFILTER
Type  : boolean
Prompt: Network packet filtering framework
   Location:
      -> Networking support (NET [=y])
(1)     -> Networking options  
   Defined at net/Kconfig:109
   Depends on: NET [=y]


By hitting the number on the left side of the option (in this case (1)) we are redirected to the location of this option:

[TRUNCATED]
       [ ] Timestamping in PHY devices
       [*] Network packet filtering framework (Netfilter)  --->
       < > The DCCP Protocol  ----
[TRUNCATED]


Hit Space to select the highlighted package (the option will be built-in when * is shown beside it). Use this method to select all options below.

  • 2) IP_NF_IPTABLES (build it as module)
Symbol: IP_NF_IPTABLES [=m]}
Type : tristate
Prompt: IP tables support (required for filtering/masq/NAT)
[...]

 

  • 3) NF_CONNTRACK
Symbol: NF_CONNTRACK [=y]
Type  : tristate
Prompt: Netfilter connection tracking support
[...]

 

  • 4) NF_CONNTRACK_IPV4
Symbol: NF_CONNTRACK_IPV4 [=y]
Type  : tristate
Prompt: IPv4 connection tracking support (required for NAT)
[...]

 

  • 5) NF_NAT_IPV4
Symbol: NF_NAT_IPV4 [=y]
Type : tristate
Prompt: IPv4 NAT
[...]

 

  • 6) NF_NAT_MASQUERADE_IPV4
Symbol: NF_NAT_MASQUERADE_IPV4 [=y]
Type  : tristate
Prompt: IPv4 masquerade support
[...]

 

  • 7) IP_NF_NAT (build as module)
Symbol: IP_NF_NAT [=m]
Type  : tristate
Prompt: iptables NAT support
[...]

 

  • 8) IP_NF_TARGET_MASQUERADE (build as module)
Symbol: IP_NF_TARGET_MASQUERADE [=m]
Type  : tristate
Prompt: MASQUERADE target support
[...]

 

  • 8) IP_NF_FILTER (build as module)
Symbol: IP_NF_FILTER [=m]
Type  : tristate
Prompt: Packet filtering
[...]


Save your configuration and exit the menuconfig

Starting the build & transferring files


Start the build with:

espressobin@buildserver:~/kernel/4.4.52$ make -j4


Now we need to transfer the new kernel image and dtb file to a microSD card or USB stick containing the desired Ubuntu file system. In the example below we mounted our microSD card to /mnt/sdcard and transferred the kernel image and dtb file to the boot directory:

espressobin@buildserver:~/kernel/4.4.52$ sudo cp arch/arm64/boot/Image /mnt/sdcard/boot/
espressobin@buildserver:~/kernel/4.4.52$ sudo cp arch/arm64/boot/dts/marvell/armada-3720-community.dtb /mnt/sdcard/boot/


We also need to install the generated kernel modules:

espressobin@buildserver:~/kernel/4.4.52$ sudo make ARCH=arm64 modules_install INSTALL_MOD_PATH=/mnt/sdcard/


In the command above, mnt/sdcard/ is the root of the file system on your removable media.

Unmount the SD card and boot from the SD card or USB stick as shown in Boot from MicroSD card/USB stick - Ubuntu.

Once the board has booted, follow the steps in the section below to configure routing.

Installing necessary packages


Now that Ubuntu has booted successfully, we will first enable Internet connection in order to download packages necessary for routing. Connect one end of an Ethernet cable into the WAN port on ESPRESSObin and the other to your router. In the console issue:

root@localhost:~# ifconfig eth0 up
root@localhost:~# dhclient wan


Open the /etc/apt/sources.list file and there add the universe repository:

root@localhost:~# vim /etc/apt/sources.list
#append universe to the first line
deb http://ports.ubuntu.com/ubuntu-ports/ xenial main universe


This repository is needed to download the dnsmasq package which is recommended to use with network managers other than Ubuntu's Network Manager. Save your changes and exit the editor. Now update and install the necessary packages:

root@localhost:~# apt-get update
root@localhost:~# apt-get install bridge-utils
root@localhost:~# apt-get install samba
root@localhost:~# apt-get install dnsmasq
root@localhost:~# apt-get install iptables
root@localhost:~# apt-get install libpam-systemd
root@localhost:~# apt-get install iptables-dev

 

Network configuration


Now on to creating the required network files and a virtual network device file for our bridge. This setup is similar to the default network configuration present when booting Arch Linux, as shown in Boot from MicroSD card/USB stick - ArchLinux.

br0.netdev

root@localhost:~# cat /etc/systemd/network/br0.netdev
[NetDev]
Name=br0
Kind=bridge

br0.network

root@localhost:~# cat /etc/systemd/network/br0.network
[Match]
Name=br0

[Network]
Address=192.168.22.1/24
IPForward=ipv4
IPMasquerade=yes
ConfigureWithoutCarrier=yes

eth0.network

root@localhost:~# cat /etc/systemd/network/eth0.network
[Match]
Name=eth0

lan.network

root@localhost:~# cat /etc/systemd/network/lan.network
[Match]
Name=lan*

[Network]
Bridge=br0
BindCarrier=eth0

wan.network

root@localhost:~# cat /etc/systemd/network/wan.network
[Match]
Name=wan

[Network]
DHCP=yes
BindCarrier=eth0
IPForward=ipv4


Now make a backup of the default dnsmasq.conf configuration file and create a new file:

root@localhost:~# mv /etc/dnsmasq.conf /etc/dnsmasq.conf.bak
root@localhost:~# vim /etc/dnsmasq.conf


and in there paste the following:

interface=br0
bind-interfaces
dhcp-range=192.168.22.5,192.168.22.250,255.255.255.0,24h
dhcp-option=option:router,192.168.22.1


Now disable Ubuntu's default networking service and enable systemd-networkd:

root@localhost:~# systemctl disable networking
root@localhost:~# systemctl enable systemd-networkd


In the [Unit] section of the /lib/systemd/system/dnsmasq.service file append the following options for the bridge interface to be brought up before dnsmasq:

root@localhost:~# vim /lib/systemd/system/dnsmasq.service
[Unit]
...
After=network-online.target
Wants=network-online.target


Save your changes and exit the editor. Now set the iptable rule to start routing:

root@localhost:~# iptables -t nat -A POSTROUTING -o wan -j MASQUERADE


To preserve iptables rules upon reboot, first install the iptables-persistent package:

root@localhost:~# apt-get install iptables-persistent


followed by running:

root@localhost:~# netfilter-persistent save
root@localhost:~# netfilter-persistent reload


The rules will be saved to /etc/iptables/rules.v4. Finally, reboot the ESPRESSObin board, which should now act as a gateway between your laptop and Internet.