Android 网络防火墙的实现 Iptables解决方案

15 篇文章 0 订阅
15 篇文章 0 订阅

转自:   http://blog.csdn.net/zengyangtech/article/details/5579311


通过对Android SDK帮助文档的阅读,我没有发现Android的高层提供的API,于是通过更底层考虑,我发现了可以采用Iptables实现防火墙的功能。而且linux下主流的防火墙也是Iptables。

     

Iptables的介绍:

iptables 是与最新的 2.6.x 版本 Linux 内核集成的 IP 信息包过滤系统。如果 Linux 系统连接到因特网或 LAN、服务器或连接 LAN 和因特网的代理服务器,则该系统有利于在 Linux 系统上更好地控制 IP 信息包过滤和防火墙配置。

其工作原理:

netfilter/iptables IP 信息包过滤系统是一种功能强大的工具, 可用于添加、编辑和除去规则,这些规则是在做信息包过滤决定时,防火墙所遵循和组成的规则。这些规则存储在专用的信息包过滤表中, 而这些表集成在 Linux 内核中。 在信息包过滤表中,规则被分组放在我们所谓的 链(chain)中。我马上会详细讨论这些规则以及如何建立这些规则并将它们分组在链中。

虽然 netfilter/iptables IP 信息包过滤系统被称为单个实体,但它实际上由两个组件 netfilter和 iptables 组成。

netfilter 组件也称为 内核空间(kernelspace),是内核的一部分,由一些信息包过滤表组成, 这些表包含内核用来控制信息包过滤处理的规则集。

iptables 组件是一种工具,也称为 用户空间(userspace),它使插入、修改和除去信息包过滤表中的规则变得容易。 除非您正在使用 Red Hat Linux 7.1或更高版本,否则需要从 netfilter.org 下载该工具并安装使用它。

通过使用用户空间,可以构建自己的定制规则,这些规则存储在内核空间的信息包过滤表中。 这些规则具有 目标,它们告诉内核对来自某些源、前往某些目的地或具有某些协议类型的信息包做些什么。 如果某个信息包与规则匹配,那么使用目标 ACCEPT 允许该信息包通过。还可以使用目标 DROP 或REJECT 来阻塞并杀死信息包。对于可对信息包执行的其它操作,还有许多其它目标。

根据规则所处理的信息包的类型,可以将规则分组在链中。处理入站信息包的规则被添加到 INPUT 链中。处理出站信息包的规则被添加到 OUTPUT 链中。处理正在转发的信息包的规则被添加到 FORWARD 链中。这三个链是基本信息包过滤表中内置的缺省主链。 另外,还有其它许多可用的链的类型(如 PREROUTING 和 POSTROUTING ), 以及提供用户定义的链。每个链都可以有一个 策略, 它定义“缺省目标”,也就是要执行的缺省操作,当信息包与链中的任何规则都不匹配时,执行此操作。

建立规则并将链放在适当的位置之后,就可以开始进行真正的信息包过滤工作了。 这时内核空间从用户空间接管工作。当信息包到达防火墙时,内核先 检查信息包的头信息,尤其是信息包的目的地。 我们将这个过程称为 路由。

如果信息包源自外界并前往系统,而且防火墙是打开的,那么内核将它传递到内核空间信息包过滤表的 INPUT 链。如果信息包源自系统内部或系统所连接的内部网上的其它源,并且此信息包要前往另一个外部系统, 那么信息包被传递到 OUTPUT 链。类似的,源自外部系统并前往外部系统的信息包被传递到 FORWARD 链。

接下来,将信息包的头信息与它所传递到的链中的每条规则进行比较,看它是否与某条规则完全匹配。 如果信息包与某条规则匹配,那么内核就对该信息包执行由该规则的目标指定的操作。 但是,如果信息包与这条规则不匹配,那么它将与链中的下一条规则进行比较。 最后,如果信息包与链中的任何规则都不匹配,那么内核将参考该链的策略来决定如何处理该信息包。 理想的策略应该告诉内核 DROP 该信息包。下图用图形说明了这个信息包过滤过程。

 

使用Iptables进行防火墙软件设计的解决方案。

由于Iptables已经有了完善的防火墙规则,我们只需要设计一个基于Iptables的Android前台即可,通过运行脚本,调用iptables设置防火墙规则即可。

 

  大家可以学习下Droid wall的源代码

[java]  view plain copy
  1. package com.googlecode.droidwall;  
  2. /** 
  3.  * Contains shared programming interfaces. 
  4.  * All iptables "communication" is handled by this class. 
  5.  * 
  6.  * Copyright (C) 2009  Rodrigo Zechin Rosauro 
  7.  * 
  8.  * This program is free software: you can redistribute it and/or modify 
  9.  * it under the terms of the GNU General Public License as published by 
  10.  * the Free Software Foundation, either version 3 of the License, or 
  11.  * (at your option) any later version. 
  12.  * 
  13.  * This program is distributed in the hope that it will be useful, 
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  16.  * GNU General Public License for more details. 
  17.  * 
  18.  * You should have received a copy of the GNU General Public License 
  19.  * along with this program.  If not, see <http://www.gnu.org/licenses/>. 
  20.  * 
  21.  * @author Rodrigo Zechin Rosauro 
  22.  * @version 1.0 
  23.  */  
  24. import java.io.IOException;  
  25. import java.io.InputStreamReader;  
  26. import java.io.OutputStreamWriter;  
  27. import java.util.Arrays;  
  28. import java.util.HashMap;  
  29. import java.util.LinkedList;  
  30. import java.util.List;  
  31. import java.util.StringTokenizer;  
  32. import android.app.AlertDialog;  
  33. import android.content.Context;  
  34. import android.content.SharedPreferences;  
  35. import android.content.SharedPreferences.Editor;  
  36. import android.content.pm.ApplicationInfo;  
  37. import android.content.pm.PackageManager;  
  38. import android.util.Log;  
  39. /** 
  40.  * Contains shared programming interfaces. 
  41.  * All iptables "communication" is handled by this class. 
  42.  */  
  43. public final class Api {  
  44.         public static final String VERSION = "1.3.6";  
  45.         // Preferences  
  46.         public static final String PREFS_NAME           = "DroidWallPrefs";  
  47.         public static final String PREF_ALLOWEDUIDS = "AllowedUids";  
  48.         public static final String PREF_PASSWORD        = "Password";  
  49.         public static final String PREF_MODE            = "BlockMode";  
  50.         public static final String PREF_ITFS            = "Interfaces";  
  51.         // Modes  
  52.         public static final String MODE_WHITELIST = "whitelist";  
  53.         public static final String MODE_BLACKLIST = "blacklist";  
  54.         // Interfaces  
  55.         public static final String ITF_3G = "2G/3G";  
  56.         public static final String ITF_WIFI = "Wi-fi";  
  57.         // Cached applications  
  58.         public static DroidApp applications[] = null;  
  59.         // Do we have "Wireless Tether for Root Users" installed?  
  60.         public static String hastether = null;  
  61.         // Do we have root access?  
  62.         private static boolean hasroot = false;  
  63.     /** 
  64.      * Display a simple alert box 
  65.      * @param ctx context 
  66.      * @param msg message 
  67.      */  
  68.         public static void alert(Context ctx, CharSequence msg) {  
  69.         if (ctx != null) {  
  70.                 new AlertDialog.Builder(ctx)  
  71.                 .setNeutralButton(android.R.string.ok, null)  
  72.                 .setMessage(msg)  
  73.                 .show();  
  74.         }  
  75.     }  
  76.     /** 
  77.      * Purge and re-add all rules (internal implementation). 
  78.      * @param ctx application context (mandatory) 
  79.      * @param uids list of selected uids to allow or disallow (depending on the working mode) 
  80.      * @param showErrors indicates if errors should be alerted 
  81.      */  
  82.         private static boolean applyIptablesRulesImpl(Context ctx, List<Integer> uids, boolean showErrors) {  
  83.                 if (ctx == null) {  
  84.                         return false;  
  85.                 }  
  86.                 final SharedPreferences prefs = ctx.getSharedPreferences(PREFS_NAME, 0);  
  87.                 final boolean whitelist = prefs.getString(PREF_MODE, MODE_WHITELIST).equals(MODE_WHITELIST);  
  88.                 boolean wifi = false// Wi-fi selected ?  
  89.                 final String itfs = prefs.getString(PREF_ITFS, ITF_3G);  
  90.                 String itfFilter;  
  91.                 if (itfs.indexOf("|") != -1) {  
  92.                         itfFilter = ""// Block all interfaces  
  93.                         wifi = true;  
  94.                 } else if (itfs.indexOf(ITF_3G) != -1) {  
  95.                         itfFilter = "-o rmnet+";; // Block all rmnet interfaces  
  96.                 } else {  
  97.                         itfFilter = "-o tiwlan+";; // Block all tiwlan interfaces  
  98.                         wifi = true;  
  99.                 }  
  100.         final StringBuilder script = new StringBuilder();  
  101.                 try {  
  102.                         int code;  
  103.                         script.append("iptables -F || exit/n");  
  104.                         final String targetRule = (whitelist ? "ACCEPT" : "REJECT");  
  105.                         if (whitelist && wifi) {  
  106.                                 // When "white listing" Wi-fi, we need ensure that the dhcp and wifi users are allowed  
  107.                                 int uid = android.os.Process.getUidForName("dhcp");  
  108.                                 if (uid != -1) script.append("iptables -A OUTPUT " + itfFilter + " -m owner --uid-owner " + uid + " -j ACCEPT || exit/n");  
  109.                                 uid = android.os.Process.getUidForName("wifi");  
  110.                                 if (uid != -1) script.append("iptables -A OUTPUT " + itfFilter + " -m owner --uid-owner " + uid + " -j ACCEPT || exit/n");  
  111.                         }  
  112.                         for (Integer uid : uids) {  
  113.                                 script.append("iptables -A OUTPUT " + itfFilter + " -m owner --uid-owner " + uid + " -j " + targetRule + " || exit/n");  
  114.                         }  
  115.                         if (whitelist) {  
  116.                                 script.append("iptables -A OUTPUT " + itfFilter + " -j REJECT || exit/n");  
  117.                         }  
  118.                 StringBuilder res = new StringBuilder();  
  119.                         code = runScriptAsRoot(script.toString(), res);  
  120.                         if (showErrors && code != 0) {  
  121.                                 String msg = res.toString();  
  122.                                 Log.e("DroidWall", msg);  
  123.                                 // Search for common error messages  
  124.                                 if (msg.indexOf("Couldn't find match `owner'") != -1 || msg.indexOf("no chain/target match") != -1) {  
  125.                                         alert(ctx, "Error applying iptables rules./nExit code: " + code + "/n/n" +  
  126.                                                 "It seems your Linux kernel was not compiled with the netfilter /"owner/" module enabled, which is required for Droid Wall to work properly./n/n" +  
  127.                                                 "You should check if there is an updated version of your Android ROM compiled with this kernel module.");  
  128.                                 } else {  
  129.                                         // Remove unnecessary help message from output  
  130.                                         if (msg.indexOf("/nTry `iptables -h' or 'iptables --help' for more information.") != -1) {  
  131.                                                 msg = msg.replace("/nTry `iptables -h' or 'iptables --help' for more information.""");  
  132.                                         }  
  133.                                         // Try `iptables -h' or 'iptables --help' for more information.  
  134.                                         alert(ctx, "Error applying iptables rules. Exit code: " + code + "/n/n" + msg.trim());  
  135.                                 }  
  136.                         } else {  
  137.                                 return true;  
  138.                         }  
  139.                 } catch (Exception e) {  
  140.                         if (showErrors) alert(ctx, "error refreshing iptables: " + e);  
  141.                 }  
  142.                 return false;  
  143.     }  
  144.     /** 
  145.      * Purge and re-add all saved rules (not in-memory ones). 
  146.      * This is much faster than just calling "applyIptablesRules", since it don't need to read installed applications. 
  147.      * @param ctx application context (mandatory) 
  148.      * @param showErrors indicates if errors should be alerted 
  149.      */  
  150.         public static boolean applySavedIptablesRules(Context ctx, boolean showErrors) {  
  151.                 if (ctx == null) {  
  152.                         return false;  
  153.                 }  
  154.                 final String savedNames = ctx.getSharedPreferences(PREFS_NAME, 0).getString(PREF_ALLOWEDUIDS, "");  
  155.                 List<Integer> uids = new LinkedList<Integer>();  
  156.                 if (savedNames.length() > 0) {  
  157.                         // Check which applications are allowed  
  158.                         final StringTokenizer tok = new StringTokenizer(savedNames, "|");  
  159.                         while (tok.hasMoreTokens()) {  
  160.                                 uids.add(android.os.Process.getUidForName(tok.nextToken()));  
  161.                         }  
  162.                 }  
  163.                 return applyIptablesRulesImpl(ctx, uids, showErrors);  
  164.         }  
  165.     /** 
  166.      * Purge and re-add all rules. 
  167.      * @param ctx application context (mandatory) 
  168.      * @param showErrors indicates if errors should be alerted 
  169.      */  
  170.         public static boolean applyIptablesRules(Context ctx, boolean showErrors) {  
  171.                 if (ctx == null) {  
  172.                         return false;  
  173.                 }  
  174.                 final SharedPreferences prefs = ctx.getSharedPreferences(PREFS_NAME, 0);  
  175.                 List<Integer> uidsToApply = new LinkedList<Integer>();  
  176.                 final DroidApp[] apps = getApps(ctx);  
  177.                 // Builds a pipe-separated list of names  
  178.                 final StringBuilder newnames = new StringBuilder();  
  179.                 for (int i=0; i<apps.length; i++) {  
  180.                         if (apps[i].selected) {  
  181.                                 if (newnames.length() != 0) newnames.append('|');  
  182.                                 newnames.append(apps[i].username);  
  183.                                 uidsToApply.add(apps[i].uid);  
  184.                         }  
  185.                 }  
  186.                 // save the new list of names if necessary  
  187.                 if (!newnames.toString().equals(prefs.getString(PREF_ALLOWEDUIDS, ""))) {  
  188.                         Editor edit = prefs.edit();  
  189.                         edit.putString(PREF_ALLOWEDUIDS, newnames.toString());  
  190.                         edit.commit();  
  191.                 }  
  192.                 return applyIptablesRulesImpl(ctx, uidsToApply, showErrors);  
  193.     }  
  194.     /** 
  195.      * Purge all iptables rules. 
  196.      * @param ctx context optional context for alert messages 
  197.      * @return true if the rules were purged 
  198.      */  
  199.         public static boolean purgeIptables(Context ctx) {  
  200.         StringBuilder res = new StringBuilder();  
  201.                 try {  
  202.                         int code = runScriptAsRoot("iptables -F || exit/n", res);  
  203.                         if (code != 0) {  
  204.                                 alert(ctx, "error purging iptables. exit code: " + code + "/n" + res);  
  205.                                 return false;  
  206.                         }  
  207.                         return true;  
  208.                 } catch (Exception e) {  
  209.                         alert(ctx, "error purging iptables: " + e);  
  210.                         return false;  
  211.                 }  
  212.     }  
  213.         /** 
  214.          * Display iptables rules output 
  215.          * @param ctx application context 
  216.          */  
  217.         public static void showIptablesRules(Context ctx) {  
  218.                 try {  
  219.                 final StringBuilder res = new StringBuilder();  
  220.                         runScriptAsRoot("iptables -L/n", res);  
  221.                         alert(ctx, res);  
  222.                 } catch (Exception e) {  
  223.                         alert(ctx, "error: " + e);  
  224.                 }  
  225.         }  
  226.     /** 
  227.      * @param ctx application context (mandatory) 
  228.      * @return a list of applications 
  229.      */  
  230.         public static DroidApp[] getApps(Context ctx) {  
  231.                 if (applications != null) {  
  232.                         // return cached instance  
  233.                         return applications;  
  234.                 }  
  235.                 hastether = null;  
  236.                 // allowed application names separated by pipe '|' (persisted)  
  237.                 final String savedNames = ctx.getSharedPreferences(PREFS_NAME, 0).getString(PREF_ALLOWEDUIDS, "");  
  238.                 String allowed[];  
  239.                 if (savedNames.length() > 0) {  
  240.                         // Check which applications are allowed  
  241.                         final StringTokenizer tok = new StringTokenizer(savedNames, "|");  
  242.                         allowed = new String[tok.countTokens()];  
  243.                         for (int i=0; i<allowed.length; i++) {  
  244.                                 allowed[i] = tok.nextToken();  
  245.                         }  
  246.                         // Sort the array to allow using "Arrays.binarySearch" later  
  247.                         Arrays.sort(allowed);  
  248.                 } else {  
  249.                         allowed = new String[0];  
  250.                 }  
  251.                 try {  
  252.                         final PackageManager pkgmanager = ctx.getPackageManager();  
  253.                         final List<ApplicationInfo> installed = pkgmanager.getInstalledApplications(0);  
  254.                         final HashMap<Integer, DroidApp> map = new HashMap<Integer, DroidApp>();  
  255.                         String name;  
  256.                         DroidApp app;  
  257.                         for (final ApplicationInfo apinfo : installed) {  
  258.                                 app = map.get(apinfo.uid);  
  259.                                 name = pkgmanager.getApplicationLabel(apinfo).toString();  
  260.                                 // Check for the tethering application (which causes conflicts with Droid Wall)  
  261.                                 if (apinfo.packageName.equals("android.tether")) {  
  262.                                         hastether = name;  
  263.                                 }  
  264.                                 if (app == null) {  
  265.                                         app = new DroidApp();  
  266.                                         app.uid = apinfo.uid;  
  267.                                         app.username = pkgmanager.getNameForUid(apinfo.uid);  
  268.                                         app.names = new String[] { name };  
  269.                                         map.put(apinfo.uid, app);  
  270.                                 } else {  
  271.                                         final String newnames[] = new String[app.names.length + 1];  
  272.                                         System.arraycopy(app.names, 0, newnames, 0, app.names.length);  
  273.                                         newnames[app.names.length] = name;  
  274.                                         app.names = newnames;  
  275.                                 }  
  276.                                 // check if this application is allowed  
  277.                                 if (!app.selected && Arrays.binarySearch(allowed, app.username) >= 0) {  
  278.                                         app.selected = true;  
  279.                                 }  
  280.                         }  
  281.                         /* add special applications to the list */  
  282.                         final DroidApp special[] = {  
  283.                                 new DroidApp(android.os.Process.getUidForName("root"), "root""(Applications running as root)"false),  
  284.                                 new DroidApp(android.os.Process.getUidForName("media"), "media""Media server"false),  
  285.                         };  
  286.                         for (int i=0; i<special.length; i++) {  
  287.                                 app = special[i];  
  288.                                 if (app.uid != -1 && !map.containsKey(app.uid)) {  
  289.                                         // check if this application is allowed  
  290.                                         if (Arrays.binarySearch(allowed, app.username) >= 0) {  
  291.                                                 app.selected = true;  
  292.                                         }  
  293.                                         map.put(app.uid, app);  
  294.                                 }  
  295.                         }  
  296.                         applications = new DroidApp[map.size()];  
  297.                         int index = 0;  
  298.                         for (DroidApp application : map.values()) applications[index++] = application;  
  299.                         return applications;  
  300.                 } catch (Exception e) {  
  301.                         alert(ctx, "error: " + e);  
  302.                 }  
  303.                 return null;  
  304.         }  
  305.         /** 
  306.          * Check if we have root access 
  307.          * @param ctx optional context to display alert messages 
  308.          * @return boolean true if we have root 
  309.          */  
  310.         public static boolean hasRootAccess(Context ctx) {  
  311.                 if (hasroot) return true;  
  312.                 try {  
  313.                         // Run an empty script just to check root access  
  314.                         if (runScriptAsRoot("exit 0"null20000) == 0) {  
  315.                                 hasroot = true;  
  316.                                 return true;  
  317.                         }  
  318.                 } catch (Exception e) {  
  319.                 }  
  320.                 alert(ctx, "Could not acquire root access./n" +  
  321.                         "You need a rooted phone to run Droid Wall./n/n" +  
  322.                         "If this phone is already rooted, please make sure Droid Wall has enough permissions to execute the /"su/" command.");  
  323.                 return false;  
  324.         }  
  325.     /** 
  326.      * Runs a script as root (multiple commands separated by "/n"). 
  327.      * 
  328.      * @param script the script to be executed 
  329.      * @param res the script output response (stdout + stderr) 
  330.      * @param timeout timeout in milliseconds (-1 for none) 
  331.      * @return the script exit code 
  332.      */  
  333.         public static int runScriptAsRoot(String script, StringBuilder res, final long timeout) {  
  334.                 final ScriptRunner runner = new ScriptRunner(script, res);  
  335.                 runner.start();  
  336.                 try {  
  337.                         if (timeout > 0) {  
  338.                                 runner.join(timeout);  
  339.                         } else {  
  340.                                 runner.join();  
  341.                         }  
  342.                         if (runner.isAlive()) {  
  343.                                 // Timed-out  
  344.                                 runner.interrupt();  
  345.                                 runner.destroy();  
  346.                                 runner.join(50);  
  347.                         }  
  348.                 } catch (InterruptedException ex) {}  
  349.                 return runner.exitcode;  
  350.     }  
  351.     /** 
  352.      * Runs a script as root (multiple commands separated by "/n") with a default timeout of 5 seconds. 
  353.      * 
  354.      * @param script the script to be executed 
  355.      * @param res the script output response (stdout + stderr) 
  356.      * @param timeout timeout in milliseconds (-1 for none) 
  357.      * @return the script exit code 
  358.      * @throws IOException on any error executing the script, or writing it to disk 
  359.      */  
  360.         public static int runScriptAsRoot(String script, StringBuilder res) throws IOException {  
  361.                 return runScriptAsRoot(script, res, 15000);  
  362.         }  
  363.     /** 
  364.      * Small structure to hold an application info 
  365.      */  
  366.         public static final class DroidApp {  
  367.                 /** linux user id */  
  368.         int uid;  
  369.         /** application user name (Android actually uses a package name to identify) */  
  370.         String username;  
  371.         /** application names belonging to this user id */  
  372.         String names[];  
  373.         /** indicates if this application is selected (checked) */  
  374.         boolean selected;  
  375.         /** toString cache */  
  376.         String tostr;  
  377.         public DroidApp() {  
  378.         }  
  379.         public DroidApp(int uid, String username, String name, boolean selected) {  
  380.                 this.uid = uid;  
  381.                 this.username = username;  
  382.                 this.names = new String[] {name};  
  383.                 this.selected = selected;  
  384.         }  
  385.         /** 
  386.          * Screen representation of this application 
  387.          */  
  388.         @Override  
  389.         public String toString() {  
  390.                 if (tostr == null) {  
  391.                         final StringBuilder s = new StringBuilder(uid + ": ");  
  392.                         for (int i=0; i<names.length; i++) {  
  393.                                 if (i != 0) s.append(", ");  
  394.                                 s.append(names[i]);  
  395.                         }  
  396.                         tostr = s.toString();  
  397.                 }  
  398.                 return tostr;  
  399.         }  
  400.     }  
  401.         /** 
  402.          * Internal thread used to execute scripts as root. 
  403.          */  
  404.         private static final class ScriptRunner extends Thread {  
  405.                 private final String script;  
  406.                 private final StringBuilder res;  
  407.                 public int exitcode = -1;  
  408.                 private Process exec;  
  409.                 /** 
  410.                  * Creates a new script runner. 
  411.                  * @param script script to run 
  412.                  * @param res response output 
  413.                  */  
  414.                 public ScriptRunner(String script, StringBuilder res) {  
  415.                         this.script = script;  
  416.                         this.res = res;  
  417.                 }  
  418.                 @Override  
  419.                 public void run() {  
  420.                         try {  
  421.                                 // Create the "su" request to run the command  
  422.                                 // note that this will create a shell that we must interact to (using stdin/stdout)  
  423.                                 exec = Runtime.getRuntime().exec("su");  
  424.                                 final OutputStreamWriter out = new OutputStreamWriter(exec.getOutputStream());  
  425.                                 // Write the script to be executed  
  426.                                 out.write(script);  
  427.                                 // Ensure that the last character is an "enter"  
  428.                                 if (!script.endsWith("/n")) out.write("/n");  
  429.                                 out.flush();  
  430.                                 // Terminate the "su" process  
  431.                                 out.write("exit/n");  
  432.                                 out.flush();  
  433.                                 final char buf[] = new char[1024];  
  434.                                 // Consume the "stdout"  
  435.                                 InputStreamReader r = new InputStreamReader(exec.getInputStream());  
  436.                                 int read=0;  
  437.                                 while ((read=r.read(buf)) != -1) {  
  438.                                         if (res != null) res.append(buf, 0, read);  
  439.                                 }  
  440.                                 // Consume the "stderr"  
  441.                                 r = new InputStreamReader(exec.getErrorStream());  
  442.                                 read=0;  
  443.                                 while ((read=r.read(buf)) != -1) {  
  444.                                         if (res != null) res.append(buf, 0, read);  
  445.                                 }  
  446.                                 // get the process exit code  
  447.                                 if (exec != nullthis.exitcode = exec.waitFor();  
  448.                         } catch (InterruptedException ex) {  
  449.                                 if (res != null) res.append("/nOperation timed-out");  
  450.                         } catch (Exception ex) {  
  451.                                 if (res != null) res.append("/n" + ex);  
  452.                         } finally {  
  453.                                 destroy();  
  454.                         }  
  455.                 }  
  456.                 /** 
  457.                  * Destroy this script runner 
  458.                  */  
  459.                 public synchronized void destroy() {  
  460.                         if (exec != null) exec.destroy();  
  461.                         exec = null;  
  462.                 }  
  463.         }  
  464. }  
 

 

实质就是通过运行IPTABLES的脚本来实现防火墙规则的定制

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值