前言 本文将介绍 Debian 12 如何基于 StrongSwan 搭建 IPSec VPN,以此在多台 Linux 服务器(处于不同的数据中心 - IDC)之间实现内网通信。
内网互连方案介绍 在多台 Linux 服务器(处于不同的数据中心 - IDC)之间实现内网互连,有以下几种方案:
IPSec VPN 的简单介绍 IPSec 是什么 IPSec 是虚拟私有网络(VPN)的一种连接协议,用于在服务器和客户端之间建立加密隧道,并传输敏感数据。它由两个阶段组成,第一阶段(Phrase 1, ph1),交换密钥建立连接,使用互联网密钥交换协议(ike);ike 密钥交换协议有两个版本,分别是 IKEV1、IKEV2;第二阶段(Phrase 2, ph2),连接建立后对数据进行加密传输,使用封装安全载荷(ESP)协议。
IKEV1 与 IKEV2 IKE 属于一种混合型协议,由 Internet 安全关联和密钥管理协议(ISAKMP)和两种密钥交换协议 OAKLEY 与 SKEME 组成。IKE 创建在由 ISAKMP 定义的框架上,沿用了 OAKLEY 的密钥交换模式以及 SKEME 的共享和密钥更新技术,还定义了它自己的两种密钥交换方式:主模式和积极模式(IKEV1 才有)。IKE 有两个版本,分别是 IKEV1 与 IKEV2。值得一提的是,IKEV2 不兼容 IKEV1,IKEV1 不支持认证,IKEV2 支持认证。IKEV2 支持 EAP 认证,支持 NAT 穿透,支持私密性、完整性、源认证。工作在 UDP 的 500 /4500 端口。NAT-T 用的是 UDP 4500 端口。
OpenSwan 与 StrongSwan Linux 系统有两种比较常见的 IPSec 实现,分别是 OpenSwan 与 StrongSwan,两者的主要区别如下:
协议支持
OpenSwan主要支持 IKEV1 协议,兼容旧版设备。 默认使用 KLIPS 内核模块实现 IPSec(需手动为旧内核打补丁),对 Linux 2.6.9+
内核支持 NETKEY。 StrongSwan专注 IKEV2 协议,安全性更高且简化配置流程。 原生支持 NETKEY 内核模块(无需额外补丁),对现代 Linux 内核(如 4.x+
)兼容性更佳。 配置复杂度
OpenSwan依赖 ipsec.conf
配置文件,需手动管理多参数(如 protostack=netkey
需显式声明)。 对 NAT 穿透支持较弱(旧内核需额外补丁)。 StrongSwan使用模块化配置(如 strongswan.conf
),支持动态加载插件(如 charon
进程管理 IKE)。 内置 NAT-Traversal 功能,适配复杂网络环境更便捷。 维护与扩展性
OpenSwan社区维护停滞,新版 Linux 发行版(如 Debian 12、Ubuntu 22.04+
)默认移除了 OpenSwan 的支持。 适合需兼容老旧设备的场景。 StrongSwan项目持续更新,支持 X.509 证书认证、EAP 扩展认证等现代安全机制。 使用 C 语言编写,提供线程池优化,大大提升多连接场景下的协商效率。 性能表现
OpenSwan在低带宽场景下性能稳定,但加密转发带宽受限(实测最高约 700 Mbps)。 StrongSwan通过优化加密算法(如 AES-NI 加速)和线程池技术,转发性能更高(实测带宽可达 1 Gbps+)。 适用场景总结
OpenSwan:需兼容旧版设备(如 Linux 2.4
内核)、使用 IKEV1 协议的场景。 StrongSwan:现代网络环境、需要 IKEV2 协议、高安全认证及性能优化的场景。 IPSec VPN 实现内网互连 由于 Debian 12 的 Linux 内核版本是 6.x
,因此这里选择基于 StrongSwan 搭建 IPSec VPN,以此在多台 Linux 服务器(处于不同的数据中心 - IDC)之间实现内网通信。各服务器的网络信息如下所示:
服务器 公网 IP 内网 IP 备注 服务器一 101.53.225.204 10.0.8.9 云服务器 服务器二 49.135.225.57 10.0.20.6 云服务器
准备工作执行 在两台 Debian 服务器上,分别执行以下操作,为后续安装和配置 IPSec VPN 做准备。
1 2 sudo apt install -y wget curl telnet tcpdump net-tools vim -y
1 2 sudo vim /etc/sysctl.conf
1 2 3 4 5 6 7 # 允许转发,默认值是 0 net.ipv4.ip_forward = 1 net.ipv6.conf.all.forwarding = 1 # 关闭重定向,防止恶意用户可以使用 IP 重定向来修改远程主机中的路由表 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.all.send_redirects = 0
1 2 sudo apt install -y ufw
1 2 3 4 5 6 7 8 sudo ufw allow 22/tcp sudo ufw allow 500/udp sudo ufw allow 4500/udp
1 2 3 4 5 sudo ufw enable sudo ufw verbose
1 2 3 4 5 sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE sudo iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
提示
为了方便后续配置 IPSec VPN 和排查问题,可以先暂时不配置防火墙,也就是可以等 IPSec VPN 正常工作后再配置防火墙。 IPSec VPN 默认监听在 UDP 的 500
和 4500
两个端口,其中 UDP 500
是用于 IKE 密钥交换协商,UDP 4500
是用于 NAT 穿透。 服务器一配置 安装 StrongSwan 1 2 sudo apt install -y strongswan strongswan-charon strongswan-libcharon libstrongswan libcharon-extra-plugins
1 2 sudo systemctl enable strongswan-starter
1 sudo cp /etc/ipsec.conf /etc/ipsec.conf.bak
1 2 sudo vim /etc/ipsec.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 config setup charondebug="all" conn %default # 配置ike默认参数 ikelifetime=1440m # ike协议的SA生命周期 keylife=60m # IPSec连接的密钥生命周期为60分钟 rekeymargin=3m # 3分钟过后密钥生命周期结束后重新生成密钥 keyingtries=0 # 密钥交换期间允许最大的重试次数为0次 keyexchange=ikev1 # IPSec连接使用IKE协议的版本 authby=secret # 使用预共享密钥认证方式 conn ipsecvpn # 创建ipsecvpn leftid=101.53.225.204 # 本地网关设备的标识 left=101.53.225.204 # 本地网关设备的公网IP地址,如果使用本地网关的私网IP地址建立IPSec-VPN连接,则本项需配置为本地网关设备的私网IP地址 leftsubnet=10.0.8.0/22 # 本地设备的内网网段 right=49.135.225.57 # 远端设备的出口网关的公网IP地址 rightsubnet=10.0.20.0/22 # 远端设备的内网网段 auto=start # 主模式 type=tunnel # 隧道模式 ike=3des-md5-modp1024 # IKE使用3des-md5-modp1024加密套件 esp=3des-md5 # esp使用3des-md5加密套件 forceencaps=yes # 强制使用NAT-T封装,即使NAT-T不是必需的
特别注意
强烈建议加上配置 forceencaps=yes
,因为这在云服务器(如阿里云、腾讯云)场景下特别重要,因为它们的公网 IP 可能是 NAT 映射的地址。为了适配 NAT 场景,还可以添加 nat-ikev1-method=natd
配置。 1 2 sudo vim /etc/ipsec.secrets
1 2 # 秘钥需要使用双引号包裹 101.53.225.204 49.135.225.57 : PSK "mysecret"
或者
1 2 # 秘钥需要使用双引号包裹 %any : PSK "mysecret"
启动 StrongSwan 1 2 3 4 5 systemctl restart strongswan-starter systemctl status strongswan-starter
1 2 3 4 5 6 7 8 ipsec reload ipsec restart ipsec up ipsecvpn
关闭 StrongSwan 若 StrongSwan 服务无法正常启动,可以使用以下命令先关闭 IPSec 和 StrongSwan 服务,然后再重新启动服务 1 2 3 4 5 6 7 8 sudo ipsec down ipsecvpn sudo ipsec stop sudo systemctl stop strongswan-starter
服务器二配置 安装 StrongSwan 1 2 sudo apt install -y strongswan strongswan-charon strongswan-libcharon libstrongswan libcharon-extra-plugins
1 2 sudo systemctl enable strongswan-starter
1 sudo cp /etc/ipsec.conf /etc/ipsec.conf.bak
1 2 sudo vim /etc/ipsec.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 config setup charondebug="all" conn %default # 配置ike默认参数 ikelifetime=1440m # ike协议的SA生命周期 keylife=60m # IPSec连接的密钥生命周期为60分钟 rekeymargin=3m # 3分钟过后密钥生命周期结束后重新生成密钥 keyingtries=0 # 密钥交换期间允许最大的重试次数为0次 keyexchange=ikev1 # IPSec连接使用IKE协议的版本 authby=secret # 使用预共享密钥认证方式 conn ipsecvpn # 创建ipsecvpn leftid=49.135.225.57 # 本地网关设备的标识 left=49.135.225.57 # 本地网关设备的公网IP地址,如果使用本地网关的私网IP地址建立IPSec-VPN连接,则本项需配置为本地网关设备的私网IP地址 leftsubnet=10.0.8.0/22 # 本地设备的内网网段 right=101.53.225.204 # 远端设备的出口网关的公网IP地址 rightsubnet=10.0.20.0/22 # 远端设备的内网网段 auto=start # 主模式 type=tunnel # 隧道模式 ike=3des-md5-modp1024 # IKE使用3des-md5-modp1024加密套件 esp=3des-md5 # esp使用3des-md5加密套件 forceencaps=yes # 强制使用NAT-T封装,即使NAT-T不是必需的
特别注意
强烈建议加上配置 forceencaps=yes
,因为这在云服务器(如阿里云、腾讯云)场景下特别重要,因为它们的公网 IP 可能是 NAT 映射的地址。为了适配 NAT 场景,还可以添加 nat-ikev1-method=natd
配置。 1 2 sudo vim /etc/ipsec.secrets
1 2 # 秘钥需要使用双引号包裹 49.135.225.57 101.53.225.204 : PSK "mysecret"
或者
1 2 # 秘钥需要使用双引号包裹 %any : PSK "mysecret"
启动 StrongSwan 1 2 3 4 5 systemctl restart strongswan-starter systemctl status strongswan-starter
1 2 3 4 5 6 7 8 ipsec reload ipsec restart ipsec up ipsecvpn
当两台服务器都执行 ipsec up ipsecvpn
命令后,就会一直检测对方服务器是否正常启动 IPSec,如果正常启动,它们自己会互相连接成功,如下图所示(图片来源自网络,仅供参考 ):
关闭 StrongSwan 若 StrongSwan 服务无法正常启动,可以使用以下命令先关闭 IPSec 和 StrongSwan 服务,然后再重新启动服务 1 2 3 4 5 6 7 8 sudo ipsec down ipsecvpn sudo ipsec stop sudo systemctl stop strongswan-starter
验证 VPN 连接 在服务一查看 IPSec 的运行状态,如下图所示(图片来源自网络,仅供参考 ):
在服务二查看 IPSec 的运行状态,如下图所示(图片来源自网络,仅供参考 ):
IPSec VPN 常见配置问题 UDP 500 端口无法正常通信 问题描述
在服务器一(101.53.225.204
)中,执行 systemctl status strongswan-starter
命令查看 StrongSwan 服务的运行状态,出现以下错误信息:
1 2 3 4 5 6 7 8 9 10 Mar 25 21:38:49 debian charon[274510]: 04[NET] error writing to socket: Network is unreachable Mar 25 21:39:02 debian charon[274510]: 11[IKE] sending retransmit 3 of request message ID 0, seq 1 Mar 25 21:39:02 debian charon[274510]: 11[NET] sending packet: from 101.53.225.204[500] to 49.135.225.57[500] (248 bytes) Mar 25 21:39:02 debian charon[274510]: 04[NET] error writing to socket: Network is unreachable Mar 25 21:39:26 debian charon[274510]: 12[IKE] sending retransmit 4 of request message ID 0, seq 1 Mar 25 21:39:26 debian charon[274510]: 12[NET] sending packet: from 101.53.225.204[500] to 49.135.225.57[500] (248 bytes) Mar 25 21:39:26 debian charon[274510]: 04[NET] error writing to socket: Network is unreachable Mar 25 21:40:08 debian charon[274510]: 13[IKE] sending retransmit 5 of request message ID 0, seq 1 Mar 25 21:40:08 debian charon[274510]: 13[NET] sending packet: from 101.53.225.204[500] to 49.135.225.57[500] (248 bytes) Mar 25 21:40:08 debian charon[274510]: 04[NET] error writing to socket: Network is unreachable
问题分析
分析错误信息可得知,可能是服务器二(49.135.225.57
)的 UDP 500
端口不能正常访问导致。
问题解决
(1) 在服务器二中,检查 IPSec VPN 是否有正常监听 UDP 500
和 UDP 4500
端口。1 2 netstat -ulnp | grep -E '500|4500'
(2) 在服务器二中,若 Debian 系统有启用 UFW 防火墙,则需要开放 UDP 500
和 UDP 4500
端口。1 2 3 4 5 sudo ufw allow 500/udp sudo ufw allow 4500/udp
(3) 在服务器二中,使用 tcpdump
工具检测 UDP 500
和 UDP 4500
端口是否有接收到进站的流量。1 tcpdump -i any -nn udp port 500 or udp port 4500
若 tcpdump
工具没有检测到进站的流量,那么在服务器一中,可以执行以下命令手动发送数据包,以此检测服务器二 UDP 500
端口的可达性。当提示 “Connection refused” 或 “Network is unreachable”,则说明 UDP 500
端口未开放,需要检查防火墙配置。 1 nc -u -z -v 49.135.225.57 500
(4) 在服务器一中,检查网络接口是否绑定了公网 IP。若在上述命令的输出中,没有显示公网 IP 101.53.225.204
,则可能需要通过云服务商控制台将该 IP 绑定到服务器的弹性网卡(如 eth0
)。若公网 IP 是通过 NAT 映射(如云服务器弹性 IP),则需要确保 NAT 规则正确配置。 若公网流量需要通过特定网关(非默认内网网关),则需要在服务器一中添加静态路由,其中 <公网网关IP>
需替换为云服务商提供的公网网关地址(例如 VPN 网关 ),详细教程请看 这里 。 1 2 ip route add 49.135.225.57/32 via <公网网关IP> dev eth0
验证路由是否生效,在服务器一中执行以下命令后,预期输出应该包含公网接口(如 dev eth0
)和正确网关。若仍指向内网网关,则需要调整路由优先级或联系云服务商检查底层网络配置。 1 2 ip route get 49.135.225.57
(5) 两台服务器分别调整 StrongSwan 配置,尝试显式指定源 IP(公网 IP),避免自动选择内网 IP。1 2 3 4 5 6 conn ipsecvpn # 创建ipsecvpn leftid=101.53.225.204 # 本地网关设备的标识 left=101.53.225.204 # 本地网关设备的公网IP地址,如果使用本地网关的私网IP地址建立IPSec-VPN连接,则本项需配置为本地网关设备的私网IP地址 leftsubnet=10.0.8.0/22 # 本地设备的内网网段 leftsourceip=101.53.225.204 # 本地设备的源IP(公网IP) ......
(6) 若上述步骤都无法定位或者解决问题,那么可以查看 IPSec 的运行状态和 StrongSwan 的日志信息来进一步定位问题。1 2 3 4 5 journalctl -u strongswan-starter journalctl -u strongswan-starter --no-pager | tail -n 30
参考资料 IPSec VPN 技术科普 IPSec VPN 网络性能测试 OpenSwan 搭建 IPSec VPN StrongSwan 搭建 IPSec VPN