nmcli: Common Tasks Without the GUI
Introduction¶
On current RHEL, Fedora, and Ubuntu Server, NetworkManager manages network
interfaces. Hand-editing /etc/sysconfig/network-scripts/ifcfg-* or
/etc/network/interfaces either doesn't work or gets overwritten. nmcli is the
scriptable way to drive it.
The model: connections vs devices¶
- A device is a physical or virtual interface (
eth0,ens3,bond0). - A connection ("connection profile") is a named configuration that can be
applied to a device — IP settings, DNS, routes, VLAN tags. Stored under
/etc/NetworkManager/system-connections/.
One device can have several connection profiles (home, office); only one is
active at a time. This indirection is why nmcli feels different from ip.
nmcli device status # devices and which connection is active
nmcli connection show # all profiles
nmcli connection show --active
nmcli -f ip4,dns device show eth0
Static IP¶
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 9.9.9.9" \
ipv4.dns-search example.com
nmcli connection up "Wired connection 1" # apply
Back to DHCP:
nmcli connection modify "Wired connection 1" ipv4.method auto \
ipv4.gateway "" ipv4.addresses "" ipv4.dns ""
nmcli connection up "Wired connection 1"
Add a second IP without replacing the first: nmcli con mod NAME +ipv4.addresses
10.0.0.9/24. The +/- prefixes add/remove list items.
Add a static route¶
nmcli connection modify "Wired connection 1" \
+ipv4.routes "10.20.0.0/16 192.168.1.254"
nmcli connection up "Wired connection 1"
ip route # verify
DNS only (keep DHCP for addressing)¶
nmcli con mod "Wired connection 1" ipv4.ignore-auto-dns yes ipv4.dns "1.1.1.1"
nmcli con up "Wired connection 1"
VLAN¶
nmcli connection add type vlan con-name vlan100 dev eth0 id 100 \
ipv4.method manual ipv4.addresses 10.100.0.5/24 ipv4.gateway 10.100.0.1
Bond (active-backup)¶
nmcli con add type bond con-name bond0 ifname bond0 \
bond.options "mode=active-backup,miimon=100"
nmcli con add type ethernet con-name bond0-p1 ifname eth1 master bond0
nmcli con add type ethernet con-name bond0-p2 ifname eth2 master bond0
nmcli con mod bond0 ipv4.method manual ipv4.addresses 10.0.0.10/24 ipv4.gateway 10.0.0.1
nmcli con up bond0
cat /proc/net/bonding/bond0 # which slave is active, link status
For LACP use mode=802.3ad and configure the switch side to match.
Bridge (for VMs / containers)¶
nmcli con add type bridge con-name br0 ifname br0 \
ipv4.method manual ipv4.addresses 192.168.1.50/24 ipv4.gateway 192.168.1.1 \
bridge.stp no
nmcli con add type ethernet con-name br0-port ifname eth0 master br0
nmcli con up br0
Note: attaching eth0 to the bridge moves the IP to br0; do this on the
console or via a script with a rollback timer, not over the SSH session you'd
lose.
Wi-Fi¶
nmcli device wifi list
nmcli device wifi connect "SSID-Name" password "secret"
nmcli connection modify "SSID-Name" connection.autoconnect yes
Verification and troubleshooting¶
nmcli connection show "Wired connection 1" | grep -Ei 'ipv4|ipv6|route'
nmcli device show eth0
journalctl -u NetworkManager -f # watch what NM does on `con up`
nmcli general logging level DEBUG domains ALL # crank up logging temporarily
- Edited
ifcfg-eth0/ netplan yaml and nothing changed — NetworkManager owns it. Usenmcli, ornmcli connection reloadafter editing the keyfile under/etc/NetworkManager/system-connections/directly. nmcli con upfails "Connection activation failed: IP configuration could not be reserved" — DHCP got no answer, or the static config conflicts (duplicate IP, wrong subnet).journalctl -u NetworkManagerhas the reason.- Changes revert after reboot — you used
ip addr add(runtime only) ornmcli device modify(not persisted) instead ofnmcli connection modify. - Device shows "unmanaged" — it's excluded in
/etc/NetworkManager/NetworkManager.confor a.nmconnectiondoesn't exist for it.nmcli device set eth0 managed yes. - DNS not what you set —
systemd-resolvedis in the path; checkresolvectl status. NM feeds resolved unlessdns=none/dns=defaultis configured otherwise. - Lost SSH after a bridge/bond change — always wrap risky changes:
nmcli con up NAME & sleep 60 && nmcli con up OLD_PROFILEas a dead-man switch, or usenmclifrom console/IPMI.
Related tools and reading¶
- On-site: Subnet Calculator, IP address lookup, DNS lookup.
- Related posts: ss and conntrack for connection debugging, Linux permissions and ACLs.
Stuck on something this site can't fix?Reach out to Prabath directly on LinkedIn.More in Linux & Sysadmin
resolv.conf and systemd-resolved
On modern distros /etc/resolv.conf points at a stub resolver managed by systemd-resolved. Editing it directly usually does nothing — here's the real model.
October 24, 2026Tuning Open File Limits on Linux
Four different limits control how many files a process can open. 'Too many open files' means you're hitting one specific one — here's how to find and raise it.
October 24, 2026ss and conntrack for Connection Debugging
ss shows you every socket and its send/receive queues; conntrack shows what the firewall is tracking. Together they explain most 'connection refused' and 'no buffer space' problems.
October 24, 2026