strongSwan 5.9.5 常用 CLI 命令详解

strongSwan 5.9.5 日常运维三套命令工具实测详解:swanctl 命令树、配置装载、隧道生命周期、诊断统计逐条真实回显,ipsec 遗留命令对照迁移(含 PSK 排障实测),pki 证书工具链与四层验证组合拳,附 7 条实测 FAQ。

strongSwanVPNCLI命令运维2026/10/20

strongSwan 5.9.5 常用 CLI 命令详解

目标:把 strongSwan 日常运维要用的三套命令工具——swanctl(当前主控面)、ipsec(遗留 starter 线)、pki(证书签发)——逐条讲清:每条命令的用途、常用选项、真实回显与排障用法。全部回显在两台 5.9.5 网关的真实站点到站点隧道上实测采集,命令树与帮助文本直接取自实测环境。安装与配置背景见《Ubuntu 22.04 安装 strongSwan 指南》《strongSwan 5.9.5 配置参数详解》。

一、环境信息

  • 实测时间:2026-10-20;版本:strongSwan 5.9.5-2ubuntu2.8(Ubuntu 22.04 jammy)
  • 实测拓扑:网关 moon(10.89.57.11,moon.quzuo.lab,网段 192.168.30.0/24)↔ 网关 sun(10.89.57.12,sun.quzuo.lab,网段 192.168.40.0/24),IKEv2 证书认证主线连接 net-30-40,PSK 扩展连接 net-psk,自签 CA quzuo Lab Root CA
  • 三套工具的入口(jammy 实测包来源):
命令控制通道所在包地位
swanctlVICI(Unix 套接字 /var/run/charon.vici)strongswan-swanctl当前主控面,官方推荐
ipsec(starter/stroke 线)stroke(/var/run/charon.ctl)strongswan-starter遗留体系,5.9.5 仍完整可用
pki本地离线证书工具strongswan-pkiX.509 签发链工具集

⚠️ 6.1.0 起 ipsec 命令与 starter 默认不再构建(详见《strongSwan 6.1.0 介绍与选型指南》),新运维脚本应统一落位 swanctl;本篇第六节给出两套命令的映射关系,便于从老文档迁移。

二、swanctl 命令树总览

swanctl --help 实测(头部节选,全文 26 条子命令,均可 swanctl <command> --help 看单条帮助):

strongSwan 5.9.5 swanctl
loaded plugins: aesni aes rc2 sha2 sha1 md5 mgf1 random nonce x509 revocation constraints pubkey pkcs1 pkcs7 pkcs8 pkcs12 pgp dnskey sshkey pem openssl fips-prf gmp agent xcbc hmac gcm drbg
usage:
  swanctl --reload-settings  (-r)  reload daemon strongswan.conf
  swanctl --stats            (-S)  show daemon stats information
  swanctl --version          (-v)  show version information
  swanctl --log              (-T)  trace logging output
  swanctl --load-pools       (-a)  (re-)load pool configuration
  swanctl --load-creds       (-s)  (re-)load credentials
  swanctl --load-conns       (-c)  (re-)load connection configuration
  swanctl --load-authorities (-b)  (re-)load authority configuration
  swanctl --load-all         (-q)  load credentials, authorities, pools and connections
  swanctl --flush-certs      (-f)  flush cached certificates
  swanctl --list-algs        (-g)  show loaded algorithms
  swanctl --list-pools       (-A)  list loaded pool configurations
  swanctl --list-certs       (-x)  list stored certificates
  swanctl --list-conns       (-L)  list loaded configurations
  swanctl --list-authorities (-B)  list loaded authority configurations
  swanctl --list-pols        (-P)  list currently installed policies
  swanctl --monitor-sa       (-m)  monitor for IKE_SA and CHILD_SA changes
  swanctl --list-sas         (-l)  list currently active IKE_SAs
  swanctl --install          (-p)  install a trap or shunt policy
  swanctl --uninstall        (-u)  uninstall a trap or shunt policy
  swanctl --redirect         (-d)  redirect an IKE_SA
  swanctl --rekey            (-R)  rekey an SA
  swanctl --terminate        (-t)  terminate a connection
  swanctl --initiate         (-i)  initiate a connection
  swanctl --counters         (-C)  list or reset IKE event counters
  swanctl --help             (-h)  show usage information

命令分五组:

分组代表命令干什么
配置装载--load-all --load-conns --load-creds --load-pools --load-authorities把 /etc/swanctl/ 下配置压入 charon
状态查询--list-sas --list-conns --list-certs --list-pools --list-algs --list-pols --stats --version只读,随时可跑
生命周期--initiate --terminate --rekey --redirect --install --uninstall建/拆/重协商隧道与策略
监控流--monitor-sa --log --counters长驻输出,Ctrl-C 退出
缓存/重载--flush-certs --reload-settings清理证书缓存、热重载守护进程 strongswan.conf

常用全局选项:--uri(连别的 VICI 套接字,远程管理用)、--raw(输出原始 VICI 消息,便于脚本解析)、--timeout(initiate 等待秒数)、--noprompt(私钥加密口令交互禁用,自动化必备)。

三、配置装载与凭据命令

3.1 swanctl --load-all

一条命令装载凭据+连接+池+CA(等价于依次执行 load-creds/load-authorities/load-pools/load-conns),实测(moon 侧):

loaded certificate from '/etc/swanctl/x509/moon-cert.pem'
loaded certificate from '/etc/swanctl/x509ca/ca-cert.pem'
loaded RSA key from '/etc/swanctl/private/moon-key.pem'
no authorities found, 0 unloaded
no pools found, 0 unloaded
loaded connection 'net-30-40'
successfully loaded 1 connections, 0 unloaded

解读:证书/私钥按文件装载;no authorities found 提示 authorities 段为空(本系列信任锚直接用 x509ca 目录,合法);loaded connection 'net-30-40' 说明连接进入 charon。改配置后必须重跑,swanctl 不会自动感知文件变化。

带池与 PSK 环境的装载回显(实测):

loaded ike secret 'ike-quzuo'
loaded pool 'rw-pool'
successfully loaded 1 pools, 0 unloaded
loaded connection 'net-30-40'
successfully loaded 1 connections, 0 unloaded

💡 技术拓展:--load-conns 与 --load-all 的区别

--load-all 是全量装载,还会清掉 charon 中已不在配置文件里的"孤儿"连接(回显里 0 unloaded 表示没有孤儿被卸载);--load-conns 只增改连接不清理。批量改完配置用 --load-all,语义最干净。

3.2 swanctl --list-certs

查看 charon 已装载的证书(实测节选):

List of X.509 End Entity Certificates

  subject:  "C=CN, O=quzuo Lab, CN=moon.quzuo.lab"
  issuer:   "C=CN, O=quzuo Lab, CN=quzuo Lab Root CA"
  validity:  not before Oct 20 11:14:10 2026, ok
             not after  Feb 01 11:14:10 2030, ok (expires in 1199 days)
  serial:    44:06:eb:b2:c8:34:cb:69
  altNames:  moon.quzuo.lab, 10.89.57.11
  flags:     serverAuth 
  authkeyId: c8:ad:64:26:ba:96:f1:69:c0:b7:7c:4b:68:6f:c7:ea:bf:57:f8:de
  subjkeyId: d0:64:99:6a:65:01:44:96:6a:d4:2e:26:59:6c:33:ee:ae:d3:73:8d
  pubkey:    RSA 2048 bits, has private key
  keyid:     2f:cb:15:c7:04:3b:3a:6f:1e:eb:cc:a7:36:3e:90:0c:7e:3e:27:e4
  subjkey:   d0:64:99:6a:65:01:44:96:6a:d4:2e:26:59:6c:33:ee:ae:d3:73:8d

CA 证书以 List of X.509 CA Certificates 段单列。排障口诀:--list-certs 里看不到的证书,认证时一定用不了;flags 行可见 EKU(serverAuth),altNames 行就是身份匹配的落点。

3.3 缓存清理与设置重载:--flush-certs / --reload-settings

$ swanctl --flush-certs
(静默成功,无输出)
$ swanctl --reload-settings
reloaded

实测:--flush-certs 清空 charon 的证书缓存,成功即静默;--reload-settings 热重载守护进程侧 strongswan.conf,回显仅一行 reloaded。换证书/换 CA 的标准流程:放新文件 → --flush-certs → --load-all → --list-certs 确认。

3.4 swanctl --list-pools / --list-conns

$ swanctl --list-pools
rw-pool              10.3.0.0                            0 / 0 / 254

(三段数字 = 在线 / 正使用 / 容量。)--list-conns 输出连接的本地/远程认证配置与流量选择器摘要,用于核对 --load-conns 后的生效配置。

四、隧道生命周期命令

4.1 swanctl --initiate

发起 IKE_SA 与 CHILD_SA(实测主线回显,节选):

[IKE] initiating IKE_SA net-30-40[1] to 10.89.57.12
[CFG] selected proposal: IKE:AES_CBC_256/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_2048
[IKE] authentication of 'moon.quzuo.lab' (myself) with RSA_EMSA_PKCS1_SHA2_256 successful
...
[IKE] CHILD_SA net-30-40{1} established with SPIs cc4a9223_i c2b63dc2_o and TS 192.168.30.0/24 === 192.168.40.0/24
initiate completed successfully

常用选项:--child <name>(子 SA 名)、--ike <name>(复用某条 IKE_SA)、--timeout <s>(等待上限)、--force replace(替换已有)。两个实测细节:

  • IKE_SA 已存在时,--initiate --child 只补建 CHILD_SA(实测日志为 CREATE_CHILD_SA request 而非完整 IKE_AUTH);
  • --timeout 是 initiate 的等待上限;脚本里用退出码判断成败。另注意区分:服务未起时任何 swanctl 命令都会报 Error: connecting to 'default' URI failed: No such file or directory(实测,根因见 Q1),与隧道协商超时无关。

4.2 swanctl --list-sas(核心状态命令)

net-30-40: #1, ESTABLISHED, IKEv2, 15d94f3226fe7474_i* fe730fef042176c7_r
  local  'moon.quzuo.lab' @ 10.89.57.11[4500]
  remote 'sun.quzuo.lab' @ 10.89.57.12[4500]
  AES_CBC-256/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_2048
  established 14s ago, rekeying in 13485s
  net-30-40: #1, reqid 1, INSTALLED, TUNNEL, ESP:AES_GCM_16-256
    installed 14s ago, rekeying in 3481s, expires in 3946s
    in  cc4a9223,      0 bytes,     0 packets
    out c2b63dc2,      0 bytes,     0 packets
    local  192.168.30.0/24
    remote 192.168.40.0/24

读法:第一层是 IKE_SA(ESTABLISHED + IKE 密码套件),第二层是 CHILD_SA(INSTALLED, TUNNEL + ESP 套件 + 双向 SPI + 字节/包计数 + 流量选择器)。压测后 bytes/packets 增长即真实隧道流量的最直接证据(实测打流后):

    in  cc4a9223,    252 bytes,     3 packets,     0s ago
    out c2b63dc2,    252 bytes,     3 packets,     0s ago

4.3 swanctl --terminate / --rekey

$ swanctl --terminate --child net-30-40
[IKE] closing CHILD_SA net-30-40{2} with SPIs ca73a293_i (0 bytes) c3e080a9_o (0 bytes) and TS 192.168.30.0/24 === 192.168.40.0/24
[IKE] sending DELETE for ESP CHILD_SA with SPI ca73a293
[ENC] generating INFORMATIONAL request 4 [ D ]
[NET] sending packet: from 10.89.57.11[4500] to 10.89.57.12[4500] (88 bytes)
[NET] received packet: from 10.89.57.12[4500] to 10.89.57.11[4500] (88 bytes)
[ENC] parsed INFORMATIONAL response 4 [ D ]
[IKE] received DELETE for ESP CHILD_SA with SPI c3e080a9
[IKE] CHILD_SA closed
terminate completed successfully
$ swanctl --terminate --ike net-30-40
(连 IKE_SA 一起拆,上面这条只拆子 SA)
$ swanctl --rekey --child net-30-40
rekey completed successfully

实测:initiate/terminate/rekey 这类操作型命令会把协商过程日志流式打到 stdout,最后一行是执行结果;--rekey 本身只打印一行 rekey completed successfully,新 SA 用 --list-sas 核实。

实测排障重点:一侧 terminate 后隧道可能"自己活过来"——对端 dpd_action = restart 会自动重建(本次实测中子 SA 被拆后,sun 侧发起重建,--list-sas 里 SPI 全新)。要真正下线请两侧改配置(dpd_action 改 clear 后 --load-conns),详见配置篇 FAQ。

4.4 swanctl --install / --uninstall(陷阱策略)

$ swanctl --install --child net-30-40
install completed successfully
$ swanctl --uninstall --child net-30-40
uninstall completed successfully

--install 只装内核 XFRM 陷阱策略(有流量才协商),不建链。验证用 ip xfrm policy(见第七节),实测策略带 reqid 1 与 proto esp ... mode tunnel 模板。

4.5 监控流:--log / --monitor-sa / --counters

$ swanctl --log
10[CFG] vici initiate CHILD_SA 'net-30-40'
07[IKE] establishing CHILD_SA net-30-40{4}
07[ENC] generating CREATE_CHILD_SA request 3 [ SA No KE TSi TSr ]
07[NET] sending packet: from 10.89.57.11[4500] to 10.89.57.12[4500] (472 bytes)
...
(Ctrl-C 或断开时:disconnecting...)

--log 实时流式输出 charon 全部日志(等价于 ipsec restart 前台化的日志面,临时排障神器的存在);--monitor-sa 流式输出 SA 状态变化事件(无事件时静默等待,实测超时打印 disconnecting... 退出);--counters 输出计数器(实测片段):

global:
  ike-rekey-init        : 0
  ike-rekey-resp        : 0
  child-rekey           : 0
  invalid               : 0
  invalid-spi           : 0
  ike-init-in-req       : 0
  ike-init-in-resp      : 0
  ike-init-out-req      : 0
  ike-init-out-resp     : 0

五、诊断与统计命令

5.1 swanctl --stats

uptime: 24 seconds, since Oct 20 11:36:48 2026
worker threads: 16 total, 11 idle, working: 4/0/1/0
job queues: 0/0/0/0
jobs scheduled: 3
IKE_SAs: 1 total, 0 half-open
mallinfo: sbrk 3190784, mmap 0, used 1404848, free 1785936
loaded plugins: charon aesni aes rc2 sha2 sha1 md5 mgf1 random nonce x509 revocation constraints pubkey pkcs1 pkcs7 pkcs8 pkcs12 pgp dnskey sshkey pem openssl fips-prf gmp agent xcbc hmac gcm drbg attr kernel-netlink resolve socket-default connmark stroke vici updown eap-mschapv2 xauth-generic counters

一把抓:运行时长、线程池水位(busy/idle)、half-open 数(DoS/网络异常时飙升)、插件清单(stroke 与 vici 同载,证实 5.9.5 双控制面并存)。

5.2 swanctl --list-algs

输出按用途分段(完整分段清单实测为:encryption, integrity, aead, hasher, prf, xof, drbg, dh, rng, nonce-gen),各段条目格式为 算法名[实现插件](实测节选):

encryption:
  AES_CBC[aesni]
  AES_ECB[aesni]
  AES_CTR[aesni]
  RC2_CBC[rc2]
  3DES_CBC[openssl]
  AES_CFB[openssl]
  CAMELLIA_CBC[openssl]
  CAST_CBC[openssl]
  BLOWFISH_CBC[openssl]
  DES_CBC[openssl]
  DES_ECB[openssl]
aead:
  AES_CCM_8[aesni]
  AES_CCM_12[aesni]
  AES_CCM_16[aesni]
  AES_GCM_8[aesni]
  AES_GCM_12[aesni]
  ...
dh:
  MODP_3072[openssl]
  MODP_4096[openssl]
  MODP_6144[openssl]
  MODP_8192[openssl]
  MODP_2048[openssl]
  ...

写 proposals/esp_proposals 之前先看这里——列表里没有的算法写进提案必然 NO_PROPOSAL_CHOSEN。

5.3 swanctl --version / --list-pols

$ swanctl --version
strongSwan swanctl 5.9.5

--list-pols 输出 swanctl 装入的内核策略(空载时静默)。

六、ipsec 遗留命令对照(stroke 线)

6.1 命令树

ipsec --help 实测(全文照录,17 组命令名覆盖 40+ 子命令):

ipsec command [arguments]

Commands:
	start|restart [arguments]
	update|reload|stop
	up|down|route|unroute <connectionname>
	down-srcip <start> [<end>]
	status|statusall [<connectionname>]
	listalgs|listpubkeys|listcerts [--utc]
	listcacerts|listaacerts|listocspcerts [--utc]
	listacerts|listgroups|listcainfos [--utc]
	listcrls|listocsp|listplugins|listall [--utc]
	listcounters|resetcounters [name]
	leases [<poolname> [<address>]]
	rereadsecrets|rereadcacerts|rereadaacerts
	rereadocspcerts|rereadacerts|rereadcrls|rereadall
	purgecerts|purgecrls|purgeike|purgeocsp
	scepclient|pki
	stroke
	version

Refer to the ipsec(8) man page for details.
Some commands have their own man pages, e.g. pki(1) or scepclient(8).

高频子集与用途:

命令用途对应 swanctl 侧
ipsec start/stop/restart拉起/停止 starter + charonsystemctl start/stop strongswan-starter
ipsec update / reload重读 ipsec.conf(不断链 / 重置全部)swanctl --load-conns / --load-all
ipsec up <conn> / down <conn>建/拆隧道swanctl --initiate / --terminate
ipsec status / statusall看 SA 状态(简/全)swanctl --list-sas
ipsec rereadsecrets / rereadall重读 ipsec.secrets/证书swanctl --load-creds
ipsec listcerts / listall看证书缓存swanctl --list-certs

6.2 statusall 实测

Status of IKE charon daemon (strongSwan 5.9.5, Linux 6.8.0-138-generic, x86_64):
  uptime: 4 minutes, since Oct 20 11:12:23 2026
  malloc: sbrk 3198976, mmap 0, used 1444176, free 1754800
  worker threads: 11 of 16 idle, 5/0/0/0 working, job queue: 0/0/0/0, scheduled: 6
  loaded plugins: charon aesni aes rc2 sha2 sha1 md5 mgf1 random nonce x509 revocation constraints pubkey pkcs1 pkcs7 pkcs8 pkcs12 pgp dnskey sshkey pem openssl fips-prf gmp agent xcbc hmac gcm drbg attr kernel-netlink resolve socket-default connmark stroke vici updown eap-mschapv2 xauth-generic counters
Listening IP addresses:
  10.89.57.11
Connections:
   net-30-40:  10.89.57.11...10.89.57.12  IKEv2, dpddelay=30s
   net-30-40:   local:  [moon.quzuo.lab] uses public key authentication
   net-30-40:    cert:  "C=CN, O=quzuo Lab, CN=moon.quzuo.lab"
   net-30-40:   remote: [sun.quzuo.lab] uses public key authentication
   net-30-40:   child:  192.168.30.0/24 === 192.168.40.0/24 TUNNEL, dpdaction=restart
Security Associations (1 up, 0 connecting):
   net-30-40[1]: ESTABLISHED 77 seconds ago, 10.89.57.11[moon.quzuo.lab]...10.89.57.12[sun.quzuo.lab]
   net-30-40[1]: IKEv2 SPIs: 15d94f3226fe7474_i* fe730fef042176c7_r, rekeying in 3 hours
   net-30-40[1]: IKE proposal: AES_CBC_256/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_2048
   net-30-40{1}:  DELETED, TUNNEL, reqid 1
   net-30-40{1}:   192.168.30.0/24 === 192.168.40.0/24
   net-30-40{2}:  INSTALLED, TUNNEL, reqid 1, ESP SPIs: ca73a293_i c3e080a9_o
   net-30-40{2}:  AES_GCM_16_256/MODP_2048, 0 bytes_i, 0 bytes_o, rekeying in 55 minutes
   net-30-40{2}:   192.168.30.0/24 === 192.168.40.0/24

(老脚本最依赖的输出形态,字段与 --list-sas 等价;实测捕获时刚做完一次子 SA rekey,所以 {1} 已 DELETED、{2} 为新 INSTALLED——正好展示了 rekey 后新老 CHILD_SA 共存的视图。)

6.3 遗留线 PSK 实测与经典坑

用 ipsec.conf + ipsec.secrets 建一条 PSK 隧道的实测(两侧 conn legacy-net + authby=psk,auto=add 后手动 up):

$ ipsec up legacy-net
sending cert request for "C=CN, O=quzuo Lab, CN=quzuo Lab Root CA"
authentication of '10.89.57.11' (myself) with pre-shared key
no shared key found for '10.89.57.11' - '10.89.57.12'
establishing connection 'legacy-net' failed

实测定位:secrets 里写的是 @moon @sun : PSK "legacy-psk-2026",而连接未配 leftid/rightid,本端按 IP 身份去找密钥——错误链完整出现在回显里:先用 10.89.57.11(myself)做 PSK 认证,然后在两端 IP 身份对 10.89.57.11 - 10.89.57.12 里找不到共享密钥。修正 secrets 为 IP 对后再实测:

$ ipsec up legacy-net
CHILD_SA legacy-net{1} established with SPIs c65f141d_i c34df89c_o and TS 192.168.30.0/24 === 192.168.40.0/24
peer supports MOBIKE
connection 'legacy-net' established successfully
$ ipsec status legacy-net
  legacy-net[1]: IKEv2 SPIs: 1528b7cc2ce6c83b_i* d6f461073a2cb76d_r, pre-shared key reauthentication in 2 hours
  legacy-net[1]: IKE proposal: AES_CBC_256/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/MODP_2048
  legacy-net{1}:  INSTALLED, TUNNEL, reqid 1, ESP SPIs: c65f141d_i c34df89c_o
  legacy-net{1}:  AES_GCM_16_256, 0 bytes_i, 0 bytes_o, rekeying in 48 minutes
  legacy-net{1}:   192.168.30.0/24 === 192.168.40.0/24

拆除用 ipsec down legacy-net(对照表见 6.1);ipsec up 成功回显里没有 no shared key 字样、结尾是 connection 'legacy-net' established successfully,这两点可以直接当脚本里的成功判据。

💡 swanctl 侧 PSK 的对应关系:secrets.<n>.id 必须与对端身份逐字一致,语义同这里的 @id,配置写法见配置篇 5.2 节。

七、pki 证书工具

自签 CA → 网关证书的完整实测序列(moon 上操作,全部真实回显):

# 1. 生成 CA 私钥与自签证书
pki --gen --type rsa --size 2048 --outform pem > ca-key.pem
pki --self --ca --lifetime 3650 --in ca-key.pem --type rsa \
    --dn "C=CN, O=quzuo Lab, CN=quzuo Lab Root CA" --outform pem > ca-cert.pem

# 2. 生成网关密钥并签发证书(moon)
pki --gen --type rsa --size 2048 --outform pem > moon-key.pem
pki --pub --in moon-key.pem --type rsa | \
    pki --issue --lifetime 1200 --cacert ca-cert.pem --cakey ca-key.pem \
        --dn "C=CN, O=quzuo Lab, CN=moon.quzuo.lab" \
        --san moon.quzuo.lab --san 10.89.57.11 \
        --flag serverAuth --outform pem > moon-cert.pem

签发过程回显(实测):5.9.5 的 pki --issue 成功时完全静默——stdout/stderr 均无任何输出,退出码 0,证书经 --outform pem 直接进入重定向的输出流。别等回显,产物用文件大小和 --print 核验。

对 sun 网关证书执行 --print 验签(实测):

  subject:  "C=CN, O=quzuo Lab, CN=sun.quzuo.lab"
  issuer:   "C=CN, O=quzuo Lab, CN=quzuo Lab Root CA"
  validity:  not before Oct 20 11:14:19 2026, ok
             not after  Feb 01 11:14:19 2030, ok (expires in 1200 days)
  serial:    41:98:5d:93:72:6e:d0:ac
  altNames:  sun.quzuo.lab, 10.89.57.12
  flags:     
  authkeyId: c8:ad:64:26:ba:96:f1:69:c0:b7:7c:4b:68:6f:c7:ea:bf:57:f8:de
  subjkeyId: 4b:23:f5:ba:4d:12:7f:0b:2d:25:55:ca:e7:5e:2d:2c:1f:2b:ab:ab
  pubkey:    RSA 2048 bits
  keyid:     85:ae:d8:d0:9b:77:bf:2d:a2:63:4c:3f:dd:f7:3d:47:81:17:f8:ef
  subjkey:   4b:23:f5:ba:4d:12:7f:0b:2d:25:55:ca:e7:5e:2d:2c:1f:2b:ab:ab

(注意 sun 证书 flags 行为空——签发它时没加 --flag serverAuth;对比 3.2 节 moon 证书的 flags: serverAuth,两份证书都能完成 IKEv2 认证,EKU 只是声明用途。)

子命令速查:--gen(生成密钥)、--self(自签 CA/根证书)、--pub(从私钥导公钥)、--issue(CA 签发实体证书,--san 决定身份匹配、--flag 决定 EKU)、--print(解析证书/密钥/请求)、--verify(链式验签)、--req(生成 CSR,交第三方 CA 场景用)。身份匹配的两条硬规则实测验证:SAN 优先,DN 回退;remote.id 必须命中 SAN 或 DN,否则 AUTH_FAILED。

💡 技术拓展:SAN 还是 DN?

身份载体写法匹配行为建议
SAN(SubjectAltName)--san moon.quzuo.lab 或 --san 10.89.57.11精确匹配,扩展性最好首选,FQDN+IP 双 SAN
DN(可辨识名)--dn "C=CN, O=..., CN=..."remote.id 写完整 DN 串老设备兼容

本系列证书同时写 FQDN 与 IP 双 SAN,两侧连接分别用 FQDN 身份(主线)与身份化 PSK(扩展线),覆盖两种匹配路径。

八、验证工具链(组合拳)

隧道排障从上到下四层,全部实测可用:

# 1. 控制面状态(swanctl)
swanctl --list-sas

# 2. 监听端口(IKE 500 / NAT-T 4500)
ss -lunp | grep -E ':(500|4500)\b'
UNCONN 0      0            0.0.0.0:4500       0.0.0.0:*    users:(("charon",pid=553,fd=12))
UNCONN 0      0            0.0.0.0:500        0.0.0.0:*    users:(("charon",pid=553,fd=11))
...

# 3. 内核 SA/策略
ip xfrm state | head -2
src 10.89.57.11 dst 10.89.57.12
	proto esp spi 0xc2b63dc2 reqid 1 mode tunnel

# 4. 真实流量与抓包
ping -I 192.168.30.1 -c 3 192.168.40.1
3 packets transmitted, 3 received, 0% packet loss, time 2081ms
rtt min/avg/max/mdev = 0.065/0.071/0.083/0.008 ms
tcpdump -ni eth0 'esp' -c 4
11:16:22.527624 IP 10.89.57.11 > 10.89.57.12: ESP(spi=0xc2b63dc2,seq=0x4), length 120
11:16:22.527658 IP 10.89.57.12 > 10.89.57.11: ESP(spi=0xcc4a9223,seq=0x4), length 120
11:16:23.564598 IP 10.89.57.11 > 10.89.57.12: ESP(spi=0xc2b63dc2,seq=0x5), length 120
11:16:23.564629 IP 10.89.57.12 > 10.89.57.11: ESP(spi=0xcc4a9223,seq=0x5), length 120

分层判责:--list-sas 无 SA → 控制面问题(查日志/证书/密钥);有 SA 而 ip xfrm state 缺 → 内核接口异常(查 kernel-netlink/内核模块);xfrm 有但 ping 不通 → 路由/防火墙/选择器不匹配;ping 通但性能差 → --counters/tcpdump 看分片与封装。

九、常见问题(FAQ)

Q1:任何 swanctl 命令都报 connecting to 'unix:///var/run/charon.vici' failed: No such file or directory? 实测原因:charon 没起。systemctl start strongswan-starter.service(或 ipsec start)后再执行;swanctl 是 VICI 客户端,套接字随守护进程生灭。

Q2:swanctl --initiate --child xxx 只发 CREATE_CHILD_SA,没走完整认证? 实测行为:IKE_SA 已存在时 initiate 复用它只补子 SA。要看完整 IKE_AUTH 协商,先 --terminate --ike 再 initiate(注意对端 dpd_action=restart 会抢着重连,见 Q3)。

Q3:--terminate 后 --list-sas 里隧道又出现? 实测原因:对端 dpd_action = restart 自动重建,SPI 换新。这是配置行为;真要下线两侧改配置,见配置篇 FAQ-3。

Q4:遗留线 ipsec up 报 no shared key found for 'x.x.x.x' - 'y.y.y.y'? 实测原因:ipsec.secrets 的 @id 与连接实际身份(未设 leftid 时为 IP)不匹配,错误信息里的两个 IP 就是它正在找的身份对。用 IP 对写 secrets 或显式配 leftid/rightid,实测修正过程见第六节 6.3。

Q5:--flush-certs/--rereadall 没有任何输出,成功了吗? 实测:成功即静默。用 --list-certs / statusall 验证结果,不要等回显。

Q6:--monitor-sa 一直挂着不退出? 实测行为:长驻监听 SA 事件,无事件即静默等待。脚本里用 timeout 包裹(实测 timeout 3 swanctl --monitor-sa 到点输出 disconnecting... 退出)。

Q7:6.x 还能用 ipsec 命令吗? 6.1.0 源码默认构建不含 starter/stroke,make install 后没有 ipsec 命令;stroke 插件仍可显式启用,但官方方向是 swanctl。新脚本直接落位 swanctl,本篇第六节对照表可用于迁移。

十、参考链接