Adding a static IP to a DHCP-enabled NetworkManager connection

I have to be honest here, I’m really not a fan of NetworkManager. I realize that the Linux community is trying to make things easier for the average user, but that has come at a cost: losing some power user features. One of these features is assigning multiple IP addresses (multi-homing) to a single network card.

In my work environment, I use multi-homing to talk on our corporate network, but to also reach a test network with a bunch of test equipment attached. On my corporate network, I want the card to obtain a DHCP address. However, for the test network, I really want to specify a static IP address. Unfortunately, this turns out to be impossible to setup via the NetworkManager GUI. However, my clever systems administrator, Brian, discovered a way to make it happen via the command line despite the severe lack of documentation out there.

The trick here is that the NetworkManager command line tool, nmcli, grew the ability to edit a network connection (you need Fedora 21 or better for this feature). Using this mechanism, it’s possible to set additional IP addresses and still keep using DHCP for the main address.

On a Fedora 25 system, the network card’s configuration might look like this:

$ cat /etc/sysconfig/network-scripts/ifcfg-em1
HWADDR=00:0C:29:75:12:6C
TYPE=Ethernet
BOOTPROTO=dhcp
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=em1
UUID=51a67f2a-d999-3d05-b6c9-cc0d956fb3f6
ONBOOT=yes
AUTOCONNECT_PRIORITY=-999

Using the NetworkManager command line interface, we can edit the connection for em1 and print the associated settings:

$ nmcli con edit em1

===| nmcli interactive connection editor |===

Editing existing '802-3-ethernet' connection: 'em1'

Type 'help' or '?' for available commands.
Type 'describe [<setting>.<prop>]' for detailed property description.

You may edit the following settings: connection, 802-3-ethernet (ethernet), 802-1x, dcb, ipv4, ipv6
nmcli> print ipv4
['ipv4' setting values]
ipv4.method:                            auto
ipv4.dns:
ipv4.dns-search:
ipv4.dns-options:                       (default)
ipv4.dns-priority:                      0
ipv4.addresses:
ipv4.gateway:                           --
ipv4.routes:
ipv4.route-metric:                      -1
ipv4.ignore-auto-routes:                no
ipv4.ignore-auto-dns:                   no
ipv4.dhcp-client-id:                    --
ipv4.dhcp-timeout:                      0
ipv4.dhcp-send-hostname:                yes
ipv4.dhcp-hostname:                     --
ipv4.dhcp-fqdn:                         --
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv4.dad-timeout:                       -1 (default)

Next, we can add the necessary static IP addresses. In this case, I’m going to add 2 of them: 192.168.100.10, and 192.168.100.11.

nmcli> set ipv4.addresses 192.168.100.10/24,192.168.100.11/24
Do you also want to set 'ipv4.method' to 'manual'? [yes]: no

Note that I opted not change ipv4.method to manual. You definitely want to leave it as auto so that it will continue to obtain a DHCP address.

Next, we’ll save the configuration, print the new settings, and then exit the tool:

nmcli> save
Connection 'em1' (51a67f2a-d999-3d05-b6c9-cc0d956fb3f6) successfully updated.
nmcli> print ipv4
['ipv4' setting values]
ipv4.method:                            auto
ipv4.dns:
ipv4.dns-search:
ipv4.dns-options:                       (default)
ipv4.dns-priority:                      0
ipv4.addresses:                         192.168.100.10/24, 192.168.100.11/24
ipv4.gateway:                           --
ipv4.routes:
ipv4.route-metric:                      -1
ipv4.ignore-auto-routes:                no
ipv4.ignore-auto-dns:                   no
ipv4.dhcp-client-id:                    --
ipv4.dhcp-timeout:                      0
ipv4.dhcp-send-hostname:                yes
ipv4.dhcp-hostname:                     --
ipv4.dhcp-fqdn:                         --
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv4.dad-timeout:                       -1 (default)
nmcli> quit

Finally, we can see that our configuration changes where made to network configuration:

$ cat /etc/sysconfig/network-scripts/ifcfg-em1
HWADDR=00:0C:29:75:12:6C
TYPE=Ethernet
BOOTPROTO=dhcp
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=em1
UUID=51a67f2a-d999-3d05-b6c9-cc0d956fb3f6
ONBOOT=yes
AUTOCONNECT_PRIORITY=-999
IPADDR=192.168.100.10
PREFIX=24
IPADDR1=192.168.100.11
PREFIX1=24
PEERDNS=yes
PEERROUTES=yes
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes

While it’s unfortunate that we cannot do this via the NetworkManager GUI, at least it’s possible to make it happen via NetworkManager now. The only solution prior to this was to disable NetworkManager altogether–which, to be honest, wasn’t that bad of a solution. I imagine that ability will disappear someday soon, so it’s at least comforting that there’s a path with NetworkManager. Let’s hope a future version allows you to do this via the GUI. I won’t hold my breath though… I’ve been waiting years for that feature to show up.