25.4 nmcli: NetworkManager Command-Line Interface
Alright, let’s talk about nmcli. If you’ve ever stared at a headless server or a minimal GUI-less install and wondered how to politely ask it to get on the internet, this is your tool. It’s the command-line face of NetworkManager, the sometimes-controversial but undeniably ubiquitous service that manages your network interfaces. Forget clunky old ifconfig; this is the new guard. And while it has a reputation for being a bit… verbose, once you understand its logic, it’s incredibly powerful.
The key to not hating nmcli is to understand its object model. It thinks in terms of connections and devices. A device (eth0, wlan0) is the actual physical (or virtual) network interface hardware. A connection is a profile—a collection of settings like IP addresses, DNS servers, and security secrets—that you can apply to a device. One device can have multiple connection profiles, but only one can be active at a time. This is brilliant for laptops: you can have a “Work” profile and a “Home” profile for the same Wi-Fi card and switch between them effortlessly.
Getting the Lay of the Land
First, let’s see what we’re working with. The command nmcli by itself is painfully terse. You’ll want to use the general status and device status subcommands to get a quick overview.
$ nmcli general status
STATE CONNECTIVITY WIFI-HW WIFI WWAN-HW WWAN
connected full enabled enabled enabled enabled
$ nmcli device status
DEVICE TYPE STATE CONNECTION
wlp3s0 wifi connected My-Secure-SSID
enp0s31f6 ethernet disconnected --
p2p-dev-wlp3s0 wifi-p2p disconnected --
lo loopback unmanaged --
See? Immediately useful. My wireless card wlp3s0 is connected using the connection profile named “My-Secure-SSID”. My ethernet cable enp0s31f6 is unplugged, hence ‘disconnected’. The unmanaged state for lo is normal; NetworkManager rightly doesn’t mess with the loopback interface.
Peeking Under the Hood of a Connection
So, what’s actually in that “My-Secure-SSID” connection profile? For that, we use nmcli connection show. To see all the gory details of a specific one, add its name.
$ nmcli connection show My-Secure-SSID
connection.id: My-Secure-SSID
connection.uuid: 8766a0d4-6ba7-4e89-9c4f-55d5a4c45678
connection.type: 802-11-wireless
connection.interface-name: --
ipv4.method: auto
ipv4.dns: 192.168.1.1,1.1.1.1
ipv4.ignore-auto-dns: no
...
802-11-wireless.ssid: My-Secure-SSID
802-11-wireless-security.key-mgmt: wpa-psk
802-11-wireless-security.psk: **************************
This output is the reason people get frustrated. It’s a firehose of key-value pairs. The trick is to be specific. Want to see only the IP4 settings?
$ nmcli connection show My-Secure-SSID | grep ipv4
Or, even better, use nmcli’s -f (fields) flag to specify exactly what you want to see.
$ nmcli -f ipv4.method,ipv4.addresses,ipv4.gateway,ipv4.dns connection show My-Secure-SSID
ipv4.method: auto
ipv4.addresses: --
ipv4.gateway: --
ipv4.dns: 192.168.1.1, 1.1.1.1
Ah, much more readable. This tells me the connection is using DHCP (auto) and has picked up two DNS servers.
Taking Control: Editing a Connection
The nmcli connection modify command is where you do your real work. Its syntax is… particular. You specify the connection name and then the property you want to set, using a dotted notation. Let’s say I hate my ISP’s DNS and want to use Cloudflare’s for everything.
$ nmcli connection modify My-Secure-SSID ipv4.dns "1.1.1.1 1.0.0.1"
$ nmcli connection modify My-Secure-SSID ipv4.ignore-auto-dns yes
$ nmcli connection up My-Secure-SSID
The first command sets the DNS servers (note: spaces, not commas, separate them in this context). The second is crucial: it tells NetworkManager, “Stop listening to whatever junk DNS the DHCP server is telling you; I’m the boss here.” The final command brings the connection back up to apply the changes. If you forget the up command, you’ll be sitting there wondering why your change did nothing. I’ve done it more times than I care to admit.
Creating a New Connection from Scratch
For a new static IP on your ethernet interface, you’d build it piece by piece. This looks long, but it’s just one command.
$ nmcli connection add type ethernet con-name "Static-LAN" ifname enp0s31f6 ipv4.method manual ipv4.addresses 192.168.1.42/24 ipv4.gateway 192.168.1.1 ipv4.dns 192.168.1.1
Breaking it down: we’re adding a new connection of type ethernet, naming it (con-name) “Static-LAN”, binding it to the enp0s31f6 device, and setting all the IP settings manually. The /24 on the address is the CIDR netmask notation (equivalent to 255.255.255.0). Run this, and you’ll have a new profile ready to activate with nmcli connection up Static-LAN.
The biggest pitfall with nmcli is its stubborn insistence on using its own specific property names (ipv4.dns-search, not domain-search) and its sometimes inscrutable error messages. If a command fails, double-check the property names with nmcli connection show --help—it lists them all. It’s not intuitive, but it’s precise. And in system administration, precise beats intuitive every time.