Android下基于Iptables的一种app网络访问控制方案(一)
1.什么是iptable?
百度百科对于iptables有详细的介绍。简单地说,iptables是linux内核提供的一套ip信息包过滤,对外由iptables命令提供设置过滤规则的入口。
android是基于linux的操作系统,支持iptables。执行iptables命令需要root权限。
2.如何配置iptables命令链?
假设一个安卓系统网络访问管理体系,需要针对不同的app、不同的域名配置不同的网络访问控制策略(允许访问/禁止访问),譬如,规定使用uc可以访问sina,使用360浏览器不可以访问sohu,等等。
在root过的android设备上,通过adb shell,调试iptables命令链。
第1步:根据user id区分不同的app
android系统安装apk的时候,会为每一个应用分配一个userid,userid在此设备上将唯一且不再变化(但同一个app在不同的设备上userid可能不同)。另外,应用也可以通过在androidmanifest.xml中通过android:shareuserid字段来和其他应用共享userid,但有其他限制,比如签名等,此处不展开。
android系统中/data/system/packages.xml用来记录系统中所有安装的应用信息,其中可以查到userid。针对某一个应用,根据其包名查到userid。包名可以通过在手机上启动应用,然后adb shell下通过dumpsys window查看。假设查到uc浏览器的userid为10060。
简便起见,即以10060为uc使用的规则链(chain)名。
第2步:创建规则链并且关联到app
在adb shell下执行命令创建规则链:
iptables -n 10060
执行下面命令将规则链10060与uc浏览器关联:
iptables -a output -m owner –uid-owner 10060 -j 10060
语义说明:向output规则链附加一条规则:如果ip信息报匹配到uid是10060,则跳转(-j)到规则链10060。iptables支持区分不同的uid以跳转到不同的规则链。通过iptables -l可以查询到当前内核已有的规则链。其中output是内核自动创建的处理本地生成的ip信息包的规则链。
在具体配置规则链10060之前,可以运行下面命令将10060内容清掉:
iptables -f 10060
为什么要在output中添加规则链,而不是在input?
因为往往需要实现网络访问白名单功能,即允许访问某个域名,其他的不允许。有很多网站的内容ip包并不仅仅是自己的域名下,还包括一些其他的域名,譬如新浪的域名是http://www.sina.com.cn/,新浪微博的域名是http://weibo.com/,新浪域名下的很多网页可能内容来自新浪微博。这种情况难以统计清楚或预估,所以如果在input中只放行白名单域名关键字的ip包,往往会丢失内容。
在output中添加规则链,利用http协议中的host头域,只放行白名单域名的请求。能更好的地实现白名单需求。
第3步:配置访问规则
白名单功能:
允许访问某一域名(www.abc.com)禁止访问其他域名
iptables -a 10060 -p tcp -m string –string host: –algo bm -j mark –set-mark 1
iptables -a 10060 -p tcp -m mark –mark 1 -m string –string abc –algo bm -j accept
iptables -a 10060 -p tcp -m mark –mark 1 -j reject
黑名单功能:
禁止访问某一域名(www.abc.com)允许访问其他域名
iptables -a 10060 -m string –string abc –algo bm -j reject
iptables -a 10060 -j accept
说明:对于黑名单,逻辑比较简单,只要把所有包含abc的ip包reject即可,其余的accept,即使没有第二条命令,默认也是accept。
对于白名单,针对host头域,原因如上。对于包含host的ip包先做一次mark(标记),然后对此标记的ip包判断是否包含abc。