在一台主机上无冲突地运行 VPN 和网站
一台主机既能提供网站服务,也能终结 VPN 对端,但前提是对监听、身份和管理作出明确决定。之后再去检验边界。
把一台主机同时用于公开网站和 VPN,你继承的是两个问题而不是一个:谁在哪里监听,以及谁认证谁。在动配置文件之前先回答这两个问题,因为默认值出错的方式只有在负载下才会显现。能通过 HTTPS 打开的页面只证明 Web 监听在应答,对 VPN 对端的监听一无所知。接下来是一套决策顺序,避免两者互相吞噬。
决定谁在哪个地址和传输层上监听
写一张三列表格,列出地址、传输层和端口,每个服务一行,包括管理界面。网站的 TCP 443 和 VPN 的 UDP 443 即使数字相同也不冲突,因为传输层不同。同一地址、传输层和端口上的两个服务需要实现方有文档的约定,而不是故障时临时编出来的约定。这张表也是让下一次变更可评审的产物。
分开地址或另用一个端口会让归属关系在抓包里看得见,这比优雅更有价值。有些 VPN 实现支持与 Web 服务器共用端口,但机制是特定的:守护进程检查最初的字节,把不属于自己协议的流量转走。通用 HTTP 反向代理不会这样做,改写头部也不会让它理解加密隧道的握手。请阅读该协议的部署说明,例如 OpenVPN 监听文档,并遵循它描述的约定。
决定哪种身份属于哪个服务
浏览器证书和 VPN 对端凭据是两种对象,信任模型也不同。Web 证书由公共机构验证并指明主机名,而对端凭据把设备或用户认证给集中器,可以是自签名或内部签发。把其中一个当另一个用只在很窄的场景成立,很少值得这种耦合。为了让共享证书能用而关闭校验不是分离方案,它删掉了赋予凭据意义的那道检查。
让两个存储彼此独立,并写明各自由哪个机构签发。轮换其中一个时,另一个不应需要改动;如果需要,该修的就是这处耦合。
决定管理界面放在哪里
VPN 的管理界面属于管理路径,永远不放在公开监听上,即使主机已经在提供互联网服务。443 上的 Web 服务器并不意味着对端控制台应当随处可达,而控制台通常是价值更高的目标。把它绑定到回环或管理地址,按来源限制,并保留一条不依赖隧道在线的恢复路径。恢复路径重要,因为常见故障就是修锁的时候把自己锁在外面。
为每个监听写窄防火墙规则,并在平台支持时指明接口或服务账号。因为网站需要 443 就打开主机的宽规则,正是管理界面进入扫描器索引的方式。
每次新增服务都对一遍监听表复查这些规则。复查很便宜,而且能抓到有人在凌晨两点加的那条规则。
决定两者争用时怎么办
共享主机意味着共享 CPU、内存、文件描述符和带宽,而争用的资源不总是显而易见的那一个。繁忙的网站可能填满连接表、耗尽工作槽位,或者把磁盘队列压到 VPN 日志卡住。要看每个服务的使用量而不是主机总量,因为平均值会掩盖到底哪个进程在挨饿。如果一种负载反复干扰另一种,就把它们隔离,而不是围着症状调参数。
隔离可以是一个容器、一个 cgroup 限制、一条独立队列或第二台主机,正确选择取决于争用的是哪种资源。改端口在这里解决不了问题,如果限制是一条饱和的队列,更大的实例也解决不了。用测量来决策:点名资源、施加负载,然后选能消除争用的最小隔离。
从外部验证,然后在重启之后再验证一次
从不在主机自身网络上的设备测试:打开网站、拉起隧道,并访问一个必须依赖它的资源。然后分别重启每个服务,再重复另一项测试,因为重启正是共享监听安排丢失顺序的时刻。如果 VPN 先于持有共享端口的 Web 服务器启动,共享机制可能永远挂不上,症状就是昨天还能用的隧道。把依赖写进单元顺序里,让它显式可见。
接着确认边界:网站在自己的端口上应答,VPN 在自己的端口上应答,管理界面只从管理路径应答。把结果连同日期记在监听表旁边。重启之后三项检查都通过的主机,才是可以不做交接说明就交给别人的主机。