让 OpenVPN 客户端经 Cloudflare 转发?先确认它扮演的角色
设备客户端不是路由器。确认 Cloudflare 的角色会转发其他主机的数据包,再把服务器自身的隧道留在原来的路径上。
你有一台可用的 OpenVPN 服务器,还有一台同时运行 Cloudflare 设备软件的主机,而看似显而易见的下一步就是把客户端流量指向它。一台机器上的两个可用连接加起来也不是一个中转网关。缺的是一个有文档说明、可以转发属于他人数据包的角色,以及一套在这些数据包到达时对其进行分类的策略。
在任何规则之前先有四问:哪些流量进入、它接下来去哪里、回应如何找到回程,以及当第二条路径失效时设计会怎么做。前两个属于能力问题。
同一台主机上的两个服务不构成中转路径
设备客户端是为处理源自其运行主机的流量而构建的。它拦截名称解析或选定的应用流量,并通过自己的隧道发送,它的策略是为该设备的用户和该设备的进程编写的。从 OpenVPN 客户端转发来的数据包不是本地输出,所以同一套规则不会对它分类。这不是可以用更宽的规则掩盖的配置细节,因为它决定软件到底能不能看到这个数据包。
所以设计问题其实是能力问题。要么已安装的产品拥有一个有文档说明、能为其他网络转发流量的角色,要么中转功能完全属于别处。
Cloudflare 的哪个角色有权转发
Cloudflare 的设备客户端提供范围不同的模式:只做名称解析、只处理设备流量,有时两者兼有。这些模式都不会把主机变成私有网段的路由器,而该网段是从另一条隧道进来的。专用的路由角色是另一个产品,有自己的连接器、注册流程和网络模型。
| Question | What has to answer it |
|---|---|
| Does the installed product forward packets from other hosts? | A documented routing or connector role, not a device mode |
| Which prefixes does the connector advertise? | Its own configuration and status output |
| Does the server's own transport still take the old path? | ip route get for the endpoint, before and after |
| Do replies return through the same path? | Connection tracking counters on the forward rule |
在围绕它设计路由之前,先检查已安装的角色。阅读连接器创建了哪个接口、它是否宣告特定前缀或默认路由,以及本地策略是否同时适用于转发的数据包和本地数据包。如果只处理本地流量,那么无论翻译规则怎么写,OpenVPN 服务器都不能成为中转点。
公共出口的需求也必须在这里精确表述。Cloudflare 为转发的客户端流量提供出口是一个具体用例,必须对照你实际拥有的服务来确认。
让外层隧道独立于新路由
一旦你添加指向新接口的默认路由,服务器自身的出站流量就开始争用它,其中既包括对 OpenVPN 客户端的回应,也包括你到这台机器的 SSH 会话。常见症状是隧道建立后随即断开,或者改动看似生效,管理员却被锁在门外。比较改动前后到端点的 ip route get,并用策略路由或主机路由把服务器自身的传输留在原处。这项比较要在机器本身上做,因为服务器对自己路由的看法才是关键。
只为服务器公网地址开例外本身不够,因为每个远程管理员的回程都是不同的流。先决定哪些流必须挺过这次改动,然后逐一验证,而不是假设第一个能覆盖其余。
把转发和翻译限制在一条流上
收到的数据包走转发路径而不是本地输出路径,所以真正重要的规则在 forward 钩子里。当下一跳接口需要翻译时,把源限制在客户端池、目的限制在允许范围、出口限制在那一个接口。只绑定接口的 masquerade 规则自己并不选路,也不会允许绕过任何其他过滤器的转发。
提前决定失败时关闭的行为,然后进行测试。停掉后续路径,确认客户端失去预期出口,而不是悄悄回落到普通上行链路,因为那正是直到流量从错误的门出去才有人注意到的结果。对名称解析和 IPv6 重复检查,因为只针对 v4 的规则集会留下一条开放的 v6 路径。
写下你最终确定的四个答案,以及证明每一条的观察。你能描述出来的中转路径,才是下次事故复盘时你能为之辩护的路径。