一、概述
"熱情、務(wù)實、專業(yè)、創(chuàng)新”我們不忘初心,砥礪前行,實在做人,認真做事,始終如一的專注企業(yè)互聯(lián)網(wǎng)品牌建設(shè)與網(wǎng)絡(luò)營銷推廣服務(wù)。高端網(wǎng)站設(shè)計本著讓客戶滿意的目標,幫助企業(yè)通過互聯(lián)網(wǎng)創(chuàng)造價值.成都創(chuàng)新互聯(lián)公司全體員工將通過不懈努力,力爭成為客戶在信息化領(lǐng)域中值得長期信賴的合作伙伴。
為了使讀此簡筆的人對Iptables有一個簡單的了解,此處強行百度了一波概念,如果想深入的了解Iptables的各種配置規(guī)則和內(nèi)核對其的管理運行機制請自行www.baidu.com,這些并不是本簡筆的目的所在。
閑言少敘,開始正文
---->以下概述來自baidu,讀者可酌情跳過
iptables的前身叫ipfirewall (內(nèi)核1.x時代),是從freeBSD上移植過來的,能夠工作在內(nèi)核當中的,對數(shù)據(jù)包進行檢測的一款簡易訪問控制工具。但是ipfirewall工作功能極其有限(它需要將所有的規(guī)則都放進內(nèi)核當中,這樣規(guī)則才能夠運行起來,而放進內(nèi)核,這個做法一般是極其困難的)。當內(nèi)核發(fā)展到2.x系列的時候,軟件更名為ipchains,它可以定義多條規(guī)則,將他們串起來,共同發(fā)揮作用,而現(xiàn)在,它叫做iptables,可以將規(guī)則組成一個列表,實現(xiàn)絕對詳細的訪問控制功能。
他們都是工作在用戶空間中,定義規(guī)則的工具,本身并不算是防火墻。它們定義的規(guī)則,可以讓在內(nèi)核空間當中的netfilter來讀取,并且實現(xiàn)讓防火墻工作。而放入內(nèi)核的地方必須要是特定的位置,必須是tcp/ip的協(xié)議棧經(jīng)過的地方。而這個tcp/ip協(xié)議棧必須經(jīng)過的地方,可以實現(xiàn)讀取規(guī)則的地方就叫做 netfilter.(網(wǎng)絡(luò)過濾器)
---->以下是本文所關(guān)注的重點
二、Iptables網(wǎng)絡(luò)黑白名單(防火墻)實現(xiàn)細節(jié)
因為考慮到一些權(quán)限的問題所以在實現(xiàn)方法上采用的是創(chuàng)建一個systemserver來運行這些方法。并提供出manager到三方應(yīng)用,這樣在調(diào)用時可以排除一些權(quán)限的限制。同時本文只是做一個簡單的參考概述,所以在后文中只提供了增加黑白名單的方法和iptables規(guī)則,并沒有提供相應(yīng)的刪除規(guī)則等,原理類似大家可自行補充添加。
2.1、創(chuàng)建systemserver
2.1.1、 在/system/sepolicy/service.te中添加
type fxjnet_service, system_api_service, system_server_service, service_manager_type;
2.2.2、在/system/sepolicy/service_contexts中添加如下,
fxjnet u:object_r:fxjnet_service:s0
2.2.3、在frameworks/base/core/java/android/content/Context.java中添加
也可以不添加這個,只不過為了后面調(diào)用方便所以添加了。如果跳過此步,那么后面出現(xiàn)Context.FXJNET_SERVICE的地方都用字串代替即可。
public static final String FXJNET_SERVICE="fxjnet";
2.2.4、在/frameworks/base/core/java/android/app/SystemServiceRegistry.java的靜態(tài)代碼塊中添加如下代碼注冊service。
registerService(Context.FXJNET_SERVICE, FXJNETManager.class, new CachedServiceFetcher() { @Override public FXJNETManager createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(Context.FXJNET_SERVICE); IFXJNETService service = IFXJNETService.Stub.asInterface(b); return new FXJNETManager(ctx, service); }});
2.2.5、在frameworks/base/services/java/com/android/server/SystemServer.java中添加如下代碼,將service加入systemserver中。
ServiceManager.addService(Context.FXJNET_SERVICE, new FXJNETService());
2.2.6 、AIDL文件
package android.os; interface IFXJNETService{ void addNetworkRestriction(ListipName,int type); }
2.2.7、提供給外部的FXJNETManager
package android.app; import android.os.IFXJNETService; import android.os.RemoteException; import android.content.Context; public class FXJNETManager{ IFXJNETService mService; public FXJNETManager(Context ctx,IFXJNETService service){ mService=service; } public void addNetworkRestriction(ListipName,int type) { try{ mService.addNetworkRestriction(ipName,type); }catch (RemoteException e){ } }//end addNetworkRestriction }
2.2.8、系統(tǒng)服務(wù)即AIDL的實現(xiàn)server
package com.android.server; import android.os.IFXJNETService; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; public class FXJNETService extends IFXJNETService.Stub { final File file = new File("/data/fxj/", "firewall.sh"); /** * 增加{網(wǎng)絡(luò)IP訪問}黑白名單數(shù)據(jù) */ public void addNetworkRestriction(ListipName,int type) { String str= getIPlist(type,ipName); setiptablesRestriction(); } //構(gòu)建Iptables的規(guī)則,1-黑名單 ;2-白名單 private String getIPlist(int type,List iplist){ StringBuilder sb = new StringBuilder(); sb.append("echo runscript start\n"); sb.append("iptables -F OUTPUT\n"); if (type == 1){ if (iplist != null && iplist.size() > 0){ for (int i = 0 ; i < iplist.size() ;i++){ String ipname = iplist.get(i); sb.append("echo blacklist mode\n"); sb.append("iptables -I OUTPUT -d "); sb.append(ipname); sb.append(" -j DROP\n"); } } }else if (type == 2){ if (iplist != null && iplist.size() > 0){ for (int i = 0 ; i < iplist.size() ; i++){ String ipname =iplist.get(i); sb.append("echo whitelist mode\n"); sb.append("iptabless -P OUTPUT DROP\n"); sb.append("iptables -I OUTPUT -d "); sb.append(ipname); sb.append(" -j ACCEPT\n"); } } } sb.append("run script end\n"); return sb.toString(); } private void setiptablesRestriction(String ipName){ final FXJScriptRunner runner = new FXJScriptRunner(file,ipName,new StringBuilder()); new Thread(new Runnable() { @Override public void run() { runner.run(); } }).start(); } }
2.2.9、運行IPTABLES腳本命令的工具類
package com.android.server; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import android.os.FileUtils; import android.os.SystemProperties; import android.util.Log; public class FXJScriptRunner extends Thread{ private final File file; private final String script; private final StringBuilder res; public int exitcode = -1; private final String TAG = "ScriptRunner" ; public ScriptRunner(File file, String script, StringBuilder res, boolean asroot) { this.file = file; this.script = script; this.res = res; } @Override public void run() { // TODO Auto-generated method stub try { file.delete(); file.createNewFile(); final String abspath = file.getAbsolutePath(); // make sure we have execution permission on the script file FileUtils.setPermissions(abspath, 00700, -1, -1); Runtime.getRuntime().exec("chmod 777 " + abspath).waitFor();//給創(chuàng)建的sh文件設(shè)置權(quán)限 // Write the script to be executed final OutputStreamWriter out = new OutputStreamWriter( new FileOutputStream(file)); if (new File("/system/bin/sh").exists()) { out.write("#!/system/bin/sh\n"); } out.write(script); if (!script.endsWith("\n")) out.write("\n"); out.write("exit 0\n"); out.flush(); out.close(); //通過 SystemProperties.set("ctl.start", "fxjmotnitor")執(zhí)行service,來運行腳本, //fxjmotnitor為service名稱,可以根據(jù)自己的愛好隨便叫 SystemProperties.set("ctl.start", "fxjmotnitor"); } catch (Exception ex) { if (res != null) res.append("\n" + ex); } finally { //destroy(); } } }
三、fxjmotnitor service的創(chuàng)建步驟如下。
3.1、在/system/core/rootdir/init.rc中添加如下,使得service在開機時就運行起來
service fxjmotnitor /system/bin/sh /data/fxj/firewall.sh class main oneshot seclabel u:r:fxjmotnitor:s0
3.2、在/sepolicy/目錄下創(chuàng)建fxjmotnitor.te文件,內(nèi)容如下
type fxjmotnitor, domain; type fxjmotnitor_exec, exec_type, file_type; init_daemon_domain(fxjmotnitor) allow fxjmotnitor shell_exec:file { entrypoint getattr read };
3.3、在/sepolicy/file_contexts中添加
/data/fxj/firewall.sh u:object_r:fxjmotnitor_exec:s0
3.4、在sepolicy/Android.mk中的
BOARD_SEPOLICY_UNION += \ #追加如下 ......\ fxjmotnitor.te \ ......\
以上就是基于iptables規(guī)則對ip地址進行管控,從而限制手機那些ip可以訪問那些不可訪問的流程實現(xiàn)之細節(jié),當然iptables的作用不僅僅局限于此,有興趣的可自行了解學習。也希望大家多多支持創(chuàng)新互聯(lián)。