Skip to content

109.2 Persistent network configuration

Weight: 4

Candidates should be able to manage the persistent network configuration of a Linux host.

Objectives

  • Understand basic TCP/IP host configuration
  • Configure ethernet and wi-fi network configuration using NetworkManager
  • Awareness of systemd-networkd

Terms

/etc/hostname, /etc/hosts, /etc/nsswitch.conf, /etc/resolv.conf, nmcli, hostnamectl, ifup, ifdown

Persistent versus temporary

Every device on a network needs an IP configuration: an IP address, a netmask, a default gateway and DNS servers. A laptop changes networks all the time and must adapt. A server stays in the same place for years, and its settings must come back after every reboot, power cut, upgrade or hardware change.

Settings made with commands like ip addr add are temporary: they disappear at reboot. Persistent settings are stored in files under /etc/ (or by a service like NetworkManager) and are applied automatically at every boot. That is what this objective is about.

The settings come from one of two places:

  • static: you write the address, netmask and gateway yourself.
  • DHCP (Dynamic Host Configuration Protocol): as soon as the cable or Wi-Fi link is up, the machine asks a DHCP server on the network (often your router), and the server answers with the IP address, netmask, default route, DNS servers and more.

Network interfaces

A network interface is how the system talks to a piece of network hardware, the NIC (Network Interface Card), like an ethernet card or a Wi-Fi adapter. The exception is the loopback interface, lo. It is virtual and always present, and the system uses it to talk to itself, at address 127.0.0.1.

ip link show lists the interfaces. Listing does not change anything, so a normal user can run it:

$ ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp3s5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 00:16:3e:8d:2b:5b brd ff:ff:ff:ff:ff:ff

If NetworkManager is running, nmcli device lists them too:

$ nmcli device
DEVICE  TYPE      STATE      CONNECTION
enp3s5  ethernet  connected  Gigabit Powerline Adapter
lo      loopback  unmanaged  --

Interface names

Old systems named ethernet cards eth0, eth1... and Wi-Fi cards wlan0, wlan1..., in the order the kernel found them. The name told you nothing about which port was which, and two cards could even swap names after a reboot.

Modern systems (using the systemd naming scheme) use predictable names. The first two letters give the type:

Prefix Type
en Ethernet
wl wireless LAN (Wi-Fi)
ww wireless WAN (mobile data)
ib InfiniBand
sl serial line IP (SLIP)

The rest of the name comes from the first rule that works, from highest to lowest priority:

Rule Example
1. the index given by the BIOS or firmware for on-board devices eno1
2. the PCI Express slot index ens1
3. the address on the bus enp3s5
4. the MAC address enx78e7d1ea46da
5. the old style eth0

So enp3s5 is ethernet at bus 3, slot 5. lspci shows that exact device, at address 03:05.0:

$ lspci | fgrep Ethernet
03:05.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL-8110SC/8169SC Gigabit Ethernet (rev 10)

Common modern names: eno1 (on-board), enp3s0 (PCI ethernet), wlp108s0 or wlan0 (wireless), and enx<MAC> (by MAC, common for USB adapters). For example:

$ ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 ...
2: wlp108s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
    link/ether 00:bb:60:97:6b:07 brd ff:ff:ff:ff:ff:ff

Temporary changes: ifconfig and ip

ifconfig is the old tool. It is deprecated because it handles little beyond ethernet, but you should recognise it. Changing anything needs root:

$ sudo ifconfig enp0s25 192.168.42.42
$ ifconfig enp0s25
enp0s25: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 192.168.42.42  netmask 255.255.255.0  broadcast 192.168.42.255
        ether f0:de:f1:62:c5:73  txqueuelen 1000  (Ethernet)
(...)
# ifconfig eth0 192.168.42.42 netmask 255.255.255.0
$ sudo ifconfig enp0s25 down
$ ifconfig wlp3s0
wlp3s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.35  netmask 255.255.255.0  broadcast 192.168.1.255
# ifconfig enp0s25 192.168.42.42 netmask 255.255.255.0    # set address + mask
# ifconfig enp0s25 down                                   # bring it down

After down, the interface disappears from the plain ifconfig list. ifconfig -a shows all interfaces, including those that are down.

ip replaced ifconfig. It also manages routes and tunnels (109.3 covers it in detail):

ip addr add 172.19.1.10/24 dev eth2       # add an IP address
ip addr show eth2
ip addr del 172.19.1.10/24 dev eth2       # remove it
ip link set eth2 up                       # bring the interface up
ip route show
ip route add default via 192.168.1.1      # add a default gateway

All of these are temporary. They are lost at reboot, or when NetworkManager reconfigures the interface. For permanent settings, use the configuration files or NetworkManager, below.

ifup, ifdown and /etc/network/interfaces

On Debian and its relatives (Ubuntu too), the classic persistent configuration lives in /etc/network/interfaces. ifup and ifdown read it to bring interfaces up and down. They normally run automatically at boot, but you can call them by hand:

auto lo
iface lo inet loopback

auto enp3s5
iface enp3s5 inet dhcp

The format:

Line Means
auto enp3s5 bring this interface up at boot (and with ifup -a), in the order listed
iface enp3s5 inet dhcp configure enp3s5, address family inet, method dhcp
Part Values
address family inet (IPv4), inet6 (IPv6), ipx
method loopback for lo, dhcp to ask a DHCP server, static to set it yourself

With dhcp, ifup runs a DHCP client that fetches the settings:

# ifup enp3s5
Internet Systems Consortium DHCP Client 4.4.1
(...)
Listening on LPF/enp3s5/00:16:3e:8d:2b:5b
Sending on   LPF/enp3s5/00:16:3e:8d:2b:5b
DHCPDISCOVER on enp3s5 to 255.255.255.255 port 67 interval 4
DHCPOFFER of 10.90.170.158 from 10.90.170.1
DHCPREQUEST for 10.90.170.158 on enp3s5 to 255.255.255.255 port 67
DHCPACK of 10.90.170.158 from 10.90.170.1
bound to 10.90.170.158 -- renewal in 1616 seconds.

You can read the four DHCP steps in the output: Discover, Offer, Request, Ack. ifdown enp3s5 turns the interface off.

Without a DHCP server, use static and write the settings yourself:

auto eth0
iface eth0 inet static
    address 192.168.1.10
    netmask 255.255.255.0
    gateway 192.168.1.1
    dns-nameservers 4.2.2.4

The address can also be written with its prefix, address 192.168.1.2/24, without a separate netmask line. If one interface has more than one iface block, all of them are applied, which is how you give one card both an IPv4 and an IPv6 address.

Red Hat style: /etc/sysconfig/network-scripts/

This format is not standard across distributions. Red Hat based systems (like CentOS) keep one file per interface in /etc/sysconfig/network-scripts/, in a slightly different format:

$ cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
ONBOOT=yes
TYPE=Ethernet
IPADDR=192.168.1.10
NETMASK=255.255.255.0
DNS1=4.2.2.4

and the default gateway in /etc/sysconfig/network:

NETWORKING=yes
HOSTNAME=lpictest
GATEWAY=192.168.1.1

These files plus ifup/ifdown (for example ifup eth0) are the legacy path. Modern Ubuntu uses netplan (/etc/netplan/*.yaml) as a front end that hands the real work to NetworkManager or systemd-networkd.

NetworkManager and nmcli

Most distributions today use the NetworkManager service. Its goal is to make networking simple and automatic: with DHCP it fetches the address, sets the routes and updates the DNS servers for you. It prefers a wired connection when both wired and Wi-Fi are available, tries to keep at least one connection active, and reconnects to known Wi-Fi networks by itself. That is why your laptop just works when you open it at home.

Things to know:

  • NetworkManager leaves alone the interfaces listed in /etc/network/interfaces, so it does not fight with that method. It manages the others.
  • The daemon runs as root, but normal users can create and change connections through client programs, which ask the daemon to do the work.
  • Graphical clients come with the desktop (nm-applet, network-manager-gnome, plasma-nm, nm-tray). On the command line there are two: nmtui, a text menu interface, and nmcli, which can do everything and also works in scripts.

nmcli objects

nmcli takes an object first, then a command:

Object Controls
general NetworkManager's general status
networking networking as a whole, on or off
radio the radio switches (Wi-Fi, mobile)
connection saved connections
device the network devices
agent the secret agent or polkit agent
monitor watches for changes

With no command, status is used, so nmcli general means nmcli general status:

$ nmcli general
STATE      CONNECTIVITY  WIFI-HW  WIFI     WWAN-HW  WWAN
connected  full          enabled  enabled  enabled  enabled

STATE says whether the system is connected. CONNECTIVITY shows full when everything works. portal there means a login page in the browser must be completed first. The columns ending in -HW show whether the hardware itself is enabled.

Connecting to Wi-Fi

List the networks around you, then connect by name (the SSID):

$ nmcli device wifi list
IN-USE  BSSID              SSID       MODE   CHAN  RATE        SIGNAL  BARS  SECURITY
        90:F6:52:C5:FA:12  Hypnotoad  Infra  11    130 Mbit/s  67      ▂▄▆_  WPA2
        10:72:23:C7:27:AC  Jumbao     Infra  1     130 Mbit/s  55      ▂▄__  WPA2
        00:1F:33:33:E9:BE  NETGEAR    Infra  1     54 Mbit/s   35      ▂▄__  WPA1 WPA2
$ nmcli device wifi connect Hypnotoad password MyPassword
$ nmcli device wifi connect AxLTE password "AFunkyPassword"

In a graphical terminal you can leave out password, and a dialog asks for it. Extra arguments:

Add When
hidden yes the network hides its SSID
ifname wlo1 you have several Wi-Fi adapters and want this one

NetworkManager saves the connection under the SSID name and reconnects to it automatically from now on.

Managing connections and devices

$ nmcli connection show
NAME       UUID                                  TYPE      DEVICE
Ethernet   53440255-567e-300d-9922-b28f0786f56e  ethernet  enp3s5
tun0       cae685e1-b0c4-405a-8ece-6d424e1fb5f8  tun       tun0
Hypnotoad  6fdec048-bcc5-490a-832b-da83d8cb7915  wifi      wlo1
4G         a2cf4460-0cb7-42e3-8df3-ccb927f2fd88  gsm       --
$ nmcli connection down Hypnotoad
Connection 'Hypnotoad' successfully deactivated
Command Does
nmcli connection show lists saved connections
nmcli connection down Hypnotoad / up Hypnotoad turns a saved connection off or on, by name
nmcli device disconnect wlo1 / connect wlo1 the same, by interface name
nmcli radio wifi off / on turns the Wi-Fi radio off (to save power) or on

Use the connection name, not the UUID: the UUID changes every time the connection comes up.

You can also define a persistent static ethernet connection, change it, and remove it:

# nmcli con add type ethernet con-name office ifname eth0 \
      ip4 192.168.1.10/24 gw4 192.168.1.1
# nmcli con mod office ipv4.dns "4.2.2.4 8.8.8.8"
# nmcli con up office          # activate it (con down office deactivates)
# nmcli con delete office      # forget a saved connection

systemd-networkd

Systems with systemd can use its own network daemons instead: systemd-networkd configures the interfaces and systemd-resolved handles name resolution. For the exam you only need to be aware of it.

Its configuration files can be in three directories:

Directory Is
/lib/systemd/network the system's files
/run/systemd/network runtime files (temporary)
/etc/systemd/network your files, the administrator's

Files in /etc win over /run, and /run wins over /lib, when names are the same. So to change a setting, put a file with the same name in /etc/systemd/network instead of editing the original. Files are read in alphabetical order, which is why their names usually start with a number.

The file suffix says what it is for:

Suffix Purpose
.network addresses and routes: the one you will write
.netdev creates virtual devices, like a bridge or tun device
.link low-level settings for an interface

A .network file picks its interface in [Match] (by Name=, which accepts globs like en*, or by MACAddress=) and sets it up in [Network]. Static, in /etc/systemd/network/30-lan.network:

[Match]
Name=enp3s5

[Network]
Address=192.168.0.100/24
Gateway=192.168.0.1

or with DHCP:

[Match]
MACAddress=00:16:3e:8d:2b:5b

[Network]
DHCP=yes

DHCP=yes asks for both IPv4 and IPv6, DHCP=ipv4 for IPv4 only and DHCP=ipv6 for IPv6 only.

For a password-protected Wi-Fi network, WPA supplicant must first join the network. Store the passphrase with wpa_passphrase in a file named after the interface, then start the matching service:

# wpa_passphrase MyWifi > /etc/wpa_supplicant/wpa_supplicant-wlo1.conf
# systemctl start wpa_supplicant@wlo1.service
# systemctl enable wpa_supplicant@wlo1.service

A .network file matching wlo1 then configures the address once the adapter has joined.

The hostname

The hostname is the name the machine calls itself. Set one even on a machine that never joins a network. At boot, the system reads it from the first line of /etc/hostname (lines starting with # are ignored).

You can edit that file, or use hostnamectl, which writes it for you:

# hostnamectl set-hostname storage
# cat /etc/hostname
storage
# hostnamectl set-hostname mycoolmachine
# cat /etc/hostname
mycoolmachine
# hostnamectl status
   Static hostname: mycoolmachine
         Icon name: computer

The running shell keeps showing the old name in its prompt until you start a new shell.

hostnamectl knows three kinds of hostname:

Kind Option Is
static --static the name stored in /etc/hostname and used at boot. Up to 64 characters, best kept to lowercase letters, no spaces or dots
pretty --pretty a free-form, descriptive name with any characters, like "LAN Shared Storage"
transient --transient a temporary name, often set automatically, used when no static name is set

hostnamectl --transient set-hostname ... sets only the temporary name. Without an option, all three are set. Only the static name is saved in /etc/hostname.

# hostnamectl --pretty set-hostname "LAN Shared Storage"
# hostnamectl --transient set-hostname generic-host
$ hostnamectl status
   Static hostname: storage
   Pretty hostname: LAN Shared Storage
Transient hostname: generic-host
         Icon name: computer-server
           Chassis: server
        Machine ID: d91962a957f749bbaf16da3c9c86e093
           Boot ID: 8c11dcab9c3d4f5aa53f4f4e8fdc6318
  Operating System: Debian GNU/Linux 10 (buster)
            Kernel: Linux 4.19.0-8-amd64
      Architecture: x86-64

status is the default, so plain hostnamectl shows the same.

Name resolution: hosts, DNS and nsswitch

People remember names, computers need IP addresses. There are two ways to turn one into the other: a local file (/etc/hosts) or a DNS server. The file /etc/nsswitch.conf decides which is asked first.

  ping storage
       |
       v
 /etc/nsswitch.conf      hosts: files dns
       |
       +--> 1. files  =  /etc/hosts          found? use it
       |
       +--> 2. dns    =  servers listed in /etc/resolv.conf

/etc/nsswitch.conf

The Name Service Switch file says, for each database (hosts, passwd, group and others), which sources to use and in what order:

# cat /etc/nsswitch.conf
passwd:     files
group:      files
shadow:     files

hosts:      files dns myhostname
networks:   files

protocols:  files
services:   files
ethers:     files
rpc:        files

The hosts line is the one to know. hosts: files dns means: first look in /etc/hosts, then ask DNS. If you swap it to hosts: dns files, DNS is asked first, and /etc/hosts is used only when DNS has no answer. User accounts work the same way: passwd: files means passwords come from the local files.

/etc/hosts

A simple list: one IP address per line, followed by its names:

127.0.0.1       localhost
::1             localhost ip6-localhost ip6-loopback
192.168.1.10    foo.mydomain.org foo

Another example with LAN machines:

127.0.0.1        localhost
::1              localhost
192.168.1.22     amoledtesting
198.74.56.50     jobs.nagato.net

It is the quick way to name a machine without running a DNS server. 127.0.0.1 is the IPv4 loopback address, and ::1 the IPv6 one, which is why both are called localhost. Extra names after the first are aliases: shorter or alternative names for the same address, so ping foo reaches 192.168.1.10. The rules:

  • fields are separated by spaces or tabs,
  • anything after # is a comment,
  • names may contain only letters, digits, - and .,
  • a name must start with a letter and end with a letter or digit.

/etc/resolv.conf

When the answer is not in /etc/hosts, the resolver asks a DNS server. Its configuration file is /etc/resolv.conf:

nameserver 8.8.4.4
nameserver 8.8.8.8
domain mydomain.org
search mydomain.net mydomain.com

Another one:

nameserver 192.168.1.1
nameserver 4.2.2.4
domain nagato.net
search nagato.net company.com
Keyword Means
nameserver the IP address of a DNS server. One is needed, up to three are used, the extra ones are fallbacks. With none, the machine asks a name server on itself
domain the local domain, so short names inside it work: tv means tv.mydomain.org
search a list of domains to try for a short name. In the first example, tv is tried as tv.mydomain.net, then tv.mydomain.com. With search nagato.net company.com, it is tried as tv.nagato.net then tv.company.com. By default it holds only the local domain

Summary

I split networking into "what interface" and "what name". A host needs an address, a netmask, a gateway and DNS servers, either written by hand (static) or received from a DHCP server. Commands like ip addr add, ip route add and ifconfig change them only until the next reboot; persistent settings live in files or in NetworkManager. Interfaces have predictable names shown with ip link show: the prefix gives the type (en ethernet, wl Wi-Fi) and the rest comes from the firmware index (eno1), the PCI slot (ens1), the bus address (enp3s5, enp3s0) or the MAC address, giving names like wlp108s0 for Wi-Fi, and lo is the loopback.

On Debian, /etc/network/interfaces holds the classic configuration: auto brings an interface up at boot and iface name inet dhcp|static|loopback describes it, with address, netmask and gateway for static. ifup and ifdown apply it. Red Hat systems use /etc/sysconfig/network-scripts/ifcfg-* instead. For persistence today I mostly use NetworkManager, often via DHCP; it manages every interface not listed in that file. With nmcli I check general status, list Wi-Fi with device wifi list, join a network with device wifi connect SSID password ..., create and change connections with con add and mod, list and toggle saved connections with connection show|up|down, and switch the radio with radio wifi off|on; nmtui gives a text menu. I am also aware of systemd-networkd, configured by .network files with [Match] and [Network] sections in /etc/systemd/network.

For names, the host's own name is stored in /etc/hostname and set with hostnamectl set-hostname, which has static, pretty and transient variants. Name resolution follows the hosts: line of /etc/nsswitch.conf, normally hosts: files dns: first /etc/hosts, a static local table that maps IP addresses to names and aliases, then the DNS servers in /etc/resolv.conf, where nameserver lists up to three servers and domain and search let me use short names.