Debian 12 搭建 IPSec VPN 实现内网互连

前言

本文将介绍 Debian 12 如何基于 StrongSwan‌ 搭建 IPSec VPN,以此在多台 Linux 服务器(处于不同的数据中心 - IDC)之间实现内网通信。

内网互连方案介绍

在多台 Linux 服务器(处于不同的数据中心 - IDC)之间实现内网互连,有以下几种方案:

  • 虚拟专用网络(Virtual Private Network - VPN)

    • 通过建立虚拟专用网络连接,将服务器与内网之间建立起安全的通信隧道,实现互通。可以使用软件或硬件设备来实现虚拟专用网络连接。
  • 隧道技术(Tunneling)

    • 使用隧道技术,将服务器的网络流量封装在内网的流量中传输,从而实现互通。常见的隧道技术有 SSH 隧道、GRE 隧道、IPSec 隧道等。
  • NAT(Network Address Translation,网络地址转换)

    • 在内网中配置 NAT 设备,将服务器的私有 IP 地址映射为内网的公共 IP 地址,从而实现互通。
  • 配置防火墙规则

    • 在内网的防火墙中配置相应的规则,允许服务器与内网之间的通信。可以通过指定源 IP 地址、目标 IP 地址、端口等来限制通信。

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.20410.0.8.9 云服务器
服务器二 49.135.225.5710.0.20.6 云服务器

准备工作执行

在两台 Debian 服务器上,分别执行以下操作,为后续安装和配置 IPSec VPN 做准备。

  • 安装工具软件
1
2
# 更新软件索引
sudo apt update
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 sysctl -p
  • 防火墙开放端口
1
2
# 安装 UFW 防火墙
sudo apt install -y ufw
1
2
3
4
5
6
7
8
# 开放 TCP 22 端口(SSH)
sudo ufw allow 22/tcp

# 开放 UDP 500 端口(IPSec VPN)
sudo ufw allow 500/udp

# 开放 UDP 4500 端口(IPSec VPN)
sudo ufw allow 4500/udp
1
2
3
4
5
# 启用 UFW 防火墙
sudo ufw enable

# 查看防火墙所有已开放的端口
sudo ufw verbose
1
2
3
4
5
# 添加路由表规则(可选操作),通过 iptables 修改出站流量的源 IP,匹配云服务器 NAT 映射规则,否则服务器之间的网络可能会不通
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 的 5004500 两个端口,其中 UDP 500 是用于 IKE 密钥交换协商,UDP 4500 是用于 NAT 穿透。

服务器一配置

安装 StrongSwan

  • 安装 StrongSwan
1
2
# 安装 StrongSwan 服务
sudo apt install -y strongswan strongswan-charon strongswan-libcharon libstrongswan libcharon-extra-plugins
1
2
# 开机自启 StrongSwan 服务
sudo systemctl enable strongswan-starter
  • 备份 IPSec 主配置文件
1
sudo cp /etc/ipsec.conf /etc/ipsec.conf.bak
  • 编辑 IPSec 主配置文件
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 配置。
  • 配置 IPSec 预共享密钥
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

  • 启动 StrongSwan
1
2
3
4
5
# 重启 StrongSwan 服务
systemctl restart strongswan-starter

# 查看 StrongSwan 服务的运行状态
systemctl status strongswan-starter
  • 启动 IPSec 服务
1
2
3
4
5
6
7
8
# 重新加载 IPSec 配置文件
ipsec reload

# 启动 IPSec 服务
ipsec restart

# 启动名称为 ipsecvpn 的 IPSec 连接(这里暂时不会启动成功,因为另一台服务器还没有配置 IPSec)
ipsec up ipsecvpn

关闭 StrongSwan

  • 若 StrongSwan 服务无法正常启动,可以使用以下命令先关闭 IPSec 和 StrongSwan 服务,然后再重新启动服务
1
2
3
4
5
6
7
8
# 关闭名称为 ipsecvpn 的 IPSec 连接
sudo ipsec down ipsecvpn

# 关闭 IPSec 服务
sudo ipsec stop

# 关闭 StrongSwan 服务
sudo systemctl stop strongswan-starter

服务器二配置

安装 StrongSwan

  • 安装 StrongSwan
1
2
# 安装 StrongSwan 服务
sudo apt install -y strongswan strongswan-charon strongswan-libcharon libstrongswan libcharon-extra-plugins
1
2
# 开机自启 StrongSwan 服务
sudo systemctl enable strongswan-starter
  • 备份 IPSec 主配置文件
1
sudo cp /etc/ipsec.conf /etc/ipsec.conf.bak
  • 编辑 IPSec 主配置文件
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 配置。
  • 配置 IPSec 预共享密钥
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

  • 启动 StrongSwan
1
2
3
4
5
# 重启 StrongSwan 服务
systemctl restart strongswan-starter

# 查看 StrongSwan 服务的运行状态
systemctl status strongswan-starter
  • 启动 IPSec 服务
1
2
3
4
5
6
7
8
# 重新加载 IPSec 配置文件
ipsec reload

# 启动 IPSec 服务
ipsec restart

# 启动名称为 ipsecvpn 的 IPSec 连接
ipsec up ipsecvpn

当两台服务器都执行 ipsec up ipsecvpn 命令后,就会一直检测对方服务器是否正常启动 IPSec,如果正常启动,它们自己会互相连接成功,如下图所示(图片来源自网络,仅供参考):

关闭 StrongSwan

  • 若 StrongSwan 服务无法正常启动,可以使用以下命令先关闭 IPSec 和 StrongSwan 服务,然后再重新启动服务
1
2
3
4
5
6
7
8
# 关闭名称为 ipsecvpn 的 IPSec 连接
sudo ipsec down ipsecvpn

# 关闭 IPSec 服务
sudo ipsec stop

# 关闭 StrongSwan 服务
sudo systemctl stop strongswan-starter

验证 VPN 连接

  • 在服务一查看 IPSec 的运行状态,如下图所示(图片来源自网络,仅供参考):
1
2
# 查看 IPSec 的运行状态
sudo ipsec statusall

  • 在服务二查看 IPSec 的运行状态,如下图所示(图片来源自网络,仅供参考):
1
2
# 查看 IPSec 的运行状态
sudo ipsec statusall

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
# 开放 UDP 500 端口(IPSec VPN)
sudo ufw allow 500/udp

# 开放 UDP 4500 端口(IPSec VPN)
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。
1
ip addr show eth0
  • 若在上述命令的输出中,‌没有显示公网 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
# 查看 IPSec 的运行状态
sudo ipsec statusall
1
2
3
4
5
# 查看 StrongSwan 的所有日志信息
journalctl -u strongswan-starter

# 或者只查看 StrongSwan 的最新日志信息
journalctl -u strongswan-starter --no-pager | tail -n 30

参考资料

IPSec VPN 技术科普

IPSec VPN 网络性能测试

OpenSwan 搭建 IPSec VPN

StrongSwan 搭建 IPSec VPN