内核里的 IPsec
Linux 把 IPsec 实现在内核 XFRM 子系统里:协商出来的一组参数(SPI、算法、密钥、生存期)称为 SA,存在 state 表;哪些流量需要被加密、按什么方向处理,写在 policy 表里。strongSwan、Libreswan 这些只是上层管理面,负责跑 IKE、算密钥,然后把结果下发给内核。因此当管理面显示已连接、业务却不通时,必须回到内核视角检查 state 与 policy 是否真的装好,以及计数是否在增长。
基本信息
| state | 内核 SA:SPI、加密与完整性算法、字节与包计数 |
|---|---|
| policy | 选择符与方向:dir in/out/fwd,决定哪些流量进隧道 |
| 查看工具 | ip xfrm state、ip xfrm policy、ip -s xfrm state |
| 事件观察 | ip xfrm monitor 实时看 SA 增删 |
| 权限要求 | 需要 root 或具备相应网络管理能力 |
典型使用场景
- 隧道显示已建立但业务不通:确认 state 是否真的下发到内核
- 单向不通:对比两个方向的字节与包计数,找出被丢的方向
- 策略冲突排查:多条 policy 的选择符重叠时确认匹配顺序
- 更换加密算法后验证:kernel 中实际生效的算法与配置是否一致
- 抓包对不上:确认内核是否把报文送进了 ESP 处理路径
检查命令
检查命令
ip -s xfrm state # 看 SA 及字节/包计数
ip xfrm policy # 看策略方向与选择符
ip xfrm state list | grep -A3 'proto esp' # 只看 ESP 相关条目
ip xfrm monitor # 实时观察 SA 新增与删除事件
# strongSwan 侧对照
swanctl --list-sas # 管理面状态,异常时与内核对比输出字段读法
| 字段 | 含义 | 正常与异常 |
|---|---|---|
| src/dst | SA 两端的隧道地址 | 与配置的公网地址不符说明选错了源接口 |
| proto/spi | 封装协议与安全参数索引 | 两端 SPI 应匹配同一对 SA |
| sel | 选择符,即被保护的流量范围 | 过窄会导致部分业务未加密,过宽会误加密 |
| bytes/packets | 加解密计数 | 方向上一侧长期为零即为单向不通 |
| dir | 策略方向 in/out/fwd | 缺 in 或 out 会导致对应方向流量被丢 |
state 与 policy 是两套独立的表:有 state 没 policy,报文不会进隧道;有 policy 没 state,内核会因找不到 SA 而丢弃并可能触发重新协商。
多条 policy 的选择符存在包含关系时,处理顺序会影响结果;调整策略时应先记录当前条目,避免改动后部分流量落到错误的策略上。