解决了一下 Android 把 VPN 识别成流量而不能更新

前言

Android 不知道从什么时候开始, 连接 VPN 会被当作是在用流量, 也不知道是 feature 还是 bug, 总之这个问题直接导致了不能下载系统更新. 解决办法通常要么连一个无墙的 WIFI, 要么手动下载 OTA 包然后 adb sideload 升级.

问题

然而我家里的路由器没这么高级, 做不到从路由器上进行翻墙. 那只能用电脑开热点给手机用了, 然而笔记本用的是 Intel AC 8260 的无线网卡, 虽然说支持 AP 功能, 然而在 Linux 环境下试了各种办法都无法识别网卡, 也就不能开启热点.

Windows 上用 netsh 的话则直接明确的说, 驱动不支持热点. 我 TM...

不过令人奇怪的是, 以前是可以连接有线网络之后用 Win10 设置里面的热点功能开启的. 不过当时试了一下, 又不能开启了, 一直说开启失败. 这也不知道是 Win10 的一个 feature 还是 bug.

解决

突然想到可以用笔记本作网关, 转发手机的包从 VPN 出去. 正好笔记本平时也不关.

那首先就得修改 Android 上的 WIFI 设置, 把原有的 WIFI 的 DHCP 改成静态 IP, 手动填好自己的静态 IP, 然后将网关一栏从路由器的地址, 改成自己笔记本的内网地址. DNS 的话可以自己填一个公共 DNS, 也可以填自己的路由器地址.

改好之后手机目前还是不能上网的, 需要在 Linux 上修改一些.

第一件要做的事情当然是启用 IP 转发功能.

echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf
# 如果有 IPv6 的需要
echo net.ipv6.ip_forward=1 >> /etc/sysctl.conf

sysctl -p

启用好之后, 现在手机应该就可以上网. 不过此时上网走的还是非 VPN 的网络.

接下来要做的就是, 把来自手机的流量用 VPN 的方式出去.

因为我笔记本连接的是 IPSec 的 VPN, 这种情况下会在网卡上添加一个 VPN 的内网 IP, 比如我目前网卡情况就是

3: wlp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 44:85:00:f8:81:17 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.103/24 brd 10.0.0.255 scope global dynamic noprefixroute wlp3s0
       valid_lft 6985sec preferred_lft 6985sec
    inet 10.4.1.1/32 scope global wlp3s0
       valid_lft forever preferred_lft forever
    inet6 fe80::e40d:ffa0:7b13:75ec/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

可以看到有两个 IP, 10.0.0.103 是从路由器上分配到的 IP, 而 10.4.1.1 则是连接 IPSec 之后从服务器分配到的 IP.

对于 IPSec 来说, 要想让流量走 VPN, 只需要简单的用 SNAT 将源地址改成 10.4.1.1 就行了.

iptables -t nat -A POSTROUTING -s 10.0.0.101 -j SNAT --to 10.4.1.1

net 表的 POSTROUTING 链上加一条规则, 把从手机上发来的数据包, 修改源地址成 VPN 的地址, 即 10.4.1.1, 这样手机发来的包就会从 VPN 走出去了.

至于你要问我源地址都改成 10.4.1.1, 回包是怎么返回给手机的, 那这就是属于内核的事情了. 做 SNAT 的时候会记录下的, 数据包返回的时候会查询表, 查到源地址修改前是 10.0.0.101 的.

结束

做了这样的修改之后, 手机的流量就会通过笔记本上的 VPN 转发出去, 也就能正常下载 OTA 包了, 同时手机上也就不用再连接 VPN了.

当然这种办法还有一种用处就是, 抓包.

笔记本上就可以抓到手机上的所有数据流量了, 对于想分析手机流量的来说, 也是一直非常简单的办法了.

发表评论

电子邮件地址不会被公开。 必填项已用*标注