封禁 Transmission 的入站端口并不是 VPN 策略。种子客户端会向对等节点和追踪器建立出站连接、解析域名,还可能暴露一个远程控制监听端口,而其中任何一项都可能从一个你并未预期的网络接口离开。按顺序完成五项检查,并把防火墙规则——而不是客户端设置——当作边界。最后两项检查正是人们常跳过的,而它们决定了隧道断开时这项保证是否依然成立。

找出真正持有传输的进程

桌面应用与系统守护进程运行在不同的账户下,而基于所有者的规则跟随账户,而不是程序名。写任何规则之前,先确认运行的是哪一个。专用服务账户给策略一个精确的主体,而桌面用户则会与浏览器、编辑器以及会话中的其他一切共享同一身份。请确认 UID,而不要假设安装包给出的账户名就是实际使用的那一个。

systemctl status transmission-daemon
ps -o user=,pid=,cmd= -C transmission-daemon

如果该账户还不存在,就为这一用途新建它,并且不要让它运行其他任何东西。把账户与 UID 写进规则的注释里,因为一条没有主体的规则,就是没人能安全修改的规则。

把监听字段与路由分开

Transmission 4.x 把对等节点监听地址与 rpc-bind-address 分开记录,这个区别很重要。RPC 设置只控制远程控制监听器,因此改动它并不会为对等流量选择路由。把这两项设置当成一项来读,正是一份看似严谨的配置仍然泄漏的最常见原因。同一份文档还描述了当地址无效时的回退情形,也就是说,地址不可用属于已记录的回退情况,而不是必然拒绝。

grep -E '"(peer-port|rpc-bind-address|bind-address-ipv4)"' /var/lib/transmission-daemon/.config/transmission-daemon/settings.json

按本意使用客户端自带的控制项,而把保证交给防火墙。监听设置仍然可能有价值,但它并不能证明追踪器联系、本地发现或委托解析都经由隧道离开。当两者不一致时,起决定作用的是防火墙。

把所有者匹配写进正确的链

Netfilter 关于所有者匹配的手册解释了本地生成的报文如何归属到套接字文件的属主用户或属组。这种归属并不延伸到转发流量,而附加组的匹配需要显式选项。请阅读你实际使用的那项扩展的手册,而不是随手找到的第一个示例。

iptables -A OUTPUT -m owner --uid-owner transmission -o tun0 -j ACCEPT
iptables -A OUTPUT -m owner --uid-owner transmission -j REJECT
ip6tables -A OUTPUT -m owner --uid-owner transmission -o tun0 -j ACCEPT
ip6tables -A OUTPUT -m owner --uid-owner transmission -j REJECT

顺序与匹配同样重要。链中靠前的宽泛放行会抵消靠后的精确拒绝,所以要通读整条链,而不是追加一条规则然后指望它生效。若主机运行 IPv6,务必把两种地址族都纳入,因为只覆盖 v4 的策略会留下一条无人看管的通路。让规则在客户端与隧道的重启之间始终保留。

决定 tun0 消失时会发生什么

失败策略正是这项练习的要点。如果隧道消失,而同一个钩子顺手删掉了规则,客户端就有权使用物理接口,直到别的东西把它拦住。安全的设计保留规则并让它们继续拒绝,这正是让边界不依赖隧道健康状况的原因。一个顺带删除规则的拆除钩子,恰恰是失败策略的反面。

ip link show tun0
iptables -S OUTPUT

要有意验证:停掉隧道,发起一次可以放心放弃的传输,观察是否有流量出去。然后恢复隧道,确认预期路径重新工作。

覆盖规则看不见的路径

域名解析可能由单独的解析进程处理,而一个命名空间或专用网关也能提供另一层边界,前提是它的共享与引导路径经过设计。确定哪个组件负责 DNS,以及它是否遵循同一条出口规则。接着看 RPC:如果启用了 rpc-whitelist,那么被批准的管理网段属于这份约定的一部分,而宽泛的 RFC1918 网段不是。

ss -tunp | grep -i transmission

接口计数器能为观察提供佐证,却无法证明是哪一进程产生了这些字节。做一次你被允许放弃的传输:先走可用路径,再在启动时无隧道,然后经历一次中断、一次重连和一个新建接口。既要测试全新尝试,也要测试已经打开的连接,因为规则可能并未作用于较早的套接字。把日期、账户与结果随测试一并记录下来。

粘贴一份清空整条链的示例,是用一个漏洞换好几个,所以应当追加规则而不是清除。当五项检查全部通过,这项保证就是明确的:客户端流量要么经由隧道离开,要么根本不离开,而执行它的规则能挺过隧道自身的故障。

相关文章