修公司的VPN修了一整天

Shi Yi2026/7/15fixvpnipseclinux

背景

公司的 VPN 是为了访问内网资源,并且对每个 IP 和账号做了不同的权限控制。

最近公司的 VPN 老是断连,刚连上去半个小时就给我断了,然后我就被安排修了。


环境

先看一眼环境:

CentOS 7 (kernel 3.10.0-1160) + Libreswan 3.25 (pluto) + xl2tpd + pppd

WARNING

大家也可以想到,CentOS 7 的 yum 下载的东西新不到哪里去。Libreswan 现在应该都 5 版本了,这还是 3.25 呢。听同事说,他们当初搭这个 VPN 服务器的时候尝试了很多方案,很多新特性都支持不了。


问题一:频繁断连

因果链分析

主要因果链如下:

options.xl2tpd 缺少 LCP echo 配置

隧道空闲时无心跳包发送

公司路由器 NAT UDP 会话映射超时(约 60 秒),端口映射被清除

IPsec SA(UDP 4500)失效,客户端检测到连接中断

客户端发起 SA 重协商(每 ~60 秒一次,日志已证实)

新 SA 建立 → 又空闲 60 秒 → NAT 又超时 → 又 rekey(死循环)

某次 rekey 碰到网络抖动 → rekey 失败

keyingtries=3 已耗尽 + dpdaction=clear 不重连 → 彻底断开

修改 options.xl2tpd

增加 LCP 保活心跳,每 10 秒发送一次(远小于 NAT 60 秒超时):

+ lcp-echo-interval 10
+ lcp-echo-failure 3
  nodefaultroute
参数说明
lcp-echo-interval10每 10 秒发一次 LCP Echo-Request 心跳包
lcp-echo-failure3连续 3 次(30 秒)无 Echo-Reply 才判定断开

修改 ipsec.conf

- keyingtries=3
+ keyingtries=%forever

- dpdaction=clear
+ dpdaction=restart
参数修改前修改后说明
keyingtries3%forever无限重试,不轻易放弃
dpdactionclearrestart掉线后自动重连

结果

测试了几个小时都没有发生断连,第一个问题解决。

TIP

但是除非有其他设备在连,这就会触发第二个问题。


问题二:NAT 环境下设备抢占

这个协议对 NAT 设备不友好,会和其他设备抢占端口,一个 NAT 环境下只有一个设备可以连接上。

INFO

为什么必须是 NAT 设备呢?太简单了就不解释了。

为什么之前要用 IKEv1?因为软件太老了,很多方便的东西不支持。

解决方案:切换到 IKEv2

我用的是 IKEv2,但是:

  • Windows 内置的 VPN 客户端不支持 IKEv2 + PSK
  • Libreswan 3.25 不支持 IKEv2 + EAP-MSCHAPv2
  • 最后只能用 IKEv2 + 证书

WARNING

真的超级麻烦,明明账号密码新版早就支持了,PSK 也早就支持了,就是用不了,真是无解了。


踩过的坑

坑一:连上 VPN 没网了

明明在服务端设置了分流模式,看了半天。然后 GPT 给我看了一下,说我客户端是全隧道模式,真是给我蠢爆了。

坑二:证书验证通过但同事连不上

我导入证书验证连接通过了,但是同事通过不了,直接让 AI 写了一个脚本运行批量导入。


总结

TIP

如果是 Ubuntu 最新版该多好呀,那就好多都可以用了。

  1. 断连问题:核心原因是缺少 LCP 保活心跳,加上 NAT 超时导致的死循环,通过配置 lcp-echo-intervaldpdaction=restart 解决
  2. NAT 抢占问题:IKEv1 协议天然对 NAT 不友好,升级到 IKEv2 + 证书认证解决
  3. 老系统是原罪:CentOS 7 + Libreswan 3.25 限制了太多选项,能升级就升级
Last Updated 7/15/2026, 12:36:07 PM