详解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的作用不仅仅局限于此,有兴趣的可自行了解学习。也希望大家多多支持我们。

(0)

相关推荐

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

    一.概述 为了使读此简笔的人对Iptables有一个简单的了解,此处强行百度了一波概念,如果想深入的了解Iptables的各种配置规则和内核对其的管理运行机制请自行www.baidu.com,这些并不是本简笔的目的所在. 闲言少叙,开始正文 ---->以下概述来自baidu,读者可酌情跳过 iptables的前身叫ipfirewall (内核1.x时代),是从freeBSD上移植过来的,能够工作在内核当中的,对数据包进行检测的一款简易访问控制工具.但是ipfirewall工作功能极其有限(它需要

  • 详解Android如何实现好的弹层体验效果

    目录 前言 弹层的形式选择 中间弹层 左右抽屉弹层 顶部弹层 底部弹层 总结 前言 当前 App 的设计趋势越来越希望给用户沉浸式体验,这种设计会让用户尽量停留在当前的界面,而不需要太多的跳转,这就需要引入弹层.比如,抖音引入购物功能后,就实现了在观看视频界面可以通过弹层完成加入购物车.下单操作,无需离开当前的视频界面.本篇我们就来讲讲弹层这块需要注意哪些用户体验. 弹层的形式选择 弹层从形式上来说有中间弹层.左侧弹层.右侧弹层.底部弹层和顶部弹层,如下图所示. 移动端经过这么多年的发展,不同的

  • 详解Swift 利用Opration和OprationQueue来下载网络图片

    详解Swift 利用Opration和OprationQueue来下载网络图片 1. 基于Opration封装的获取网络数据组件 import Foundation import UIKit public typealias OpreationClosure = ((_ data:Data? , _ error: Error?) -> Void) class LJOpreationManager: Operation { /** * 下载用的url */ public var imageUrl

  • 实例详解Android文件存储数据方式

    总体的来讲,数据存储方式有三种:一个是文件,一个是数据库,另一个则是网络.下面通过本文给大家介绍Android文件存储数据方式. 1.文件存储数据使用了Java中的IO操作来进行文件的保存和读取,只不过Android在Context类中封装好了输入流和输出流的获取方法. 创建的存储文件保存在/data/data/<package name>/files文件夹下. 2.操作. 保存文件内容:通过Context.openFileOutput获取输出流,参数分别为文件名和存储模式. 读取文件内容:通

  • 详解Android中图片的三级缓存及实例

    详解Android中图片的三级缓存及实例 为什么要使用三级缓存 如今的 Android App 经常会需要网络交互,通过网络获取图片是再正常不过的事了 假如每次启动的时候都从网络拉取图片的话,势必会消耗很多流量.在当前的状况下,对于非wifi用户来说,流量还是很贵的,一个很耗流量的应用,其用户数量级肯定要受到影响 特别是,当我们想要重复浏览一些图片时,如果每一次浏览都需要通过网络获取,流量的浪费可想而知 所以提出三级缓存策略,通过网络.本地.内存三级缓存图片,来减少不必要的网络交互,避免浪费流量

  • 详解Android 中AsyncTask 的使用

    详解Android 中AsyncTask 的使用 1.首先我们来看看AsyncTask 的介绍:   Handler 和 AsyncTask 都是android 中用来实现异步任务处理的方式:其中: Handler 实例向 UI 线程发送消息,完成界面更新, 优点:对整个过程控制的比较精细:         缺点:代码相对臃肿,多个任务同时执行时,不易对线程进行精确的控制: AsyncTask :比Handler 更轻量级一些,适用于简单的异步处理: 优点:简单 | 快捷 | 过程可控:    

  • 详解Android studio如何导入jar包方法

    下面我就总结一下Android studio大家在导入jar包时遇到的一些问题和解决方法: 1,首先先说一下怎么在AS 中找到sdk,jdk,ndk的安装路径,可能一部分人一开始找不到,下面贴出方法: Android studio 中更改sdk的路径,如下图,在右边红色方框中更改sdk的路径 还有一种更好的方式可以把sdk,jdk,ndk的路径全部找到,首先File---Other Settings---Default Project Structure...,打开如下图界面,从红方框处即可直接

  • 详解Android StrictMode严格模式的使用方法

    Android 2.3提供一个称为严苛模式StrictMode的调试特性,Google称该特性已经使数百个Android上的Google应用程序受益.那它都做什么呢?它将报告与线程及虚拟机相关的策略违例.一旦检测到策略违例policy violation,你将获得警告,其包含了一个栈trace显示你的应用在何处发生违例.你可以强制用警告代替崩溃crash,也可以仅将警告计入日志让你的应用继续执行.StrictMode是一个十分有用的类,它可以很方便地应用于检查Android应用程序的性能和存在的

  • 详解Android 基于TCP和UDP协议的Socket通信

    本来想讲一下基础的网络通信方面的知识点,发现太枯燥乏味了,不过笔试中也经常会问到这方面的问题,所以关于通信方面的知识点,小编会放到面试中去,因为实战中也就面试会用到这方面知识点 Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信.两者的最大差异在于,http连接使用的是"请求-响应方式",即在请求时建立连接通道,当客户端向服务器发送请求后,服务器端才能向客户端返回数据. 而Socket通信中基于TCP/IP协议的通信则是在双方建立起连接后就可以直接进行数

  • 详解Android 硬布局item的高级写法

    本文主要介绍了Android 硬布局item的高级写法,分享给大家,具体如下: 效果: 这种布局应该是非常常见了,且写的比较多. 今天简单探讨一下效果图中上下两种布局的写法. 比较 上下效果一致 行数 层级 上部分 121 3 下部分 55 2 下部分继续精简 28 2 可以看出,对比还是很明显的,精简到最后只有最开始的四分之一. 上部分 先看常规item写法,横向的LinearLayout嵌套三个子View,分别是 左边的ImageView, 中间的TextView, 和右边的ImageVie

随机推荐