如何在 Ubuntu 16.04 上使用 StrongSwan 设置 IKEv2 VPN 服务器
介绍
虚拟专用网络或 VPN 允许您在流量通过不受信任的网络(例如咖啡店、会议或机场的网络)时对其进行安全加密。
IKEv2 或 Internet Key Exchange v2 是一种允许在服务器和客户端之间建立直接 IPSec 隧道的协议。在 IKEv2 VPN 实施中,IPSec 为网络流量提供加密。 IKEv2 在新平台(OS X 10.11+、iOS 9.1+ 和 Windows 10)上得到原生支持,无需额外的应用程序,它可以非常顺畅地处理客户端问题。
在本教程中,您将在 Ubuntu 16.04 服务器上使用 StrongSwan 设置 IKEv2 VPN 服务器,并从 Windows、iOS 和 macOS 客户端连接到它。
先决条件
要完成本教程,您需要:
- 一台具有多个 CPU 的 Ubuntu 16.04 服务器,按照 Ubuntu 16.04 初始服务器设置指南进行配置,包括 sudo 非根用户和防火墙。
此外,您应该熟悉 IPTables。在继续之前查看 Iptables 防火墙的工作原理。
第 1 步 — 安装 StrongSwan
首先,我们将安装 StrongSwan,这是一个开源 IPSec 守护进程,我们将其配置为我们的 VPN 服务器。我们还将安装 StrongSwan EAP 插件,它允许对客户端进行密码身份验证,而不是基于证书的身份验证。我们需要创建一些特殊的防火墙规则作为此配置的一部分,因此我们还将安装一个实用程序,使我们能够使新的防火墙规则持久化。
执行以下命令安装这些组件:
- sudo apt-get install strongswan strongswan-plugin-eap-mschapv2 moreutils iptables-persistent
注意:在安装 iptables-persistent
时,安装程序会询问是否保存当前的 IPv4 和 IPv6 规则。由于我们希望任何以前的防火墙配置保持不变,因此我们将在两个提示中选择是。
现在一切都已安装,让我们继续创建我们的证书:
第 2 步 — 创建证书颁发机构
IKEv2 服务器需要一个证书来向客户端标识自己。为了帮助我们创建所需的证书,StrongSwan 附带了一个实用程序来生成证书颁发机构和服务器证书。首先,让我们创建一个目录来存储我们将要处理的所有内容。
- mkdir vpn-certs
- cd vpn-certs
现在我们有了一个目录来存储所有内容,让我们生成我们的根密钥。这将是一个 4096 位 RSA 密钥,将用于签署我们的根证书颁发机构,因此通过确保只有根用户可以读取它来保护此密钥也非常重要。
执行这些命令以生成和保护密钥:
- ipsec pki --gen --type rsa --size 4096 --outform pem > server-root-key.pem
- chmod 600 server-root-key.pem
现在我们有了密钥,我们可以继续创建我们的根证书颁发机构,使用密钥签署根证书:
- ipsec pki --self --ca --lifetime 3650 \
- --in server-root-key.pem \
- --type rsa --dn "C=US, O=VPN Server, CN=VPN Server Root CA" \
- --outform pem > server-root-ca.pem
您可以根据需要将可分辨名称 (DN) 值(例如国家/地区、组织和通用名称)更改为其他名称。这里的通用名称只是指标,所以你甚至可以编造一些东西。
稍后,我们会将根证书 (server-root-ca.pem
) 复制到我们的客户端设备,以便它们可以在连接时验证服务器的真实性。
现在我们已经启动并运行了根证书颁发机构,我们可以创建一个 VPN 服务器将使用的证书。
第 3 步 — 为 VPN 服务器生成证书
我们现在将为 VPN 服务器创建证书和密钥。该证书将允许客户端验证服务器的真实性。
首先,使用以下命令为 VPN 服务器创建私钥:
- ipsec pki --gen --type rsa --size 4096 --outform pem > vpn-server-key.pem
然后使用您在上一步中创建的证书颁发机构的密钥创建并签署 VPN 服务器证书。执行以下命令,但将通用名称 (CN) 和主题备用名称 (SAN) 字段更改为您的 VPN 服务器的 DNS 名称或 IP 地址:
- ipsec pki --pub --in vpn-server-key.pem \
- --type rsa | ipsec pki --issue --lifetime 1825 \
- --cacert server-root-ca.pem \
- --cakey server-root-key.pem \
- --dn "C=US, O=VPN Server, CN=server_name_or_ip" \
- --san server_name_or_ip \
- --flag serverAuth --flag ikeIntermediate \
- --outform pem > vpn-server-cert.pem
将证书复制到允许 StrongSwan 读取证书的路径:
- sudo cp ./vpn-server-cert.pem /etc/ipsec.d/certs/vpn-server-cert.pem
- sudo cp ./vpn-server-key.pem /etc/ipsec.d/private/vpn-server-key.pem
最后,保护密钥,使其只能由 root 用户读取。
- sudo chown root /etc/ipsec.d/private/vpn-server-key.pem
- sudo chgrp root /etc/ipsec.d/private/vpn-server-key.pem
- sudo chmod 600 /etc/ipsec.d/private/vpn-server-key.pem
在此步骤中,我们创建了一个证书对,用于保护客户端和服务器之间的通信。我们还使用我们的根密钥签署了证书,因此客户端将能够验证 VPN 服务器的真实性。现在我们已经准备好所有证书,我们将继续配置软件。
第 4 步 — 配置 StrongSwan
我们已经创建了我们需要的所有证书,所以是时候配置 StrongSwan 本身了。
StrongSwan 有一个默认配置文件,但在我们进行任何更改之前,让我们先备份它,以便我们有一个参考文件,以防出现问题:
- sudo cp /etc/ipsec.conf /etc/ipsec.conf.original
示例文件比较长,为了防止误配置,我们将清除默认配置文件,重新编写自己的配置。首先,清除原来的配置:
- echo '' | sudo tee /etc/ipsec.conf
然后在文本编辑器中打开文件:
- sudo nano /etc/ipsec.conf
首先,我们将告诉 StrongSwan 记录守护进程状态以进行调试并允许重复连接。将这些行添加到文件中:
config setup
charondebug="ike 1, knl 1, cfg 0"
uniqueids=no
然后,我们将为我们的 VPN 创建一个配置部分。我们还将告诉 StrongSwan 创建 IKEv2 VPN 隧道并在启动时自动加载此配置部分。将以下行附加到文件中:
conn ikev2-vpn
auto=add
compress=no
type=tunnel
keyexchange=ikev2
fragmentation=yes
forceencaps=yes
接下来,我们将告诉 StrongSwan VPN 使用哪种加密算法。附加这些行:
ike=aes256-sha1-modp1024,3des-sha1-modp1024!
esp=aes256-sha1,3des-sha1!
我们还将配置 dead-peer 检测以清除任何“悬空”连接,以防客户端意外断开连接。添加这些行:
dpdaction=clear
dpddelay=300s
rekey=no
然后我们将配置服务器(左侧)端的 IPSec 参数。将此添加到文件中:
left=%any
leftid=@server_name_or_ip
leftcert=/etc/ipsec.d/certs/vpn-server-cert.pem
leftsendcert=always
leftsubnet=0.0.0.0/0
注意:配置服务器 ID (leftid
) 时,如果您的 VPN 服务器将由域名标识,则仅包含 @
字符:
leftid=@vpn.example.com
如果服务器将通过其 IP 地址识别,只需将 IP 地址放入:
leftid=111.111.111.111
然后我们配置客户端(右侧)IPSec 参数,如私有 IP 地址范围和要使用的 DNS 服务器:
right=%any
rightid=%any
rightauth=eap-mschapv2
rightsourceip=10.10.10.0/24
rightdns=8.8.8.8,8.8.4.4
rightsendcert=never
最后,我们将告诉 StrongSwan 在连接时向客户端询问用户凭据:
eap_identity=%identity
配置文件应如下所示:
config setup
charondebug="ike 1, knl 1, cfg 0"
uniqueids=no
conn ikev2-vpn
auto=add
compress=no
type=tunnel
keyexchange=ikev2
fragmentation=yes
forceencaps=yes
ike=aes256-sha1-modp1024,3des-sha1-modp1024!
esp=aes256-sha1,3des-sha1!
dpdaction=clear
dpddelay=300s
rekey=no
left=%any
leftid=@server_name_or_ip
leftcert=/etc/ipsec.d/certs/vpn-server-cert.pem
leftsendcert=always
leftsubnet=0.0.0.0/0
right=%any
rightid=%any
rightauth=eap-mschapv2
rightdns=8.8.8.8,8.8.4.4
rightsourceip=10.10.10.0/24
rightsendcert=never
eap_identity=%identity
确认您已按所示配置内容后,保存并关闭文件。
现在我们已经配置了 VPN 参数,让我们继续创建一个帐户,以便我们的用户可以连接到服务器。
第 5 步 — 配置 VPN 身份验证
我们的 VPN 服务器现在已配置为接受客户端连接,但我们尚未配置任何凭据,因此我们需要在名为 ipsec.secrets
的特殊配置文件中配置一些内容:
- 我们需要告诉 StrongSwan 在哪里可以找到我们服务器证书的私钥,这样服务器才能加密和解密数据。
- 我们还需要设置一个允许连接到 VPN 的用户列表。
让我们打开秘密文件进行编辑:
- sudo nano /etc/ipsec.secrets
首先,我们将告诉 StrongSwan 在哪里可以找到我们的私钥。
server_name_or_ip : RSA "/etc/ipsec.d/private/vpn-server-key.pem"
然后我们将创建用户凭证。您可以组成任何您喜欢的用户名或密码组合,但我们必须告诉 StrongSwan 允许该用户从任何地方连接:
your_username %any% : EAP "your_password"
保存并关闭文件。现在我们已经完成了 VPN 参数的处理,我们将重新加载 VPN 服务,以便应用我们的配置:
- sudo ipsec reload
现在 VPN 服务器已经完全配置了服务器选项和用户凭证,是时候继续配置最重要的部分了:防火墙。
第 6 步 — 配置防火墙和内核 IP 转发
现在我们已经配置了 VPN 服务器,我们需要配置防火墙以转发并允许 VPN 流量通过。我们将为此使用 IPTables。
首先,如果您设置了 UFW,请禁用它,因为它可能与我们需要配置的规则冲突:
- sudo ufw disable
然后删除 UFW 创建的所有剩余防火墙规则:
- iptables -P INPUT ACCEPT
- iptables -P FORWARD ACCEPT
- iptables -F
- iptables -Z
为了防止我们被锁定在 SSH 会话之外,我们将接受已经接受的连接。我们还将打开端口 22
(或您配置的任何端口),以便将来通过 SSH 连接到服务器。执行这些命令:
- sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
- sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
我们还需要接受本地环回接口上的连接:
- sudo iptables -A INPUT -i lo -j ACCEPT
然后我们将告诉 IPTables 接受 IPSec 连接:
- sudo iptables -A INPUT -p udp --dport 500 -j ACCEPT
- sudo iptables -A INPUT -p udp --dport 4500 -j ACCEPT
接下来,我们将告诉 IPTables 转发 ESP(封装安全有效负载)流量,以便 VPN 客户端能够连接。 ESP 为我们的 VPN 数据包在穿越不受信任的网络时提供额外的安全性:
- sudo iptables -A FORWARD --match policy --pol ipsec --dir in --proto esp -s 10.10.10.10/24 -j ACCEPT
- sudo iptables -A FORWARD --match policy --pol ipsec --dir out --proto esp -d 10.10.10.10/24 -j ACCEPT
我们的 VPN 服务器将充当 VPN 客户端和互联网之间的网关。由于 VPN 服务器只有一个公共 IP 地址,我们需要配置伪装以允许服务器代表客户端从互联网请求数据;这将允许流量从 VPN 客户端流向互联网,反之亦然:
- sudo iptables -t nat -A POSTROUTING -s 10.10.10.10/24 -o eth0 -m policy --pol ipsec --dir out -j ACCEPT
- sudo iptables -t nat -A POSTROUTING -s 10.10.10.10/24 -o eth0 -j MASQUERADE
为了防止某些客户端上的 IP 数据包碎片,我们将告诉 IPTables 通过调整数据包的最大段大小来减小数据包的大小。这可以防止某些 VPN 客户端出现问题。
- sudo iptables -t mangle -A FORWARD --match policy --pol ipsec --dir in -s 10.10.10.10/24 -o eth0 -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360
为了更好的安全性,我们将删除与我们配置的规则不匹配的所有其他内容:
- sudo iptables -A INPUT -j DROP
- sudo iptables -A FORWARD -j DROP
现在我们将使防火墙配置持久化,这样我们所有的配置工作都不会在重启时被擦除:
- sudo netfilter-persistent save
- sudo netfilter-persistent reload
最后,我们将在服务器上启用数据包转发。数据包转发使我们的服务器能够将数据从一个 IP 地址“路由”到另一个 IP 地址。本质上,我们让我们的服务器充当路由器。
编辑文件 /etc/sysctl.conf
:
- sudo nano /etc/sysctl.conf
我们需要在这里配置一些东西:
- 首先,我们将启用 IPv4 数据包转发。
- 我们将禁用路径 MTU 发现以防止数据包碎片问题。
- 我们也不接受 ICMP 重定向,也不发送 ICMP 重定向以防止中间人攻击。
您需要对该文件进行的更改在以下代码中突出显示:
. . .
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1
. . .
# Do not accept ICMP redirects (prevent MITM attacks)
net.ipv4.conf.all.accept_redirects = 0
# Do not send ICMP redirects (we are not a router)
net.ipv4.conf.all.send_redirects = 0
. . .
net.ipv4.ip_no_pmtu_disc = 1
进行这些更改、保存文件并退出编辑器。然后重启服务器:
- sudo reboot
当它重新启动时,您会与服务器断开连接,但这是预料之中的。服务器重新启动后,以 sudo 非根用户身份重新登录到服务器。您已准备好在客户端上测试连接。
第 7 步 – 在 Windows、iOS 和 macOS 上测试 VPN 连接
现在您已设置好所有内容,是时候尝试一下了。首先,您需要复制您创建的根证书并将其安装在将连接到 VPN 的客户端设备上。最简单的方法是登录到您的服务器并执行此命令以显示证书文件的内容:
- cat ~/vpn-certs/server-root-ca.pem
你会看到类似这样的输出:
Output-----BEGIN CERTIFICATE-----
MIIFQjCCAyqgAwIBAgIIFkQGvkH4ej0wDQYJKoZIhvcNAQEMBQAwPzELMAkGA1UE
. . .
EwbVLOXcNduWK2TPbk/+82GRMtjftran6hKbpKGghBVDPVFGFT6Z0OfubpkQ9RsQ
BayqOb/Q
-----END CERTIFICATE-----
将此输出复制到您的计算机,包括 -----BEGIN CERTIFICATE-----
和 -----END CERTIFICATE-----
行,并将其保存到具有可识别名称的文件中,例如 vpn_root_certificate.pem
。确保您创建的文件具有 .pem
扩展名。
或者,使用 SFTP 将文件传输到您的计算机。
将 vpn_root_certificate.pem
文件下载到您的计算机后,您可以设置与 VPN 的连接。
从 Windows 连接
首先,按照以下步骤导入根证书:

然后使用以下步骤配置 VPN:
- 启动控制面板,然后导航至网络和共享中心。
- 点击“设置新连接或网络”,然后选择“连接到工作场所”。
- 选择使用我的互联网连接 (VPN)。
- 输入 VPN 服务器详细信息。在 Internet 地址字段中输入服务器的域名或 IP 地址,然后用描述您的 VPN 连接的内容填写目标名称。然后点击完成。
您的新 VPN 连接将显示在网络列表下。选择 VPN,然后单击“连接”。系统将提示您输入用户名和密码。输入它们,单击“确定”,您将被连接。
从 iOS 连接
要在 iOS 设备上配置 VPN 连接,请执行以下步骤:
- 给自己发送一封附有根证书的电子邮件。
- 在您的 iOS 设备上打开电子邮件并点击附加的证书文件,然后点击安装并输入您的密码。安装完成后,点击完成。
- 前往“设置”、“通用”、“VPN”,然后点击“添加 VPN 配置”。这将打开 VPN 连接配置屏幕。
- 点击类型并选择 IKEv2。
- 在描述字段中,输入 VPN 连接的简称。这可以是您喜欢的任何内容。
- 在服务器和远程 ID 字段中,输入服务器的域名或 IP 地址。本地 ID 字段可以留空。
- 在身份验证部分输入您的用户名和密码,然后点按完成。
- 选择您刚刚创建的 VPN 连接,点击页面顶部的开关,即可连接。
从 macOS 连接
按照以下步骤导入证书:
- 双击证书文件。 Keychain Access 将弹出一个对话框,显示“Keychain Access 正在尝试修改系统钥匙串。输入您的密码以允许此操作。”
- 输入您的密码,然后点击修改钥匙串
- 双击新导入的 VPN 证书。这将打开一个小属性窗口,您可以在其中指定信任级别。将 IP 安全 (IPSec) 设置为始终信任,系统将再次提示您输入密码。输入密码后,此设置会自动保存。
既然证书很重要且值得信赖,请使用以下步骤配置 VPN 连接:
- 转到“系统偏好设置”并选择“网络”。
- 点击网络列表左下角的小“加号”按钮。
- 在出现的弹出窗口中,将接口设置为 VPN,将 VPN 类型设置为 IKEv2,并为连接命名。
- 在服务器和远程 ID 字段中,输入服务器的域名或 IP 地址。将本地 ID 留空。
- 单击身份验证设置,选择用户名,然后输入您为 VPN 用户配置的用户名和密码。然后单击“确定”。
最后,单击连接以连接到 VPN。您现在应该连接到 VPN。
排除连接故障
如果您无法导入证书,请确保文件具有 .pem
扩展名,而不是 .pem.txt
。
如果您无法连接到 VPN,请检查您使用的服务器名称或 IP 地址。服务器的域名或 IP 地址必须与您在创建证书时配置为通用名称 (CN) 的内容相匹配。如果它们不匹配,VPN 连接将无法工作。如果你用vpn.example.com
的CN设置证书,你进入VPN时必须使用vpn.example.com
服务器详细信息。仔细检查您用于生成证书的命令,以及您在创建 VPN 连接时使用的值。
最后,仔细检查 VPN 配置以确保 leftid
值配置有 @
符号(如果您使用的是域名):
leftid=@vpn.example.com
如果您使用的是 IP 地址,请确保省略 @
符号。
结论
在本教程中,您构建了一个使用 IKEv2 协议的 VPN 服务器。现在您可以放心,无论您走到哪里,您的在线活动都将保持安全!
要添加或删除用户,只需再次查看第 5 步。每行对应一个用户,因此添加或删除用户就像编辑文件一样简单。
从这里开始,您可能想要研究设置日志文件分析器,因为 StrongSwan 将其日志转储到系统日志中。教程如何在 VPS 上安装和使用 Logwatch 日志分析器和报告器有更多关于设置的信息。
您可能还对 EFF 关于在线隐私的指南感兴趣。