ipconfig.co.uk

Linux: nmcli, networkctl, resolvectl, ss, ethtool and the config files

ip shows and changes the live kernel state, but something else decides what that state should be at boot and when a cable is plugged in. On desktops that is NetworkManager; on servers it is systemd-networkd, Netplan, ifupdown or the legacy network-scripts. This page covers those managers, the DNS resolver, and the diagnostic tools that surround them.

Which manager is running?

Linux · Terminal
systemctl is-active NetworkManager systemd-networkd
nmcli general status 2>/dev/null
networkctl list 2>/dev/null
ls /etc/netplan/ /etc/network/interfaces /etc/sysconfig/network-scripts/ 2>/dev/null
resolvectl status 2>/dev/null | head -5
DistributionDefault managerConfig locationDNS resolver
Ubuntu Desktop 18.04+NetworkManager (via Netplan renderer)/etc/netplan/*.yaml, NM profiles in /etc/NetworkManager/system-connections/systemd-resolved
Ubuntu Server 18.04+systemd-networkd (via Netplan)/etc/netplan/*.yamlsystemd-resolved
Debian 12ifupdown; NetworkManager on desktops/etc/network/interfaces/etc/resolv.conf (plain)
Fedora, RHEL 8/9, Rocky, AlmaNetworkManager/etc/NetworkManager/system-connections/*.nmconnection (RHEL 8 still supports network-scripts)NetworkManager writes /etc/resolv.conf; systemd-resolved on Fedora 33+
ArchNone by default; user picks NetworkManager, systemd-networkd or iwddependsdepends
openSUSEwicked (server) or NetworkManager (desktop)/etc/sysconfig/network/ifcfg-*netconfig
Alpineifupdown-ng / BusyBox/etc/network/interfaces/etc/resolv.conf
Raspberry Pi OS (Bookworm+)NetworkManagerNM profilesNM
Raspberry Pi OS (Bullseye and earlier)dhcpcd/etc/dhcpcd.confdhcpcd

Interface names

systemd's predictable network interface names replaced eth0/wlan0 in 2013 so that names stay stable across reboots and hardware changes. The prefix says the type, the rest says where the hardware is.

NameMeaning
en, wl, wwEthernet, wireless LAN, wireless WAN (mobile broadband)
eno1Onboard device, index 1 from firmware
ens3PCI hotplug slot 3 (common in VMs)
enp3s0PCI bus 3, slot 0
enp0s31f6PCI bus 0, slot 31, function 6
wlp2s0Wireless, PCI bus 2, slot 0
enx001122334455Named by MAC address (USB adapters)
eth0, wlan0Kernel default names: containers, old distributions, Raspberry Pi OS, or net.ifnames=0 on the kernel command line
loLoopback
docker0, br-…, veth…Docker bridge and container ends
virbr0, vnet0libvirt/KVM
tun0, tap0, wg0, ppp0, tailscale0VPNs and tunnels

To get the old names back, add net.ifnames=0 biosdevname=0 to the kernel command line. To name an interface yourself, create a .link file in /etc/systemd/network/ matching on MAC and setting Name=lan0.

NetworkManager and nmcli

nmcli is the command-line client. It manages devices (hardware) and connections (profiles that can be applied to a device). Changes made with nmcli con mod are saved to disk and survive reboots.

Viewing

Linux · Terminal
nmcli                                # overview: every device with addresses, routes, DNS
nmcli general status
nmcli device status                  # devices and their state
nmcli device show enp3s0             # full detail for one device
nmcli connection show                # saved profiles
nmcli connection show "Wired connection 1"   # every property of a profile
nmcli -g ip4.address device show enp3s0        # one field, script-friendly
nmcli -t -f DEVICE,STATE device      # terse output
Output
$ nmcli device status
DEVICE   TYPE      STATE                   CONNECTION
enp3s0   ethernet  connected               Wired connection 1
wlp2s0   wifi      disconnected            --
docker0  bridge    connected (externally)  docker0
lo       loopback  connected (externally)  lo

Static IP with nmcli

Linux · Terminal
sudo nmcli connection modify "Wired connection 1" \
  ipv4.method manual \
  ipv4.addresses 192.168.1.50/24 \
  ipv4.gateway 192.168.1.1 \
  ipv4.dns "1.1.1.1 1.0.0.1" \
  ipv4.dns-search home.arpa
sudo nmcli connection up "Wired connection 1"    # apply

Back to DHCP

Linux · Terminal
sudo nmcli connection modify "Wired connection 1" ipv4.method auto ipv4.addresses "" ipv4.gateway "" ipv4.dns ""
sudo nmcli connection up "Wired connection 1"

Renew DHCP, restart networking

Linux · Terminal
sudo nmcli connection down "Wired connection 1" && sudo nmcli connection up "Wired connection 1"
sudo nmcli device reapply enp3s0
sudo nmcli device disconnect enp3s0 && sudo nmcli device connect enp3s0
sudo nmcli networking off && sudo nmcli networking on
sudo systemctl restart NetworkManager

Wi-Fi

Linux · Terminal
nmcli device wifi list
nmcli device wifi list --rescan yes
sudo nmcli device wifi connect "MySSID" password "secret"
sudo nmcli device wifi connect "MySSID" password "secret" hidden yes
nmcli connection show --active
sudo nmcli connection delete "MySSID"
nmcli radio wifi off && nmcli radio wifi on
sudo nmcli device wifi hotspot ifname wlp2s0 ssid MyHotspot password "12345678"
nmcli -s connection show "MySSID" | grep psk      # show the saved password

Other useful modifications

Linux · Terminal
# clone or randomise MAC
sudo nmcli con mod "Wired connection 1" ethernet.cloned-mac-address 02:11:22:33:44:55
sudo nmcli con mod "MySSID" wifi.cloned-mac-address random
# ignore DHCP-supplied DNS and use your own
sudo nmcli con mod "Wired connection 1" ipv4.ignore-auto-dns yes ipv4.dns 1.1.1.1
# disable IPv6 on a profile
sudo nmcli con mod "Wired connection 1" ipv6.method disabled
# MTU
sudo nmcli con mod "Wired connection 1" ethernet.mtu 1400
# route metric (lower = preferred)
sudo nmcli con mod "Wired connection 1" ipv4.route-metric 50
# add a static route
sudo nmcli con mod "Wired connection 1" +ipv4.routes "10.0.0.0/8 192.168.1.254"
# don't use this connection as the default route
sudo nmcli con mod "Wired connection 1" ipv4.never-default yes
# tell NetworkManager to leave an interface alone
sudo nmcli device set enp3s0 managed no
# add a new profile from scratch
sudo nmcli con add type ethernet ifname enp3s0 con-name lan ipv4.method manual ipv4.addresses 192.168.1.50/24 ipv4.gateway 192.168.1.1
# interactive editor
nmcli connection edit "Wired connection 1"

The text UI nmtui offers the same operations in a menu, which is easier for one-off changes over SSH.

systemd-networkd and networkctl

systemd-networkd reads .network, .netdev and .link files from /etc/systemd/network/. It is common on servers, Arch, and Ubuntu Server (through Netplan).

Linux · Terminal
networkctl list
networkctl status                 # overview with addresses, gateway, DNS
networkctl status enp3s0          # one interface, including DHCP lease and driver
networkctl lldp                   # LLDP neighbours (switch port names)
sudo networkctl reconfigure enp3s0
sudo networkctl renew enp3s0      # renew DHCP
sudo networkctl reload            # re-read config files
sudo networkctl up enp3s0 / down enp3s0   # systemd 248+
Output
$ networkctl list
IDX LINK    TYPE     OPERATIONAL SETUP
  1 lo      loopback carrier     unmanaged
  2 enp3s0  ether    routable    configured
  3 wlp2s0  wlan     off         unmanaged

3 links listed.
File
# /etc/systemd/network/20-wired.network
[Match]
Name=enp3s0

[Network]
DHCP=yes
# or static:
# Address=192.168.1.50/24
# Gateway=192.168.1.1
# DNS=1.1.1.1
# DNS=1.0.0.1

[DHCPv4]
UseDNS=yes
RouteMetric=100

Netplan (Ubuntu)

Netplan is a YAML front end that generates configuration for either NetworkManager or systemd-networkd, chosen by the renderer key. Files live in /etc/netplan/ and are applied in lexical order.

YAML
# /etc/netplan/50-cloud-init.yaml (Ubuntu Server example)
network:
  version: 2
  renderer: networkd
  ethernets:
    enp3s0:
      dhcp4: true
      dhcp6: true
# static alternative:
#    enp3s0:
#      dhcp4: false
#      addresses: [192.168.1.50/24]
#      routes:
#        - to: default
#          via: 192.168.1.1
#      nameservers:
#        addresses: [1.1.1.1, 1.0.0.1]
#        search: [home.arpa]
Linux · Terminal
sudo netplan get                 # show the merged config
sudo netplan try                 # apply with automatic rollback after 120 s unless confirmed
sudo netplan apply
sudo netplan --debug apply
netplan status                   # Ubuntu 22.10+: live state per interface

YAML indentation errors are the number one cause of Invalid YAML or Error in network definition. Use two spaces, no tabs. The older gateway4: key is deprecated in favour of routes:. The cloud-init file will be regenerated on cloud instances unless you disable cloud-init networking with a file in /etc/cloud/cloud.cfg.d/.

ifupdown (Debian)

File
# /etc/network/interfaces
auto lo
iface lo inet loopback

auto enp3s0
iface enp3s0 inet dhcp

# static alternative
# iface enp3s0 inet static
#     address 192.168.1.50/24
#     gateway 192.168.1.1
#     dns-nameservers 1.1.1.1 1.0.0.1   # needs the resolvconf package
Linux · Terminal
sudo ifdown enp3s0 && sudo ifup enp3s0
sudo ifup -a
sudo systemctl restart networking
ifquery --state

Legacy network-scripts (RHEL 7 and earlier)

File
# /etc/sysconfig/network-scripts/ifcfg-eth0
TYPE=Ethernet
BOOTPROTO=none
NAME=eth0
DEVICE=eth0
ONBOOT=yes
IPADDR=192.168.1.50
PREFIX=24
GATEWAY=192.168.1.1
DNS1=1.1.1.1
DNS2=1.0.0.1
Linux · Terminal
sudo ifdown eth0 && sudo ifup eth0
sudo systemctl restart network      # RHEL 7
sudo nmcli connection reload        # RHEL 8, which reads ifcfg files through NetworkManager

RHEL 9 removed the network-scripts package; profiles migrated to .nmconnection keyfiles. nmcli connection migrate converts them.

DHCP clients

If no manager is running, or you are in a rescue shell, drive the DHCP client directly.

Linux · Terminal
# ISC dhclient (Debian/Ubuntu until 24.04, RHEL until 8)
sudo dhclient -r enp3s0      # release
sudo dhclient enp3s0         # obtain
sudo dhclient -v enp3s0      # verbose: see DISCOVER/OFFER/REQUEST/ACK
cat /var/lib/dhcp/dhclient.leases

# dhcpcd (Raspberry Pi OS Bullseye, Arch, Alpine)
sudo dhcpcd -k enp3s0        # release
sudo dhcpcd enp3s0
sudo dhcpcd -n enp3s0        # rebind/renew
dhcpcd -U enp3s0             # dump lease variables

# systemd-networkd's built-in client
sudo networkctl renew enp3s0

# NetworkManager's built-in client (default since NM 1.20)
sudo nmcli device reapply enp3s0

# BusyBox udhcpc
sudo udhcpc -i eth0

Watching the exchange with sudo tcpdump -i enp3s0 -n port 67 or port 68 is the definitive way to see whether a DHCP server is answering at all.

DNS: resolvectl and resolv.conf

On any system running systemd-resolved (Ubuntu, Fedora, many others), /etc/resolv.conf is a symlink pointing at a stub file that lists only 127.0.0.53. The real upstream servers are shown by resolvectl.

Linux · Terminal
resolvectl status                     # servers per interface, DNSSEC, DNS-over-TLS state
resolvectl dns                        # just the servers
resolvectl domain                     # search domains
resolvectl query example.com
resolvectl query -t MX example.com
resolvectl statistics                 # cache hits and misses
sudo resolvectl flush-caches
sudo resolvectl dns enp3s0 1.1.1.1 1.0.0.1      # set servers for this boot
sudo resolvectl domain enp3s0 home.arpa
sudo resolvectl revert enp3s0
ls -l /etc/resolv.conf
# older name for the same tool
systemd-resolve --status
sudo systemd-resolve --flush-caches
Output
$ resolvectl status
Global
         Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
  resolv.conf mode: stub

Link 2 (enp3s0)
    Current Scopes: DNS
         Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 192.168.1.1
       DNS Servers: 192.168.1.1
        DNS Domain: home

To make systemd-resolved use DNS-over-TLS, set DNSOverTLS=yes and DNS=1.1.1.1#cloudflare-dns.com in /etc/systemd/resolved.conf, then sudo systemctl restart systemd-resolved. Without systemd-resolved, /etc/resolv.conf is a plain file with nameserver, search and options lines, and there is no cache to flush unless you run nscd, dnsmasq or unbound. Flush DNS on Linux →

Name lookup order is set in /etc/nsswitch.conf on the hosts: line: typically files mdns4_minimal [NOTFOUND=return] dns, meaning hosts file, then mDNS for .local, then DNS. getent hosts example.com resolves a name the way applications do; dig and nslookup bypass all of that and talk to DNS directly.

Sockets: ss (and netstat)

Linux · Terminal
ss -tulpn                  # TCP+UDP listening sockets with process (sudo for all PIDs)
ss -tan                    # all TCP, numeric
ss -tan state established
ss -tp dst 192.168.1.10
ss -s                      # summary counts
ss -tln sport = :22
ss -x                      # Unix domain sockets
ss -i                      # TCP internals: cwnd, rtt, retransmits
ss -K dst 203.0.113.5      # kill connections (needs CONFIG_INET_DIAG_DESTROY)
Output
$ sudo ss -tulpn
Netid State  Recv-Q Send-Q Local Address:Port  Peer Address:Port Process
udp   UNCONN 0      0        127.0.0.53%lo:53        0.0.0.0:*     users:(("systemd-resolve",pid=612,fd=13))
tcp   LISTEN 0      128            0.0.0.0:22        0.0.0.0:*     users:(("sshd",pid=891,fd=3))
tcp   LISTEN 0      511                  *:80              *:*     users:(("nginx",pid=1203,fd=6))

The flags mirror netstat's: t TCP, u UDP, l listening, p process, n numeric, a all. netstat -tulpn still works if net-tools is installed but is slower on busy hosts because it reads /proc/net/tcp rather than using netlink.

ethtool: link speed, duplex, driver, offloads

Linux · Terminal
sudo ethtool enp3s0             # speed, duplex, auto-negotiation, link detected
ethtool -i enp3s0               # driver and firmware version
ethtool -S enp3s0               # detailed NIC statistics
ethtool -k enp3s0               # offload features (tso, gro, checksum)
sudo ethtool -K enp3s0 tso off gro off    # turn offloads off (for capture accuracy or driver bugs)
sudo ethtool -s enp3s0 speed 100 duplex full autoneg off
sudo ethtool -s enp3s0 autoneg on
sudo ethtool -p enp3s0 10       # blink the port LED for 10 seconds to find the cable
ethtool -g enp3s0               # ring buffer sizes
sudo ethtool -G enp3s0 rx 4096
sudo ethtool -s enp3s0 wol g    # Wake-on-LAN magic packet
ethtool --show-eee enp3s0
Output
Settings for enp3s0:
	Supported ports: [ TP ]
	Supported link modes:   10baseT/Half 10baseT/Full
	                        100baseT/Half 100baseT/Full
	                        1000baseT/Full
	Speed: 1000Mb/s
	Duplex: Full
	Auto-negotiation: on
	Port: Twisted Pair
	Link detected: yes

Speed: 100Mb/s on a gigabit port with Duplex: Half means a cable fault (one pair broken) or a bad switch port; it is the classic cause of "my network is slow and ifconfig shows errors".

Wi-Fi: iw and iwconfig

Linux · Terminal
iw dev                          # wireless interfaces
iw dev wlp2s0 link              # SSID, BSSID, signal, bitrate
iw dev wlp2s0 info
sudo iw dev wlp2s0 scan | grep -E 'SSID|signal|freq'
iw dev wlp2s0 station dump      # per-station stats (AP mode or connected)
iw reg get                      # regulatory domain
sudo iw reg set GB
iw list                         # hardware capabilities: bands, channels, modes
rfkill list                     # is the radio blocked?
sudo rfkill unblock wifi
iwconfig                        # legacy wireless-tools; may not be installed
iwgetid -r                      # just the SSID (wireless-tools)

To connect without NetworkManager, use wpa_supplicant with wpa_passphrase, or iwd's iwctl (iwctl station wlan0 scan, iwctl station wlan0 connect SSID).

hostname and friends

Linux · Terminal
hostname                 # short name
hostname -f              # FQDN
hostname -I              # all addresses on one line (capital i); useful in scripts
hostname -i              # address per /etc/hosts; often 127.0.1.1 and not what you want
hostnamectl              # static, transient and pretty names, plus OS info
sudo hostnamectl set-hostname server1
cat /etc/hostname /etc/hosts

Reading /proc and /sys directly

Everything the tools show comes from the kernel's virtual filesystems. In a minimal container or rescue image with no tools at all, these still work:

Linux · Terminal
cat /proc/net/dev                        # counters per interface
cat /sys/class/net/enp3s0/address        # MAC
cat /sys/class/net/enp3s0/operstate      # up / down
cat /sys/class/net/enp3s0/speed          # Mb/s
cat /sys/class/net/enp3s0/mtu
cat /sys/class/net/enp3s0/carrier        # 1 = link
ls /sys/class/net/                       # interface names
cat /proc/net/route                      # routes in hex
cat /proc/net/arp                        # ARP cache
cat /proc/net/if_inet6                   # IPv6 addresses
cat /proc/sys/net/ipv4/ip_forward        # forwarding on?
cat /proc/net/wireless

Diagnostics toolkit

ToolPackageUse
ping, ping -6iputilsReachability; ping -M do -s 1472 host tests MTU
traceroute, tracepath, mtrtraceroute, iputils, mtrPath and per-hop loss; mtr -rw host for a report; tracepath needs no root and shows path MTU
dig, host, nslookupbind-utils / dnsutilsDNS queries; dig +short, dig @1.1.1.1 example.com AAAA, dig -x 1.1.1.1
arpingiputilsARP-level ping: sudo arping -I enp3s0 192.168.1.1; also finds duplicate IPs with -D
nc / ncatnetcat / nmap-ncatPort test: nc -zv host 443
curl -v, wgetcurl, wgetHTTP-level tests; curl -4 / -6 forces a family
tcpdumptcpdumpCapture: sudo tcpdump -i enp3s0 -n host 192.168.1.1; -w file.pcap for Wireshark
nmapnmapScan your own network: nmap -sn 192.168.1.0/24 lists live hosts
lsof -ilsofWhich process owns which socket
iftop, nload, bmon, vnstatrespectiveLive and historical bandwidth per interface
nft list ruleset, iptables -L -n -vnftables, iptablesFirewall rules
ufw status verbose, firewall-cmd --list-allufw, firewalldFirewall front ends
journalctl -u NetworkManager -fsystemdWatch what NetworkManager is doing
dmesg -w | grep -i -E "link|eth|wlan"util-linuxDriver messages: link up/down, resets

Related pages

Last reviewed . Command syntax verified against Windows 11, Ubuntu 24.04, macOS 15 and FreeBSD 14 unless noted otherwise.

Spotted a mistake or a switch we have missed? Every page on this site is written to be checked against real output, so please test on your own machine and compare.