Linux 上的 NordVPN 封锁了局域网:允许列表与 DNS
终止开关会封锁隧道之外的一切,包括私有网段。先读懂规则,放行一个前缀,再单独修复名称解析。
一切看起来都正常,直到你想访问自己桌上的某个东西。隧道已经建立,网页能打开,网络磁盘却超时了。断开连接,磁盘在你话还没说完时就回来了,这比任何日志都更能说明问题:客户端在刻意拒绝不进入隧道的流量,而你的局域网恰恰在那条分界的错误一侧。
终止开关在履行职责
终止开关的存在是为了在隧道不可用时阻止流量外泄。私有地址段也算作不进入隧道的流量,因此严格的实现会把它们和其他一切一起封锁。这不是人们提交报告时所说的那种程序缺陷。
先阅读客户端自己的视角。一条命令打印当前设置,另一条显示客户端创建的防火墙对象。你要找的是出现在任何隧道例外之前的 drop 或 reject,因为正是这个顺序让局域网变得不可达。
nordvpn settings
sudo nft list ruleset
sudo iptables -S
然后做一个把问题一分为二的测试。先按地址访问设备,再按名称访问。地址通而名称不通,说明防火墙是无辜的,解析器有问题。两者都不通,说明防火墙在拒绝数据包,本文其余部分都适用。
允许列表:按症状选择条目类型
客户端提供带三类条目的允许列表,选对类型就是大部分工作。子网覆盖主机。端口覆盖某个服务,与目标无关。多播组覆盖发现流量,这与发往单个主机的任何流量形态都不同。
nordvpn allowlist add subnet 192.168.1.0/24
nordvpn allowlist add port 22
nordvpn allowlist add subnet 239.255.255.250/32
sudo nft list ruleset | grep -i allow
发现失败常让人意外,因为打印机或媒体服务器可能是通过发往组地址的查询被找到的,而不是查询它自己的地址。加上主机的子网并不会自动覆盖那个组,于是设备依然不可见,而你直接输入地址时它的网页却加载正常。
让例外尽可能窄,只到症状允许的程度。一个宽前缀输入过一次就会被遗忘多年,日后没人能解释它原本要放行哪些机器。项目结束时删掉相关条目,并在更新之后检查还剩下什么。
较新的版本还提供一个局域网发现开关。它很方便,而且它与允许列表是交互关系而非叠加关系:打开它可能清空已有的私有子网条目,而它保持开启时,手写的私有子网规则可能被拒绝。
主机名需要单独的决定
允许一个子网只恢复了按地址的连接,命名部分原封不动。本地主机名仍会被送往客户端在隧道建立时配置的解析器,所以过去能解析的名字现在什么都不返回。
把客户端指向路由器的解析器一步就能修好,同时也悄悄改变了你买到的保护。此后每次查询(不只是本地查询)都经路由器发出,隧道不再保护你浏览中会暴露意图的部分。
更窄的做法是保留隧道的解析器,只补上少数重要的名字,写进搜索域或作为单独条目。这要多花些心思,但保住了你付费换来的性质。
用系统解析器调用来验证结果,而不是用浏览器。浏览器越来越多地自行进行加密解析,并乐于从不经过你 shell 的路径给出答案,于是地址栏看着正常,系统解析器却仍然是坏的。
先出现的安装问题
这类报告中有相当一部分根本没走到防火墙,因为命令根本不存在。厂商的引导包只注册软件源和签名密钥。它并不安装客户端,所以紧接着命令缺失是预期结果而不是失败。
刷新软件包列表并按名称安装。如果包管理器抱怨缺少公钥,说明密钥没有落到它查找的位置,解决办法是在再次刷新之前把密钥放进去。
如果软件源的主机名解析到私有地址,停下来把那个结果读两遍。你可能已经运行着解析器在为公网名字作答的隧道,再重试安装只会无限重复同一条消息。
合上盖子之前先写下来
确认隧道是唯一变化的东西,然后只放行能恢复症状的最小范围。把命名当作独立决定,单独留一条备注。
记录哪条例外是为哪台设备存在的、由谁提出。一个只因为有人输入了宽前缀才可用的局域网,是一个早已超出其理由的决定。
客户端更新后重新测试。防火墙布局会随版本变化,上个月的允许列表不是这个月的事实。