不同Linux内核,有不同的报文过滤软件
- Linux Kernal 2.0使用ipfwadm
- Linux Kernal 2.2使用ipchains
- Linux Kernal 2.4-2.6 使用iptables
iptables用来设置报文的过滤规则和匹配动作,这些规则和动作都是通过iptables这个工具设置到netfilter上,当有报文进出时,netfilter会根据定义的规则从上到下的逐一匹配,当某个报文匹配到一条规则后,执行该条规则的相关动作,如果没有匹配到任何一条规则,执行默认的动作。
上面的描述中,有一点是很重要的,就是规则定义的顺序,这个需要在实际情况具体考虑。
iptables 中的表(table)与链(chain)
iptables预设了3张表(由tables可以看出有多张表),每张表中有不同的链chain,我们的规则和动作就存放在chain中。也可以自定义iptables的表,iptables预定的表包括:
- filter,过滤器表,与进出主机的报文相关,包括以下chain
- INPUT:存放检查进入主机的报文的规则和匹配的动作
- OUTPUT:存放检查由主机发出的报文的规则和动作
- FORWARD:存放由主机转发的报文的规则和动作
- nat(Network Address Translation)地址转换,主要对来源IP、目的IP、来源port、目的port的转换,包括以下chain
- PREROUTING:报文刚进入网卡,还未进行路由判断之前要进行的规则转换,比如修改报文的目标地址
- POSTROUTING:已进行路由判断,报文进入网卡发送队列,即将发出时进行的规则转换,比如修改报文的原地址
- OUTPUT:与发出去的报文相关
- mangle破坏者,这个table主要与特殊的报文路由旗标相关,很少用到
iptables的工作流程如下:
iptables的请求响应工作流程:报文进入 --> nat(PREROUTING) --> 路由判断 --> filter(INPUT) --> Linux程序 --> 路由判断 --> nat(OUTPUT) --> filter(OUTPUT) --> nat(POSTROUTING) --> 报文传出
iptables的转发流程:报文进入 --> nat(PREROUTING) --> 路由判断 --> filter(FORWARD) --> nat(POSTROUTING) --> 报文传出
由上面可以看出,如果当我们不做NAT时,该流程还可以进一步简化为至filter表相关的链。
iptables 语法
查看防火墙规则命令
命令iptables [-t tables] -L [chain] -n -v
用来查看防火墙规则
- -t tables,tables是具体的表名,默认是filter表,如果要看nat表,就是 -t nat
- -L [chain], L是List的缩写,表示列出规则,后面可以跟链的名字,如果不跟则表示查看指定表的所有链,
iptables -L INPUT
表示查看filter表的INPUT链上的规则。 - -n ,n是numeric的缩写,表示不进行ip->hostname,port->appname的查询,即以数字的方式显示规则,而不以主机名和app名称的方式显示,这样可以提高显示的速度。
- -v,verbose的缩写,显示更多的信息。命令默认显示
target prot opt source destination
这几栏,加了v选项后变成pkts bytes target prot opt in out source destination
栏。
举例查看filter表的INPUT链的规则,因为默认是filter表,这里就省略了-t filter的选项。
iptables -L INPUT -nv
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
208M 67G ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
38372 2678K ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
1854K 113M ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
38253 2193K ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
342K 19M ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:80
1236 58500 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:443
2153 135K ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:1521
...
492K 99M REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
结果的第一行Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
指出当前的链表是INPUT,而括号中的policy ACCEPT表示的是INPUT链的默认规则是放行,不过最后一条规则表示拒绝所有的输入请求,也就是如果前面的规则都没有匹配到的话,那就是要拒绝这个报文。
表头说明
-
pkts
表示接收到的报文总数量; -
bytes
表示所有报文的大小总和; -
target
表示如果匹配到该条规则后的动作; -
prot
是protocol的缩写,表示的是报文的协议; -
opt
表示额外的选项说明; -
in
表示匹配的报文输入的网卡,这里的第三条规则可以看到,匹配的是lo(回环网卡)中的报文。在规则设置时使用-i
--in-interface选项设置接收报文的网卡,应用在INPUT FORWARD PREROUTING
链表上。如iptables -I INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
命令,设置在eth0网卡上,能够匹配通过sshd(sshd是tcp协议,端口为22)的报文,如果不输入-i
选项默认就是所有网卡; -
out
表示匹配输入的网卡,这查看的是INPUT链,所以是看不到对输出网卡的规则限制,可以通过-o
--out-interface选项设置输出网卡的规则,输入网卡选项用在FORWARD OUTPUT POSTROUTING
链上; -
source
表示源ip,使用-s
source选项设置; -
destination
表示目标地址,使用-d
destination选项设置; - 最后一栏没有标题,是扩展匹配
command命令
命令都是以大写开头
-
-A
选项是append的缩写,语法为-A chain
,后面需要跟链名,表示附加规则到链的最后一行 -
-I
选项是insert的缩写,语法为-I chain [rulenum]
,后面必须跟链名,rulenum表示要插入到第几行,如果不加rulenum表示插入到第一行。 -
-R
选项是replace的缩写,语法为-R chain rulenum
,表示替换链中的第几条规则,注意链名和行数都是必须的 -
-D
选项是delete的缩写,语法为-D chain rulenum
,表示删除链中的第几条规则,注意链名和行数都是必须的 -
-F
选项是flush的缩写,语法为-F [chain]
,表示删除的意思,如果加上链名,表示删除链下的所有规则,如果不加,表示删除表的所有链的规则,注意,-D
是删除链中的指定条目的规则,而-F
是表示删除表或链中的所有规则 -
-X
选项是delete-chain的缩写,语法为-X [chain]
,表示删除自定义的链(系统的链不能删除),如果不加链名,删除的是表中的所有链。注意:要删除自定义的链,链中不能包含规则。 -
-Z
选项是zero的缩写,语法为-Z [chain [rulenum]]
,表示置零一条链或一个规则的pkts和bytes数据。 -
-N
选项是new-chain的缩写,语法为-N chain
,表示新建一个自定义的链。 -
-P
选项是policy的缩写,语法为-P chain target
,表示设置链的默认策略。
选项
选项一般都是小写
-
-p
是protocol的缩写,表示协议,后面跟{tcp,udp,icmp}等 -
-s
是source的缩写,表示源ip地址 -
-d
是destination的缩写,表示目标ip地址 -
-m
是match的缩写,这个表示启用扩展模块,语法-m modulename
,当启动用了对应的扩展模块后,就可以使用该扩展模块的参数,详细可以参见man iptables-extentions
。iptables有很多扩展模块包括像:state模块,tcp模块,udp模块,dnat模块,snat模块等。在这些模块中,tcp,udp等协议模块可以使用-p tcp
参数表示,这种情况叫隐含扩展,使用了隐含扩展后就可以不需要添加-m tcp
,比如-p tcp --dport 80
表示的是目标端口为80,而这个--dport
就是tcp扩展模块中的参数。再比如-m state
表示启用state模块,这样就可以定义更细致的规则,比如在状态匹配模块下,设置要匹配的状态参数iptables -I INPUT -p tcp -dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
,表示在INPUT链上,允许新建和连接ssh服务。每个连接都有4中状态,对应到state模块的4个状态:- NEW 表示连接的一个报文
- ESTABLISHED 表示连接已建立
- RELATED 表示一个已建立的连接发起的一个新的连接,这个新的连接就是RELATED状态
- INVALID 不属于上面的状态,这种情况通常执行DROP
-
-j
是jump的缩写,语法-j target
,表示规则匹配后,要执行的动作{ACCEPT, DROP, REJECT}
iptables命令实例
清除本机防火墙 (filter) 的所有规则,-F
删除filter表下所有chain的规则,-X
删除自定义的chain,-Z
把chain的统计数(pkts,bytes)置零
# 先确保INPUT的默认策略为ACCEPT后在清空规则,防止在设置规则时不能远程登录的情况。
iptables -P INPUT ACCEPT
iptables -F
iptables -X
iptables -Z
设置链的默认策略都为ACCEPT。INPUT链在最后加上拒绝所有输入的规则,
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
设置规则:已建立或相关联的报文都通过,只要是不合法报文就丢弃。实际上就是文章开头的查看iptables规则的第一条规则。允许icmp协议通过。
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A INPUT -p icmp -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
设置应用的规则,这里以sshd和http服务为例,应为第一条规则已经设定了RELATED,ESTABLISHED的都能通过,这里只需要检查状态NEW就行了。
iptables -A INPUT -m state --state NEW -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -m state --state NEW -p tcp --dport 80 -j ACCEPT
设置拒绝不满足条件的规则,这里有两种方式,一种是设置默认策略为DROP,第二种是设置最后一条规则为拒绝所有。我比较推荐使用设置默认策略为DROP,这样在后面添加规则时,可以直接用-A选项加在最后,如果使用第二种方式的话,不方面用-A选项,因为-A是加载所有规则的最后,第二种方法会拦截后面新加的规则。
iptables -P INPUT DROP
# 或者设置最后一条规则为拒绝所有
# iptables -A INPUT -j REJECT
查看和保存
iptables -L INPUT -nv --line-number
#将规则保存到配置文件/etc/sysconfig/iptables中,下次开机后该规则仍然有效
service iptables save
#iptables-save 是查看当前的规则,并没有保存到/etc/sysconfig/iptables中
iptabes-save
网友评论