MACsec setup with NetworkManager

A few months ago, on this blog, we talked about MACsec. In this post, I want to introduce the work we've done since then. Since that work revolves around methods to configure MACsec, this will also act as a guide to configure it by two methods: wpa_supplicant alone, or NetworkManager with wpa_supplicant.

If you read the previous MACsec post, you probably thought that this whole business of generating keys and creating "secure associations" isn't very convenient, especially given that you then have to monitor your associations and generate new keys manually. And you're right: it's not.

Besides, if you run RHEL or Fedora, you're probably used to configuring your network with NetworkManager, so you would expect to be able to configure MACsec with NetworkManager as well. We're going to describe this below. First, let's go a little bit behind the scenes.

Integration with wpa_supplicant

"wpa_supplicant? Wait, isn't that a WiFi thing?" Not really! While wpa_supplicant is mainly used for WiFi, it also handles port-based authentication with 802.1X. In a network using 802.1X, your switch port is effectively shut down until something running on your machine (the supplicant) authenticates with the rest of the network (or rather, a specific entity called the authenticator).

MACsec Key Agreement

With MACsec, we take this one step further, and use an extension to 802.1X called MACsec Key Agreement protocol (MKA, described in IEEE 802.1X-2010), to set up the required secure channels and associations, and to perform key exchange between nodes. After this setup phase, your traffic will be secured by MACsec. wpa_supplicant will also keep running to ensure your associations remain up to date and will perform new key exchange when necessary (before the current key expires, to provide a seamless transition).

In detail, this is what happens:

  • wpa_supplicant on the host communicates with the MKA agent on the switch's MACsec port (there can be multiple of those).
  • After the host and the switch have mutually authenticated each other in step 1 [1], they both configure a pair of secure channels with matching identifiers (step 2).
  • The switch will then generate a key for each direction (step 3). These keys will be used to encrypt and decrypt the actual traffic.
  • In step 4, secure associations using these keys are configured on both host and switch.
  • wpa_supplicant translates the information derived through MKA and configures the kernel's MACsec implementation.
  • From that point on, the kernel sends packets protected by MACsec on the "macsec0" interface, a separate network device dedicated to encrypted traffic.
  • Step 3 and 4 are later repeated (as many times as necessary) while wpa_supplicant keeps running, to transition to a new key when the current key expires.

Configuration example

If you're using MACsec with a switch that performs authentication using a pre-shared CAK/CKN pair, here's what you would put in your wpa_supplicant configuration file:

ctrl_interface=/var/run/wpa_supplicant
eapol_version=3
ap_scan=0
fast_reauth=1

network={
        key_mgmt=NONE
        eapol_flags=0
        macsec_policy=1

        mka_cak=0011... # 16 bytes hexadecimal
        mka_ckn=2233... # 32 bytes hexadecimal
}

You'll have to choose a CAK/CKN pair [2], and set it up on your switch as well. This is quite similar to using WPA-PSK on WiFi.

And, assuming you're using eth0 to connect to your network, you would then start wpa_supplicant this way:

# wpa_supplicant -i eth0 -Dmacsec_linux -c wpa_supplicant.conf

Note, that your version of wpa_supplicant may not support MACsec with the Linux kernel implementation, as this feature is quite recent and is not part of a released version of wpa_supplicant yet (the current release as of this writing is v2.6, and does not contain the macsec_linux driver). On Fedora, this is available if you have installed wpa_supplicant 2.6-4 or newer (it's in Fedora 26).

You can check if your version of wpa_supplicant supports MACsec with the Linux kernel by running wpa_supplicant -h, and looking for macsec_linux in the drivers: section of the command's output. For example, on a Fedora 26 machine:

# wpa_supplicant -h
wpa_supplicant v2.6
Copyright (c) 2003-2016, Jouni Malinen  and contributors

[...]

drivers:
  nl80211 = Linux nl80211/cfg80211
  wext = Linux wireless extensions (generic)
  wired = Wired Ethernet driver
  macsec_linux = MACsec Ethernet driver for Linux
options:
[...]

You can also use wpa_supplicant to set up an "ad-hoc" MACsec network between two or more machines. For this, you will need a switch that forwards 802.1X frames (by default, the Linux "bridge" module doesn't do that [3]; "dumb" switches will likely let them through; more advanced switches might not).

Then you just need to configure and run wpa_supplicant on all of your machines, just as was done above.

NetworkManager

NetworkManager 1.6, which was released in January, supports configuring MACsec connections through wpa_supplicant. Like in the previous example, we need to indicate that we want to use this pre-shared key mode, specify the CAK/CKN pair, and the link we want to use to connect to the network.

The following diagram should look quite familiar: the main difference between this setup and the previous one is with what piece of software the administrator interacts.

Here is the nmcli [4] command equivalent to the previous wpa_supplicant configuration:

MKA_CAK=0011... # 16 bytes hexadecimal
MKA_CKN=2233... # 32 bytes hexadecimal

nmcli connection add type macsec \
      con-name test-macsec+ ifname macsec0 \
      connection.autoconnect no \
      macsec.parent eth0 macsec.mode psk \
      macsec.mka-cak $MKA_CAK \
      macsec.mka-cak-flags 0 \
      macsec.mka-ckn $MKA_CKN

nmcli connection up test-macsec+

And that's it. NetworkManager can then be used in the usual way to configure IP addresses etc.

As before, you will need to choose a CAK/CKN pair, and configure them on your peer (another Linux machine, or a switch). That's a fundamental requirement of this "pre-shared CAK/CKN" mode.

Conclusion

This post described how you can deploy MACsec in a convenient way, that doesn't require constant supervision, using either NetworkManager combined with wpa_supplicant, or wpa_supplicant directly.

Fedora 26 will ship with NetworkManager 1.8 and a version of wpa_supplicant that supports MACsec. Packages for NetworkManager and wpa_supplicant supporting MACsec will also be available in RHEL 7.4.


Footnotes:

  1. Mutual authentication is done by verifying that the CAK/CKN pair – Connectivity Association Key/CAK Name (see IEEE 802.1X-2010 for more details) – match. (go back)
  2. You can, for example, generate a 16-byte key in hexadecimal notation this way:
    dd if=/dev/urandom count=16 bs=1 2> /dev/null | hexdump -e '1/2 "%02x"'

    (go back)

  3. To be precise: by default, the Linux bridge module blocks traffic to group addresses (of the form 01-80-C2-00-00-0X). This can be changed with the group_fwd_mask setting:
    echo 8 > /sys/class/net/$BRIDGE/bridge/group_fwd_mask

    (go back)

  4. More information about nmcli is available on the Fedora Project wiki. (go back)
Last updated: March 23, 2023