systemd-networkd network setup¶
Arch Linux networking¶
When starting my Arch Linux system setup, I was surprised at just how minimal the initial installation is. Networking is not set up in any way on a freshly installed system.
Of course, that's a bit of a problem if you don't know what you're doing (as was the case for me), and you need to have Internet access to be able to install a network manager.
Luckily Arch Linux has good documentation on how to get your network going, at least with a fixed IP, so you can get online to get the DHCP client and network manager you think you want or need.
NetworkManager and dhcpd¶
Coming from a legacy background, I knew nothing better than to install NetworkManager and dhcpd. This works, nothing wrong with it. I got it all configured fine, but since my hardware has four Ethernet ports, I still wanted to set it up so it could work as a network switch on the other ports.
So I did more research and found out that I don't need extra programs at all to handle any of this. systemd can take care of all of this stuff on its own!
systemd-networkd¶
Some people don't like systemd
. I have never understood why exactly, since
I've always found it to be superior in implementation, ease-of-use and
configuration compared to the legacy solutions it attempts to replace.
From the point of view of embedded systems design, it is awesome to have a single tool that integrates all kinds of functionality versus needing a different program for everything.
It turns out I didn't need to get Internet access to install a network
manager after all, a perfectly good network manager was already present on
the freshly installed system in the form of systemd
. So I uninstalled
NetworkManager
and dhcpd
. All that was needed to get online was add a
single file /etc/systemd/network/20-wired.network
with the following
contents:
[Match]
Name=enp2s0
[Network]
DHCP=yes
And then enable and start systemd-networkd
:
# systemctl enable systemd-networkd
# systemctl start systemd-networkd
systemd-resolved¶
I also used another systemd
service to handle DNS lookups. I wanted to
have mDNS enabled so I could
get easy access to the machine using [hostname].local
.
This is the config I ended up with in /etc/systemd/resolved.conf
:
[Resolve]
DNS=1.1.1.1
MulticastDNS=yes
DNSStubListener=no
It uses 1.1.1.1
as the default DNS lookup. MulticastDNS=yes
turns on
mDNS. DNSStubListener=no
turned out to be important when I was trying to
set up Pi-hole. Since Pi-hole will be our network's
DNS server, this setting needs to be set to no
so systemd-resolved
doesn't
start a DNS listener on port 53
. Otherwise Pi-hole would complain that port
53
was alread in use.
And then enable and start systemd-resolved
:
# systemctl enable systemd-resolved
# systemctl start systemd-resolved
Final config with network bridge¶
Now I had basic networking, it was time to figure out how to change my config so I could use the extra Ethernet ports to connect other devices to the network (use the PC as a network switch). As is often the case, the most difficult part of that was to figure out the correct search terms to use. I found numerous articles about how to set up a Linux system to be a router, but I did not want address translation. I wanted the devices connected to the PC to be on the same network as everything else.
Turns out the correct term for that is bridge. Once I figured that out
I made progress with guides that just use the ip
command. I needed to
translate these to a working systemd-networkd
configuration. Below is what
I eventually ended up with (after removing the old config file).
First make a bridge device with the file /etc/systemd/network/10-br0.netdev
,
containing:
[NetDev]
Name=br0
Kind=bridge
Then set the network connection info on the bridge device. This was an
important thing to figure out, things kept not working when I was trying to
set up my uplink information on a physical network device! In this case
I wanted a fixed IP address instead of DHCP and ended up with this file
/etc/systemd/network/20-br0.network
:
[Match]
Name=br0
[Network]
Address=192.168.1.201/24
Gateway=192.168.1.1
MulticastDNS=true
IPForward=true
[Link]
Multicast=true
AllMulticast=true
Promiscuous=true
Then I needed to add a third file /etc/systemd/network/30-bind.network
to connect all physical Ethernet ports to the bridge:
[Match]
Name=enp*
[Network]
Bridge=br0
With this config, everything works as expected. The PC connects to my network, it doesn't even matter which port I use for the uplink. And any devices connected to the remaining Ethernet ports also connect to my network.