两份对端配置被并排比较,一份有 remote 行,另一份没有,结论是其中一份坏了。这个推断错得足够频繁,值得拆开细看。该指令描述的是第一个数据包该发往哪里。它并不选择进程是作为主动发起的客户端还是等待连接的网关,也不决定哪一方去向另一方证明身份。

remote 究竟规定了什么

一条 remote 记录指定一个主机,可选地指定端口和传输方式,还可以可选地给出多条这样的记录,按顺序依次尝试。

它缺失时的含义是明确的,而非含糊的:进程会等待,除非该对端通过认证,否则不会处理来自某个地址的数据包。因此,服务漫游用户的网关没有理由事先点名其中任何一位。

把这条记录理解为一种地址关系。对端是否可信,由证书和验证选项来回答,而不是由写下一个地址这一事实来回答。

三种安排决定答案

漫游客户端需要一个目标,因为它必须主动发起,没有目标就不知道网关在哪里。多客户端网关不需要为每个用户指定目标,因为客户端会主动连入并通过认证。已知两端的、刻意建立的双对端链路,可以只有一端有目标、两端都有,或两端都没有,取决于哪一方发起。

把固定的客户端地址粘进通用网关,正是忽视上述分类后产生的错误。它只对那台被记录下地址的对端有效,却会误导其他所有人。

这条指令不会把配置变成多客户端服务器,它的存在也不妨碍服务器角色。OpenVPN 2.6 参考手册把可选参数与「无 remote」时的行为分开记述,这恰恰暗示两者相互独立。

ArrangementNeeds a destination
Roaming clientYes, which gateway to contact
Multi-client gatewayNo, peers authenticate on arrival
Two known peersDepends on which side initiates

传输角色是另一条轴

在 TCP 下,一方等待,另一方拨号。这些是与目标不同的指令,把它们混为一谈,就会得到一对双方都在等待、或双方都在拨号的配置。

还存在 TCP 源地址过滤这一角色,正因如此,「服务器绝不能包含 remote」这种一刀切的说法是错的。

在 UDP 下没有需要建立的连接,因此两端都使用相应的 UDP 传输方式,指令只说明往哪里瞄准。已认证对端更换地址由专门行为处理,而不是靠增加更多记录。传输方式正确是目标能够成立的前提,把两者混为一谈,就会得到看似合理、却永远完不成握手的配置。

为什么缺少 remote 不是敞开的大门

没有目标的进程依然会拒绝未通过认证的对端的流量,人们把缺失的那一行读成「对所有人开放的监听」时,恰恰漏掉了这一点。

认证与目标是相互独立的,而对信任而言重要的是前者。

反向的错误更危险。固定源地址因为具体、易于检查,会让人感觉像访问控制,但它并不能证明另一端是谁。请保留证书验证,也保留把证书与其角色绑定的身份检查。用地址匹配取代它们,是拿真实的控制换取控制的表象。

写下这套配置假定了什么

对每一侧记录三件事:第一个数据包如何到达对端、哪一侧能够接受该传输方式、每一侧对另一方验证什么。

这些假定就是设计本身。指令只是它的拼写。

如果两份文件不同,请检查它们是否在表达不同的假定,而不是先假定其中一份错了。一对对称的文件对可用隧道既非必要也非充分,而不对称往往正是让拓扑成立的那一部分。

相关文章