哪个 macOS 工具能把单个应用限制为只走 VPN?
只走 VPN 的边界既需要路径,也需要拒绝。比较按应用划分的配置、代理、过滤器和 PF,然后测试你真正关心的那一个应用。
需求文档里一句「这个应用可以走 VPN,别的都不行」,其实是在悄悄要求两套机制,而没有任何一个开关同时提供它们。流量既需要有进入指定隧道的路径,也需要直连出口被拒绝。只做好其中一半、另一半完全不管的工具很常见,所以只问「它能不能拦截」的比较,只能自信地回答半个问题。先把边界写下来,再挑选能覆盖这两半的组件。
一句话里藏着的两个需求
引导,是把连接放进隧道或代理的那一半。拒绝,是不让同一条连接从其他路径出去的那一半。两者由不同组件实现,失败方式也不同,而一个产品可以在其中一半上很出色,却对另一半只字不提:
| Approach | Steers traffic | Refuses direct egress | Knows the app identity |
|---|---|---|---|
| Per-app VPN profile | Yes, for the apps it names | Only if a filter or firewall also blocks | Yes, within its own rules |
| Application proxy setting | Partly, for requests that honour it | No | No |
| Content filter | No | Yes | Yes, if the filter is written that way |
| Local PF ruleset | No | Yes, by address and port | Not reliably |
把这张表当清单看,而不是排行榜。没有任何一行能同时填满中间两列;能覆盖这两列的,是两个组件在配合:一个负责路径,另一个负责拒绝。身份这一列之所以重要,是因为无法指名应用的规则,也无法对那个应用执行规则。无论你部署什么,它都必须同时回答这三项,否则文档里的边界就不是机器上的边界。
只有引导,等于留了一条出路
应用代理设置是「有引导、无拒绝」最清楚的例子。它可以引导尊重系统代理的应用发出的请求,但除此之外什么都不覆盖:辅助进程、更新器、后台服务或另一种协议,都可以完全不读这项设置而走自己的路。因此在一个面板里选一个 SOCKS 端点,并不会为该应用建立「禁止直连出口」的策略。如果需求针对的是整个应用,就要问:规则究竟识别了哪些组件。
按应用划分的 VPN 配置比代理引导得更彻底,因为决定哪些应用进入隧道的是平台,而不是每个应用自己说了算。但它依然什么都不拒绝:配置提供了一条路径,不匹配的流量仍走普通路由。这道缺口,正是第二个组件应当出场的地方,也是看起来只有一个开关的产品通常由两个部件组成的原因。
只有拒绝,会让应用直接不可用
Apple 的内容过滤器文档描述了流量经过网络栈时的「允许或阻止」判定。这个判定不是隧道,也不是代理连接,因为它决定的是「能不能继续」,而不是「去哪里」。单独一个过滤器能把拒绝执行得很完美,却让应用完全不可用,日志干净,却没有任何解释。过滤器的判定能拦住连接,却永远不提供隧道,所以把它和引导配对,是设计决策,而不是可选附加项。
本地管理的 PF 规则集位于这套光谱的另一端。在管理员自己拥有的机器上,这是一个正当的支持决策;但它不会自动成为可分发的产品基础,因为谁拥有规则集,谁就同时拥有它与其他防火墙使用者的交互、它的升级路径,以及规则出错时的恢复方式。把 PF 加进产品,并不能消除这个归属问题,只是把它定义了。
部署方式决定了规则明天是否还在
Network Extension 在 Apple 平台上如何部署,取决于提供方类型、打包方式和眼前的系统版本。macOS 上的应用扩展运行在用户上下文中,用户注销就会结束;系统扩展则拥有不依赖会话的全局上下文。如果防护必须扛过注销,这一差别就是整个设计,而不是脚注。在承诺行为之前先确认部署路径,因为同一份代码,随扩展类型不同会落到完全不同的位置。
源码可得性与实际生效是两件事。读仓库只能告诉你某样东西如何实现,不能告诉你已安装的二进制在这台机器上被允许做什么。签名、安装与授权依然适用;围绕过时的内核扩展或库注入技巧构建的说明,描述的是另一个平台、另一种风险姿态,无论它们当年多好用。
一个点名应用的验收用例
挑一个应用会自行执行的动作,记下它应当到达的地址、该地址是 IPv4 还是 IPv6,然后在已批准的「无隧道」状态下重复同一动作。第二次运行必须产生事先声明的拒绝,而不是悄无声息的直连重试。这恰恰是人们常常没有写明的那一半,也是唯一能证明拒绝确实存在的那一半。先在有隧道时跑一遍,这样两次结果的差异只可能来自缺失的隧道。
接着走一遍需求点名的各种切换:重启应用、辅助进程被触发、隧道重连、机器切换网络,以及适用时的注销或重启。浏览器的公网 IP 页面不是对另一个应用套接字的测试,因此替代不了这一项。如果没有受支持的部署能覆盖应用的真实行为,那么一个具备显式网关、没有其他出口的授权隔离环境,是一项自带管理成本的遏制决策,而不是勾选框的替代品。
最后写下四条:应用由哪些组件构成、谁拥有引导、谁拥有拒绝,以及规则仍须成立的状态。公开仓库可以成为选择标准之一,但它不是那四条之一;真正决定某个工具是否满足网络需求的,正是这四条。