
strongswan v6.1.0
strongSwan - 基于IPsec的VPN
strongSwan 配置
概述
strongSwan 是一个基于 IPsec 的开源 VPN 解决方案。
本文档只是对 strongSwan swanctl 命令的简短介绍, 它使用了现代的 vici 多功能 IKE 配置接口。已弃用的 ipsec 命令使用传统的 stroke 配置接口,见 这里。 如需更详细的信息,请查阅手册页、我们新的 文档站点 以及旧的 wiki。
快速入门
用户、主机和网关的证书由一个虚构的
strongSwan CA 签发。在我们的示例场景中,CA 证书 strongswanCert.pem
必须存在于所有 VPN 端点上,以便能够认证
对端。对于您的特定 VPN 应用,您既可以使用来自任何第三方 CA 的证书,也可以
使用 strongSwan pki 工具自己生成所需的私钥和证书,
该工具的使用方法将在下面的某个
章节中介绍。
站点到站点场景
在此场景中,两个安全网关 moon 和 sun 将通过在两个网关之间建立的 VPN 隧道,将两个子网 moon-net 和 sun-net 相互连接:
10.1.0.0/16 -- | 192.168.0.1 | === | 192.168.0.2 | -- 10.2.0.0/16
moon-net moon sun sun-net
网关 moon 上的配置:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/moonCert.pem
/etc/swanctl/private/moonKey.pem
/etc/swanctl/swanctl.conf:
connections {
net-net {
remote_addrs = 192.168.0.2
local {
auth = pubkey
certs = moonCert.pem
}
remote {
auth = pubkey
id = "C=CH, O=strongSwan, CN=sun.strongswan.org"
}
children {
net-net {
local_ts = 10.1.0.0/16
remote_ts = 10.2.0.0/16
start_action = trap
}
}
}
}
网关 sun 上的配置:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/sunCert.pem
/etc/swanctl/private/sunKey.pem
/etc/swanctl/swanctl.conf:
connections {
net-net {
remote_addrs = 192.168.0.1
local {
auth = pubkey
certs = sunCert.pem
}
remote {
auth = pubkey
id = "C=CH, O=strongSwan, CN=moon.strongswan.org"
}
children {
net-net {
local_ts = 10.2.0.0/16
remote_ts = 10.1.0.0/16
start_action = trap
}
}
}
}
此场景中使用的本地和远程身份是终端实体证书中包含的 subjectDistinguishedNames。 证书和私钥通过以下命令加载到 charon 守护进程中:
swanctl --load-creds
而
swanctl --load-conns
加载 swanctl.conf 中定义的连接。使用 start_action = trap 时,IPsec 连接会在第一个想要通过隧道的明文负载 IP 数据包出现时自动建立。
主机到主机场景
这是两台没有子网在其后的单主机之间的设置。虽然 IPsec 传输模式足以用于主机到主机的连接,但我们将使用默认的 IPsec 隧道模式。
| 192.168.0.1 | === | 192.168.0.2 |
moon sun
主机 moon 上的配置:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/moonCert.pem
/etc/swanctl/private/moonKey.pem
/etc/swanctl/swanctl.conf:
connections {
host-host {
remote_addrs = 192.168.0.2
local {
auth=pubkey
certs = moonCert.pem
}
remote {
auth = pubkey
id = "C=CH, O=strongSwan, CN=sun.strongswan.org"
}
children {
net-net {
start_action = trap
}
}
}
}
主机 sun 上的配置:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/sunCert.pem
/etc/swanctl/private/sunKey.pem
/etc/swanctl/swanctl.conf:
connections {
host-host {
remote_addrs = 192.168.0.1
local {
auth = pubkey
certs = sunCert.pem
}
remote {
auth = pubkey
id = "C=CH, O=strongSwan, CN=moon.strongswan.org"
}
children {
host-host {
start_action = trap
}
}
}
}
远程访问用户场景
这是一种非常常见的场景:strongSwan 网关为任意数量的远程 VPN 客户端提供服务,这些客户端通常具有动态 IP 地址。
10.1.0.0/16 -- | 192.168.0.1 | === | x.x.x.x |
moon-net moon carol
网关 moon 上的配置:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/moonCert.pem
/etc/swanctl/private/moonKey.pem
/etc/swanctl/swanctl.conf:
connections {
rw {
local {
auth = pubkey
certs = moonCert.pem
id = moon.strongswan.org
}
remote {
auth = pubkey
}
children {
net-net {
local_ts = 10.1.0.0/16
}
}
}
}
远程访问用户 carol 的配置:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/carolCert.pem
/etc/swanctl/private/carolKey.pem
/etc/swanctl/swanctl.conf:
connections {
home {
remote_addrs = moon.strongswan.org
local {
auth = pubkey
certs = carolCert.pem
id = [email protected]
}
remote {
auth = pubkey
id = moon.strongswan.org
}
children {
home {
local_ts = 10.1.0.0/16
start_action = start
}
}
}
}
对于 remote_addrs,选择了主机名 moon.strongswan.org,它将在运行时由 DNS 解析为相应的目标 IP 地址。在此场景中,远程访问用户 carol 的身份是电子邮件地址 [email protected],该地址必须作为 subjectAlternativeName 包含在远程访问用户证书 carolCert.pem 中。
带虚拟 IP 的远程访问用户场景
远程访问用户通常拥有其当前所连接 ISP 分配的动态 IP 地址。为了简化从 moon-net 返回到远程访问客户端 carol 的路由,如果远程访问用户拥有一个从预定义地址池中选择的内部 IP 地址,那将是理想的。
10.1.0.0/16 -- | 192.168.0.1 | === | x.x.x.x | -- 10.3.0.1
moon-net moon carol virtual IP
在我们的示例中,虚拟 IP 地址从地址池 10.3.0.0/16 中选择,可以通过添加以下小节来配置:
pools {
rw_pool {
addrs = 10.3.0.0/16
}
}
将其添加到网关的 swanctl.conf 中,使用以下命令将它们加载到 charon 守护进程中:
swanctl --load-pools
要从该地址池请求 IP 地址,远程访问用户可以使用 IKEv1 模式配置或 IKEv2 配置负载。两者的配置相同:
vips = 0.0.0.0
网关 moon 上的配置:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/moonCert.pem
/etc/swanctl/private/moonKey.pem
/etc/swanctl/swanctl.conf:
connections {
rw {
pools = rw_pool
local {
auth = pubkey
certs = moonCert.pem
id = moon.strongswan.org
}
remote {
auth = pubkey
}
children {
net-net {
local_ts = 10.1.0.0/16
}
}
}
}
pools {
rw_pool {
addrs = 10.30.0.0/16
}
}
远程访问用户 carol 的配置:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/carolCert.pem
/etc/swanctl/private/carolKey.pem
/etc/swanctl/swanctl.conf:
connections {
home {
remote_addrs = moon.strongswan.org
vips = 0.0.0.0
local {
auth = pubkey
certs = carolCert.pem
id = [email protected]
}
remote {
auth = pubkey
id = moon.strongswan.org
}
children {
home {
local_ts = 10.1.0.0/16
start_action = start
}
}
}
}
使用 EAP 认证的远程访问用户场景
这是一种非常常见的场景:strongSwan 网关为任意数量的远程 VPN 客户端提供服务,这些客户端通过基于密码的 扩展认证协议(例如 EAP-MD5 或 EAP-MSCHAPv2)进行身份认证。
10.1.0.0/16 -- | 192.168.0.1 | === | x.x.x.x |
moon-net moon carol
网关 moon 上的配置:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/moonCert.pem
/etc/swanctl/private/moonKey.pem
/etc/swanctl/swanctl.conf:
connections {
rw {
local {
auth = pubkey
certs = moonCert.pem
id = moon.strongswan.org
}
remote {
auth = eap-md5
}
children {
net-net {
local_ts = 10.1.0.0/16
}
}
send_certreq = no
}
}
swanctl.conf 文件还包含一个 secrets 小节,用于定义所有客户端凭据:
secrets {
eap-carol {
id = [email protected]
secret = Ar3etTnp
}
eap-dave {
id = [email protected]
secret = W7R0g3do
}
}
远程访问用户 carol 的配置:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/swanctl.conf:
connections {
home {
remote_addrs = moon.strongswan.org
local {
auth = eap
id = [email protected]
}
remote {
auth = pubkey
id = moon.strongswan.org
}
children {
home {
local_ts = 10.1.0.0/16
start_action = start
}
}
}
}
secrets {
eap-carol {
id = [email protected]
secret = Ar3etTnp
}
}
使用 EAP 身份的远程访问用户场景
通常,客户端 EAP 身份通过 EAP 进行交换,它与外部 IKEv2 身份不同。在此示例中,IKEv2 身份默认为客户端的 IPv4 地址。
10.1.0.0/16 -- | 192.168.0.1 | === | x.x.x.x |
moon-net moon carol
网关 moon 上的配置:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/moonCert.pem
/etc/swanctl/private/moonKey.pem
/etc/swanctl/swanctl.conf:
connections {
rw {
local {
auth = pubkey
certs = moonCert.pem
id = moon.strongswan.org
}
remote {
auth = eap-md5
eap_id = %any
}
children {
net-net {
local_ts = 10.1.0.0/16
}
}
send_certreq = no
}
}
secrets {
eap-carol {
id = carol
secret = Ar3etTnp
}
eap-dave {
id = dave
secret = W7R0g3do
}
}
远程访问用户 carol 的配置:
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/swanctl.conf:
connections {
home {
remote_addrs = moon.strongswan.org
local {
auth = eap
eap_id = carol
}
remote {
auth = pubkey
id = moon.strongswan.org
}
children {
home {
local_ts = 10.1.0.0/16
start_action = start
}
}
}
}
secrets {
eap-carol {
id = carol
secret = Ar3etTnp
}
}
生成证书和 CRL
本节并不是关于如何使用 strongSwan pki 工具的完整教程。它仅列出了一些与您想要生成自己的证书和 CRL 以用于 strongSwan 相关的要点。
生成 CA 证书
pki 语句
pki --gen --type ed25519 --outform pem > strongswanKey.pem
生成一个加密强度为 128 位的椭圆 Edwards-Curve 密钥。 相应的公钥被打包到一个自签名的 CA 证书中, 有效期为 10 年(3652 天)。
pki --self --ca --lifetime 3652 --in strongswanKey.pem \
--dn "C=CH, O=strongSwan, CN=strongSwan Root CA" \
--outform pem > strongswanCert.pem
可以使用以下命令列出该证书:
pki --print --in strongswanCert.pem
subject: "C=CH, O=strongSwan, CN=strongSwan Root CA"
issuer: "C=CH, O=strongSwan, CN=strongSwan Root CA"
validity: not before May 18 08:32:06 2017, ok
not after May 18 08:32:06 2027, ok (expires in 3651 days)
serial: 57:e0:6b:3a:9a:eb:c6:e0
flags: CA CRLSign self-signed
subjkeyId: 2b:95:14:5b:c3:22:87:de:d1:42:91:88:63:b3:d5:c1:92:7a:0f:5d
pubkey: ED25519 256 bits
keyid: a7:e1:6a:3f:e7:6f:08:9d:89:ec:23:92:a9:a1:14:3c:78:a8:7a:f7
subjkey: 2b:95:14:5b:c3:22:87:de:d1:42:91:88:63:b3:d5:c1:92:7a:0f:5d
如果您希望 CA 私钥和 X.509 证书采用二进制 DER 格式,则只需省略 --outform pem 选项。目录 /etc/swanctl/x509ca 包含所有必需的 CA 证书,可以是二进制 DER 或 Base64 PEM 格式。无论文件后缀如何,strongSwan 都会自动确定正确的格式。
生成主机或用户终端实体证书
我们再次使用命令
pki --gen --type ed25519 --outform pem > moonKey.pem
为主机 moon 生成一个 Ed25519 私钥。或者,您可以输入
pki --gen --type rsa --size 3072 > moonKey.der
以生成传统的 3072 位 RSA 密钥,并将其存储为二进制 DER 格式。另外,每个较新的 Intel 平台上都有的 TPM 2.0 可信平台模块 可以用作虚拟智能卡,以安全地存储 RSA 或 ECDSA 私钥。有关详细信息,请参阅 TPM 2.0 HOWTO。
下一步,使用命令
pki --req --type priv --in moonKey.pem \
--dn "C=CH, O=strongswan, CN=moon.strongswan.org" \
--san moon.strongswan.org --outform pem > moonReq.pem
创建一个必须由 CA 签名的 PKCS#10 证书请求。通过[多次]使用 --san 参数,可以向请求中添加任意数量的所需 subjectAlternativeNames。这些可以采用以下形式:
--san sun.strongswan.org # fully qualified host name
--san [email protected] # RFC822 user email address
--san 192.168.0.1 # IPv4 address
--san fec0::1 # IPv6 address
基于证书请求,CA 使用以下命令签发签名的终端实体证书:
pki --issue --cacert strongswanCert.pem --cakey strongswanKey.pem \
--type pkcs10 --in moonReq.pem --serial 01 --lifetime 1826 \
--outform pem > moonCert.pem
如果省略了带十六进制参数的 --serial 参数,则会生成一个随机序列号。一些第三方 VPN 客户端要求 VPN 网关证书包含 TLS 服务器认证 扩展密钥用法(EKU)标志,可以通过以下选项包含该标志:
--flag serverAuth
如果您想使用后续某个章节中描述的动态 CRL 获取功能,则可以使用 --crl 参数在您的终端实体证书中包含一个或多个 crlDistributionPoints:
--crl http://crl.strongswan.org/strongswan.crl
--crl "ldap://ldap.strongswan.org/cn=strongSwan Root CA, o=strongSwan,c=CH?certificateRevocationList"
可以使用以下命令列出签发的主机证书:
pki --print --in moonCert.pem
subject: "C=CH, O=strongSwan, CN=moon.strongswan.org"
issuer: "C=CH, O=strongSwan, CN=strongSwan Root CA"
validity: not before May 19 10:28:19 2017, ok
not after May 19 10:28:19 2022, ok (expires in 1825 days)
serial: 01
altNames: moon.strongswan.org
flags: serverAuth
CRL URIs: http://crl.strongswan.org/strongswan.crl
authkeyId: 2b:95:14:5b:c3:22:87:de:d1:42:91:88:63:b3:d5:c1:92:7a:0f:5d
subjkeyId: 60:9d:de:30:a6:ca:b9:8e:87:bb:33:23:61:19:18:b8:c4:7e:23:8f
pubkey: ED25519 256 bits
keyid: 39:1b:b3:c2:34:72:1a:01:08:40:ce:97:75:b8:be:ce:24:30:26:29
subjkey: 60:9d:de:30:a6:ca:b9:8e:87:bb:33:23:61:19:18:b8:c4:7e:23:8f
通常,基于 Windows、OSX、Android 或 iOS 的 VPN 客户端需要其私钥、其主机或用户证书以及 CA 证书。加载此信息最方便的方式是将所有内容放入一个 PKCS#12 容器中:
openssl pkcs12 -export -inkey carolKey.pem \
-in carolCert.pem -name "carol" \
-certfile strongswanCert.pem -caname "strongSwan Root CA" \
-out carolCert.p12
strongSwan pki 工具目前无法创建 PKCS#12 容器,因此必须使用 openssl。
生成 CRL
可以使用以下命令生成由 CA 签名的空 CRL:
pki --signcrl --cacert strongswanCert.pem --cakey strongswanKey.pem \
--lifetime 30 > strongswan.crl
如果省略 --lifetime 选项,则使用默认值 15 天。CRL 可以上传到 HTTP 或 LDAP 服务器,也可以以二进制 DER 或 Base64 PEM 格式放入 /etc/swanctl/x509crl 目录,使用以下命令将它们加载到 charon 守护进程中:
swanctl --load-creds### 吊销证书 ###
特定终端实体证书通过以下命令吊销:
pki --signcrl --cacert strongswanCert.pem --cakey strongswanKey.pem \
--lifetime 30 --lastcrl strongswan.crl \
--reason key-compromise --cert moonCert.pem > new.crl
除了证书文件(本例中为 moonCert.pem)之外,还可以使用 --serial 参数指定要吊销的证书的序列号。pki --signcrl --help 命令列出了所有可能的吊销原因,但也可以省略 --reason 参数。新 CRL 文件的内容可以通过以下命令查看:
pki --print --type crl --in new.crl
issuer: "C=CH, O=strongSwan, CN=strongSwan Root CA"
update: this on May 19 11:13:01 2017, ok
next on Jun 18 11:13:01 2017, ok (expires in 29 days)
serial: 02
authKeyId: 2b:95:14:5b:c3:22:87:de:d1:42:91:88:63:b3:d5:c1:92:7a:0f:5d
1 revoked certificate:
01: May 19 11:13:01 2017, key compromise
本地缓存 CRL
strongswan.conf 选项
charon {
cache_crls = yes
}
启用从 HTTP 或 LDAP 服务器动态获取的 CRL 的本地缓存。缓存副本存储在 /etc/swanctl/x509crl 中,文件名由签发者的 subjectKeyIdentifier 和 .crl 后缀唯一构成。
有了缓存副本,CRL 在启动后立即可用。当本地副本过期时,在下次 IKEv2 认证期间会自动从定义的 CRL 分发点之一获取更新的 CRL。