strongSwan
IPSec 是一种加密和身份验证标准,可用于构建安全的虚拟专用网络 (VPN)。
Linux 内核原生支持它,但加密密钥的配置留给用户。因此,IPSec VPN 中使用 IKE 协议,以使用各种方式(包括证书、预共享密钥或两者)安全地自动协商密钥交换。
它们通常在服务器端的用户空间守护程序中实现。strongSwan 是一个 IKE 守护程序,完全支持 IKEv1 和 IKEv2。大多数现代客户端都原生支持它,包括 Linux、Windows 7、Apple iOS、Mac OSX、FreeBSD 和 BlackBerry OS。
安装
安装 strongswan 软件包。
证书
第一步是生成 X.509 证书,包括证书颁发机构 (CA)、服务器证书和至少一个客户端证书。
证书颁发机构
让我们首先创建一个自签名根 CA 证书
$ cd /etc/ipsec.d/ $ ipsec pki --gen --type rsa --size 4096 --outform pem > private/strongswanKey.pem $ chmod 600 private/strongswanKey.pem $ ipsec pki --self --ca --lifetime 3650 --outform pem \ --in private/strongswanKey.pem --type rsa \ --dn "C=CH, O=strongSwan, CN=strongSwan Root CA" \ > cacerts/strongswanCert.pem
结果是一个 4096 位的 RSA 私钥 strongswanKey.pem
(第 2 行)和一个有效期为 10 年(3650 天)的自签名 CA 证书 strongswanCert.pem
(第 7 行)。这些文件以 PEM 编码格式存储。
您可以将可分辨名称 (DN) 更改为更相关的国家 (C)、组织 (O) 和通用名称 (CN) 值,但这不是必须的。
要列出新生成的证书的属性,请输入以下命令
$ ipsec pki --print --in cacerts/strongswanCert.pem
cert: X509 subject: "C=CH, O=strongSwan, CN=strongSwan Root CA" issuer: "C=CH, O=strongSwan, CN=strongSwan Root CA" validity: not before Nov 22 11:55:41 2013, ok not after Nov 20 11:55:41 2023, ok (expires in 3649 days) serial: 65:39:93:df:a0:f8:40:03 flags: CA CRLSign self-signed authkeyId: 45:30:11:da:a4:0e:0b:0a:a3:41:a5:81:41:ab:d8:04:7a:40:6c:c0 subjkeyId: 45:30:11:da:a4:0e:0b:0a:a3:41:a5:81:41:ab:d8:04:7a:40:6c:c0 pubkey: RSA 4096 bits keyid: dc:15:91:95:04:07:a5:13:69:5f:77:65:26:d7:02:3f:60:ec:73:c8 subjkey: 45:30:11:da:a4:0e:0b:0a:a3:41:a5:81:41:ab:d8:04:7a:40:6c:c0
/etc/ipsec.d/private/strongswanKey.pem
应移动到安全的地方,可能移动到无法访问互联网的专用签名主机。盗窃此主签名密钥将完全危及您的公钥基础设施。主机证书
此证书将用于验证 VPN 服务器的身份。运行以下命令
$ cd /etc/ipsec.d/ $ ipsec pki --gen --type rsa --size 2048 --outform pem > private/vpnHostKey.pem $ chmod 600 private/vpnHostKey.pem $ ipsec pki --pub --in private/vpnHostKey.pem --type rsa | \ ipsec pki --issue --lifetime 730 --outform pem \ --cacert cacerts/strongswanCert.pem \ --cakey private/strongswanKey.pem \ --dn "C=CH, O=strongSwan, CN=vpn.example.com" \ --san vpn.example.com \ --flag serverAuth --flag ikeIntermediate \ > certs/vpnHostCert.pem
结果是一个 2048 位的 RSA 私钥 vpnHostKey.pem
(第 2 行)。在第 4 行,我们提取其公钥并通过管道将其传输以颁发 vpnHostCert.pem
(第 11 行),这是一个由您的 CA 签名的主机证书。该证书的有效期为两年(730 天)。它通过其完全限定域名 (FQDN)(此处:vpn.example.com
)标识 VPN 主机。
CN=
) 和/或主题备用名称 (--san
) 中,但最好两者都包含。请务必两次将 vpn.example.com
替换为您的 VPN 主机名 - 否则客户端和服务器之间的连接将失败!serverAuth
扩展密钥用法标志添加到您的主机证书,如上所示,否则客户端将拒绝连接。此外,OS X 10.7.3 或更早版本需要 ikeIntermediate
标志,我们在此处也添加了该标志。
让我们看一下新生成的证书的属性。
$ ipsec pki --print --in certs/vpnHostCert.pem
cert: X509 subject: "C=CH, O=strongSwan, CN=vpn.example.com" issuer: "C=CH, O=strongSwan, CN=strongSwan Root CA" validity: not before Nov 22 21:16:51 2013, ok not after Nov 22 21:16:51 2015, ok (expires in 729 days) serial: 0c:05:d7:d5:57:0e:d9:48 altNames: vpn.example.com flags: serverAuth iKEIntermediate authkeyId: 9b:57:35:fb:cd:9e:2d:20:37:1d:61:4c:e7:c4:5b:5e:dc:64:ad:fc subjkeyId: 5f:12:c2:06:ee:2b:1e:cc:5f:78:54:ff:f0:f3:7b:a0:2b:c0:b4:d6 pubkey: RSA 2048 bits keyid: 6f:a7:99:60:27:27:09:96:02:c1:b9:d9:7d:c1:b0:10:e3:e1:d5:45 subjkey: 5f:12:c2:06:ee:2b:1e:cc:5f:78:54:ff:f0:f3:7b:a0:2b:c0:b4:d6
客户端证书
任何客户端都需要个人证书才能使用 VPN。该过程与生成主机证书类似,不同之处在于我们使用客户端的电子邮件地址而不是主机名来标识客户端证书。
$ cd /etc/ipsec.d/ $ ipsec pki --gen --type rsa --size 2048 --outform pem > private/ClientKey.pem $ chmod 600 private/ClientKey.pem $ ipsec pki --pub --in private/ClientKey.pem --type rsa | \ ipsec pki --issue --lifetime 730 --outform pem \ --cacert cacerts/strongswanCert.pem \ --cakey private/strongswanKey.pem \ --dn "C=CH, O=strongSwan, CN=myself@example.com" \ --san myself@example.com \ > certs/ClientCert.pem
结果是一个 2048 位的 RSA 私钥 ClientKey.pem
(第 2 行)。在第 6 行,我们提取其公钥并通过管道将其传输以颁发 ClientCert.pem
(第 10 行),这是由您的 CA 签名的第一个客户端证书。该证书的有效期为两年(730 天),并通过其电子邮件地址(此处:myself@example.com
)标识客户端。
最后,我们将所有需要的证书和密钥捆绑到一个带有密码的 PKCS#12 文件中,这是客户端最方便的格式。
$ openssl pkcs12 -export -name "My own VPN client certificate" \ -inkey private/ClientKey.pem \ -in certs/ClientCert.pem \ -certfile cacerts/strongswanCert.pem \ -caname "strongSwan Root CA" \ -out Client.p12
VPN 变体
最容易运行的配置是隧道模式中的 IPSec,如下所述。
隧道模式中的 IPSec
VPN 配置可以在 /etc/ipsec.conf
中找到。以下内容包含构建基本功能性 VPN 服务器所需的选项
/etc/ipsec.conf
# ipsec.conf - strongSwan IPsec configuration file config setup # By default only one client can connect at the same time with an identical # certificate and/or password combination. Enable this option to disable # this behavior. # uniqueids=never # Slightly more verbose logging. Very useful for debugging. charondebug="cfg 2, dmn 2, ike 2, net 2" # Default configuration options, used below if an option is not specified. # See: https://wiki.strongswan.org/projects/strongswan/wiki/ConnSection conn %default # Use IKEv2 by default keyexchange=ikev2 # Prefer modern cipher suites that allow PFS (Perfect Forward Secrecy) ike=aes128-sha256-ecp256,aes256-sha384-ecp384,aes128-sha256-modp2048,aes128-sha1-modp2048,aes256-sha384-modp4096,aes256-sha256-modp4096,aes256-sha1-modp4096,aes128-sha256-modp1536,aes128-sha1-modp1536,aes256-sha384-modp2048,aes256-sha256-modp2048,aes256-sha1-modp2048,aes128-sha256-modp1024,aes128-sha1-modp1024,aes256-sha384-modp1536,aes256-sha256-modp1536,aes256-sha1-modp1536,aes256-sha384-modp1024,aes256-sha256-modp1024,aes256-sha1-modp1024! esp=aes128gcm16-ecp256,aes256gcm16-ecp384,aes128-sha256-ecp256,aes256-sha384-ecp384,aes128-sha256-modp2048,aes128-sha1-modp2048,aes256-sha384-modp4096,aes256-sha256-modp4096,aes256-sha1-modp4096,aes128-sha256-modp1536,aes128-sha1-modp1536,aes256-sha384-modp2048,aes256-sha256-modp2048,aes256-sha1-modp2048,aes128-sha256-modp1024,aes128-sha1-modp1024,aes256-sha384-modp1536,aes256-sha256-modp1536,aes256-sha1-modp1536,aes256-sha384-modp1024,aes256-sha256-modp1024,aes256-sha1-modp1024,aes128gcm16,aes256gcm16,aes128-sha256,aes128-sha1,aes256-sha384,aes256-sha256,aes256-sha1! # Dead Peer Discovery dpdaction=clear dpddelay=300s # Do not renegotiate a connection if it is about to expire rekey=no # Server side left=%any leftsubnet=0.0.0.0/0 leftcert=vpnHostCert.pem # Client side right=%any rightdns=8.8.8.8,8.8.4.4 rightsourceip=%dhcp # IKEv2: Newer version of the IKE protocol conn IPSec-IKEv2 keyexchange=ikev2 auto=add # IKEv2-EAP conn IPSec-IKEv2-EAP also="IPSec-IKEv2" rightauth=eap-mschapv2 rightsendcert=never eap_identity=%any # IKEv1 (Cisco-compatible version) conn CiscoIPSec keyexchange=ikev1 # forceencaps=yes rightauth=pubkey rightauth2=xauth auto=add
传输模式中的 IPSec
与隧道模式相比,传输模式不加密原始 IP 标头(从其角度来看)。如果某些其他东西(即 GRE)在 IPSec 获取它之前已经封装了要通过隧道传输的原始数据包,这将非常有用。从 IPSec 的角度来看,它认为的原始 IP 标头实际上是已经为隧道设置的 IP 标头,它将加密真正原始的 IP 标头,将其作为封装数据包有效负载的一部分,而没有意识到它正在这样做。
IPSec/L2TP
L2TP/IPsec VPN 客户端设置 页面描述了如何设置客户端以连接到 IPSec/L2TP 服务器。与纯 IPSec 相比,这种 IPSec VPN 变体的优势在于允许隧道传输非 IP 数据包,但代价是必须运行额外的 L2TP 守护程序。
密钥
服务器的私钥需要在 /etc/ipsec.secrets
中配置,如下例所示
/etc/ipsec.secrets
# RSA private key for this host : RSA vpnHostKey.pem
当 strongSwan 运行时,每当您编辑 /etc/ipsec.secrets
时,都必须重新加载该文件
$ ipsec rereadsecrets
网络
您几乎完成了服务器的设置。还剩下一些事情要做,以使您的 VPN 服务器正确路由 VPN 隧道
/etc/sysctl.d/10-net-forward.conf
# VPN net.ipv4.ip_forward = 1 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.all.send_redirects = 0
上面的 VPN 配置使用 DHCP 自动为客户端分配 IP 地址,因此您需要有一个可用的 DHCP 服务器。如果服务器与 strongSwan 在同一主机上运行,您可能需要像这样编辑 /etc/strongswan.d/charon/dhcp.conf
/etc/strongswan.d/charon/dhcp.conf
dhcp { force_server_address = yes server = 192.168.0.255 }
您可能还需要在防火墙中允许以下协议
- ESP(加密安全负载):标准 IPSec 流量
- UDP 4500: “NAT 穿越”模式下的 IPSec 流量
- UDP 500:密钥交换 (IKE)
启动
最后,您可以启动和启用 strongswan-starter.service
。
在容器中运行 Strongswan
为了在像 systemd-nspawn 这样的容器中运行 strongswan
,您需要以下服务文件
/etc/systemd/system/systemd-nspawn@.service.d/override.conf}
[Service] ExecStart= ExecStart=/usr/bin/systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --settings=override --machine=%I --capability=CAP_NET_ADMIN --network-veth
故障排除
路由问题
如果您在将流量从客户端(漫游战士)路由到远程网络时遇到问题,请尝试在服务器上禁用 bypass-lan
插件。自 5.6.0 版本以来,此插件在官方 Arch 软件包中默认启用。请参阅 strongswan bugtracker 中的相关 问题。
/etc/strongswan.d/charon/bypass-lan.conf
# Whether to load the plugin. Can also be an integer to increase the # priority of this plugin. load = no
SSL 握手超时
一些用户遇到过间歇性 SSL 握手超时,例如
curl -v https://example.com
卡在 "TLSv1.3 (OUT), TLS handshake, Client hello (1):"- Firefox 加载页面停滞,显示 “正在执行与 www.example.com 的 TLS 握手”
一些用户通过将其网络接口 mtu 降低到 1422-1438 范围来修复(或解决?)此问题,即使他们在没有 VPN 或使用 OpenVPN 时不需要这样做。[1] [2]
降低 mtu 可能会潜在地导致其他问题,因此您的效果可能会有所不同。此修复/解决方法可能会稍微降低互联网和内部网络性能。(但是,SSL 握手将停止停滞。)如果您使用巨型帧,这可能会显着降低内部网络性能。
检查您的接口的 mtu:(用于连接 VPN 的那个)
$ ip link
认为此默认值(可能为 1500)是不好的。
您可以有效地尝试找到一个防止 SSL 超时的 mtu,方法是重复此过程,也许从一个非常低的trial-mtu(如 1300)开始,或者如果仍然失败则更低:(interface 是 ip link
上面显示的名称,而不是像 /dev/device
这样的完整路径)
# ip link set dev interface mtu trial-mtu $ while(curl -v https://example.com); do > sleep 2 > done
如果它成功的次数足够多,让您确信应该发生间歇性故障,请将此 mtu 视为良好,并按 CTRL+C
。使用介于此 mtu 和您最接近的已知不良 mtu 之间的trial-mtu 重新运行上述命令。
如果它卡在 TLS 握手上,请将其视为不良,并按 CTRL+C
。使用介于此 mtu 和您最接近的已知良好 mtu 之间的中间值重新运行上述命令。
连接已建立但无流量
在某些设置中,例如 KDE,您可能会使用 ipsec up
建立连接,但您无法访问任何外部计算机。这可能是由于未安装 openresolv 软件包。它是一个可选依赖项,但在您的情况下可能需要它。
参见
- strongSwan 5:如何创建您自己的 VPN — 用于编写本文初始版本的来源,已获得原作者的许可。
- 如何在 Ubuntu 16.04 上使用 StrongSwan 设置 IKEv2 VPN 服务器