可能是贫穷限制了我的想象力,我一直以为Android
手机设置里的USB
网络共享是用PC
的网络供给手机上网,一直没用过。直到有一次工作中某个通过4G
上网的设备没有流量之后,我便想要要用这个功能用电脑“救济”一下这个设备,用了之后我就傻了,这是用来把Android
设备的流量供给电脑用,不能使用电脑的网络。在贫穷的我看来这个功能简直鸡肋。
后来发现开启USB网络共享之后,会在Windows
里增加一个网络适配器,网络经验丰富的前辈告诉我说可以试一下用NAT
转发。当时我脑中一片空白,虽然大学里也学过计算机网络,但从来没有实战过,而且NAT
是个啥,书上有么。
于是为了实现这个黑科技,我几乎又研究了一遍计算机网络,了解了NAT
,iptables
,linux
系统的防火墙设计。收获颇多,就有了这篇文字。
不熟悉iptables
的可以先看一篇文章了解一下: http://cn.linux.vbird.org/linux_server/0250simple_firewall_3.php
通过USB
线连接电脑和手机,Windows
的网络适配器里会出现一个新的适配器。
给它一个固定
ip
方便后续操作我们先将电脑的网络共享给USB
适配器。
最开始我希望是到这里就结束了,后来发现我还是太天真。
下面所有操作都需要进入Android
手机的shell
,同时需要有设备的root
权限。
开启ip
转发
Linux系统缺省并没有打开IP转发功能,要确认IP转发功能的状态,可以使用下面命令:
cat /proc/sys/net/ipv4/ip_forward
如果这个值为0
,则需要打开它:
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables
现在需要说一下iptables
的使用,我也只能说使用,我对其实现原理也不知道,就按普通的DSL
使用就好了。我们先实现一个小目标,实现设备内部可以ping
通外网,整个转发只涉及一个端口rndis0
。单个端口转发弄清楚,后面再实现多端口转发就简单了。
Linux 的
iptables
至少有三个表,包括管理本机进出的 filter
、管理后端主机 (防火墙内部的其他计算机) 的 nat
、管理特殊旗标使用的 mangle
(较少使用) 。在这里我们只关注filter
和nat
。
以下是filter
涉及到3条主要的链
-
INPUT
:主要与想要进入Linux
本机的封包有关 -
OUTPUT
:主要与Linux
本机所要送出的封包有关 -
FORWARD
:主要与转发有关
以下是nat
涉及到3条主要的链
-
PREROUTING
:在进行路由判断之前所要进行的规则(DNAT/REDIRECT
) -
POSTROUTING
:在进行路由判断之后所要进行的规则(SNAT/MASQUERADE
) -
OUTPUT
:与发送出去的封包有关
先清除所有规则
iptables -F
iptables -X
iptables -Z
再查看可操作的网络端口(netcfg
)
我们需要允许数据从rndis0
进出
iptables -t nat -I POSTROUTING -o rndis0 -j ACCEPT
iptables -I FORWARD -i rndis0 -m state --state RELATED,ESTABLISHED -j ACCEPT
将rndis0
设为软路由
ip route add default dev rndis0 via 192.168.42.1 table local
此时我们已经能在shell
里ping
通外网了,但仅限ping ip
地址,所以我们还需要给路由添加DNS
服务地址
ndc resolver setnetdns rndis0 "" 114.114.114.114
此时我们就可以通过域名ping
通外网了
如果需要将设备的网络通过wifi热点共享出去,就很简单的,只需要在上述基础上,添加ap0
端口的转发,此处不再赘述。
上述对iptables
的操作在设备重启之后会被清除,所以可以写一个简单的脚本或者app
实现逆转网络共享。