Initscripts’ ifcfg-rh Format in NetworkManager and its Future

NetworkManager is a daemon for configuring the network on Linux. It’s all about connection profiles, which are created by the user and “activated” by NetworkManager. A profile is just a bunch of settings and configuration values with defined keys and values, that can be sent over D-Bus or persisted to disk. Currently two file formats exists for that purpose: keyfile and ifcfg-rh. Let’s take a look at the history and future of the ifcfg-rh format.

Eliška no longer uses ifcfg files with NetworkManager.

About initscripts

The very short version of the history is that various Linux distributions use the System V “initscripts” for system configuration and management. For example, the Fedora variant is (un)maintained at github/fedora-sysv. One part of initscripts is concerned about network and provides two scripts ifup and ifdown and a SysV-style init service network. On Fedora and RHEL, users would edit files like /etc/sysconfig/network-scripts/ifcfg-eth0 according to the documentation. These files are the “profiles” in the sense that they are configurations for a network interface.

The network-scripts part of initscripts are really a bunch of shell scripts that parse ifcfg files (by executing them as shell scripts) and configure the network accordingly. They do so by calling iproute2 (the ip tool) to setup interfaces and IP addresses in kernel. But the scripts can also start ISC’s dhclient to do DHCP, in which case the DHCP daemon keeps running in the background.

As such, initscripts are a simple thing that work well for what they are. But they are one-shot commands that do their task and quit. This is a fundamental limitation, despite that they leave some state for the next time when they run — like the PID file of dhclient or an IP address configured on an interface. Another problem is that their API essentially is to have users write an ifcfg file and reboot. Yes, you can also manually call ifup and ifdown to apply changes, but that might not reliably work in subtle cases. For example if you change the DEVICE= name in the ifcfg file that is currently up, ifdown wouldn’t know that there was something to tear down. Or calling ifup twice in a row can lead to errors. The scripts simply don’t know the current state. Such an API is not well suited to build applications that configure the network, like a GUI or cockpit. Providing such an API is the main reason why NetworkManager exists.

NetworkManager handles ifcfg Files

When NetworkManager was first introduced at around 2004, initscripts and ifcfg was the way to configure the network on Fedora Core. Consequently, NetworkManager persisted its connection profiles also in ifcfg format because users were already familiar with the format and because it already existed. Also initscripts on Fedora/RHEL started to integrate with NetworkManager. When you called ifup, the script would check whether NetworkManager is running and manages the profile, in which case the script will call nmcli connection up to let NetworkManager handle it. This can be prevented by configuring a key NM_CONTROLLED=no in the ifcfg file.

While a goal was that the same ifcfg file can be used both by initscripts and NetworkManager in a similar way, in practice this only works with simple configurations. NetworkManager defines a large number of additional shell variables that are not supported by initscripts. And likewise, in several ways initscripts will behave differently than NetworkManager. For example, NetworkManager does not support IP aliases and the way Openvswitch and Wi-Fi configuration is expressed in ifcfg files is fundamentally incompatible. Also, not every NetworkManager profile can be persisted in ifcfg format, in which case NetworkManager always uses the keyfile format.

In Fedora 29 the network-scripts package was split out of the initscripts package. On recent Fedora and RHEL, the network-scripts package is not installed by default. They are considered deprecated but still available for installation. Note that the initscripts package itself does things beyond network configuration and that part is still in use.

Moving away from ifcfg files

As far as NetworkManager is concerned, it keeps handling ifcfg files. Regardless whether network-scripts are in use, the file format is used by NetworkManager, along side the keyfile format which has ini style files in /{etc,run,usr/lib}/NetworkManager/system-connections. Note that the keyfile backend is the preferred format of NetworkManager and the one that can handle all connection types. It is thus always enabled in NetworkManager. You can only select whether to use the ifcfg-rh backend in addition. This is done via the main.plugins setting in NetworkManager.conf. Before Fedora 34, this setting had a default of main.plugins=ifcfg-rh,keyfile. Since Fedora 34 it defaults to main.plugins=keyfile,ifcfg-rh. The difference is that now NetworkManager preferably writes new profiles in keyfile format. This change is a step away from using the ifcfg-rh format.

It will probably take a while until NetworkManager completely gets rid of supporting ifcfg-rh format. The difficulty is that this concerns user configuration on disk, and it is important to NetworkManager to not break during package upgrade or during upgrade to a newer Fedora/RHEL release. To do this, we will also need to write migration tools that can convert ifcfg files to keyfile format. And in the end, if a user or tool relied on finding an ifcfg file, the change will be noted and might break existing setups. There is no hurry for you to migrate, but be aware that eventually we want to get rid of the ifcfg file format. The reason is that maintaining multiple formats has an overhead, not only for the development but for users who need to learn two formats and for tools that not work if an unexpected format is used. It’s also desirable that NetworkManager on Fedora/RHEL uses the same format as it does on most other Linux distributions.

Example of the ifcfg Format

If we create a new connection profile with

nmcli connection add type ethernet con-name eth0 \
     ifname eth0 autoconnect no

then this results in the following ifcfg file:

# cat /etc/sysconfig/network-scripts/ifcfg-eth0 
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
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=eth0
UUID=a64c3983-5a14-46ef-90e4-e3ec4e57e8a5
DEVICE=eth0
ONBOOT=no

In comparison, in keyfile format this looks like

# cat /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
uuid=fbd13bf5-01d9-4569-ba79-f2d79daf79c8
type=ethernet
autoconnect=false
interface-name=eth0
permissions=

[ethernet]
mac-address-blacklist=

[ipv4]
dns-search=
method=auto

[ipv6]
addr-gen-mode=stable-privacy
dns-search=
method=auto

[proxy]

Subjectively, I find the ini style format nicer. It’s also based on glib’s GKeyfile API that can parse these files into some form of dictionary. Also, libnm provides an API to convert NMConnection instaces to/from keyfile.

2 thoughts on “Initscripts’ ifcfg-rh Format in NetworkManager and its Future”

  1. Dear Thomas Haller,

    I used Network Manager a long time with my old Debian 9 andit worked even fine while upgrading up to 10.7. My configuration had two network cards, one onboard, one via USB. For both I had a lot of networks configured.

    Now, after a fresh install of Debian 10.8 the NetworkManager Applet is not able to configure and handle the two network cards with manual configuration. Sometimes one, sometimes the other card is deactivated. Trying to configure confuses both cards.

    Maybe you can add test scenarios with multiple cards with manually configured networks to your testing and see, if there is a problem…

    Best regards
    Roland Härter

Leave a Reply

Your email address will not be published. Required fields are marked *