Modern linux networking basics

Table of contents

The long-standing net-tools package is slowly being faded out in favor of the iproute2 suite of tools. For linux operators, this means introducing new tools to manage network tasks with increased performance and better support for modern protocols like IPv6.

Network managers

A network manager is used to interface with the networking stack in the linux kernel, providing persistent configurations of network devices. For most modern distributions, this will be either systemd-networkd or NetworkManager.

systemd-networkd is part of the systemd suite and neatly integrates with it's ecosystem. It is a fairly simple networking service relying on files for configuration. Mainly aimed at server usage, it offers common features like network device management, DHCP support and static IP configurations with excellent performance, but cannot natively handle end-user networking technologies like broadband or wifi. DNS support is not natively part of systemd-networkd, relying on systemd-resolved or other external DNS services.

NetworkManager is a much more complex suite of tools, typically preferred for desktop or workstation deployments. It supports wifi, broadband, simplified VPN configurations, ships with DNS support out of the box and comes with multiple configuration options: raw terminal commands using nmcli, a terminal ui with nmtui or built-in graphical settings apps for desktop environments like gnome.

To compare them, think of NetworkManager as the opinionated all-in-one solution for networking, whereas systemd-networkd only does basic networking tasks, allowing administrators to choose different services for advanced features like DNS resolution or wifi support.

The ip command

The primary way to interact with network configurations and make ephemeral changes is the ip command. It handles a large variety of tasks, like showing or editing network interfaces, ip addresses, the routing table or arp table, as well as multicast addresses. It is the preferred replacement for previous commands like ifup, ifdown and ifconfig.

Keep in mind that the ip command will only make temporary changes to your network config, rebooting will revert to the initial state. It is a great option to handle most network debugging tasks and works the same regardless of network manager service installed. If you want to persist changes, you still need to configure them in your network manager.

View ip addresses and network interfaces

The most common use of the ip command is to find one's own IP address. This is as simple as:

ip address show

The output will list all ip addresses associated with each network interface:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
   link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
   inet 127.0.0.1/8 scope host lo
      valid_lft forever preferred_lft forever
   inet6 ::1/128 scope host
      valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
   link/ether 08:00:27:36:1b:7d brd ff:ff:ff:ff:ff:ff
   inet 192.168.1.100/24 brd 192.168.1.255 scope global dynamic enp0s3
      valid_lft 86383sec preferred_lft 86383sec
   inet6 fe80::a00:27ff:fe36:1b7d/64 scope link
      valid_lft forever preferred_lft forever

Each device is divided into segments of different information:

Along with the ip addresses, more important information is provided, such as broadcast addresses and netmasks. Each interface may be assigned one or more ip addresses, making lines beyond the first one optional. The first device in the list will typically be the local loopback devices.

Network interface names

The default names for interfaces are designed to be reliable across reboots. For example, enp0s3 refers the an ethernet device (en) located on PCI bus 0 (p0) in slot 3 (s3). This naming scheme ensures that devices have the same name even when other interfaces are added or removed.

Sometimes, interfaces will have names using the MAC address instead of the PCI bus information, such as USB adapters. They may receive names like wlx00c0ca958e17.

Interface names should not be renamed if avoidable, to prevent errors and misconfigurations when changing the network interfaces on the system.

Activate and deactivate network devices

For temporary state changes during debugging, the ip command replaces the older ifup/ifdown commands. You first need to find the name of the desired network interface by listing all available ones:

ip link show

Enabling a device, eth0 in this example,

sudo ip link set dev eth0 up

Use down to deactivate it instead.

To maintain the interface state between reboots, you need to persist them to your network manager config.

For systemd-networkd:

First create a config file for the interface, for example /etc/systemd/network/10-eth0.network:

[Match]
Name=eth0

[Network]
LinkDown=yes # prevents automatic activation at boot

Restart systemd-networkd to load the new configuration:

sudo systemctl restart systemd-networkd

For NetworkManager:

sudo nmcli connection add type ethernet ifname eth0 # create connection if not already present
sudo nmcli connection modify eth0 connection.autoconnect no # set to "yes" to automatically activate on boot

Note that the second command takes a "connection name", which may differ from your interface name (e.g. for wireless networks). See nmcli device for a list of all devices and their connection names.

Configuring static IPs and gateways

Primarily used for servers, static IP configurations enable networks to function without dedicated infrastructure like a DHCP service. Changes should be tested first using the ip command:

sudo ip address add 10.0.0.2/24 dev eth0

The command adds the local IP address 10.0.0.2 to the interface eth0. Depending on network configuration, you may also need a gateway to reach beyond the local network. You can add one with:

sudo ip route add 10.0.0.0/24 via 10.0.0.1

This adds 10.0.0.1 as the gateway for the 10.0.0.0/24 network. You can also replace the network address with the keyword default to create a default gateway route:

sudo ip route add default via 10.0.0.1

To persist changes between reboots, the network manager needs to be reconfigured.

For systemd-networkd:

Create or edit the configuration file for your interface, in this example /etc/systemd/network/10-eth0.network:

[Match]
Name=eth0 

[Network]
Address=10.0.0.2/24
Gateway=10.0.0.1

Restart systemd-networkd to load the new configuration:

sudo systemctl restart systemd-networkd

For NetworkManager:

Start by finding the connection name for the desired interface:

nmcli connection show

Then apply the commands using the connection name (may differ from interface name!)

sudo nmcli connection modify eth0 ipv4.addresses 10.0.0.2/24
sudo nmcli connection modify eth0 ipv4.gateway 10.0.0.1
sudo nmcli connection modify eth0 ipv4.method manual

Reactivate the connection for changes to take effect:

sudo nmcli connection down eth0
sudo nmcli connection up eth0

Enabling and disabling DHCP

IP address configurations can be automated if a DHCP service is available in the network. Network managers will typically automatically detect and use DHCP by default. You can change the state of DHCP from the network manager.

For systemd-networkd:

Create or edit the configuration file for your interface, in this example /etc/systemd/network/10-eth0.network:

[Match]
Name=eth0

[Network]
DHCP=yes # set to "no" to disable dynamic IP assignment

Restart systemd-networkd to load the new configuration:

sudo systemctl restart systemd-networkd

For NetworkManager:

Find the connection name for the desired interface:

nmcli connection show

Then use the connection name to enable DHCP:

sudo nmcli connection modify eth0 ipv4.method auto
sudo nmcli connection up eth0

The second command is important, otherwise the changes won't take effect until a reboot.

Assigning DNS servers

The times of manually editing /etc/resolv.conf are long gone, and manually touching it is a bad idea for modern systems. Instead, the network manager has taken over this responsibility, internally handling the actual DNS service for the user.

Setting a DNS server for a network interface using systemd-networkd is done by creating or editing the interface configuration, for example /etc/systemd/network/10-eth0.network:

[Match]
Name=eth0

[Network]
DNS=8.8.8.8 # use Google DNS server
DNS=8.8.4.4 # use Google secondary DNS server as fallback

[DHCP]
UseDNS=no # optional; do not use DNS server configured by DHCP

For systems using NetworkManager, the changes are made with nmcli. Find the connection name for the device:

nmcli connection show

Then apply the new configuration using the connection name:

sudo nmcli connection modify eth0 ipv4.dns "8.8.8.8 8.8.4.4" # use Google DNS servers
sudo nmcli connection modify eth0 ipv4.ignore-auto-dns yes # ignore automatic DNS config from DHCP

Reactivate the connection for changes to take effect:

sudo nmcli connection down eth0
sudo nmcli connection up eth0

More articles

Understanding how RAID 5 works

Striking a balance between fault tolerance, speed and usable disk space

A practical guide to filesystems

Picking the best option to format your next drive

A primer on LVM

Making the most of your storage devices

Why boring software is a smart choice

Not everything is about excitement

Common pitfalls running docker in production

Avoiding the mistakes many make when embracing containerized deployments