4、MACsec配置实战:Linux下MACsec配置、密钥协商、VLAN集成

好,咱们直接进入正题。MACsec 这东西,说白了就是在以太网帧的尾巴上贴个「安全封条」。你想想看,车载网络里那么多 ECU 在一条总线上喊话,万一哪个节点被篡改了,那可不是闹着玩的。我当年在做一个 T-Box 项目时,就遇到过隔壁实验室的测试设备误发报文,差点把网关搞死机。从那以后,我对链路层加密就特别上心。

4.1 环境准备:你需要什么?

在动手之前,先把家伙事儿备齐。我个人习惯用 Ubuntu 20.04 或更新的版本,内核至少 5.0 以上。为什么?因为老内核的 MACsec 支持有坑,我踩过。

  • 硬件:两台 Linux 主机,或者一台主机加一个虚拟机。网卡得支持 MACsec 卸载功能(比如 Intel i210、i350),否则性能会打折扣。
  • 软件:安装 wpasupplicantlibnl-3-dev。命令很简单:sudo apt install wpasupplicant
  • 内核模块:确认 macsec 模块已加载。lsmod | grep macsec 看看,没有的话就 sudo modprobe macsec
小提示:如果你用的是树莓派或者嵌入式板子,记得编译内核时把 CONFIG_MACSEC 打开。我有一回忘了,折腾了半天才发现模块没编进去。

4.2 手动配置:先跑通再说

咱们先从最原始的方式开始——手动配置密钥。这种方式不依赖任何密钥协商协议,适合调试和验证。

4.2.1 创建 MACsec 设备

假设你的物理网卡是 eth0,IP 是 192.168.1.10/24。我们要在上面创建一个 MACsec 虚拟接口。

# 在主机 A 上
sudo ip link add link eth0 macsec0 type macsec cipher default
sudo ip link set macsec0 up
sudo ip addr add 192.168.1.10/24 dev macsec0

# 在主机 B 上(假设物理网卡也是 eth0,IP 192.168.1.20/24)
sudo ip link add link eth0 macsec0 type macsec cipher default
sudo ip link set macsec0 up
sudo ip addr add 192.168.1.20/24 dev macsec0

嗯,这里要注意:cipher default 默认是 GCM-AES-128。如果你需要 256 位密钥,可以改成 cipher gcm-aes-256。不过车载场景下 128 位已经够用了,别过度设计。

4.2.2 配置安全通道和关联

MACsec 的核心概念是「安全通道(SC)」和「安全关联(SA)」。一个 SC 包含多个 SA,每个 SA 对应一个密钥。咱们先创建一个 SC,再往里塞一个 SA。

# 主机 A 上:配置发送端
sudo ip macsec add macsec0 tx sa 0 pn 1 on key 01 1234567890abcdef1234567890abcdef
sudo ip macsec set macsec0 tx sa 0

# 主机 A 上:配置接收端(对端是 B,MAC 地址假设为 aa:bb:cc:dd:ee:ff)
sudo ip macsec add macsec0 rx port 1 address aa:bb:cc:dd:ee:ff
sudo ip macsec add macsec0 rx port 1 address aa:bb:cc:dd:ee:ff sa 0 pn 1 on key 01 1234567890abcdef1234567890abcdef

等等,别急着复制。你得把 aa:bb:cc:dd:ee:ff 换成主机 B 的真实 MAC 地址。怎么查?ip link show eth0 就能看到。

主机 B 上的配置是对称的,只是 MAC 地址要换成主机 A 的。

关键点:密钥是 16 字节的十六进制串。我这里用的 1234567890abcdef1234567890abcdef 只是演示,生产环境必须用随机数生成器产生。我曾经见过有人把密钥写在脚本里,结果代码泄露了……嗯,不说了。

4.2.3 验证连通性

配置完后,从主机 A ping 主机 B 的 MACsec 接口 IP:

ping -c 4 192.168.1.20

如果能通,恭喜你,MACsec 已经跑起来了。你可以用 ip -s macsec show 查看加密统计信息。看看 InPktsDecryptedOutPktsEncrypted 是不是在增长。

4.3 密钥协商:用 wpa_supplicant 实现 802.1X

手动配密钥太累了,而且密钥不会自动更新。在车载环境里,你不可能让维修工去敲命令行换密钥。所以我们需要 802.1X 密钥协商。

这里我用 wpa_supplicant 来扮演 supplicant 角色。它本来是为 Wi-Fi 设计的,但也能驱动 MACsec。

4.3.1 配置 wpa_supplicant

创建一个配置文件 /etc/wpa_supplicant/macsec0.conf

network={
    key_mgmt=IEEE8021X
    eap=MD5
    identity="user1"
    password="secret123"
    macsec_policy=1
    macsec_integ_only=0
    mka_cak=00112233445566778899aabbccddeeff
    mka_ckn=abcdef1234567890
}

这里 mka_cak 是 Connectivity Association Key,mka_ckn 是 Key Name。这两个参数在预共享密钥模式下是必须的。如果是用 RADIUS 服务器,就不需要手动指定了。

注意:EAP-MD5 并不安全,仅用于测试。生产环境请用 EAP-TLS 或 EAP-AKA。我在一个车厂项目里就强制要求用证书认证,因为 MD5 太容易被破解了。

4.3.2 启动 wpa_supplicant

sudo wpa_supplicant -i macsec0 -c /etc/wpa_supplicant/macsec0.conf -D macsec_linux

加上 -d 参数可以看调试信息。如果看到 MKA: Key server elected 之类的日志,说明密钥协商成功了。

这时候你再 ping 一下,流量就已经是加密的了。而且密钥会定期刷新,默认是每 2 小时一次。你可以通过 mka_life_time 参数调整。

4.4 VLAN 集成:让 MACsec 和 VLAN 共存

车载网络里 VLAN 很常见,比如把摄像头流量和诊断流量隔离开。那 MACsec 和 VLAN 怎么一起用?顺序很重要。

我建议的架构是:先做 VLAN,再做 MACsec。也就是说,在物理网卡上创建 VLAN 子接口,然后在 VLAN 子接口上创建 MACsec 设备。

4.4.1 创建 VLAN 接口

# 在物理网卡 eth0 上创建 VLAN 100
sudo ip link add link eth0 name eth0.100 type vlan id 100
sudo ip link set eth0.100 up

4.4.2 在 VLAN 上叠加 MACsec

# 在 eth0.100 上创建 MACsec 接口
sudo ip link add link eth0.100 macsec0.100 type macsec cipher default
sudo ip link set macsec0.100 up
sudo ip addr add 10.0.100.1/24 dev macsec0.100

这样,VLAN 标签在 MACsec 加密之前就已经打上了。接收端会先解密,再剥离 VLAN 标签。你想想看,如果反过来,先加密再打 VLAN 标签,那交换机就看不到 VLAN 信息了,没法做转发。

方案 封装顺序 适用场景
VLAN over MACsec 先加密,再打 VLAN 标签 交换机需要看到 VLAN 信息做转发
MACsec over VLAN 先打 VLAN 标签,再加密 需要端到端加密,交换机只做透传

我个人更推荐 MACsec over VLAN,因为加密是在终端设备上完成的,中间交换机不需要知道密钥,安全性更高。

避坑指南:我曾经在一个项目里把 VLAN 和 MACsec 的顺序搞反了,结果抓包发现 VLAN 标签是明文的,但 MACsec 的 SecTAG 却不见了。后来查了 IEEE 802.1AE 标准才明白,MACsec 默认不加密 VLAN 标签,只加密 payload。所以顺序一定要想清楚。

4.5 性能调优:别让加密拖慢车速

MACsec 加密会消耗 CPU 资源。在车载环境下,ECU 的算力通常有限。我建议做几件事:

  • 开启硬件卸载:如果网卡支持,用 ethtool -K eth0 macsec-hw-offload on 开启。实测能降低 60% 的 CPU 占用。
  • 调整 MTU:MACsec 会增加 32 字节的开销(SecTAG + ICV)。所以物理网卡的 MTU 要设成 1532,否则大包会被分片。
  • 使用 GCM-AES-128:256 位密钥虽然更安全,但性能下降明显。车载内部网络,128 位足够了。

嗯,差不多就这些。MACsec 配置其实不复杂,但细节很多。你只要记住:密钥别硬编码、VLAN 顺序别搞反、硬件卸载能开就开。做到这三点,基本不会出大问题。