Android OpenVPN:无需 root 手机也能添加专用路由
在 Android 真正加载的配置里添加一条路由,再确认服务器允许它。包括改动、重连和四项检查的操作步骤。
你还需要一个专用子网——比如 10.60.0.0/24——而当前配置里没有。在笔记本电脑上,加一条路由就能继续。在 Android 上,VPN 是一个应用,tun 设备属于该应用,没有 root 就没有可以编辑的路由表。路由仍须存在,但它进入客户端加载的配置里,而且只有对端同意才有效。下面依次是改动、重连、服务器侧和回退。
改动之前:路由能做什么、不能做什么
路由只回答一个问题:去往该目的地的流量走哪个接口。它不授权任何东西。如果网络所有者没有同意这台手机可以到达那个子网,正确的路由只会产生看起来正确的配置和网关处的无声丢弃,而你会花下一个小时改错文件。
先拿到那份同意,网络有所有者就拿到书面同意。然后记下你不做的事:你不给手机分配该 LAN 内的地址,不修改服务器的监听,也不按主机名选择站点。这是四件不同的事,只有第一件是你的。
| The route gives you | The route does not give you |
|---|---|
| A destination prefix associated with the tunnel | Permission to forward at the gateway |
| A path for the phone's own traffic | A return route on the target host |
| A scope for the client's virtual interface | A name in DNS, or HTTPS identity |
改客户端真正加载的那份配置
对于导入普通 OpenVPN 选项文本的兼容客户端,添加内容只有一行:
route 10.60.0.0 255.255.255.0把它加到配置主体中,放在其他路由指令附近,操作方的 endpoint、证书、密钥处理和校验行一律保持原样。不要为了借一行就整段粘贴旧示例:压缩、绝对文件路径和过时的 cipher 设置会一起带进来,让你多花一次排障时间。
人们常漏掉的一步是文件归属。如果应用导入过配置,它使用的是应用自己那份副本,改下载来的原件没有任何作用。使用客户端支持的编辑器,或通过更新路径重新导入改好的文件;存在多个相似名称时,确认当前生效配置的名字。记下你改的是哪一个。
如果配置里已经有 route-nopull,服务器下发的路由一条都不会安装,手机需要的每个前缀都必须显式列出。这是合法设计,但也意味着漏写一行看起来和服务器拒绝完全一样。
重连并在设备上验证
先断开,再重新连接你改过的那份配置,而不是让应用恢复上次会话。打开连接日志,确认客户端解析了新行;界面忽略某条路由指令,通常是改错副本的结果。
按地址而不是按名字测试目的地。对已知服务端口做 TCP 检查比 ping 更有信息量,因为很多主机会回应 ICMP,而服务端口却被过滤。地址通而名字不通,那是解析器问题而不是路由问题,下一节不适合你。
这里还有两项范围检查。按应用划分的 VPN 意味着地址路由可能存在,但你用来测试的应用不在包含集合内,所以要用确实在范围内的应用测试。另外 IPv4 前缀说明不了 IPv6 路径;服务是双栈时,要么补上对应的 IPv6 路由,要么接受客户端会选择你并不想要的路径。
有一种否定结果值得尽早识别:如果 full-tunnel 路由已经覆盖 0.0.0.0/0,前缀并没有缺失,再加一遍什么都不会变。重复覆盖既修不了服务器侧拒绝,也补不上缺失的回应。
在服务器上补完这条路
手机之外还有三件事必须成立。网关需要到目的地的路由,以及把手机源地址转发过去的权限。目标需要接受该源并把回应经网关送回,否则设计上就需要在出口做有意的地址转换。OpenVPN 手册的 route 选项只覆盖客户端侧的指令;转发和回程路由是另一台机器上的另一组设置。
如果目的地不在网关背后,而在另一个 VPN 客户端背后,服务器需要为该对端的子网配置 iroute。这条指令属于服务器,用来说明哪个客户端拥有某个前缀;手机无法从自己的配置里提供它,客户端侧怎么改都替代不了。
明确检查回程。回应走默认路由而不是隧道,会出现典型的半开症状:连接单向建立,什么也回不来。目标无法回程时,在网关做源地址转换是正当的修法,但那是有自身后果的策略决定。
回退与验收
改动前保留上一份配置。如果改动让情况更糟,用同一条重新导入的路径恢复那份副本,重连,并确认旧行为回来了——这才说明你确实改到了你以为在改的地方。回退后旧状态没有恢复,说明应用里还藏着第三份你没找到的副本。
四项都成立才算通过,并在一次全新重连之后按这个顺序测试:目的地在其服务端口上有回应;若预期存在内网名字则能解析;HTTPS 仍能校验预期主机名;重启或从 Wi-Fi 切到蜂窝之后整体仍然可用。最后一项检查,正是用来抓那种只在 Android 重建隧道之前才存在的路由。
- 动手改之前,先确认网络所有者允许该目的地。
- 把路由放进客户端加载的配置,然后重新导入并重连。
- 按正确的地址族,在按应用的范围内,通过服务端口验证。
- 转发、回程路由和 iroute 在服务器上修,不在手机上修。
- 留一份回退副本,并在重启后重测。