MACsec is an IEEE standard for security in wired ethernet LANs. This blog , will give an overview of what MACsec is, how it differs from other security standards, and present some ideas about how it can be used.
- MACsec is a Layer 2 protocol that relies on GCM-AES-128 to offer integrity and confidentiality, and operates over ethernet.
- It can secure all traffic within a LAN, including DHCP and ARP, as well as traffic from higher layer protocols.
- It is an extension to 802.1X provides secure key exchange and mutual authentication for MACsec nodes.
- IPsec (a Layer 3 security protocol) and TLS (a Layer 4 security protocol) offer different guarantees and can be a better fit, depending on the use case.
Introduction
The current landscape of cryptographic network protocols is rather narrow. By default, TCP/IP doesn't offer any security guarantee. Besides TLS and IPSec, most other protocols in use today are proprietary.
MACsec hasn't gained much traction yet, but now with an open source implementation available in the Linux kernel, this is will very likely change.
What is MACsec?
As a layer 2 specification, MACsec can protect not only IP traffic, but also ARP, neighbour discovery, and DHCP. It relies on GCM-AES to ensure the confidentiality and integrity of all the network traffic.
MACsec was standardized in 2006 by IEEE (standard IEEE 802.1AE-2006), but support was only recently added to the mainline Linux kernel (as of 4.6). In MACsec, packets flow over "secure channels", which are supported by "secure associations". The secure associations each use a separate, randomly generated key.
IEEE 802.1X-2010 defines a companion protocol, MACsec Key Agreement (MKA), which provides key exchange and allows mutual authentication of nodes that want to take part in a MACsec connectivity association. On Linux machines, this is implemented in wpa_supplicant. wpa_supplicant uses some authentication token (a pre-shared key, or a username/password pair, similarly to the authentication mechanisms used in WiFi) to establish a session with the authentication server, which can be a switch or a Linux host running hostapd. After authentication, keys are generated and exchanged (over an encrypted channel), and are used to configure the MACsec secured link.
On the wire, a MACsec packet starts with an Ethernet header with EtherType 88E5. This is followed by the MACsec SecTAG, which contains information that help the receiver identify the decryption key, as well as a packet number (for replay protection). After the SecTAG comes the payload, which can be encrypted, and the ICV (Integrity Check Value), which is generated by GCM-AES, and guarantees that the packet was indeed created by a node which was in possession of the key, and hasn't been modified on the way.
Figure An Ethernet frame, before (above) and after (below) MACsec processing and encryption
Architecture of a MACsec network
In a MACsec-protected network, each node has at least one transmit secure channel. This transmit secure channel is associated with an identifier: the secure channel identifier (SCI). The transmit secure channel also stores various configuration parameters, such as whether to perform replay protection, or whether to enable encryption.
Each node which expects to receive traffic sent through a particular transmit secure channel must configure a matching receive secure channel. This receive secure channel must have a SCI corresponding to the SCI of the transmit secure channel of the peer.
Within each secure channel (both transmit and receive), secure associations are defined. The secure associations hold the encryption keys, and are identified by their association number. Another important parameter is associated with each secure association: the packet number. On the transmit side, this packet number is put in the MACsec header and used in the encryption process. On the receive side, the packet number from the MACsec header can be checked against the packet number locally stored in the corresponding secure association to perform replay protection.
Use cases
LAN
The main use case for MACsec is to secure a standard LAN. In this setup, multiple machines connected to the same LAN are configured so that all packets exchanged between them are encrypted and can only be received by these nodes.
In these figures, a red link means that packets are not protected by MACSec. Only grey links are secured by MACsec.
Example LAN setup with a standard switch
In this first setup, the switch is not capable of encrypting frames, but it can forward MACsec-protected frames between ports. MACsec is terminated on the hosts.
An alternative solution is to use a switch which supports MACsec. In that case, MACsec is enabled on the client machines as well as on the switch ports to which these machines are connected. Those access switches often also provide 802.1X services to allow strong authentication, authorization and accounting to occur before finally allowing the client to join the network.
Example LAN setup with a MACsec-capable switch
The second of these LAN setups uses a MACsec-capable switch, but hosts 3 and 4 are not using MACsec. MACsec is terminated on the switch ports.
VXLAN
MACsec is also compatible with VXLAN and other tunneling technologies such as GENEVE and GRETAP. A cloud customer with a virtual private LAN can use MACsec to encrypt all the internal traffic before it leaves the virtual machines. That way the cloud provider cannot peek into the communication between the VMs.
Example Cloud topology with VXLAN
Comparison to other security protocols
IPsec
First of all, MACsec and IPsec operate on different network layers. IPsec works on IP packets, at layer 3, while MACsec operates at layer 2, on ethernet frames. Thus, MACsec can protect all DHCP and ARP traffic, which IPsec cannot secure. On the other hand, IPsec can work across routers, while MACsec is limited to a LAN.
With both MACsec and IPsec, user applications do not need to be modified to take advantage of the security guarantees that these standards provide.
In Red Hat Enterprise Linux, IPsec support is provided by the libreswan package.
SSL/TLS
SSL/TLS operates on yet another layer, namely the fifth (application) layer. Thus securing applications might require application changes, which can prove to be quite problematic.
On the other hand, embedding the cryptographic layer directly into applications also offers some advantages. The software is capable of checking on its own the state of encryption and authenticity based on policies and can react accordingly. Verifying those security properties directly in the application can provide end-to-end security.
In Red Hat Enterprise Linux, SSL/TLS is provided by several libraries like GnuTLS, NSS, OpenJDK/JSSE, and OpenSSL (in alphabetical order).
Configuration example
Going back to the first use case, where MACsec was used in a LAN with a legacy switch. We will create MACsec devices on both machines, and setup channels and encryption keys so that they can communicate.
Note: the MAC addresses in the examples below are the addresses used by the devices in my environment. You will need to replace them with the MAC addresses of the interfaces in your setup.
On the first machine:
host1# ip link show eth0 7: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 42:f8:ad:3a:e6:08 brd ff:ff:ff:ff:ff:ff link-netnsid 0 host1# ip link add link eth0 macsec0 type macsec encrypt on host1# ip link show macsec0 8: macsec0@eth0: <BROADCAST,MULTICAST> mtu 1468 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 42:f8:ad:3a:e6:08 brd ff:ff:ff:ff:ff:ff host1# ip macsec show 8: 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: 42f8ad3ae6080001 on SA 0
And similarly, on the second machine:
host2# ip link show eth0 7: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 32:53:41:bd:7c:27 brd ff:ff:ff:ff:ff:ff link-netnsid 0 host2# ip link add link eth0 macsec0 type macsec encrypt on host2# ip link show macsec0 8: macsec0@eth0: <BROADCAST,MULTICAST> mtu 1468 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 32:53:41:bd:7c:27 brd ff:ff:ff:ff:ff:ff host2# ip macsec show 8: 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: 325341bd7c270001 on SA 0
We can now add matching receive channels on both machines:
host1# ip macsec add macsec0 rx port 1 address 32:53:41:bd:7c:27 host1# ip macsec show 8: 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: 42f8ad3ae6080001 on SA 0 RXSC: 325341bd7c270001, state on
And similarly, on the second machine:
host2# ip macsec add macsec0 rx port 1 address 42:f8:ad:3a:e6:08 host2# ip macsec show 8: 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: 325341bd7c270001 on SA 0 RXSC: 42f8ad3ae6080001, state on
Let's now generate some keys. We need a key for each machine's transmit channel. That same key must be configured on the peer's matching receive channel.
These commands will generate two 128-bits keys, in a format suitable to configure with the ip
command.
# dd if=/dev/urandom count=16 bs=1 2>/dev/null | hexdump | cut -c 9- | tr -d ' \n' ead3664f508eb06c40ac7104cdae4ce5 # dd if=/dev/urandom count=16 bs=1 2>/dev/null | hexdump | cut -c 9- | tr -d ' \n' dffafc8d7b9a43d5b9a3dfbbf6a30c16
We can now configure the transmit keys on the first machine:
host1# ip macsec add macsec0 tx sa 0 pn 1 on key 00 ead3664f508eb06c40ac7104cdae4ce5 host1# ip macsec show 8: 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: 42f8ad3ae6080001 on SA 0 0: PN 1, state on, key 00000000000000000000000000000000 RXSC: 325341bd7c270001, state on
And on the second machine:
host2# ip macsec add macsec0 tx sa 0 pn 1 on key 01 dffafc8d7b9a43d5b9a3dfbbf6a30c16 host2# ip macsec show 8: 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: 325341bd7c270001 on SA 0 0: PN 1, state on, key 01000000000000000000000000000000 RXSC: 42f8ad3ae6080001, state on
We also need to configure the receive keys, so that machine 1 can decrypt the traffic coming from machine 2:
host1# ip macsec add macsec0 rx port 1 address 32:53:41:bd:7c:27 sa 0 pn 1 on key 01 dffafc8d7b9a43d5b9a3dfbbf6a30c16 host1# ip macsec show 8: 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: 42f8ad3ae6080001 on SA 0 0: PN 1, state on, key 00000000000000000000000000000000 RXSC: 325341bd7c270001, state on 0: PN 1, state on, key 01000000000000000000000000000000
And on machine 2, to decrypt traffic coming from machine 1:
host2# ip macsec add macsec0 rx port 1 address 42:f8:ad:3a:e6:08 sa 0 pn 1 on key 00 ead3664f508eb06c40ac7104cdae4ce5 host2# ip macsec show 8: 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: 325341bd7c270001 on SA 0 0: PN 1, state on, key 01000000000000000000000000000000 RXSC: 42f8ad3ae6080001, state on 0: PN 1, state on, key 00000000000000000000000000000000
Our MACsec links are now ready, we can enable them and add IP addresses on both machines:
host1# ip link set macsec0 up host1# ip addr add 10.1.0.1/24 dev macsec0
host2# ip link set macsec0 up host2# ip addr add 10.1.0.2/24 dev macsec0
All the traffic between machines 1 and 2 using the addresses 10.1.0.1 and 10.1.0.2 will be protected by MACsec.
If you send some traffic directly on eth0, using the IP address configured on that interface, that traffic won't be protected.
You can still use eth0 to communicate with machines that are not configured to use MACsec, or to connect to other networks.
Limitations
As stated earlier, MACsec only operates on layer 2, so it can only protect a single LAN, and offers no protection when traffic is routed. This single LAN can be a physical LAN, or a virtual LAN, such as those provided by overlay network technologies like VXLAN, GENEVE, etc.
MACsec also cannot protect against malicious layer 3 traffic coming from a different network interface, on a machine connected to multiple LANs. For example, attacks that rely on forcing traffic to leave from other interfaces, using ARP spoofing or IP redirects, cannot be prevented using MACsec alone. As always with security-related matters, careful configuration is necessary to eliminate flaws that lead to a weakening of the entire setup.
Conclusion
MACsec was standardized 10 years ago, but has only made its way into the Linux kernel a few months ago. We hope it will see further adoption, both in use cases we had in mind when we decided to write this implementation and in new setups.
Since MACsec provides different security properties than those of other cryptographic protocols, it might enable the use of strong encryption in cases where it would not have been convenient before.
We are still working on integration with other components (mainly NetworkManager and wpa_supplicant), and further improvements to the kernel parts.
Last updated: February 22, 2024