Android 利用Iptables实现网络黑白名单(防火墙)

一、概述
为了使读此简笔的人对Iptables有一个简单的了解,此处强行百度了一波概念,如果想深入的了解Iptables的各种配置规则和内核对其的管理运行机制请自行www.baidu.com,这些并不是本简笔的目的所在。
闲言少叙,开始正文
---->以下概述来自baidu,读者可酌情跳过
iptables的前身叫ipfirewall (内核1.x时代),是从freeBSD上移植过来的,能够工作在内核当中的,对数据包进行检测的一款简易访问控制工具。但是ipfirewall工作功能极其有限(它需要将所有的规则都放进内核当中,这样规则才能够运行起来,而放进内核,这个做法一般是极其困难的)。当内核发展到2.x系列的时候,软件更名为ipchains,它可以定义多条规则,将他们串起来,共同发挥作用,而现在,它叫做iptables,可以将规则组成一个列表,实现绝对详细的访问控制功能。
他们都是工作在用户空间中,定义规则的工具,本身并不算是防火墙。它们定义的规则,可以让在内核空间当中的netfilter来读取,并且实现让防火墙工作。而放入内核的地方必须要是特定的位置,必须是tcp/ip的协议栈经过的地方。而这个tcp/ip协议栈必须经过的地方,可以实现读取规则的地方就叫做 netfilter.(网络过滤器)

---->以下是本文所关注的重点
二、Iptables网络黑白名单(防火墙)实现细节
因为考虑到一些权限的问题所以在实现方法上采用的是创建一个systemserver来运行这些方法。并提供出manager到三方应用,这样在调用时可以排除一些权限的限制。同时本文只是做一个简单的参考概述,所以在后文中只提供了增加黑白名单的方法和iptables规则,并没有提供相应的删除规则等,原理类似大家可自行补充添加。
2.1、创建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中添加
也可以不添加这个,只不过为了后面调用方便所以添加了。如果跳过此步,那么后面出现Context.FXJNET_SERVICE的地方都用字串代替即可。

 public static final String FXJNET_SERVICE="fxjnet";

2.2.4、在/frameworks/base/core/java/android/app/SystemServiceRegistry.java的静态代码块中添加如下代码注册service。

registerService(Context.FXJNET_SERVICE, FXJNETManager.class,
             new CachedServiceFetcher<FXJNETManager>() {
             @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(List<String> ipName,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(List<String> ipName,int type) {
       try{
            mService.addNetworkRestriction(ipName,type);
      }catch (RemoteException e){
      }
  }//end addNetworkRestriction
} 

2.2.8、系统服务即AIDL的实现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");
    /**
     * 增加{网络IP访问}黑白名单数据
     */
    public void addNetworkRestriction(List<String> ipName,int type) {
           String str= getIPlist(type,ipName);
           setiptablesRestriction();
    }
//构建Iptables的规则,1-黑名单 ;2-白名单
 private String getIPlist(int type,List<String> 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();//给创建的sh文件设置权限
            // 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")执行service,来运行脚本,
//fxjmotnitor为service名称,可以根据自己的爱好随便叫
            SystemProperties.set("ctl.start", "fxjmotnitor");
        } catch (Exception ex) {
            if (res != null)
                res.append("\n" + ex);
        } finally {
            //destroy();
        }
    }
}

三、fxjmotnitor service的创建步骤如下。

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/目录下创建fxjmotnitor.te文件,内容如下

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规则对ip地址进行管控,从而限制手机那些ip可以访问那些不可访问的流程实现之细节,当然iptables的作用不仅仅局限于此,有兴趣的可自行了解学习。
笔末,祝诸君百顺!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351

推荐阅读更多精彩内容

  • 1:InputChannel提供函数创建底层的Pipe对象 2: 1)客户端需要新建窗口 2)new ViewRo...
    自由人是工程师阅读 5,284评论 0 18
  • 1.安全技术 (1)入侵检测与管理系统(Intrusion Detection Systems): 特点是不阻断任...
    尛尛大尹阅读 2,461评论 0 2
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,885评论 25 707
  • 1.1 防火墙的概念 Firewall(防火墙):组件,工作在网络边缘(主机边缘),对进出网络数据包基于一定的规则...
    扎啤阅读 2,079评论 0 0
  • 七堇年说过“被窝是青春的坟墓”,对于此刻在拥着被子打字的我来说,这句话真是形容的太贴切了,虽说我的青春早已经过去。...
    一朵胖小花阅读 386评论 2 0