53 端口上的 OpenVPN:常被混淆的三场对话
端点名称解析、加密传输和隧道建立后的 DNS 是三场不同的对话。在更换端口或解析器之前,先确定是哪一步失败了。
说 VPN 在 53 端口被封锁的报告,把三种因不同原因失败的观察混在一起。端点名称解析发生在任何隧道存在之前,加密传输是另一场对话,而之后进行的 DNS 查询是第三场。三者各有各的失败特征,其中只有一项真正与 DNS 有关。
在改动任何东西之前,先按用途给数据包分类,因为修复措施要跟着阶段走。
三场对话,一个端口号
第一场对话是端点名称的解析:你的机器向已配置的解析器询问 vpn.example.com 位于何处,而这个应答在客户端发出第一个隧道数据包之前就通过普通 DNS 到达。第二场是 OpenVPN 传输本身,它按配置文件指定的协议和端口,连接到解析得到的地址。第三场发生在隧道建立之后,应用程序请求名称时,由推送的解析器设置决定谁来应答。
这三场可以各自独立地成功或失败。客户端可以完美解析自己的端点,却仍然到达不了监听方;它也可以建立隧道,而所有内部名称解析都因为 DNS 设置从未送达而失败。
| Conversation | When it happens | What has to be true |
|---|---|---|
| Endpoint lookup | Before the client contacts a hostname | An underlying resolver path can answer for the endpoint name |
| OpenVPN transport | During tunnel establishment | The gateway listens on its configured transport, address and port, and nothing filters it |
| Application DNS | During or after the protected session | A resolver the client can reach, plus routing that carries its queries |
把这张表当作检查清单,而不是说明。如果端点名称无法解析,后面的一切都无法进行,隧道也根本不会开始。
端口号并不指明应用程序
53 端口按惯例承载 DNS,而 OpenVPN 运营者也可以在那里发布监听,这正是该端口号不具辨识力的原因。UDP 53 上的 OpenVPN 会话仍然是 OpenVPN 会话,向 53 端口上的服务器发出的 DNS 查询,并不能说明隧道是否被允许。配置文件中的 proto 和 remote 两行定义外部端点;端口号本身什么也定义不了。
诊断时这一点是双向的:向 53 端口发送通用 UDP 探测只能证明某个端口有应答,而不能证明 VPN 服务有应答。请用真实的客户端和真实的配置文件测试,因为只有这样才能演练服务所期望的握手。
先证明监听存在,再归咎于网络
在服务器上用 ss -lunp | grep 53 确认绑定了什么,并与配置文件的协议和端口对照。从客户端所在的网络,用更高的详细级别运行客户端,让日志显示它尝试了哪个地址和传输方式。如果服务器在监听而客户端的数据包没有到达,那就是路径或策略在拒绝它们,这属于与网络所有者的对话,而不是更换端口的理由。
只有当服务确实在那里监听、且部署允许时,换端口才有帮助。为了避开受管网络的过滤而挪动监听,是策略决定,不是排障步骤。改动服务之前先问网络所有者允许什么,因为违反策略的绕行方案后来照样会被关闭。把那个答复记在配置文件旁边,下一个人就不必重复询问。
隧道建立后单独检查 DNS
隧道建立后,检查 VPN 接口上的解析器状态,并查询一个内部名称和一个公共名称。如果隧道正在传输流量而内部名称失败,说明推送的 DNS 设置没有生效,这是客户端集成问题,而不是传输问题。如果公共名称失败而内部名称可用,说明分离隧道策略正在按配置执行。
DNS 改动留给解析器的所有者。为了让一次测试通过而覆盖受管的解析器配置,可能会破坏机器上其他所有场景的私有名称。如果隧道推送了解析器而客户端忽略它,应修复客户端集成,而不是在别处添加静态条目。静态条目会把故障隐藏到有人更换网络为止。写清楚每个命名空间应由哪个解析器应答。