VPN 服务能从任何其套接字绑定、且防火墙放行的地方被访问到。这是两个彼此独立的决定,而人们通常只做了其中一个。读取实际监听器只需十秒,却能解决靠猜测无法解决的问题。先从这一步开始,然后每次只改一个控制点。

下文假设你能在主机上以 root 或 sudo 执行命令。

改动之前先读取套接字

在 Linux 上,ss -lunp 会列出 UDP 监听器及其本地地址、端口和进程,ss -ltnp 对 TCP 做同样的事。找到 VPN 的端口,仔细阅读地址列。0.0.0.0:51820 和 [::]:51820 表示所有接口,而 10.0.0.5:51820 表示某个接口上的一个地址。如果输出不熟悉,ss 手册记录了各列的含义。如果缺少进程名,请用 sudo 执行同一条命令,因为属主列需要特权。

把地址记下来。这正是本手册其余部分所依赖的事实。

绑定到地址,而不是绑定到愿望

OpenVPN 用 local 指令把监听器绑定到特定地址,这是在进程层面收窄范围的受支持方式。并非每种实现都提供等价选项,而没有绑定选项的协议无法用这种方式收窄。如果你的实现没有,防火墙就是唯一的控制手段,部署说明应当明确写出这一点。在有多个地址的主机上,绑定到面向隧道的那一个;绑定到会漂移的地址通常是错误的。

必须经受地址变更的服务需要一个应对陈旧绑定的方案,而不只是一行配置。

单独检查地址族

IPv4 和 IPv6 是彼此独立的套接字。绑定到 0.0.0.0 的进程仍可能通过双栈套接字接受 IPv6,也可能不接受,取决于套接字选项和平台默认值。只读 IPv4 那一行已经骗过了不止一次部署评审。在断定监听器很窄之前,请把两个地址族都列出来。

如果 IPv6 不属于设计的一部分,在套接字层面禁用它,比指望防火墙覆盖它更干净。这是策略决定,所以请把它与其他接口选择一起记录下来。

在绑定之上叠加防火墙

窄绑定并不能取代防火墙规则,防火墙规则也不能收窄通配符绑定。两者都要用:在实现支持的地方绑定,然后只允许应当访问该端口的来源。云安全组位于主机防火墙之前,所以当路径跨越 VPC 边界时,两边都要检查。有效规则是两者的交集,而每一层都只能减少可达性。

从允许的来源和故意排除的来源分别测试。来自 localhost 的连接不能证明任何关于公网边界的事情。

记录你的选择

写下绑定的地址、拥有它的接口、防火墙规则及其目的。更换网卡或重新分配的云地址可能在不修改配置的情况下改变暴露面。给笔记标注日期,因为云地址在两次评审之间移动的频率往往超出人们的预期。

正是这份笔记,让下一次评审成为一次对比,而不是一场考古。

相关文章