你为了让一个难缠的 PPTP 配置成功连接,加了一行参数;一周之后,那台已经正常用了几个月的 L2TP 客户端却连不上了。最直观的解释是两个协议现在起了冲突。更常见的情况是:两个客户端都会启动 pppd,都会读同一份默认配置,而你加的那一行从来没有限定在正在修的那个配置文件范围内。把它们绑在一起的是这份共享的选项文件,协议本身是无辜的。

客户端启动时继承了什么

基于 PPP 的客户端很少从零开始拼自己的命令行。它启动 pppd,pppd 先读系统默认配置,再读用户级或终端级文件,最后才读客户端传入的参数;客户端还可能让它再去读一个 peer 文件。上面每一层都可能带上插件、某种认证方式或一条路由指令,而第一个设置了受保护选项的层,会让后面的改动失效。

所以有意义的问题不是哪个 VPN 坏了,而是这个设置由哪一层提供。自己生成参数的客户端看起来是自包含的,其实照样继承了系统文件里的全部内容。

改动之前先弄清这行属于谁

先看连接建立时正在运行的那个进程。命令行会显示哪些文件是显式传进去的;没有出现在那里的文件,就来自默认路径。

ps -o pid=,args= -C pppd

如果参数列表里出现了 peer 名称,就去读那个文件;如果没有,你要找的设置就藏在一条共享路径里。pppd 手册列出了这些文件的读取顺序,以及哪些选项是普通用户无法覆盖的,这也解释了为什么后加的一行有时完全不起作用。像插件路径这样的受保护选项,后面的用户级配置行无法把它替换掉,所以改错文件不会有任何可见效果。

跟在每个客户端后面的那行插件

写在系统文件里的插件是最麻烦的一种,因为不管用户点了哪个按钮,它都会改变新的 PPP 进程要加载什么。L2TP 插件就是典型例子:对某个配置文件是对的,对同样从这份默认配置启动的 PPTP 配置却毫无意义,甚至有害。

把它移到客户端会主动选择的 peer 文件里,或者在客户端支持时放进它自己的按连接设置。直接删掉它,修好了第二个客户端却弄坏了第一个,这类问题就是这样在团队之间来回传递的。

移动之后逐个验证

在同一台机器上一前一后测试两个连接,看协商出来的选项,而不是看那个显示成功的对话框。下面的 dump 会打印 pppd 实际组装出的选项集合,那才是唯一有意义的清单。

sudo pppd call office debug dump

对第二个客户端重复同样的操作,比较两份输出。你移走的那项选项应当只出现在其中一份里。如果两份都有,说明是客户端自己在重新生成它,修复应该落在那个配置文件而不是共享文件里。把该设置现在的位置记在连接旁边,下一个人就不必靠再弄坏一次来重新发现这层耦合。

相关文章