在 Linux 上不用 IPsec 运行 L2TP:xl2tpd、pppd 与 NAT
裸 L2TP 就是明文 PPP:配置 xl2tpd、pppd 选项和 chap-secrets,选择 MTU 1460,从端到端放行 UDP 1701,然后为客户端访问添加 NAT。
普通的L2TP就是装在信封里的 PPP,仅此而已。它承载你的帧,却不加密,也不证明另一端坐着谁,因此几乎所有部署都会在它下面垫一层 IPsec。运行裸版本仍有诚实可信的理由:实验室台架、迁移中的一步,或是一条本来就已经位于另一条受保护路径内的链路。
如果你仍然要做,就把这一提醒写进设计说明并保留在那里。接下来是我在 Debian 和 RHEL 系主机上使用的操作路径:哪个文件负责什么、避免经典卡死的 MTU,以及让隧道真正有用的转发规则。
三个文件分工
xl2tpd 负责终止控制连接,并把每个会话交给 PPP 守护进程,因此配置分散在两个从不读取对方文件的程序里。监听器位于 /etc/xl2tpd/xl2tpd.conf 的 [lns default] 段中,用 ip range 指定地址池,用 local ip 指定服务器端,用 pppoptfile 指向交给 PPP 的配置文件。打开 require authentication = yes,让 length bit 和 flow bit 保持启用,并选择一个主机上没有其他服务在用的地址池。
PPP 策略写在该选项所指的文件里,通常是 /etc/ppp/options.xl2tpd:auth、拒绝 pap、chap 和 mschap、require-mschap-v2、MTU 和 MRU 都为 1460,以及链路建立后客户端可以访问的 DNS 地址。凭据又放在第三个文件 /etc/ppp/chap-secrets 里,其中第二个字段必须与 LNS 段名一致,第四个字段可以固定地址池中的某个地址。
隧道为何连上又卡住
1500 字节的以太网帧放不进一条已经为自身报头花掉字节的路径。外层 IPv4 报头占 20 字节,UDP 占 8 字节,L2TP 报头约 12 字节,留给 PPP 及其载荷的就是 1460。正是在 PPP 里通告这个更小的值,才不会让大包被分片或在半路被悄悄丢弃。
症状是隧道看起来一切正常,直到真正的流量到来:ping 和控制消息能通过,文件复制却卡住,日志什么也不解释。两端要同时降低 MTU 和 MRU。只调整客户端,往往把硬卡死变成时断时续,反而更难诊断。
一个端口承载两段对话
UDP 1701 位于协议两半的共同底层,仅这一点造成的防火墙规则问题就比配置中其他任何部分都多。先来的是启动控制连接的请求及其响应;随后的会话请求与确认只建立一对标识符。之后 PPP 接手:链路控制、认证,再用 IP 控制协议商定地址。每个阶段在日志里都有自己的词汇,且没有一个会自称是 L2TP 故障。
严格按这个顺序读抓包,就能知道是哪一阶段失败;而 PPP 认证失败,改 xl2tpd 是修不好的。共享端口还解释了另一种常见故障:只放行流的前几个包的规则,会让会话建立起来,然后阻断传输。请为整个会话、双向放行 1701。
让隧道有用:转发与 NAT
会话本身只能到达服务器。客户端要上网,需要转发、在上行链路上为地址池添加 NAT 规则,以及链路建立后客户端真能查询的 DNS。地址池还必须避开 LAN 网段,否则发给客户端的应答会在本地投递,而不是被推回隧道。
在服务器上,用 sysctl -w net.ipv4.ip_forward=1 开启转发,用 iptables -t nat -A POSTROUTING -s 10.44.0.0/24 -o eth0 -j MASQUERADE 转换地址池,然后用针对 -i ppp0 -o eth0 的 FORWARD 规则放行出站隧道流量,并用镜像规则加 -m state --state RELATED,ESTABLISHED 放行回程流量。要把这些规则持久化到重启之后,因为一台重启后丢失规则的服务器,看起来和坏掉的 L2TP 配置一模一样。
访问服务器自己的 LAN 是另一件事:在 LAN 路由器上为地址池添加回程路由,或在服务器上做 proxy ARP。当 LAN 内部有设备必须直接访问客户端时,把它们藏在 NAT 后面,只会给以后再安排一次调试。
裸栈不做什么,以及如何验证
这套栈没有任何部分加密 PPP 帧,也没有任何部分把远端认证为你真正选择的那台服务器。MS-CHAPv2 确实能挡住只旁听的窃听者,但位于路径上的攻击者仍可干扰会话。Windows 自带客户端只在配合 IPsec 时才提供 L2TP,所以要把 Linux、路由器固件和第三方客户端都算作对端。把裸配置当作诊断的垫脚石,绝不要当作终点。
按固定顺序验证:在前台运行 xl2tpd -D,观察日志中的 PPP 阶段,在两端从 ip addr 读取分配到的地址,然后抓取 UDP 1701,确认会话建立后数据确实在流动。如果四项都对得上,流量仍然失败,那问题就在路由、NAT 或 MTU 上,而不是 L2TP 本身。