IPsec 配置备忘 Part7 - 证书 II
接 Part2 与 Part6。尝试折腾一下除了“以证书 DN 作为 id”以外的证书使用姿势,如果有错误或者与本文解释相冲突的情况欢迎在评论指出。
IKEv2 证书认证
在 IKEv2 里,一方需要认证另一方基本只需要两样信息,ID
和AUTH
。ID 就是之前配置文件里反复出现的那个,AUTH 一般是使用证书私钥对某些数据的签名,具体细节请参考 RFC。证书则是把两者关联了起来:如果对方给出的 AUTH 能通过证书验证,那么对方就是这份证书所表示的那个人,同时这份证书又是颁发给 ID 的,那么对方就是 ID。
验证者要取得对方的证书有几种方式:
- 管理员可以直接把证书塞进验证者的
/etc
目录里 - 被验证者可以自己把证书发送给验证者(
send_cert = always
参数) - 验证者可以向被验证者请求证书(
send_certreq = yes
参数)。当然被验证者也可以选择不发送证书(send_cert = never
参数),只是验证会失败就是了。
另外如果验证者既不询问证书(send_certreq = no
),被验证者也不主动发送证书(send_cert = ifasked
),验证一样会失败。
strongSwan 在尝试匹配 ID 和证书的时候会检查 Subject DN 和 SubjectAltName (SAN)。我们之前一直在使用 Subject DN,而 SAN 则允许我们使用域名甚至 IP 作为 ID。另外,虽然我一直称呼“域名”或是“IP”,但是实际上只要 SAN 和 ID 匹配即可,这个“域名”到底是不是我们的并没有关系。(当然只有自签才能签出这种证书)
Subject Alternative Name
要颁发带有 SAN 的证书只需要在 tmpl 文件(参见 Part2)中添加如下内容:
# 域名 SAN
dns_name="san.hosta.com"
# IP 地址 SAN
ip_address = "fd00::1"
需要注意的是,SAN 是区分类型的,比如上文的 DNS 和 IP,而 IKEv2 使用的 ID 也是分类型的(FQDN,IP,etc.)。类型需要匹配才能认证成功。有的教程会使用形如@xxx.xxx.xx.x
这样的 IP,可能原因是,某些客户端使用 IP 作为 ID 但是却标记为 FQDN,或者是生成证书的时候将 IP 标记成了域名 SAN。这种情况就需要给 IP 添加前缀@
来强制让 strongSwan 将其当作域名 ID。具体的解析规则可见 Identity Parsing 文档。
除了在证书生成上的这些零碎注意点之外,我觉得另一点导致 IKEv2 很难配置的因素是,strongSwan 允许省略很多参数,而不同的平台会给这些被省略的参数提供不同的默认值,导致你以为的设置和程序实际使用的设置出现偏差。更不用说有的平台还有一些稀奇古怪的 BUG。
Android Client w/o DN
这里我们尝试重复 Part6 中的实验,只是不出现 DN,全部用域名代替。同样的,只有有变化的部分才有注释。首先重新生成证书加入 SAN,你只需要重新用 CA 私钥签发服务器证书即可:
1 | cn = "server common name" |
然后先看客户端 Profile 的变化:
1 | jq -n \ |
主要变化之一是省略了 remote.id 并将 remote.addr 从 IP 改成域名。注意这里不是不设置 ID,而是采用客户端的默认值(remote.addr)。和服务器配置中的省略 remote.id(%any)有巨大不同。之二是使用 CA 证书而不是直接使用服务器证书,至于为什么需要设定 certreq 请参考第一段。
再看服务端配置变化:
1 | connections { |
这样我们就配置好使用域名作为 ID 的 strongSwan 服务器了。