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
第1步:根據user id區分不同的app
Android系統安裝apk的時候,會為每一個應用分配一個userId,userId在此裝置上將唯一且不再變化(但同一個app在不同的裝置上userId可能不同)。另外,應用也可以通過在AndroidManifest.xml中通過android:shareUserId欄位來和其他應用共享userId,但有其他限制,比如簽名等,此處不展開。
Android系統中/data/system/packages.xml用來記錄系統中所有安裝的應用資訊,其中可以查到userId。針對某一個應用,根據其包名查到userId。包名可以通過在手機上啟動應用,然後
簡便起見,即以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
在具體配置規則鏈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。