Detailed explanation of Android using Iptables to realize network black and white list of firewall

  • 2021-10-11 19:38:51
  • OfStack

1. Overview

In order to make people who read this short pen have a simple understanding of Iptables, Baidu has forced a wave of concepts here. If you want to have a deep understanding of various configuration rules of Iptables and the management and operation mechanism of the kernel, please use your own www.baidu.com, which is not the purpose of this short pen.

Let's talk less and start the text

---- > The following summary is from baidu, and readers can skip it as appropriate

iptables, formerly called ipfirewall (kernel 1. x era), is a simple access control tool transplanted from freeBSD, which can work in the kernel and detect data packets. But ipfirewall is extremely limited (it needs to put all the rules into the kernel so that the rules can work, which is generally extremely difficult to put into the kernel). When the kernel developed to 2. x series, the software was renamed ipchains, which can define multiple rules and string them together to play a role together. Now, it is called iptables, which can form a list of rules to realize absolutely detailed access control functions.

They are all tools that work in user space and define rules, and they are not firewalls in themselves. They define rules that can be read by netfilter in kernel space, and make the firewall work. And the place to put it in the kernel must be a specific place, which must be the place where the protocol stack of tcp/ip passes. The place where the tcp/ip protocol stack must pass and the place where the reading rules can be realized is called netfilter. (Network filter)

---- > The following are the key points of this article

2. Iptables Network Black and White List (Firewall) Implementation Details

Considering some permissions, the implementation method is to create an systemserver to run these methods. And provides manager to 3-party applications, so that the call can exclude 1 permission restrictions. At the same time, this article is only a simple reference overview, so in the following article, only the method of adding black and white list and iptables rules are provided, and the corresponding deletion rules are not provided. The principle is similar, and everyone can add it by themselves.

2.1. Create systemserver

2.1. 1 Add in/system/sepolicy/service. te


type fxjnet_service, system_api_service, system_server_service, service_manager_type;

2.2. 2, add the following in /system/sepolicy/service_contexts,


fxjnet      u:object_r:fxjnet_service:s0

2.2. 3 Add in frameworks/base/core/java/android/content/Context. java

You can also not add this, but add it for the convenience of calling later. If you skip this step, then all subsequent Context. FXJNET_SERVICE can be replaced by strings.


public static final String FXJNET_SERVICE="fxjnet";

2.2. 4 Register service by adding the following code to the static code block of/frameworks/base/core/java/android/app/SystemServiceRegistry. java.


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 Add service to systemserver by adding the following code to frameworks/base/services/java/com/android/server/SystemServer. java.


ServiceManager.addService(Context.FXJNET_SERVICE, new FXJNETService());

2.2. 6, AIDL file


package android.os;
interface IFXJNETService{
  void addNetworkRestriction(List<String> ipName,int type);
}

2.2. 7. External 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. System services, the implementation of 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");
  /**
   *  Increase { Network IP Visit } Black and white list data 
   */
  public void addNetworkRestriction(List<String> ipName,int type) {
      String str= getIPlist(type,ipName);
      setiptablesRestriction();
  }
// Build Iptables The rules, 1- Blacklist   ; 2- White list 
 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. A tool class for running IPTABLES script commands


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();// To the created sh File setting permissions 
      // 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();
// Pass  SystemProperties.set("ctl.start", "fxjmotnitor") Execute service To run the script, 
//fxjmotnitor For service Name , You can call it according to your own hobbies 
      SystemProperties.set("ctl.start", "fxjmotnitor");
    } catch (Exception ex) {
      if (res != null)
        res.append("\n" + ex);
    } finally {
      //destroy();
    }
  }
}

3. The steps to create fxjmotnitor service are as follows.

3.1. Add the following in/system/core/rootdir/init. rc to make service run on boot


service fxjmotnitor /system/bin/sh /data/fxj/firewall.sh
 class main
 oneshot
 seclabel u:r:fxjmotnitor:s0

3.2. Create the fxjmotnitor. te file under the/sepolicy/directory, as follows


fxjnet      u:object_r:fxjnet_service:s0
0

3.3. Add in /sepolicy/file_contexts


fxjnet      u:object_r:fxjnet_service:s0
1

3.4, in sepolicy/Android. mk


fxjnet      u:object_r:fxjnet_service:s0
2

Related articles: