Why
- ikev2 支持 mobike, 会极大提高 VPN 连接稳定性. (基本不掉线, 即使是移动设备上在 Mobile Network 和 Wifi 之间切换时.)
- 基于 ipsec (第三层协议), 受到的干扰较小 (至少目前).
Server (Linux) (假设 IP 为 1.2.3.4)
参考 linux上用strongswan搭建ikev2协议vpn 编译安装 Strongswan (必须是 5.0+版本, Debian / Ubuntu 的 repository 里貌似只有 Strongswan 4), 生成服务器端的 CA 和 server 的证书和密钥 (caCert.pem, caKey.pem, serverKey.pem, clientCert.pem)并放到 “/etc/ipsec.d/” 里对应目录下. (client 端证书可以不需要, windows 7 以及 Linux / Android 上的 Strongswan 客户端均可以使用 eap-mschapv2 方式用户名 / 密码验证.)
/etc/ipsec.conf
config setup uniqueids=no #允许多设备同时在线 conn ipke2vpn keyexchange=ikev2 ike=aes256-sha1-modp1024! esp=aes256-sha1! dpdaction=clear dpddelay=300s rekey=no left=%defaultroute leftsubnet=0.0.0.0/0 leftauth=pubkey leftcert=serverCert.pem leftid="C=US, O=strongSwan, CN=1.2.3.4" right=%any rightsourceip=192.168.250.0/24 rightauth=eap-mschapv2 rightsendcert=never eap_identity=%any auto=add
/etc/ipsec.secrets
: RSA serverKey.pem : PSK "Password" username: EAP "Password" username: XAUTH "Password"
‘: PSK “Password”‘ 这行是 L2TP / IPsec VPN 的配置. IKEv2 可以不需要.
/etc/strongswan.conf
charon { dns1 = 8.8.8.8 dns2 = 8.8.4.4 }
Server 端通用 VPN 配置 (PPTP / OpenVPN / L2TP 等通用, 只要 VPN 设置的虚拟IP段属于 192.168.0.0/16)
sysctl -w net.ipv4.ip_forward=1 iptables -t nat -A POSTROUTING -s 192.168.16.0/16 -j MASQUERADE
配置完后, 系统启动时应该自动开启 VPN Server, 你也可以手工启动 / 关闭 VPN
ipsec start ipsec stop ipsec start --nofork # 将 log 输出到当前终端用于调试.
Windows 7 / 8 Client
使用系统自带的 VPN Client
导入服务器生成的 CA 证书: mmc -> File -> Add / Remove Snap-in -> 左侧选择 Certificates -> 点击 Add 按钮 -> 选择 “Computer Account” (重要) -> Local Computer -> OK. 然后右击左侧列表里 “Trusted Root Certificates” -> All Tasks -> Import, 选择 caCrt.pem 文件并导入.
- 只需要导入 CA 证书. Server 证书客户端不需要
- 必须使用上面的方式导入证书. 直接使用 “certmgr.msc” 导入的证书属于 “Current User”, 无法被 VPN 连接使用.
- 你也可以使用可信 CA 签发的 Server 证书 (如 SartSSL), 这样所有 VPN 客户端 均不需要导入 CA.
在 Windows 系统网络管理面板里建立一个 VPN 连接, “Host name or IP address of destination” 里填写 VPN Server 的 IP 地址 1.2.3.4. VPN 连接配置如下:
连接时, 输入服务器 ipsec.secrets 里 配置的 EAP 方式的用户名和密码 “username”, “Password”.
Android
使用 Strongswan VPN Client 应用.
将 CA 证书文件 caCrt.pem 复制到 Android 内置存储里, 然后在 Settings -> Security -> Install from internal storage 导入.
Strongswan VPN Client VPN Profile 配置
- Android 系统导入根证书后, 有时会弹出 “Network may be monitored” 的 notification. 屏蔽方法是安装 Xposed 框架的 “Network Monitored Blocker” module.
- Android 的 Strongswan 客户端使用了 Android 的 VPN API, 每次连接 VPN 时都会提示用户确认. 自动连接的方法是安装 XPosed 的 “VpnDialog Xposed module” 并在 module settings 里将 “Strongswan VPN Client” 这个应用加入列表. (但每次连接 VPN 时仍然会有个 toast 消息, 无法消除)
- Android 4.4.2 及以下版本存在 Bug, 会导致 Stronswan 连接 VPN 后若较长时间不使用, VPN 会断开, 但 Notification Area 里仍然存在 “VPN Connected” 的消息无法消除, 并且无法重新连接 VPN, 必须重启设备. 解决这个 Bug 的唯一方法是升级到 Android 4.4.3 或 5.0.
Linux Strongswan ikev2 client
适用于桌面 Linux / 路由器等设备, 将 Strongswan 配置为 VPN Client 模式.
编译安装 Strongswan. 将 VPN Server 的 CA 证书 caCrt.pem 复制到 /etc/ipsec.d/cacerts/ 里.
/etc/ipsec.secrets 与 服务器端的完全相同.
/etc/ipsec.conf
conn ikev2-rw keyexchange=ikev2 ike=aes256-sha1-modp1024! esp=aes256-sha1! right=1.2.3.4 rightid=%1.2.3.4 # 部分 strongswan 版本可能上面那行无效,需要明确指定 rightid 为服务端设置的 leftid 值 #rightid="C=US, O=strongSwan, CN=1.2.3.4" rightsubnet=0.0.0.0/0 rightauth=pubkey leftsourceip=%config leftsendcert=never leftauth=eap-mschapv2 eap_identity=username auto=start
另外, 我发现 Linux 连接 ikev2 VPN Server 后, 会无法访问本地局域网内其他机器, 貌似因为 ikev2 VPN 自动添加的路由表 (table id 和优先级都是 220. ip route show table 220) 比系统默认路由表优先级高. Workaround:
ip rule add from 192.168.0.0/16 table main prio 1
如果想共享 VPN Connection 给局域网内其它机器:
sysctl -w net.ipv4.ip_forward=1 iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o ipsec+ -j MASQUERADE
则其它机器将 Gateway 设为 192.168.1.2 即可自动通过 VPN 访问 Internet. 还可以再加上 chnroutes.
Update:
某日更新后发现 Linux strongswan ikev2 客户端连接不会创建单独的虚拟网卡了,而直接将获取的虚拟 IP 追加绑定到默认网卡 (eth0)上(使用 ip address 可以看到)。那么客户端的NAT规则就不能写 MASQUERADE 了,必须写
# 192.168.250.2 是客户端分配到的虚拟网段地址 iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 192.168.250.2
很麻烦。不知道能不能设置回让 strongswan 单独创建一个虚拟网卡。