Have you ever been surprised when your Linux host automatically configures your network? If so, there is a good chance that NetworkManager was responsible. NetworkManager is one of the most widespread network configuration daemons in Linux distributions. If you want to know more and learn how to control it, continue reading.

However, do you instead disable NetworkManager, and wonder why your preferred Linux distro isn't using the old IP tools as the default network configuration method? Do you think NetworkManager is "just for WiFi?" Well, this blog post is for you, too. Leave behind prejudice and give this tool a fair chance by following along for a few minutes. I bet you’ll make peace, and maybe even become friends, with NetworkManager.

In this article, I show you why NetworkManager is a good choice for many scenarios (including both the command line and the GUI). Next, I’ll explain this tool's characteristic (and often misunderstood) underlying philosophy. And finally, I’ll highlight a few commands every user should know to take full control of NetworkManager.

Why NetworkManager?

There are multiple ways to configure networking on your Linux host, so you may wonder why you should specifically use NetworkManager. While there are multiple good answers, I would like to highlight one main point that is often overlooked: NetworkManager allows users and applications to retrieve and modify the network’s configuration at the same time, ensuring a consistent and up-to-date view of the network.

This tool can be configured in multiple ways, via the desktop GUI (Gnome, KDE, nm-applet), the text user interface ( nmtui ), the command line ( nmcli ), files, and a web console (Cockpit). Network Manager provides a D-Bus interface and a library ( libnm ) to make APIs available to applications. No other network configuration tool exists that can provide such flexibility.

The NetworkManager philosophy

In order to understand and control NetworkManager, you must first understand its underlying configuration philosophy. Taken from man NetworkManager :

“…attempts to make networking configuration and operation as painless and automatic as possible…”

This is quite a difference from the standard Unix daemon philosophy, isn’t it? Traditional Unix daemons require users to explicitly provide configuration—usually via a configuration file—and then restart the service. Without configuration, the daemon will not perform any action.

NetworkManager instead, when there is partial or no configuration, checks the available devices and tries its best to provide connectivity to the host. NetworkManager’s goal is to suit everyone’s needs, from the standard user looking for "networking that just works" to the advanced network administrator that needs full control of host networking.

But, here’s the point: NetworkManager expects the advanced network administrator to provide their own configuration. While it is unusual to configure a Linux daemon to avoid performing some actions (automatic configurations), doesn’t this look like a reasonable approach to accommodate any scenario?

Basic NetworkManager concepts

NetworkManager configuration is based on the concepts of device and connection. A device maps a network interface, roughly equivalent to what you get from the ip link command. Each device tracks:

If it is managed by NetworkManager

The available connections for the device

The connection active on the device (if any)

A connection represents the full configuration to be applied on a device and is just a list of properties. Properties belonging to the same configuration area are grouped into settings (e.g., the ipv4 setting group properties like addresses, gateway, and routes).

Configuring networking in NetworkManager is as easy as activating a connection on a device: the device will then be configured with all of the properties specified in the connection.

Time for some hands-on NetworkManager configuration. While multiple tools can be used as discussed earlier, we will focus here on nmcli , the command-line tool shipped with NetworkManager.

NOTE: The nmcli program has an advanced autocompletion feature. Be sure the bash-completion package is installed in order to take advantage of this.

nmcli basics

Let’s take a look at working with different aspects of your network with nmcli .

Devices

In order to list the devices detected by NetworkManager, type:

$ nmcli device DEVICE TYPE STATE CONNECTION enp1s0 ethernet connected ether-enp1s0 enp7s0 ethernet disconnected -- enp8s0 ethernet disconnected --

As you can see from the output, NetworkManager has detected three ethernet devices on the system. Only the first one, enp1s0 , has an active connection applied to it (meaning that it is configured).

If you want NetworkManager to stop taking care of one device for a while, there is no need to shut it down. Just temporarily unmanage the device:

$ nmcli device set enp8s0 managed no $ nmcli device DEVICE TYPE STATE CONNECTION enp1s0 ethernet connected ether-ens3 enp7s0 ethernet disconnected -- enp8s0 ethernet unmanaged --

This change is not persistent, however, and will not survive a reboot.

The easiest way to retrieve the IP configuration for each device is to issue the nmcli command without arguments:

$ nmcli enp1s0: connected to enp1s0 "Red Hat Virtio" ethernet (virtio_net), 52:54:00:XX:XX:XX, hw, mtu 1500 ip4 default inet4 192.168.122.225/24 route4 0.0.0.0/0 route4 192.168.122.0/24 inet6 fe80::4923:6a4f:da44:6a1c/64 route6 fe80::/64 route6 ff00::/8 enp7s0: disconnected "Intel 82574L" ethernet (e1000e), 52:54:00:XX:XX:XX, hw, mtu 1500 enp8s0: unmanaged "Red Hat Virtio" ethernet (virtio_net), 52:54:00:XX:XX:XX, hw, mtu 1500

connections

To list the available connections, type:

$ nmcli connection NAME UUID TYPE DEVICE ether-enp1s0 23e0d89e-f56c-3617-adf2-841e39a85ab4 ethernet enp1s0 Wired connection 1 fceb885b-b510-387a-b572-d9172729cf18 ethernet -- Wired connection 2 074fd16d-daa6-3b6a-b092-2baf0a8b91b9 ethernet --

The output in this example shows that the only active connection is ether-enp1s0 , applied on device enp1s0 . Two other connections are present as well, but they are not active.

To deactivate a connection, i.e., to deconfigure the associated device, just instruct NetworkManager to put the connection down. For instance, to deactivate the ether-enp1s0 connection:

$ nmcli connection down ether-enp1s0

To activate it back, and so reconfigure the device:

$ nmcli connection up ether-enp1s0

To see the details of a particular connection, we should inspect the connection's properties:

$ nmcli connection show ether-enp1s0 connection.id: ether-enp1s0 connection.uuid: 23e0d89e-f56c-3617-adf2-841e39a85ab4 connection.stable-id: -- connection.type: 802-3-ethernet connection.interface-name: enp1s0 connection.autoconnect: yes connection.autoconnect-priority: -999 connection.autoconnect-retries: -1 (default) connection.auth-retries: -1 connection.timestamp: 1559320203 connection.read-only: no [...]

The list of connection properties is quite long and grouped by settings. Each property is, in fact, specified as setting_name.property_name . Let’s highlight a few basic properties belonging to the connection and the IPv4 settings:

Table 1: Basic properties for the connection and IPv4 settings. Property Description Alias connection.id Holds a human-readable name for the connection (shown in the nmcli connection output). con-name connection.uuid Contains the universally unique identifier UUID uniquely identifying the connection. (none) connection.type Contains the connection's type. type connection.interface-name Binds the connection to a specific device, so the connection can only be activated on that device. ifname connection.autoconnect Defines whether the connection should be auto-activated or not. autoconnect ipv4.method Contains the connection's IPv4 method: auto , disabled , link local , manual , or shared . (none) ipv4.addresses Contains the connection's static IPv4 address. (none)

Note that few commonly used properties have aliases, i.e., short names that can be used in place of the full setting.property notation. Table 1 lists the aliases (if available) in the third column. Moreover, all of the nmcli commands can be truncated to use versions to perform the same action. For instance, to switch autoconnection off for the ether-enp1s0 connection, we could shorten the modify command above as: $nmcli c m ether-ens1s0 autoconnect no

When it comes to specifics, the autoconnect property controls the connection’s automatic activation. If it is enabled ( = yes , the default), as soon as the interface-name device is ready and no other connections are active on it, the connection is automatically activated by NetworkManager. With ipv4.method if it is set to auto , the IPv4 configuration is retrieved via DHCP.

If you prefer a static IPv4 configuration instead, set ipv4.method to manual , and specify a static IP address and subnet (in CIDR notation) in the ipv4.addresses property. For a fuller description of all the properties and their meanings, see the nm-settings man page ( man nm-settings ).

Now, in order to change the properties belonging to a connection, we should use the nmcli connection modify command. Let’s change our ether-enp1s0 connection to have a static IPv4 address (let’s pick 10.10.10.1), gateway (10.10.10.254), and DNS (10.10.10.254):

$ nmcli connection modify ether-enp1s0 ipv4.method manual ipv4.addresses 10.10.10.1/24 \ ipv4.gateway 10.10.10.254 ipv4.dns 10.10.10.254

This command permanently changes the connection, but the new settings will not be applied to the device immediately: They will be applied the next time the connection is activated on that device. So, to have our settings up and running right now, let’s reactivate the connection:

$ nmcli connection up ether-enp1s0

You might also want to stop NetworkManager from activating the ether-enp1s0 connection:

$ nmcli connection modify ether-ens1s0 connection.autoconnect no

From then on, you would have to activate the ether-enp1s0 connection yourself.

Creating a new connection with nmcli

Here we are, time to create a new connection in NetworkManager with nmcli ! The nmcli connection sub-command is add , and the syntax is similar to the modify sub-command:

$ nmcli con add type ethernet ifname enp0s1 con-name enp0s1_dhcp autoconnect no $ nmcli con NAME UUID TYPE DEVICE ether-enp1s0 23e0d89e-f56c-3617-adf2-841e39a85ab4 ethernet enp1s0 enp0s1_dhcp 64b499cb-429f-4e75-a54d-b3fd980c39aa ethernet -- Wired connection 1 fceb885b-b510-387a-b572-d9172729cf18 ethernet -- Wired connection 2 074fd16d-daa6-3b6a-b092-2baf0a8b91b9 ethernet --

As we haven’t specified any IPv4 property, the IPv4 configuration will be retrieved via DHCP, as the default for the ipv4.method property is auto .

When creating a connection, mandatory properties depend on the connection.type ( ethernet , wifi , bond , vpn , etc.) If any of the mandatory properties are missing, nmcli will return an error, printing the name of the missing property.

If you prefer a more interactive experience, add the --ask flag to your nmcli command. Doing so tells nmcli to interactively prompt you for what is needed to complete the command, instead of failing:

$ nmcli --ask con add Connection type: ethernet Interface name [*]: enp0s1 There are 3 optional settings for Wired Ethernet. Do you want to provide them? (yes/no) [yes] no There are 2 optional settings for IPv4 protocol. Do you want to provide them? (yes/no) [yes] no There are 2 optional settings for IPv6 protocol. Do you want to provide them? (yes/no) [yes] no There are 4 optional settings for Proxy. Do you want to provide them? (yes/no) [yes] no Connection 'ethernet-enp0s1' (64b499cb-429f-4e75-a54d-b3fd980c39aa) successfully added.

An editor mode is accessible through nmcli con edit . This mode offers inline help and an even more interactive experience. Calling this mode without any argument causes the nmcli editor to prompt you for the type of connection to create. Pass a connection name instead, and the editor will open the connection to modify it.

nmcli cheat sheet

Here the summary of the nmcli connection commands we have seen untill now:

Table 2: Cheat sheet for nmcli connection commands. Command Arguments Description down connection Will tear down the specified connection, unconfiguring the associated device. up connection Will activate the specified connection. show [connection] When used without arguments, the show can be omitted as is the default command: it lists all available connections. If a connection name or UUID is provided as an argument, the connection properties are printed. modify connection {property_name,

property_value}... Will change the properties of the connection add connection {property_name,

property_value}... Will create a new connection with the specified properties. The mandatory properties depend upon the connection type, which should always be specified.

What’s next?

We have now introduced NetworkManager’s underlying philosophy and its basic concepts (device and connection). We have also seen that NetworkManager can manage concurrent requests by multiple tools in multiple ways. Using the NetworkManager command-line tool, nmcli , we have learned how to display the actual configuration, and how to add, modify, and activate/deactivate connections on devices. This knowledge gives you the basics to understand and control NetworkManager.

NetworkManager can do much more. Many features deserve separate blog posts, such as dispatcher scripts, connectivity checkers, split DNS, MAC address randomization, hotspot configuration, and automatic configuration. So, stay tuned here for the next blog posts. Or, if you can’t wait, start looking in the NetworkManager man pages!