netfilter/iptables(简称为iptables)组成Linux平台下的包过滤防火墙,与大多数的Linux软件一样,这个包过滤防火墙是免费的,它可以代替昂贵的商业防火墙解决方案,完成封包过滤、封包重定向和网络地址转换(NAT)等功能。
iptables的前世今生
iptables的前身叫ipfirewall (内核1.x时代),是从freeBSD上移植过来的,能够工作在内核当中的,对数据包进行检测的一款简易访问控制工具。但是ipfirewall工作功能极其有限(它需要将所有的规则都放进内核当中,这样规则才能够运行起来,而放进内核,这个做法一般是极其困难的)。当内核发展到2.x系列的时候,软件更名为ipchains,它可以定义多条规则,将他们串起来,共同发挥作用,而现在,它叫做iptables,可以将规则组成一个列表,实现绝对详细的访问控制功能。
他们都是工作在用户空间中,定义规则的工具,本身并不算是防火墙。它们定义的规则,可以让在内核空间当中的netfilter来读取,并且实现让防火墙工作。而放入内核的地方必须要是特定的位置,必须是tcp/ip的协议栈经过的地方。而这个tcp/ip协议栈必须经过的地方,可以实现读取规则的地方就叫做 netfilter.(网络过滤器)
iptables实际就是维护一组规则,iptables只是Linux防火墙的管理工具而已,位于Android系统的/system/bin/iptables。真正实现防火墙功能的是 netfilter,它是Linux内核中实现包过滤的内部结构,所谓的 规则(rules)其实就是网络管理员预定义的条件,规则一般的定义为“如果数据包头符合这样的条件,就这样处理这个数据包”。规则存储在内核空间的信息 包过滤表中,这些规则分别指定了源地址、目的地址、传输协议(如TCP、UDP、ICMP)和服务类型(如HTTP、FTP和SMTP)等。当数据包与规则匹配时,iptables就根据规则所定义的方法来处理这些数据包,如放行(accept)、拒绝(reject)和丢弃(drop)等。配置防火墙的 主要工作就是添加、修改和删除这些规则。
例如下面这个开源的防火墙,实际上就是iptables命令行的一个图形化界面
在Android系统下是可以通过iptables命令进行网络屏蔽,设定某些应用禁止上网的,但是需要对手机进行root处理。
1.iptables中的“四表五链”及“堵通策略”
A.“四表”是指,iptables的功能——filter, nat, mangle, raw.
filter, 控制数据包是否允许进出及转发(INPUT、OUTPUT、FORWARD),可以控制的链路有input, forward, output
nat, 控制数据包中地址转换,可以控制的链路有prerouting, input, output, postrouting
mangle,修改数据包中的原数据,可以控制的链路有prerouting, input, forward, output, postrouting
raw,控制nat表中连接追踪机制的启用状况,可以控制的链路有prerouting, output
B.“五链”是指内核中控制网络的NetFilter定义的五个规则链,分别为
PREROUTING, 路由前
INPUT, 数据包流入口
FORWARD, 转发管卡
OUTPUT, 数据包出口
POSTROUTING, 路由后
C.堵通策略是指对数据包所做的操作,一般有两种操作——“通(ACCEPT)”、“堵(DROP)”,还有一种操作很常见REJECT.
谈谈REJECT和DROP之间的区别,Ming写了一封信,向Rose示爱。Rose如果不愿意接受,她可以不回应Ming,这个时候Ming不确定Rose是否接到了信;Rose也可以同样写一封信,在信中明确地拒绝Ming。前一种操作就如同执行了DROP操作,而后一种操作就如同REJECT操作。我的理解是如果做为防火墙用DROP更合理,这样让攻击击得到一个不确定信息。
iptables命令的语法规则
默认使用的是对filter表的操作
iptables v1.8.4
Usage: iptables -[ACD] chain rule-specification [options]
iptables -I chain [rulenum] rule-specification [options]
iptables -R chain rulenum rule-specification [options]
iptables -D chain rulenum [options]
iptables -[LS] [chain [rulenum]] [options]
iptables -[FZ] [chain] [options]
iptables -[NX] chain
iptables -E old-chain-name new-chain-name
iptables -P chain target [options]
iptables -h (print this help information)
Commands:
Either long or short options are allowed.
--append -A chain Append to chain
--check -C chain Check for the existence of a rule
--delete -D chain Delete matching rule from chain
--delete -D chain rulenum
Delete rule rulenum (1 = first) from chain
--insert -I chain [rulenum]
Insert in chain as rulenum (default 1=first)
--replace -R chain rulenum
Replace rule rulenum (1 = first) in chain
--list -L [chain [rulenum]]
List the rules in a chain or all chains
--list-rules -S [chain [rulenum]]
Print the rules in a chain or all chains
--flush -F [chain] Delete all rules in chain or all chains
--zero -Z [chain [rulenum]]
Zero counters in chain or all chains
--new -N chain Create a new user-defined chain
--delete-chain
-X [chain] Delete a user-defined chain
--policy -P chain target
Change policy on chain to target
--rename-chain
-E old-chain new-chain
Change chain name, (moving any references)
Options:
--ipv4 -4 Nothing (line is ignored by ip6tables-restore)
--ipv6 -6 Error (line is ignored by iptables-restore)
[!] --protocol -p proto protocol: by number or name, eg. `tcp'
[!] --source -s address[/mask][...]
source specification
[!] --destination -d address[/mask][...]
destination specification
[!] --in-interface -i input name[+]
network interface name ([+] for wildcard)
--jump -j target
target for rule (may load target extension)
--goto -g chain
jump to chain with no return
--match -m match
extended match (may load extension)
--numeric -n numeric output of addresses and ports
[!] --out-interface -o output name[+]
network interface name ([+] for wildcard)
--table -t table table to manipulate (default: `filter')
--verbose -v verbose mode
--wait -w [seconds] maximum wait to acquire xtables lock before give up
--wait-interval -W [usecs] wait time to try to acquire xtables lock
default is 1 second
--line-numbers print line numbers when listing
--exact -x expand numbers (display exact values)
[!] --fragment -f match second or further fragments only
--modprobe=<command> try to insert modules using this command
--set-counters PKTS BYTES set the counter during insert/append
[!] --version -V print package version.
iptables命令的管理控制选项
-A 在指定链的末尾添加(append)一条新的规则
-D 删除(delete)指定链中的某一条规则,可以按规则序号和内容删除
-I 在指定链中插入(insert)一条新的规则,默认在第一行添加
-R 修改、替换(replace)指定链中的某一条规则,可以按规则序号和内容替换
-L 列出(list)指定链中所有的规则进行查看
-E 重命名用户定义的链,不改变链本身
-F 清空(flush)
-N 新建(new-chain)一条用户自己定义的规则链
-X 删除指定表中用户自定义的规则链(delete-chain)
-P 设置指定链的默认策略(policy)
-Z 将所有表的所有链的字节和数据包计数器清零
-n 使用数字形式(numeric)显示输出结果
-v 查看规则表详细信息(verbose)的信息
-V 查看版本(version)
-h 获取帮助(help)
防火墙处理数据包的四种方式
ACCEPT 允许数据包通过
DROP 直接丢弃数据包,不给任何回应信息
REJECT 拒绝数据包通过,必要时会给数据发送端一个响应的信息。
下面是一台手机原始的iptables,可以上网的
# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
bw_INPUT all -- 0.0.0.0/0 0.0.0.0/0
fw_INPUT all -- 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy ACCEPT)
target prot opt source destination
oem_fwd all -- 0.0.0.0/0 0.0.0.0/0
fw_FORWARD all -- 0.0.0.0/0 0.0.0.0/0
bw_FORWARD all -- 0.0.0.0/0 0.0.0.0/0
tetherctrl_FORWARD all -- 0.0.0.0/0 0.0.0.0/0
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DROP udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:1900
DROP udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:1900
DROP udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:1900
DROP udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:1900
DROP udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:1900
DROP udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:1900
DROP udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:1900
DROP udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:1900
DROP udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:1900
DROP udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:1900
DROP udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:1900
DROP udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:1900
DROP udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:1900
DROP udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:1900
DROP udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:1900
DROP udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:1900
DROP udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:1900
oem_out all -- 0.0.0.0/0 0.0.0.0/0
fw_OUTPUT all -- 0.0.0.0/0 0.0.0.0/0
st_OUTPUT all -- 0.0.0.0/0 0.0.0.0/0
bw_OUTPUT all -- 0.0.0.0/0 0.0.0.0/0
Chain bw_FORWARD (1 references)
target prot opt source destination
Chain bw_INPUT (1 references)
target prot opt source destination
bw_global_alert all -- 0.0.0.0/0 0.0.0.0/0
RETURN esp -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0 mark match 0x100000/0x100000
all -- 0.0.0.0/0 0.0.0.0/0 owner socket exists
MARK all -- 0.0.0.0/0 0.0.0.0/0 MARK or 0x100000
Chain bw_OUTPUT (1 references)
target prot opt source destination
bw_global_alert all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0 policy match dir out pol ipsec
RETURN all -- 0.0.0.0/0 0.0.0.0/0 owner UID match 1029
all -- 0.0.0.0/0 0.0.0.0/0 owner socket exists
Chain bw_costly_shared (0 references)
target prot opt source destination
bw_penalty_box all -- 0.0.0.0/0 0.0.0.0/0
Chain bw_data_saver (1 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0
Chain bw_global_alert (2 references)
target prot opt source destination
all -- 0.0.0.0/0 0.0.0.0/0 ! quota globalAlert: 2097152 bytes
Chain bw_happy_box (1 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0 owner UID match 10088
RETURN all -- 0.0.0.0/0 0.0.0.0/0 owner UID match 0-9999
bw_data_saver all -- 0.0.0.0/0 0.0.0.0/0
Chain bw_penalty_box (1 references)
target prot opt source destination
bw_happy_box all -- 0.0.0.0/0 0.0.0.0/0
Chain fw_FORWARD (1 references)
target prot opt source destination
Chain fw_INPUT (1 references)
target prot opt source destination
fw_isolated all -- 0.0.0.0/0 0.0.0.0/0
Chain fw_OUTPUT (1 references)
target prot opt source destination
fw_isolated all -- 0.0.0.0/0 0.0.0.0/0
Chain fw_dozable (0 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0 owner UID match 0-9999
RETURN all -- 0.0.0.0/0 0.0.0.0/0 ! owner UID match 0-4294967294
RETURN esp -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
RETURN tcp -- 0.0.0.0/0 0.0.0.0/0 tcp flags:0x04/0x04
DROP all -- 0.0.0.0/0 0.0.0.0/0
Chain fw_isolated (2 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
RETURN tcp -- 0.0.0.0/0 0.0.0.0/0 tcp flags:0x04/0x04
Chain fw_powersave (0 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0 owner UID match 0-9999
RETURN all -- 0.0.0.0/0 0.0.0.0/0 ! owner UID match 0-4294967294
RETURN esp -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
RETURN tcp -- 0.0.0.0/0 0.0.0.0/0 tcp flags:0x04/0x04
DROP all -- 0.0.0.0/0 0.0.0.0/0
Chain fw_standby (0 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
RETURN tcp -- 0.0.0.0/0 0.0.0.0/0 tcp flags:0x04/0x04
Chain nm_mdmprxy_doze_mode_skip (0 references)
target prot opt source destination
Chain nm_mdmprxy_iface_pkt_fwder (0 references)
target prot opt source destination
Chain oem_fwd (1 references)
target prot opt source destination
Chain oem_out (1 references)
target prot opt source destination
Chain st_OUTPUT (1 references)
target prot opt source destination
Chain st_clear_caught (2 references)
target prot opt source destination
Chain st_clear_detect (0 references)
target prot opt source destination
REJECT all -- 0.0.0.0/0 0.0.0.0/0 connmark match 0x2000000/0x2000000 reject-with icmp-port-unreachable
RETURN all -- 0.0.0.0/0 0.0.0.0/0 connmark match 0x1000000/0x1000000
CONNMARK tcp -- 0.0.0.0/0 0.0.0.0/0 u32 "0x0>>0x16&0x3c@0xc>>0x1a&0x3c@0x0&0xffff0000=0x16030000&&0x0>>0x16&0x3c@0xc>>0x1a&0x3c@0x4&0xff0000=0x10000" CONNMARK or 0x1000000
CONNMARK udp -- 0.0.0.0/0 0.0.0.0/0 u32 "0x0>>0x16&0x3c@0x8&0xffff0000=0x16fe0000&&0x0>>0x16&0x3c@0x14&0xff0000=0x10000" CONNMARK or 0x1000000
RETURN all -- 0.0.0.0/0 0.0.0.0/0 connmark match 0x1000000/0x1000000
st_clear_caught tcp -- 0.0.0.0/0 0.0.0.0/0 state ESTABLISHED u32 "0x0>>0x16&0x3c@0xc>>0x1a&0x3c@0x0&0x0=0x0"
st_clear_caught udp -- 0.0.0.0/0 0.0.0.0/0
Chain st_penalty_log (0 references)
target prot opt source destination
CONNMARK all -- 0.0.0.0/0 0.0.0.0/0 CONNMARK or 0x1000000
NFLOG all -- 0.0.0.0/0 0.0.0.0/0
Chain st_penalty_reject (0 references)
target prot opt source destination
CONNMARK all -- 0.0.0.0/0 0.0.0.0/0 CONNMARK or 0x2000000
NFLOG all -- 0.0.0.0/0 0.0.0.0/0
REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
Chain tetherctrl_FORWARD (1 references)
target prot opt source destination
DROP all -- 0.0.0.0/0 0.0.0.0/0
Chain tetherctrl_counters (0 references)
target prot opt source destination
下面这个指令会屏蔽对8022端口的开放,并将策略放在最前,Insert操作
iptables -I INPUT -p TCP --dport 8022 -j DROP
下面这个指令会屏蔽对8022端口的开放,并将策略放在最后,Append操作
iptables -A INPUT -p TCP --dport 8022 -j DROP
如下图
如果想删除这个条目,要调用两次,自上而下的进行删除
iptables -D INPUT -p TCP --dport 8022 -j DROP
iptables -D INPUT -p TCP --dport 8022 -j DROP
也可以用 iptables -nvL INPUT --line-number 查看带标号
iptables -D INPUT 7
iptables -D INPUT 1
来进行删除,因为删除后序号发生变化,所有要从后向前删除
下图为执行完一次命令后的效果,可见最上一条被删除了
1.拒绝进入防火墙的所有ICMP协议数据包
iptables -I INPUT -p icmp -j REJECT
2.允许防火墙转发除ICMP协议以外的所有数据包
iptables -A FORWARD -p ! icmp -j ACCEPT
说明:使用“!”可以将条件取反。
3.拒绝转发来自192.168.1.10主机的数据,允许转发来自192.168.0.0/24网段的数据
iptables -A FORWARD -s 192.168.1.11 -j REJECT
iptables -A FORWARD -s 192.168.0.0/24 -j ACCEPT
说明:注意要把拒绝的放在前面不然就不起作用了啊。
4.丢弃从外网接口(eth1)进入防火墙本机的源地址为私网地址的数据包
iptables -A INPUT -i eth1 -s 192.168.0.0/16 -j DROP
iptables -A INPUT -i eth1 -s 172.16.0.0/12 -j DROP
iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j DROP
5.封堵网段(192.168.1.0/24),两小时后解封。
iptables -I INPUT -s 10.20.30.0/24 -j DROP
iptables -I FORWARD -s 10.20.30.0/24 -j DROP
at now 2 hours at> iptables -D INPUT 1 at> iptables -D FORWARD 1
说明:这个策略咱们借助crond计划任务来完成,就再好不过了。
[1] Stopped at now 2 hours
6.只允许管理员从202.13.0.0/16网段使用SSH远程登录防火墙主机。
iptables -A INPUT -p tcp --dport 22 -s 202.13.0.0/16 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP
说明:这个用法比较适合对设备进行远程管理时使用,比如位于分公司中的SQL服务器需要被总公司的管理员管理时。
7.允许本机开放从TCP端口20-1024提供的应用服务。
iptables -A INPUT -p tcp --dport 20:1024 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 20:1024 -j ACCEPT
8.允许转发来自192.168.0.0/24局域网段的DNS解析请求数据包。
iptables -A FORWARD -s 192.168.0.0/24 -p udp --dport 53 -j ACCEPT
iptables -A FORWARD -d 192.168.0.0/24 -p udp --sport 53 -j ACCEPT
9.禁止其他主机ping防火墙主机,但是允许从防火墙上ping其他主机
iptables -I INPUT -p icmp --icmp-type Echo-Request -j DROP
iptables -I INPUT -p icmp --icmp-type Echo-Reply -j ACCEPT
iptables -I INPUT -p icmp --icmp-type destination-Unreachable -j ACCEPT
10.禁止转发来自MAC地址为00:0C:29:27:55:3F的和主机的数据包
iptables -A FORWARD -m mac --mac-source 00:0c:29:27:55:3F -j DROP
说明:iptables中使用“-m 模块关键字”的形式调用显示匹配。咱们这里用“-m mac –mac-source”来表示数据包的源MAC地址。
11.允许防火墙本机对外开放TCP端口20、21、25、110以及被动模式FTP端口1250-1280
iptables -A INPUT -p tcp -m multiport --dport 20,21,25,110,1250:1280 -j ACCEPT
说明:这里用“-m multiport –dport”来指定目的端口及范围
12.禁止转发源IP地址为192.168.1.20-192.168.1.99的TCP数据包。
iptables -A FORWARD -p tcp -m iprange --src-range 192.168.1.20-192.168.1.99 -j DROP
说明:此处用“-m –iprange –src-range”指定IP范围。
13.禁止转发与正常TCP连接无关的非—syn请求数据包。
iptables -A FORWARD -m state --state NEW -p tcp ! --syn -j DROP
说明:“-m state”表示数据包的连接状态,“NEW”表示与任何连接无关的,新的嘛!
14.拒绝访问防火墙的新数据包,但允许响应连接或与已有连接相关的数据包
iptables -A INPUT -p tcp -m state --state NEW -j DROP
iptables -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
说明:“ESTABLISHED”表示已经响应请求或者已经建立连接的数据包,“RELATED”表示与已建立的连接有相关性的,比如FTP数据连接等。
15.只开放本机的web服务(80)、FTP(20、21、20450-20480),放行外部主机发住服务器其它端口的应答数据包,将其他入站数据包均予以丢弃处理。
iptables -I INPUT -p tcp -m multiport --dport 20,21,80 -j ACCEPT
iptables -I INPUT -p tcp --dport 20450:20480 -j ACCEPT
iptables -I INPUT -p tcp -m state --state ESTABLISHED -j ACCEPT
iptables -P INPUT DROP
补充说明
当执行下面命令时
iptables -I OUTPUT -p UDP -m owner --uid-owner 10017 -j ACCEPT
iptables -I OUTPUT -p TCP -m owner --uid-owner 10017 -j ACCEPT
iptables -I OUTPUT -p ICMP -m owner --uid-owner 10017 -j ACCEPT
等效于
iptables -I OUTPUT -p all -m owner --uid-owner 10017 -j ACCEPT
另外在执行output表时,会自上而下执行,比如策略冲突了,先Accept的会执行,后面的Reject会拦截不到
iptables -I OUTPUT -p UDP --dport 53 -m owner --uid-owner 10017 -j ACCEPT |
iptables -I OUTPUT -m string --algo kmp --string "baidu" -j DROP |
iptables -I OUTPUT -m string --algo bm --hex-string "|05|baidu|03|com|" -j DROP |
iptables -I OUTPUT -p UDP --dport 53 -m string --algo kmp --string "baidu" -j DROP |
iptables -I OUTPUT -p UDP --dport 53 -m owner --uid-owner 10017 -m string --algo kmp --string "baidu" -j DROP |
iptables -I OUTPUT -p UDP --dport 53 -m string --algo kmp --string "baidu" -m time --timestart 13:30 --timestop 20:30 -j DROP |
--algo {bm|kmp} //搜索算法,必选项 |
现在有一需求,需要禁止主机对某一个域名的DNS查询,想到用iptables的string模块,使用下面的命令: iptables -D OUTPUT -m string --string "www.baidu.com" --algo bm -j DROP 但使用上面的命令并不能过滤对www.baidu.com 的查询。根据参考链接中的文档,www.baidu.com 在DNS查询时会被编码如下: 03www05baidu03com 编码时域名以点被分为各子字符串(www,baidu和com)“.”不会被编码,每个子字符串前面是这个字符串的长度。下面是对DNS查询的抓包: 字符串 www.baidu.com 被编码十六进制为: 03 77 77 77 05 62 61 69 64 75 03 63 6f 6d 77的是w的ascii码,其余字符也可以对照ascii进行查询。77 77 77 前面的03正是www这三个字符串的长度。 根据参考链接,可以使用iptables的string模块的十六进字符串进行过滤 iptables -A OUTPUT -p udp --dport 53 -m string --hex-string "|03|www|05|baidu|03|com|" --algo bm -j DROP iptables 自动将 |03|www|05|baidu|03|com| 转换成十六进制。 |
参考
29---iptables 原理与应用_xiaohaiyinyu的博客-CSDN博客