Monitor Network Connections with nmcli

📅 February 4, 2024
If you use a Linux distribution, such as Ubuntu or Linux Mint, then you probably have NetworkManager installed. NetworkManager handles network connectivity, and you have probably already interacted with it via a GUI interface when setting up a network connection from the panel.

But did you know that NetworkManager can also be controlled from the command line?

nmcli is the command-line tool that allows us to perform NetworkManager functions straight from the terminal. This is good news because it means we can script NetworkManager’s behavior as boot up tasks or cron jobs. In fact, we can use nmcli to show all current network connections in a custom gnome-terminal.

Here are a few examples for nmcli.

Is nmcli Installed?

Try this in a terminal:

whereis nmcli

You should see a path like this:

nmcli: /usr/bin/nmcli /usr/share/man/man1/nmcli.1.gz

This means nmcli is present on your system. (Or you could just enter nmcli and it will show connection details.)

However, nmcli is a tool for NetworkManager, so you cannot use nmcli by itself. If NetworkManager is not present because your particular Linux distribution is implementing something else, then nmcli will not be available. Some distributions use NetworkManager while others do not. For example, Ubuntu Cinnamon uses NetworkManager, but Ubuntu Server does not, so Ubuntu Server cannot use nmcli.

systemctl status NetworkManager

systemctl status NetworkManager shows it running, so nmcli is also available on this Xubuntu 22.04 system.

A Few Examples

nmcli is a thorough utility with a long man page, so here are a few examples to show a little of what is possible.

nmcli 
enp0s3: connected to Wired connection 1
"Intel 82540EM"
ethernet (e1000), 08:00:27:82:C0:07, hw, mtu 1500
ip4 default
inet4 192.168.33.221/24
route4 192.168.33.0/24 metric 100
route4 default via 192.168.33.1 metric 100
route4 169.254.0.0/16 metric 1000

lo: unmanaged
"lo"
loopback (unknown), 00:00:00:00:00:00, sw, mtu 65536

DNS configuration:
servers: 192.169.213.11
domains: bubblebear.net
interface: enp0s3

By itself, nmcli shows current networks connections. Shown above is a VirtualBox Xubuntu VM. This is handy for a quick glimpse on the given system.

nmcli general

General connection status.

 

nmcli monitor

Monitor connectivity in real time. As networks go up and down, they are reflected here.

Xubuntu showing a network connection going down and then up again. This can be used to monitor live connection activity on a remote system via SSH.

 

nmcli connection show

Show all connections active (green) or not (white).

 

nmcli connection show --active
nmcli con show --active

The –active option only shows the active network connections. All others are excluded. con is an abbreviation for connection.

 

nmcli device
nmcli device status

Shows the status of all network devices. Connected or not.

 

nmcli device show enp0s3

Shows more details about a specific hardware device.

GENERAL.DEVICE: enp0s3
GENERAL.TYPE: ethernet
GENERAL.HWADDR: 08:00:27:82:C0:17
GENERAL.MTU: 1500
GENERAL.STATE: 100 (connected)
GENERAL.CONNECTION: Wired connection 2
GENERAL.CON-PATH: /org/freedesktop/NetworkManager/ActiveConnection/1
WIRED-PROPERTIES.CARRIER: on
IP4.ADDRESS[1]: 10.100.212.115/24
IP4.GATEWAY: 10.0.2.2
IP4.ROUTE[1]: dst = 10.100.21.0/24, nh = 0.0.0.0, mt = 100
IP4.ROUTE[2]: dst = 0.0.0.0/0, nh = 10.100.222.22, mt = 100
IP4.ROUTE[3]: dst = 169.254.0.0/16, nh = 0.0.0.0, mt = 1000
IP4.DNS[1]: 10.250.110.37
IP4.DOMAIN[1]: sunshinebear.net
IP6.GATEWAY: --

If the device is not connected, you will see this instead:

GENERAL.DEVICE: enp0s9
GENERAL.TYPE: ethernet
GENERAL.HWADDR: 08:00:27:12:99:DC
GENERAL.MTU: 1500
GENERAL.STATE: 20 (unavailable)
GENERAL.CONNECTION: --
GENERAL.CON-PATH: --
WIRED-PROPERTIES.CARRIER: off
IP4.GATEWAY: --
IP6.GATEWAY: --

Custom Fields

We can choose which fields are displayed using the -f option.

nmcli -f name,device,type,state,autoconnect con show --active

Custom fields in the given order.

This can be useful when used with the -t terse option to enable parsing where the colon is the delimiter.

nmcli -t -f name,device,type,state,autoconnect con show --active

Colon-delimited values facilitates command-line parsing to extract network information. Notice that the TYPE field yields 802-3-ethernet instead of plain ethernet.

Fields Available

You can pick and choose the fields you need from these:

  • NAME
  • UUID
  • TYPE
  • TIMESTAMP
  • TIMESTAMP-REAL
  • AUTOCONNECT
  • AUTOCONNECT-PRIORITY
  • READONLY
  • DBUS-PATH
  • ACTIVE
  • DEVICE
  • STATE
  • ACTIVE-PATH
  • SLAVE
  • FILENAME
nmcli -p -f name,device,type,state,autoconnect con show --active

The -p (pretty print) option produces output that is easier to read in a terminal.

Pretty print any output with -p

Scripting

Put list of network devices in a bash array

#!/bin/bash

declare -a arrDevices
for dev in $(nmcli -t device | grep '^[^l][^o]' | cut -f1 -d:)
do
    arrDevices=("${arrDevices[@]}" $dev)
done

echo "Devices: ${arrDevices[@]}"

This grabs the device names of all network devices while excluding the loopback adapter. Names are placed in an array for future use by the script.

Get IP address with device name

“How can I list an IPv4 address with a device name?”

IP addresses are not part of the available fields, so we need to obtain the IP address separately for each specific device name that we can obtain from a field. It consists of two parts, similar to this:

Get active device (active devices have IP addresses)

dev=$(nmcli -t -f device con show --active)

Note: This bash statement will return more than one device if multiple active connections are available. This example assumes only one connection is returned for the dev variable in order to keep the example simple. A for loop (shown later) is a better approach.

Get IP address from the device

nmcli -t dev show $dev

This results in more information than we need for the device when all we need is the IP4.ADDRESS line.

GENERAL.DEVICE:enp0s3
GENERAL.TYPE:ethernet
GENERAL.HWADDR:08:00:27:82:C4:01
GENERAL.MTU:1500
GENERAL.STATE:100 (connected)
GENERAL.CONNECTION:Wired connection 2
GENERAL.CON-PATH:/org/freedesktop/NetworkManager/ActiveConnection/1
WIRED-PROPERTIES.CARRIER:on
IP4.ADDRESS[1]:100.101.23.155/24
IP4.GATEWAY:10.0.2.2
IP4.ROUTE[1]:dst = 101.101.21.0/24, nh = 0.0.0.0, mt = 100
IP4.ROUTE[2]:dst = 0.0.0.0/0, nh = 10.0.2.2, mt = 100
IP4.ROUTE[3]:dst = 169.254.0.0/16, nh = 0.0.0.0, mt = 1000
IP4.DNS[1]:111.101.21.131
IP4.DOMAIN[1]:funshinebear.net
IP6.GATEWAY:

We can use grep to get just the IP4.ADDRESS line.

nmcli -t dev show $dev | grep '^IP4\.ADDRESS'
IP4.ADDRESS[1]:100.101.23.155/24

So far, so good. The -t option produces the result in a colon-delimited format, so we can use cut to extract the second field.

nmcli -t dev show enp0s3 | grep '^IP4\.ADDRESS' | cut -f2 -d:

Result

100.101.23.155/24

The output is in CIDR notation, so a further cut will remove it if desired.

nmcli -t dev show enp0s3 | grep '^IP4\.ADDRESS' | cut -f2 -d: | cut -d/ -f1

Now, we have just the IPv4 address 100.101.23.155 that can then be displayed alongside a device name.

Putting it Together

Here is a script that displays the IPv4 address with each active network device.

#!/bin/bash

IFS=$'\n'

# Delay to wait for network to initialize
sleep 2
# Header
printf "%24s %4s %15s %s\n" 'NAME' 'DEVICE' 'IPv4' 'STATE'
echo '----------------------------------------------------------'

for item in $(nmcli -t -f name,device,type,state con show --active):
do
    name=$(echo $item | cut -d':' -f1)
    dev=$(echo $item | cut -d':' -f2)
    type=$(echo $item | cut -d':' -f3)
    state=$(echo $item | cut -d':' -f4)
    ipv4=$(nmcli -t dev show "$dev" | grep '^IP4\.ADDRESS' | cut -d':' -f2)

    printf "%24s %4s %15s %s\n" $name $dev $(echo ${ipv4} | cut -d'/' -f1) ${state}
done

Only active connections shown. More devices and their IP addresses would be displayed if they were connected and active.

Why sleep?

If running this script at your own leisure after the system has booted and network connections have been made, then this is probably not necessary. However, if this is a startup script, there is the possibility that it will show unusable network information before the network device is up. If that is the case, just add a delay using sleep. Experiment with various times to find out what works best for your system.

Colorize with lolcat

./networkscript.sh | lolcat

Multiple executions showing how lolcat can customize the output to random colors each time for fun and variety! Just pipe the script to lolcat.

lolcat must be installed separately.

sudo apt install lolcat

Open in a dedicated terminal window

We can open the network script in a separate gnome-terminal. This is useful for opening upon system startup.

gnome-terminal --hide-menubar --title=active-devices --geometry 80x12+100+100 -- bash -c "./networkscript.sh | lolcat && bash"

Script running in a new window of custom size.

This example uses gnome-terminal (sudo apt install gnome-terminal if not present), but other terminals, such as xterm, should work. It is important to add the && bash to the end of the command to execute inside the new terminal or else the window will close too fast to see anything. bash keeps the window open until closed.

The terminal colors can be customized from the terminal preferences.

Conclusion

This article barely touches upon all that is possible using nmcli, so definitely explore its man page and experiment on your own system to truly understand its scope. Anything NetworkManager-related that you might want to control or monitor is possible with nmcli.

Have fun!

 

, , ,

  1. Leave a comment

Leave a comment