MACsec linux configuration using iproute2.

This is how configure the MACsec IEEE 802.1AE using linux standard toolkit iproute2. Unlike a RFC, the IEEE 802.1AE is a technical standard. MACsec was standardised in 2006 by IEEE (standard IEEE 802.1AE-2006). Using MACsec frames are switched using secure channels SC supported by secure associations SA. Each secure associations SA uses a separate randomly generated key.

The ip macsec command subset is used to configure transmit secure associations and receive secure channels and their secure associations on a MACsec device created with the ip link add command using the macsec type. The ip macsec implementation came to linux in around the year 2016 and has been implemented by Sabrina Dubroca.

Network topology

Network topology with IP addressing:

    +-------+                                   +-------+
    |       | eth0                         eth0 |       |
    |  C1   +-----------------------------------+  C2   |
    |       | .1                             .2 |       |
    +-------+ ::a                           ::b +-------+

2 linux nodes. Point to point network. Linux nodes are directly connected. Basic setup. Both nodes are connected using the eth0 NIC.

IP addressing:

IP addressing is attached to the macsec0 interface:

  • C1 - macsec0 - 192.0.2.1/30 - 2001:db8::a/127
  • C2 - macsec0 - 192.0.2.2/30 - 2001:db8::b/127

PCAP

A random packet dump will show following sequence of headers, when using A ICMP ping test:

  • Frame
  • Ethernet II
  • Internet Protocol
  • ICMP [...]

The MACsec packet dump will show following sequence of headers. This is the same ICMP output:

  • Frame
  • Ethernet II
  • 802.1AE Security tag (SecTAG)
  • Data (payload) [...]
  • Physical Source/DestinationMAC address between both endpoints
  • the payload, including ETYPE is encrypted using GCM-AES
  • encrypted payload put between the SecTAG and ICV.
  • MACsec sends frame using own ethernet type ETYPE 0x88E5

Ethernet IPv4 - EtherType: 0x0800

| SMAC | DMAC | ETYPE | Data (payload) | FCS |

MACsec - EtherType: 0x88E5

| SMAC | DMAC | SecTAG | encrypted Data (payload) | ICV | FCS |

SecTAG:

| ETYPE  | TCI/AN | SL | PN      | SCI (optional) |

SecTAG in bytes;

| 2      | 1      | 1  | 4       |  8             |

Configuration

Static CAK mode is used for links connecting routers and/or switches. Static CAK mode ensures security by frequent generation of new random security key and by sharing only the security key between the two devices on the secured point-to-point link.

The MACsec configuration process in a sequence:

  • create interface macsec0
  • configure Secure Association (SA) in the TX direction
  • configure Secure Channel (SC) in the RX direction
  • configure Secure Association (SA) in the RX direction

The linux ip macsec command is used to configure

on a MACsec device created with the ip link add command using the macsec type.

linux setup

Set the physical link eth0 to state down:

ip link set eth0 down

Verify MACSEC module is enabled in the linux kernel, grep the kernel configuration for it:

user % grep -i macsec /boot/config-6.6.11_1 CONFIG_MACSEC=m

The output shows using current linux it is build as a linux module CONFIG_MACSEC=m. Before loading check if the linux module has not been already loaded to kernel

lsmod | grep macsec

If the command output is emty load the linux kernel module, otherwise it is already loaded:

modprobe macsec

Verify the module has been loaded, now lsmod should spit out something useful:

user % lsmod | grep macsec macsec 69632 0r

link setup

Add a interface named macsec0 to the system.

The manual writes macsec0 needs the encrypt on option while being created if frames need to be send encrypted. MACsec is about authentication of the neighbours first. Encryption is a additional option that can be disabled and enabled on demand.

Create a MACsec device on link eth0

ip link add link eth0 macsec0 type macsec encrypt on

ip link command shows the new created macsec0interface.

user % ip link show

1: lo: mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: eth0: mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 link/ether 0c:cd:b4:20:00:00 brd ff:ff:ff:ff:ff:ff 3: macsec0@eth0: mtu 1468 qdisc noqueue state DOWN mode DEFAULT group default qlen 1000 link/ether 0c:cd:b4:20:00:00 brd ff:ff:ff:ff:ff:ff

Notice the default settings on the MTU in the output after interface creation

  • eth0 default link MTU size 1500 byte
  • macsec0MACsec link MTU size 1468 byte

Daniil Baturin has created a ENCAPsulation Calculator tool for IP overhead calculation called encapcalc.

Details on options used in the ip macsec command:

  • tx - TX - transmission direction, to neighbour(s).
  • sa 0 - SA - security association index (1-3)
  • pn 1 on - Packet Number starting index. Positive integer value (1 - 65535).
  • key ID KEY - ID range from 1 to 32 hex digits. The MACsec key or the CAK has to be either 32 or 64 hex digits in maximum length depending on the encryption algorithm:
    • 32 hex digits using AES-128
    • 64 hex digits using AES-256

The SCI using iproute2 implementation, in a point to point network scenario, is generated from the port and address, according to the man ip macsec:

SCI := { sci <u64> | port PORT address <lladdr> }

The PORT value range is { 1..65535 }. Port is a local value known to hosts on the link. There is no correlation to other ports on different layers.

The lladdr is the MAC address.

The Wikipedia entry on IEEE802.1AE writes on SCI usage in a point to point link scenario:

... optional LAN-wide Secure Channel Identifier (SCI), which is not required on point-to-point links. ...

It looks to me it is a LAN-wide like SCI based on port and address in the iproute2 implementation. Apparently it is somehow mandatory to define the SCI when implementing MACsec or this is implementation specific detail here for iproute2 and linux. If you know more about this, write

TX

Configure SA secure association on link device. The whole command including all above mentioned variables. That is for the TX.

  • TX
    • MAC address (own MAC implied)
    • port 1
  • sa 0
  • pn 1 on
  • key AAAA 01234567012345670123456701234567

The used key AAAA length chosen to not clutter the output and to distinguish between the key-ID and key-value. The address value entry is implied. Node knows its own MAC address value that is sending to the TX direction.

ip macsec add macsec0 tx sa 0 pn 1 on key AAAA 01234567012345670123456701234567

Half of the configuration, additionally the encryption method is not mentioned here at all while using this command. Which are the defaults? I guess aes-128-gcm. We will see

RX

Add the RX receiving direction of the MACsec configuration. Frames send to this node.

  • RX
    • MAC address 0c:84:85:57:00:00
    • port 1
  • sa 0
  • pn 1
  • key BBBB 89ABCDEF89ABCDEF89ABCDEF89ABCDEF

The MAC address of the directly connected neighbour is needed to configure as a MACsec peer:

Configure a receive channel - SC

ip macsec add macsec0 rx address 0c:84:85:57:00:00 port 1

Configure a receive association - SA

ip macsec add macsec0 rx address 0c:84:85:57:00:00 port 1 sa 0 pn 1 on key BBBB 89ABCDEF89ABCDEF89ABCDEF89ABCDEF

Now put the eth0 link into up state:

ip link set eth0 up

Check the link and verify it is UP

ip link show macsec0

The macsec0 interface should also be now in the state UP if the neighbors side is UP too.

user % ip link show

1: lo: mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: eth0: mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 link/ether 0c:cd:b4:20:00:00 brd ff:ff:ff:ff:ff:ff 3: macsec0@eth0: mtu 1468 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 0c:cd:b4:20:00:00 brd ff:ff:ff:ff:ff:ff

Now proceed with configuring the C2 client.

Here below the configuration process in one file for both nodes C1 and C2:

C1

ip link set eth0 down
modprobe macsec
ip link add link eth0 macsec0 type macsec encrypt on
ip macsec add macsec0 tx sa 0 pn 1 on key AAAA 01234567012345670123456701234567
ip macsec add macsec0 rx address 0c:84:85:57:00:00 port 1
ip macsec add macsec0 rx address 0c:84:85:57:00:00 port 1 sa 0 pn 1 on key BBBB 89ABCDEF89ABCDEF89ABCDEF89ABCDEF
ip addr add 192.0.2.1/30 dev macsec0
ip -6 addr add 2001:db8::a/127 dev macsec0
ip link set eth0 up
ip link set macsec0 up

C2

ip link set eth0 down
modprobe macsec
ip link add link eth0 macsec0 type macsec encrypt on
ip macsec add macsec0 tx sa 0 pn 1 on key BBBB 89ABCDEF89ABCDEF89ABCDEF89ABCDEF
ip macsec add macsec0 rx address 0c:cd:b4:20:00:00 port 1
ip macsec add macsec0 rx address 0c:cd:b4:20:00:00 port 1 sa 0 pn 1 on key AAAA 01234567012345670123456701234567
ip addr add 192.0.2.2/30 dev macsec0
ip -6 addr add 2001:db8::b/127 dev macsec0
ip link set eth0 up
ip link set macsec0 up

At this point MACsec configuration is finished.

Verification

Verify MACsec using the ip macsec show command:

user % ip macsec show

3: macsec0: protect on validate strict sc off sa off encrypt on send_sci on end_station off scb off replay off cipher suite: GCM-AES-128, using ICV length 16 TXSC: 0ccdb42000000001 on SA 0 0: PN 50, state on, key aaaa0000000000000000000000000000 RXSC: 0c84855700000001, state on 0: PN 50, state on, key bbbb0000000000000000000000000000 offload: off

Notice the naming in the output for the direction used

  • TXSC: Transmission Secure Channel
  • RXSC: Receiving Secure Channel
  • PN: Packet Number

ICMPv6 LL

To test the point to point link the needed IP addressing is already in place. Use the IPv6 LL addressing to test the connectivity. Show the IPv6 neighbor address using the ip -6 neighbor show command:

user % ip -6 neighbor show

fe80::e84:85ff:fe57:0 dev eth0 lladdr 0c:84:85:57:00:00 router REACHABLE fe80::e84:85ff:fe57:0 dev macsec0 lladdr 0c:84:85:57:00:00 router REACHABLE 2001:db8::b dev macsec0 lladdr 0c:84:85:57:00:00 router STALE

The neighbor fe80::e84:85ff:fe57:0 IPv6 link-layer address is reachable via eth0 AND macsec0 interface.

This is C2 pinging C1. The command uses explicit naming of the source interface macsec0

user % ping fe80::e84:85ff:fe57:0%macsec0 -c 3

PING fe80::e84:85ff:fe57:0%macsec0(fe80::e84:85ff:fe57:0%macsec0) 56 data bytes 64 bytes from fe80::e84:85ff:fe57:0%macsec0: icmp_seq=1 ttl=64 time=0.811 ms 64 bytes from fe80::e84:85ff:fe57:0%macsec0: icmp_seq=2 ttl=64 time=1.07 ms 64 bytes from fe80::e84:85ff:fe57:0%macsec0: icmp_seq=3 ttl=64 time=1.08 ms   --- fe80::e84:85ff:fe57:0%macsec0 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 0.811/0.986/1.078/0.124 ms

Use wireshark to make a packet capture. This will show following.

user % tshark -r C1-2-C2-ICMPv6-LL.pcapng

1 0.000000 0c:cd:b4:20:00:00 → 0c:84:85:57:00:00 MACSEC 150 MACsec frame 2 0.000564 0c:84:85:57:00:00 → 0c:cd:b4:20:00:00 MACSEC 150 MACsec frame 3 1.001371 0c:cd:b4:20:00:00 → 0c:84:85:57:00:00 MACSEC 150 MACsec frame 4 1.001988 0c:84:85:57:00:00 → 0c:cd:b4:20:00:00 MACSEC 150 MACsec frame 5 2.002901 0c:cd:b4:20:00:00 → 0c:84:85:57:00:00 MACSEC 150 MACsec frame 6 2.003621 0c:84:85:57:00:00 → 0c:cd:b4:20:00:00 MACSEC 150 MACsec frame 7 5.113213 0c:84:85:57:00:00 → 0c:cd:b4:20:00:00 MACSEC 118 MACsec frame 8 5.113718 0c:cd:b4:20:00:00 → 0c:84:85:57:00:00 MACSEC 110 MACsec frame

MACsec is already active on this point-to-point link. The capture above is the ICMPv6 test shown.

As you will have noticed in the previous output using macsec interface the IPv6 LL addressing has been assigned to the macsec0 interface and the identical IPv6 LL addressing is attached to the eth0. If sending ping command to the neighbor LL address using the source interface %eth0, the frames will NOT be encrypted.

IPv6 ICMP

Verify the connectivity by pinging the direclty connected IP neighbor

user % C1 ~ % ping 192.0.2.2 -c 5

PING 192.0.2.2 (192.0.2.2) 1472(1500) bytes of data. 64 bytes from 192.0.2.2: icmp_seq=1 ttl=64 time=0.747 ms 64 bytes from 192.0.2.2: icmp_seq=2 ttl=64 time=0.981 ms 64 bytes from 192.0.2.2: icmp_seq=3 ttl=64 time=0.979 ms 64 bytes from 192.0.2.2: icmp_seq=4 ttl=64 time=1.03 ms 64 bytes from 192.0.2.2: icmp_seq=5 ttl=64 time=1.00 ms   --- 192.0.2.2 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4007ms rtt min/avg/max/mdev = 0.747/0.947/1.027/0.101 ms

The ICMP results show the state from point of view of IP is as it has been when MACsec is active and the link is not adding a 32-byte overhead on top of the IP header itself. Working on a usual L2 MTU size of 1500 bytes.

MACsec stats

Show the stats by using the ip -s macsec show command to see connection specifics and counts:

user % ip -s macsec show

3: macsec0: protect on validate strict sc off sa off encrypt on send_sci on end_station off scb off replay off cipher suite: GCM-AES-128, using ICV length 16 TXSC: 0ccdb42000000001 on SA 0 stats: OutPktsUntagged InPktsUntagged OutPktsTooLong InPktsNoTag InPktsBadTag InPktsUnknownSCI InPktsNoSCI InPktsOverrun 0 0 0 21 0 0 0 0 stats: OutPktsProtected OutPktsEncrypted OutOctetsProtected OutOctetsEncrypted 0 42 0 3712 0: PN 43, state on, key aaaa0000000000000000000000000000 stats: OutPktsProtected OutPktsEncrypted 0 42 RXSC: 0c84855700000001, state on stats: InOctetsValidated InOctetsDecrypted InPktsUnchecked InPktsDelayed InPktsOK InPktsInvalid InPktsLate InPktsNotValid InPktsNotUsingSA InPktsUnusedSA 0 2928 0 0 34 0 0 0 0 0 0: PN 43, state on, key bbbb0000000000000000000000000000 stats: InPktsOK InPktsInvalid InPktsNotValid InPktsNotUsingSA InPktsUnusedSA 34 0 0 0 0 offload: off

Notify the following counters

  • OutOctetEncrypted
  • InOctetsDecrypted

will be raising when encrypted frames are passing and everything is setup correctly.

The ip -s show macsec statistics extensive output is a more lengthy version of the ip macsec show iproute2 command:

user % ip macsec show

3: macsec0: protect on validate strict sc off sa off encrypt on send_sci on end_station off scb off replay off cipher suite: GCM-AES-128, using ICV length 16 TXSC: 0ccdb42000000001 on SA 0 0: PN 49, state on, key aaaa0000000000000000000000000000 RXSC: 0c84855700000001, state on 0: PN 49, state on, key bbbb0000000000000000000000000000 offload: off

High bandwidth interfaces

For high bandwidth interfaces x > 10Gbit/s

  • 40Gbit/s
  • 100Gbit/s
  • 200Gbit/s
  • 400Gbit/s

use the cipher gcm-aes-xpn-128 extended packet number cipher, identified by the xpn. Recommended configuration.

IPv6 LL default metric preference value

If ethernet frames need to be encrypted all of the time, using the linux default IPv6 link layer configuration the routing table will show following output, take a look at the assigned default metric and preference:

user % ip -6 route

2001:db8::a/127 dev macsec0 proto kernel metric 256 pref medium fe80::/64 dev macsec0 proto kernel metric 256 pref medium fe80::/64 dev eth0 proto kernel metric 256 pref medium

Notice all routes have the same pref and metric, after a reboot you have no controll which fe80::/64 prefix appears first in the routing table. The outcome will be random.

To take sure frames are always send using the encrypted interface first, setting on the metric and priority would send frames always via interface macsec0, by lowering the eth0 route values.

user % ip -6 route

2001:db8::a/127 dev macsec0 proto kernel metric 256 pref medium fe80::/64 dev macsec0 proto kernel metric 256 pref medium fe80::/64 dev eth0 proto kernel metric 512 pref low

The metric is set to 512 and preference low on the fe80::/64 prefix on eth0 interface. Setting the preference is specific for IPv6 and setting the IP metric important for IPv4.

This setting needs to be applied to both MACsec running nodes on the point-to-point link.

IPv4 APIPA default metric

Exactly the same lowering the default IP metric applies to the APIPA IPv4 addressing which is used per default on linux distributions.

I did not bother to explain it here additionally. You need to take care of it by yourself setting up MACsec and using the ip route command

The right sequence having minimal impact on current IP routing state would be to first add the lower metric and lower preference route to the routing table:

ip route add fe80::/64 dev eth0 proto kernel metric 512 pref low

Then remove the unneeded route:

ip route del fe80::/64 dev eth0 proto kernel metric 256 pref medium 

Each linux default configuration will be slightly different regarding the default IP route specifics and setup. Setup the desired IP state right on.

This applies to the link and the connected nodes only. LL addressing has little meaning in global IP context.

See also

For a overview of IP specific values read the Administrative Distance on various network operating systems.

References

MACsec terminology

  • PN : Packet Number
  • XPN: Passing cipher gcm-aes-xpn-128 or gcm-aes-xpn-256 to ip link add command using the macsec type requires using the keyword xpn eXtended Packet Number instead of just pn Packet Number
  • CAK: Connectivity Association Key - The long term key associated with a Connectivity Association.
  • SA : Security Association represents a group of station connected via uni-directional Secure Channels
  • SAK: Secure Association Key - The secret key used by and SA.
  • SC : Secure Channel - A security relationship used to provide security guarantees for frames transmitted from one member of a CA to the others. An SC is supported by a sequence of SAs thus allowing the periodic use of fresh keys without terminating the relationship.
  • SCI: Secure Channel Identifier – An identifier for a particular SAK. In the iproute2 implementation on point to point specifically it is the combination of the MAC address and the port number.
  • SL : Short Length