xfrm 篇 假定 policy/state 已经在内核里。生产里这些对象几乎总由 IKE 守护进程写入。本系列用户态主线是 strongSwan(与 VPN 工程对比 的 swanctl 方言一致);Libreswan 同属 IKEv2→xfrm 阵营,仅作对照,不双主线。
一、进程与接口
| 组件 | 角色 |
|---|---|
| charon | IKE 守护进程:状态机、认证、密钥派生、对内核安装 SA |
| swanctl | 配置与控制 CLI(现代推荐);经 VICI 与 charon 对话 |
| kernel-netlink | 插件:用 XFRM netlink 写 ip xfrm
可见的对象 |
旧 ipsec.conf / starter |
遗留路径;新部署优先 swanctl |
flowchart LR
conf["swanctl conf"] --> vici["VICI"]
vici --> charon["charon"]
charon -->|"IKE UDP/500 or 4500"| peer["peer IKE"]
charon --> nl["kernel-netlink"]
nl --> xfrm["xfrm policy/state"]
排障第一原则:swanctl 视图与 ip xfrm
视图必须同时看。只信一侧会漏「用户态
ESTABLISHED、内核无 state」或「内核有残留 SA、用户态已
teardown」。
二、配置模型:connection 与 child
swanctl 把一座隧道拆成:
- connection:IKE SA 参数——版本、地址、本地/远端认证、IKE proposals、rekey 时间。
- children:Child
SA——
local_ts/remote_ts、ESP proposals、start_action(trap/start)、DPD 动作等。
站点互联示例结构(与第 75 篇同构,字段语义对齐 RFC):
connections {
site-a-to-site-b {
version = 2
local_addrs = 203.0.113.1
remote_addrs = 198.51.100.1
proposals = aes256gcm16-x25519-sha256
local {
auth = pubkey
certs = server-cert.pem
id = vpn-site-a.example.com
}
remote {
auth = pubkey
id = vpn-site-b.example.com
}
children {
site-to-site {
esp_proposals = aes256gcm16-x25519
local_ts = 10.1.0.0/16
remote_ts = 10.2.0.0/16
start_action = trap
dpd_action = restart
}
}
}
}映射到本系列概念:
| swanctl | 协议 / 内核 |
|---|---|
proposals |
IKE_SA_INIT 的 SA 载荷 |
esp_proposals |
Child SA 提议 |
local_ts / remote_ts |
TSi / TSr → xfrm policy 选择器 |
auth / certs /
id |
IKE_AUTH 身份与 AUTH 方法 |
start_action = trap |
感兴趣流触发获取(策略 trap) |
PSK 部署把 auth = psk 与
secrets { ike-... } 配齐即可;证书部署还要
CA、实体证书与私钥路径正确——故障常在 ID 与证书 SAN
不一致,而不是 ESP 算法。
三、安装到内核的时刻
典型时序:
swanctl --load-all(或单元启动)把连接装入 charon。- 触发(trap 流量 /
swanctl --initiate)后走 IKE_SA_INIT + IKE_AUTH。 - 派生密钥(第 3 篇)后,kernel-netlink add policy + add state。
swanctl --list-sas显示ESTABLISHED/ ChildINSTALLED;同时ip xfrm state出现对应 SPI。
Rekey:charon 按 rekey_time 发
CREATE_CHILD_SA,再替换 state;硬超时删除旧 SPI。若只看到
swanctl 更新而 ip xfrm 仍是旧
SPI,查插件错误日志与 netns 是否装错。
四、常用控制命令
swanctl --load-all
swanctl --list-conns
swanctl --list-sas
swanctl --list-pols
swanctl --initiate --child site-to-site
swanctl --terminate --ike site-a-to-site-b与内核对照:
ip xfrm state
ip xfrm policy
ip -s xfrm state # 计数是否随业务增长日志:charon 的 auth/IKE
失败原因(NO_PROPOSAL_CHOSEN、AUTHENTICATION_FAILED、TS
收窄失败)优先于盲目改 ESP 算法。
五、与 Libreswan 的一句话对照
两者都实现 IKEv2 并向 Linux xfrm 装
SA。配置语言与守护进程名不同(pluto /
ipsec.conf 等)。本系列命令与示例统一
swanctl;迁移时只翻译「连接 / 子 SA / 提议 /
TS」,不要假设文件名兼容。
六、本文边界
- 不展开每个 charon 插件(eap-*, bypass-lan, farp…)的百科。
- 不在本机未安装 strongSwan 时伪造
swanctl --list-sas输出;完整 PSK netns + charon 流程以发行版包可用为前提,数据面对象形态已由 第 5/7 篇 的手工 xfrm 实验覆盖。 - 证书生命周期(ACME、自动化轮换)只点到故障面,不写 PKI 全书。
下一篇把 排障与故障模式 收成可复现步骤。
参考资料
工程
- strongSwan 文档:swanctl、vici、kernel-netlink。
- VPN 工程对比 · strongSwan 配置
站内
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
IPSec / IKEv2 深度系列:从正确分层到 Linux xfrm
作为 WireGuard 系列的对照续作:拆解 RFC 4301 的 SPD/SAD、IKEv2 握手与密钥树、ESP/NAT-T、Linux 6.6 xfrm 与 strongSwan 落盘,并以形式化分析与后量子混合 KE 收束选型边界。
【IPSec】IKEv2 握手:IKE_SA_INIT 与 IKE_AUTH
RFC 7296 用两个交换、四条消息建立 IKE SA 并捎带首个 Child SA。本文按载荷语义拆开 IKE_SA_INIT / IKE_AUTH,说明 PSK 与证书 AUTH、Cookie 抗 DoS 边界,以及和 WireGuard 1.5 RTT 确认的差异。
【IPSec】密钥派生与 Child SA
从 SKEYSEED 与 prf+ 展开 IKEv2 密钥树,说明 SK_d/SK_e/SK_a 如何喂给 Child SA,以及 CREATE_CHILD_SA、流量选择器与 rekey 改写了哪些运行时对象。
【IPSec】Linux xfrm:从策略查找到加解密
把 RFC 4301 的 SPD/SAD 映射到 Linux 6.6 的 xfrm policy/state:查看出站 xfrm_lookup、入站策略检查与 ip xfrm 观测面,并给出本机 netns 下手工安装 ESP 的对照实验入口。