Android iptables基础、及app网络防火墙(添加系统服务,开机执行脚本)

详细文档:https://www.frozentux.net/iptables-tutorial/cn/iptables-tutorial-cn-1.1.19.html

1 iptables的原理以及命令

首先,什么是包过滤?

  包过滤是当一个数据包通过时,使用软件去查看包头信息并决定对该包的处理方式。你可以丢弃该数据包、接受该数据包亦或是其他更复杂的处理方式。

  在Linux中包过滤已经集成到内核中了,甚至还可以做一些数据包欺骗,但基本原则还是查看数据包头并决定处理方式。

 

linux集成了netfilter库,netfilter工作在tcp/ip协议栈网络层(可以看到tcp头,ip头,mac地址等信息)。然后提供五个hook点,用其他内核模块注册使用,对于iptables内核模块,就注册了这些hook函数,进行工作,iptables工具是提供的操作iptables操作内核模块的工具,前者提供机制  是内核过滤的基础架构,后者是用户工具,用来编辑具体的过滤规则提供给内核netfilter。下面是五个hook点的示意图

 

                                                                                            五个hook点

这五个点就是一个数据包进入主机后要经过的路径,一种是发给本机的包另一种是需要forward的包,流程图如下所示

 

 

iptables正式在这五个点根据用户配置的规则进行数据包的处理。大概就是这个原理。

 

对于数据包的处理可以分为三种类型

1 nat 转发(改变目标地址或源地址)

2 mangle 修改

3 filter 过滤

所以提供了三张表用于保存这些规则,三张表的名字分别是nat,filter和mangle,当请求进入主机的时候,经过的处理流程大致如吐下

 

                                               iptables表规则执行流程

三张默认的表中包含一些规则链,默认的链有INPUT、OUTPUT、PREROUTING、POSTROUTING、FORWARD,分别用于保存五个hook点所执行的操作。

 

备注:Linux防火墙所有的规则被保存在表中,默认Iptables防火墙有4个表:filter表(实现过滤功能),nat表(实现地址转换功能), mangle表(修改数据包的TOS、TTL等信息),raw表(实现数据包跟踪功能)

        
每个表中有多个数据链,而我们的具体规则被分门别类的链中。以下是每个表中的默认链:
filter表:INPUT链(入站数据过滤),FORWARD链(转发数据过滤),OUTPUT链(出站数据过滤)
nat表:PREROUTING链,POSTROUTING链,OUTPUT链
mangle表:PREROUTING链,POSTROUTING链,INPUT链,OUTPUT链,FORWARD链
raw表:OUTPUT链,PREROUTING链

 

 明白了大致流程后就可以进行规则编写了,就要说说iptables的基本命令

命令大致格式如下

iptables [-t table] command [match] [target/jump]

1  table

-t指定table,默认filter表

2 Commands 名令 

表示要执行的操作,如添加链,增删改规则等

-A 追加新的规则

-D 删除旧的规则

-R 替换旧的规则(链中根据编号)

-I 指定序号插入,插入新的规则,默认序号是1 也就是插入到最前面,注意规则执行时是按照链中规则的顺序执行的

-L 显示规则链

-F 清除链中的规则

-Z 将包过滤统计信息清零 

-X 删除链(保证不被引用)

-N 创建新的自定义规则链

-P 改变默认策略,默认的target(不符合规则默认的target,见后面target节)

3 match 匹配条件,满足匹配条件的包会执行后面的target,其他的走下链中下一个规则,否则返回父链

-p 协议

-s 源地址

-d 目的地址

-i 进入网卡

-o 出去网卡,用来比对封包要从哪片网卡送出,其中wifi有三种(参考droidwall):tiwlan+, wlan+, eth+
                                                                                  gprs有六种:rmnet+,pdp+,ppp+,uwbr+,wimax+,vsnet+

-f 分片

-sport 源端口

-dport 目的端口

--tcp-flags 

--tcp-flags [!] mask comp
匹配指定的TCP标记。第一个参数是我们要检查的标记,一个用逗号分开的列表,第二个参数是用逗号分开的标记表,是必须被设置的。标记如下:SYN ACK FIN RST URG PSH ALL NONE。因此这条命令:iptables -A FORWARD -p tcp --tcp-flags SYN, ACK, FIN, RST SYN只匹配那些SYN标记被设置而ACK、FIN和RST标记没有设置的包。

[!] --syn
只匹配那些设置了SYN位而清除了ACK和FIN位的TCP包。这些包用于TCP连接初始化时发出请求;例如,大量的这种包进入一个接口发生堵塞时会阻止进入的TCP连接,而出去的TCP连接不会受到影响。这等于 --tcp-flags SYN, RST, ACK SYN。如果"--syn"前面有"!"标记,表示相反的意思。

--tcp-option [!] number
匹配设置了TCP选项的。

--limit 限制条件 如每小时三个请求

--limit-burst  待匹配包初始个数的最大值:若前面指定的极限还没达到这个数值,则概数字加1.默认值为5

--mac-source  匹配物理地址。必须是XX:XX:XX:XX:XX这样的格式。注意它只对来自以太设备并进入PREROUTING、                                            FORWORD和INPUT链的包有效。

--uid-owner  如果给出有效的user id,那么匹配它的进程产生的包。

--gid-owner  如果给出有效的group id,那么匹配它的进程产生的包。

--pid-owner

owner
此模块试为本地生成包匹配包创建者的不同特征。只能用于OUTPUT链,而且即使这样一些包(如ICMP ping应答)还可能没有所有者,因此永远不会匹配。

--state  (INVALID,ESTABLISHED,NEW 和 RELATED) 这里state是一个逗号分割的匹配连接状态列表。可能的状态是:INVALID表示包是未知连接,ESTABLISHED表示是双向传送的连接,NEW表示包为新的连接,否则是非双向传送的,而RELATED表示包由新连接开始,但是和一个已存在的连接在一起,如FTP数据传送,或者一个ICMP错误。

--tos 这个参数可以是一个标准名称,(用iptables -m tos -h 察看该列表),或者数值。

tos
此模块匹配IP包首部的8位tos(服务类型)字段(也就是说,包含在优先位中)。

4 Targets/Jumps  后面有不同的参数,请查表

ACCEPT 之后不会匹配这个链的其他

DROP 直接丢弃,进行完此处理动作后,将不再比对其它规则,直接中断过滤程序。

REJECT 拒绝,不直接丢弃,返回错误给对方

DNET | SNET 转发

ULOG| NFLOG|LOG

MARK  用来设置包的netfilter标记值。只适用于mangle表

MASQUEREAD

QUEUE  排队

REJECT   拦阻该封包,并传送封包通知对方

REDIRECT  只适用于nat表的PREROUTING和OUTPUT链,和只调用它们的用户自定义链。它修改包的目标IP地址来发送包到机器自身(本地生成的包被安置为地址127.0.0.1)。它包含一个选项:

--to-ports <port>[<port>]
指定使用的目的端口或端口范围:不指定的话,目标端口不会被修改。只能用于指定了-p tcp 或 -p udp的规则。

RETURN  返回

TOS

TTL

 

日志记录,iptables提供三种方式,取决于编译选项。包括LOG(打印打/proc/dmesg)
ULOG 通过netlinker将log从内核发送给用户空间,单向
NFLOG通过netlinker将log从内核发送给用户空间,双向

netlinker在内核和用户空间创建socket通信,通过多播的形式将内核log送往用户空间。
对于android中的iptables只提供了ulog和nflog的方式读取log。需要写一个程序从nflog中读取数据,参考
http://www.netfilter.org/projects/libnetfilter_log/doxygen/nfulnl__test_8c_source.html

 

 iptables:该工具可以添加删除具体的过滤规则至内核包过滤表。这也意味着无论你如何设置防火墙规则,一旦机器重启所有的规则将丢失。

  永久保存规则:你设置的防火墙规则被保存在内核中,但重启会丢失。你可以使用iptables-save和iptables-restore脚本实现永久保存与恢复。

 

操作单条规则

 

  这是最基本的包过滤操作。通常你需要使用-A或-D命令选项,有时你还会使用到-I与-R命令选项。
  每条规则需要指定匹配条件以及匹配后的处理方式(ACCEPT允许,DROP丢弃,REJECT拒绝,LOG日志等),如:你可能希望丢弃素有本地回环(127.0.0.1)的ICMP数据包,这样我们的匹配条件是:ICMP协议并且源地址是127.0.0.1 匹配后做DROP处理。
  127.0.0.1是本地回环接口,即使你没有物理网卡,该接口一样存在。你可以使用ping命令产生这类数据包。

# ping -c 1 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=21.9 ms
 
--- 127.0.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 21.966/21.966/21.966/0.000 ms
 
 # iptables -A INPUT -s 127.0.0.1 -p icmp -j DROP 添加一条规则
# ping -c 1 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
 
--- 127.0.0.1 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss

  你可以看到第一次ping是成功的(-c  1 说明仅ping一次),然后我们追加了一条规则到INPUT链,该规则指定从127.0.0.1发送的ICMP协议的数据包将被丢弃。第二次再执行ping命令所有的数据100%丢失。

  我们有两种方式可以删除规则,首先我们知道INPUT链中只有一条规则,我们可以使用编号删除:
#iptables  -D  INPUT  1   // 删除INPUT链中的第一条规则

  第二种方法类似与-A选项,使用-D替换-A。当你的规则比较复杂并搞不清编号时可以使用这种方式:
#iptables  -D  INPUT  -s  127.0.0.1  -p  icmp  -j  DROP

特定过滤规则

源地址与目标地址
  源地址(-s,--source或--src),目标地址(-d,--destination或--dst)有四种使用方式:
  最常用的是使用名称,比如"localhost"或者"http://www.kernel.org"。
  第二种方法是使用IP地址如"127.0.0.1"。
  第三四种方法可以匹配IP地址区域,如"199.95.207.0/24"或"199.95.207.0/255.255.255.0"。它们都可以匹配199.95.207.0到199.95.207地址,可以使用0/0匹配所有地址。
# iptables -A INPUT -s 0/0 -j DROP 拒绝所有源地址访问本机

取反匹配
  很多标签"-s","-d"等都可以在后面添加"!"以表示否定匹配,如"-s ! localhost"将匹配所有非本地源地址。

协议匹配
  匹配协议可以使用-p标签,协议的指定可以使用数字编号(如果你知道协议的编号)或使用名称(如"TCP","UDP","ICMP"等)。协议名称前可以添加"!"如"-p  ! TCP"匹配所有非TCP协议数据包。

接口匹配
  "-i(--in-interface)"和"-o(--out-interface)"匹配指定的接口。接口是真实的物理网卡接口,-i(数据包从哪个网卡进来的),
  -o(数据从哪个网卡出去的)。你可以使用ifconfig命令查看哪些接口是开启的。
 
  注意:在INPUT链不可以使用-o选项,因为入站的数据不走出站接口。所以在INPUT链中的-o规则将无法匹配任何数据。
        同理,在OUTPUT链中不可以使用-i选项。

数据段匹配
  很多数据包因为太大无法一次完成数据的传输。此时数据包将被分割为数据片段再发送出去。接收端接受完数据后将把这些数据片段重新组合成完整的数据包。
  但问题在于当数据被分割后,只有前面的初始数据片段包含全部的数据头部信息(IP,TCP,UDP,ICMP等),
  后续的数据片段仅包含数据包头部信息的一部分信息。这时去再检查后续数据片段的头部信息是不可能的。
  当然,如果你想匹配第二个及后面被分片的数据,可以使用"-f"选项。
# iptables -A OUTPUT -f -d 192.168.1.1 -j DROP    //丢弃发送至192.168.1.1的所有数据以及分片数据

扩展iptables规则
  iptables有很好的可扩展性,也就是说内核架构与iptables工具都可以添加扩展功能。
  内核功能扩展一般放在内核模块子目录中:/lib/modules/2.6.32-220.el6.i686/kernel/net/netfilter(这里以CentOS6.2为例)。这些模块在你使用iptables时会自动加载。
  
  mac
  该模块需要使用"-m  mac"选项启用,这对应过滤进站数据包的源MAC地址很用帮助。-m 即match匹配的意思。
#iptables  -I  INPUT  -m  mac  --mac-source  00:60:08:91:CC:B7  -j  REJECT //拒绝MAC地址为00:60:08:91:CC:B7的数据包进入
 
  limit
  该模块需要使用"-m  limit"选项启用,该功能对限制网速很有效。
#iptables -A OUTPUT  -p  tcp  -m  limit  --limit  100/s  -j ACCEPT  // 每秒包个数100以内将允许发送
#iptables -P OUTPUT  REJECT  // 默认拒绝所有
  说明:以上两条可以实现,当每秒包个数大于100时,拒绝所有连接。

 
  状态匹配
  该模块需要使用"-m  state"选项启用,数据包的状态包括:NEW,ESTABLISHED,RELATED,INVALID
  NEW:创建连接的数据包
  ESTABLISHED:通过已经创建的连接通道 传输的数据包
  RELATED:与已经创建的连接相关的数据包,如ICMP错误数据包
  INVALID:无法识别的数据包
#iptables -A  INPUT  -m  state  --state  NEW  -j  DROP   //拒绝进站的连接请求(外网无法访问本机)
#iptables -A  INPUT  -m  state  --state  RESTABLISHED,RELATED  -j  ACCEPT   //允许外网数据对本机的回应信息
#iptables -P  OUTPUT  ACCEPT //允许访问外网

mark模块介绍

MARK标记用于将特定的数据包打上标签,供iptables配合TC做QOS流量限制或应用策略路由。

mark字段的值是一个无符号的整数,在32位系统上最大可以是4294967296(就是2的32次方),这足够用的了。
    比如,我们对一个流或从某台机子发出的所有的包设置了mark值,就可以利用高级路由功能来对它们进行流量控制等操作了。
mark值不是包本身的一部分,而是在包穿越计算机的过程中由内核分配的和它相关联的一个字段。它可能被用来改变包的传输路径或过滤。mark值只在本机有意义!
在本机给包设置关联的mark值后,可通过该值对包后续的传输进行控制(排队,流量控制等)。

看看和MARK相关的有哪些模块:
ls /usr/lib/iptables/|grep -i mark
libxt_CONNMARK.so
libxt_MARK.so
libxt_connmark.so
libxt_mark.so
其中大写的为标记模块,小写的为匹配模块,它们之间是相辅相成的,分别作用如下:


iptables -j MARK --help
--set-mark #标记数据包
iptables -t mangle -A PREROUTING -p tcp -j MARK --set-mark 1
#所有TCP数据标记1

iptables -m mark --help
--mark value #匹配数据包的MARK标记
iptables -t mangle -A PREROUTING -p tcp -m mark --mark 1 -j CONNMARK --save-mark
#匹配标记1的数据并保存数据包中的MARK到连接中

iptables -j CONNMARK --help
--set-mark #标记连接
--save-mark #保存数据包中的MARK到连接中
--restore-mark #将连接中的MARK设置到同一连接的其它数据包中
iptables -t mangle -A PREROUTING -p tcp -j CONNMARK --set-mark 1

iptables -m connmark --help
--mark value #匹配连接的MARK的标记
iptables -t mangle -A PREROUTING -p tcp -m connmark --mark 1 -j CONNMARK --restore-mark
#匹配连接标记1并将连接中的标记设置到数据包中
#mark的格式是--mark value[/mask],如上面的例子是没有掩码的,带掩码的例子如--mark 1/1。如果指定了掩码,就先把mark值和掩码取逻辑与,然后再和包的mark值比较。


说明:
1、以前MARK标记只能用在mangle表上,而现在可以使用在nat表上。
2、MARK标记不能作为扩路由的传递,只能在内核上传递。如果要实现,那么可以使用TOS标记。
3、使用时注意iptables的版本,不同的版本支持的方法不一样。

通过string匹配域名来过滤
iptables -I OUTPUT -p tcp -m string --string "qq.com" --algo bm -j DROP
iptables -I OUTPUT -p udp -m string --string "qq.com" --algo kmp -j DROP

--algo 设置字符匹配的查询算法,一般默认使用bm算法效果就可以了,另外还可以设置kmp算法,那是一种更复杂的算法
--string 指定要匹配的字符串
--from 指定搜索包的开始位置,默认0
--to    ,默认包大小

排除建议
  1.注意过滤规则的顺序,如果规则的第一条拒绝所有tcp连接,第二条允许192.168.1.1访问本机的tcp连接,则第二条将无效。
#iptables  -A  INPUT  -p  tcp  -j  DROP
#iptables  -A  INPUT  -p  tcp  -s  192.168.1.1  -j  ACCEPT
  以上两条规则由于第一条规则已经丢弃所有的tcp数据包,所以不会再匹配第二条规则。
  2.设置完规则后未保存,导致重启后所有规则丢失。解决方法:可以使用iptables-save,或service  iptables  save实现永久保存
#iptables-save > /etc/sysconfig/iptables
#service iptables  save
  以上以CentOS为例,两天命令任选其一即可永久保存。
  3.无效的规则及时删除,否则影响效率。
  4.匹配端口号时必须指定协议,否则会报错。
  5.公司有FTP服务器时,提前加载ftp模块:#modprobe  ip_nat_ftp

----------------------------------------------------------------------------------

app联网白名单实现思路:
通过iptables命令设置filter表,针对OUTPUT链,来源是wifi或是2g/3g的做REJECT或是DROP操作。
REJECT和DROP其效果都可以使app无法联网,所以两个任你选择使用。

iptables -t filter -A OUTPUT -o wlan+  -m owner --uid-owner 10042 -j DROP

说明:操作filter(-t filter可以省略,默认操作filter表)的OUTPUT链,封包出口是wlan+,并且来源是uid为10042的,丢弃数据包。

----------------------------------------------------------------------------------

app网络访问控制

以10060为UC使用的规则链(chain)名。

// 创建规则链,链名为10060
iptables -N 10060

// 执行下面命令将规则链10060与UC浏览器关联:
iptables -A OUTPUT -m owner --uid-owner 10060 -j 10060
语义说明:向OUTPUT规则链附加一条规则:如果IP信息报匹配到uid是10060,则跳转(-j)到规则链10060。
          iptables支持区分不同的uid以跳转到不同的规则链。通过iptables -L可以查询到当前内核已有的规则链。
          其中OUTPUT是内核自动创建的处理本地生成的IP信息包的规则链。
 

在具体配置规则链10060之前,可以运行下面命令将10060内容清掉:
iptables -F 10060

在OUTPUT中添加规则链,利用Http协议中的Host头域,只放行白名单域名的请求。能更好的地实现白名单需求。
 

第3步:配置访问规则
白名单功能:
// 允许访问某一域名(www.abc.com)禁止访问其他域名
iptables -A 10060 -p tcp -m string --string Host: --algo bm -j MARK --set-mark 1
iptables -A 10060 -p tcp -m mark --mark 1 -m string --string abc --algo bm -j ACCEPT
iptables -A 10060 -p tcp -m mark --mark 1 -j REJECT


黑名单功能:
//禁止访问某一域名(www.abc.com)允许访问其他域名
iptables -A 10060 -m string --string abc --algo bm -j REJECT
iptables -A 10060 -j ACCEPT

 说明:对于黑名单,逻辑比较简单,只要把所有包含abc的IP包REJECT即可,其余的ACCEPT,即使没有第二条命令,默认也是ACCEPT。
对于白名单,针对Host头域,原因如上。对于包含Host的IP包先做一次mark(标记),然后对此标记的IP包判断是否包含abc。
 

 

 

二、Iptables网络黑白名单(防火墙)实现细节

因为考虑到一些权限的问题所以在实现方法上采用的是创建一个systemserver来运行这些方法。并提供出manager到三方应用,这样在调用时可以排除一些权限的限制。同时本文只是做一个简单的参考概述,所以在后文中只提供了增加黑白名单的方法和iptables规则,并没有提供相应的删除规则等,原理类似大家可自行补充添加。

2.1、创建systemserver

2.1.1、 在/system/sepolicy/service.te中添加

?

1

type fxjnet_service, system_api_service, system_server_service, service_manager_type;

2.2.2、在/system/sepolicy/service_contexts中添加如下,

?

1

fxjnet      u:object_r:fxjnet_service:s0

2.2.3、在frameworks/base/core/java/android/content/Context.java中添加

也可以不添加这个,只不过为了后面调用方便所以添加了。如果跳过此步,那么后面出现Context.FXJNET_SERVICE的地方都用字串代替即可。

?

1

public static final String FXJNET_SERVICE="fxjnet";

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

?

1

2

3

4

5

6

7

8

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中。

?

1

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

2.2.6 、在源码frameworks/base/core/java/android/os/ 下面新增 一个 AIDL文件

?

1

2

3

4

package android.os;

interface IFXJNETService{

  void addNetworkRestriction(List<String> ipName,int type);

}

2.2.7、提供给外部的FXJNETManager,在frameworks/base/core/java/android/app/ 下

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

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, frameworks/base/services/core/java/com/android/server/ 下

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

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脚本命令的工具类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

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在开机时就运行起来

?

1

2

3

4

service fxjmotnitor /system/bin/sh /data/fxj/firewall.sh

 class main

 oneshot

 seclabel u:r:fxjmotnitor:s0

3.2、在/sepolicy/目录下创建fxjmotnitor.te文件,内容如下

?

1

2

3

4

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中添加

?

1

/data/fxj/firewall.sh  u:object_r:fxjmotnitor_exec:s0

3.4、在sepolicy/Android.mk中的

?

1

2

3

4

5

BOARD_SEPOLICY_UNION += \

#追加如下

......\

fxjmotnitor.te \

......\

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

参考

https://www.jianshu.com/p/b96d7036e994

https://www.jianshu.com/p/c500dc5a13b0

https://blog.csdn.net/zhanglianyu00/article/details/50177873

https://www.cnblogs.com/EasonJim/p/8414943.html

https://www.jb51.net/article/145381.htm

  • 1
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
在Linux中,可以使用iptables来配置防火墙规则来抵御DDoS攻击。以下是一个简单的示例脚本,用于添加防火墙规则以防御DDoS攻击: ```bash #!/bin/bash # 清空现有的防火墙规则 iptables -F # 设置默认策略:拒绝所有流量 iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP # 允许回环接口的流量 iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # 允许已建立的和相关的连接通过 iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT # 允许SSH访问(根据需要开启) # iptables -A INPUT -p tcp --dport 22 -j ACCEPT # 允许HTTP和HTTPS访问(根据需要开启) # iptables -A INPUT -p tcp --dport 80 -j ACCEPT # iptables -A INPUT -p tcp --dport 443 -j ACCEPT # 添加其他针对DDoS攻击的规则 # 例如限制SYN包数量 # iptables -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j ACCEPT # 其他防御规则可以根据具体需求进行添加 # 打印防火墙规则 iptables -L -v # 保存防火墙规则 iptables-save > /etc/iptables/rules.v4 ``` 以上脚本首先清空现有的防火墙规则,然后设置默认策略为拒绝所有流量。接下来,允许回环接口的流量和已建立的、相关的连接通过。你可以根据需要开放其他端口,如SSH(端口22)、HTTP(端口80)、HTTPS(端口443)等。 最后,可以添加其他针对DDoS攻击的规则,例如限制SYN包数量。你可以根据具体需求添加其他防御规则。 请注意,在使用该脚本之前,请确保你理解每个规则的含义,并根据实际情况进行修改和优化。同时,建议在测试环境中先进行测试,确保防火墙规则不会对正常流量产生影响。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值