CentOS 7防火墙iptables
在最新版的CnetOS 7中,系统安装了两个防火墙firewalld
和iptables
,并且默认使用firewalld
。由于之前的版本均使用iptables
,因此本书也介绍iptables
。要使用Linux防火墙,必须要先了解TCP/IP网络的基本原理,理解Linux防火墙的工作原理,本节主要介绍Linux防火墙方面的知识。
Linux内核防火墙的工作原理
Linux的内核提供的防火墙功能通过netfiter
框架实现,并提供了iptables
工具配置和修改防火墙的规则。
netfilter
的通用框架不依赖于具体的协议,而是为每中网络协议定义一套钩子函数。这些钩子函数在数据包经过协议栈的几个关键点时被调用,在这几点中,协议栈将数据包及钩子函数作为参数,传递给netfilter
框架。
对于每种网络协议定义的钩子函数,任何内核模块可以对每种协议的一个或多个钩子函数进行注册,实现挂接。这样当某个数据包被传递给netfilter
框架时,内核能检测到是否有有关模块对该协议和钩子函数进行了注册。如发现注册信息则调用该模块在注册时使用的回调函数,然后对应模块去检查、修改、丢弃该数据包及指示netfilter
将该数据包传入用户空间的队列。
从以上描述可以得知钩子提供了一种方便的机制,以便在数据包通过Linux内核的不同位置上截获和操作处理数据包。
1.netfilter的体系结构
网络数据包的通信主要经过以下相关步骤,对应netfilter定义的钩子函数,更多信息可以参考源代码。
- NF_IP_PRE_ROUTING:网络数据包进入系统,经过了简单的检测后,数据包转交给函数进行处理,然后根据系统设置的规则对数据包进行处理,如果数据包不被丢弃则交给路由函数进行处理。在该函数中可以替换IP包的目的地址,即DNAT。
- NF_IP_LOCAL_IN:所有发送给本机的数据包都要通过该函数的处理,该函数根据系统设置的规则对数据包进行处理,如果数据包不被丢弃则交给本地的应用程序。
- NF_IP_FORWARD:所有不是发送给本机的数据包都要通过该函数进行处理,该函数会根据系统设置的规则对数据包进行处理,如数据包不被丢弃则转NF_IP_POST_ROUTING进行处理。
- NF_IP_LOCAL_OUT:所有从本地应用程序出来的数据包必须通过该函数的处理,该函数根据系统设置的规则对数据包进行处理,如果数据包不被丢弃则交给路由函数进行处理。
- NF_IP_POST_ROUTING:所有数据包在发给其他主机之前需要通过该函数的处理,该函数根据系统设置的规则对数据包进行处理,如果数据包不被丢弃,将数据包发给数据链路层。在该函数中可以替换IP包的源地址,即SNAT。
图1.3显示了数据包在通过Linux防火墙时的处理过程。
2.包过滤
每个函数都可以对数据包进行处理,最基本的操作为对数据包进行过滤。系统管理员可以通过iptables
工具来向内核模块注册多个过滤规则,并且指明过滤规则的优先权。设置完成以后。每个钩子按照规则进行匹配,如果与规则匹配,函数就会进行一些过滤操作,这些操作主要是以下几个:
- NF_ACCEPT:继续正常地传包
- NF_DROP:丢弃包,停止传送
- NF_STOLEN:已经接管了包,不要继续传送
- NF_QUEUE:排列包
- NF_REPEAT:再次使用该钩子
3.包选择
在netfilter
框架上已经创建了一个包选择系统,这个包选择工具默认已经注册了3个表,分别是:过滤(fliter)表、网络地址转换(NAT)表mangle表。
在调用钩子函数时是按照表的顺序来调用的。例如在执行NF_IP_PRE_ROUTING
时,首先检查filter表,然后检查Mangle表,最后检查NAT表。
过滤(fliter)表过滤包而不会改变包,仅仅是过滤的作用,实际上由网络过滤框架来提供NF_IP_FORWARD钩子的输出和输入接口使得很多过滤工作变得非常简单。从图中可以看出,NF_IP_LOCAL_IN和NF_IP_LOCAL_OUT也可以做过滤,但是只是针对本机。
网络地址转换(NAT)表分别服务于两套不同的网络过滤挂钩的包,对于非本地的包,NF_IP_PRE_ROUTING和NF_IP_POST_ROUTING挂钩可以完美地解决源地址和目的地址的变更。
NAT表与filter表的区别在于只有新建连接的第1个包会在表中传送,结果将被用于以后所有来自这一连接的包。例如某一个连接的第1个数据包在这个表中被替代了源地址,那么以后这条连接的所有包都将被替换源地址。
mangle表被用于真正的改变包的信息,mangle表和所有的5个网络过滤的钩子函数都有关。
4.切换至iptables
在正式学习iptables
之前,还需要将默认使用的firewalld
停止,并让系统将iptables
作为默认防火墙。其命令如下:
#关闭并禁用firewalld
[root@node1 ~]# systemctl stop firewalld
[root@node1 ~]# systemctl disable firewalld
Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
#启动并启用iptables
[root@node1 ~]# systemctl start iptables
[root@node1 ~]# systemctl enable iptables
#如果使用了ipv6,还需要开启ip6tables
#启动并启用ip6tables
[root@node1 ~]# systemctl start ip6tables
[root@node1 ~]# systemctl enable ip6tables
使用上述命令就可以在CentOS 7中使用iptables
了。
Linux软件防火墙iptables
iptables
工具用来设置、维护和检查Linux内核的IP包过滤规则。filter、NAT和mangle表可以包含多个链(chain),每个链可以包含多条规则(rule)。iptables
主要对表table
、链(chain)和规则(rule)进行管理。
iptables
预定了5个链,分别对应netfilter
的5个钩子函数,这5个链分别是:INPUT链、FORWARD链、OUTPUT链、PREROUTING链、POSTROUTING链。
iptables
指令语法如下:
iptables [-t table] command [match] [-j target/jump]
“-t table”参数用来指定规则表,内建的规则表分为nat、mangle和filter,当为指定规则表时,默认为filter。各个规则表的功能如下:
- nat:此规则表主要针对PREROUTING和POSTROUTING两个规则链,主要功能为进行源地址或目的地址的网址转换工作(SNART、DNAT)。
- mangle:此规则表主要针对PREROUTING、FORWARD和POSTROUTING 3个规则链,某些特殊应用可以在此规则表里设定,比如为数据包做标记。
- filter:这个规则表是默认规则表,针对INPUT、FORWARD和OUTPUT 3个规则链,这个规则表主要用来进行封包过滤的处理动作,如DROP、LOG、ACCEPT或REJECT。
iptables
的简单用法如【示例1-1】所示。
【示例1-1】
[root@node1 ~]# iptables -t filter -A FORWARD -s 192.168.19.0/24 -j DROP
[root@node1 ~]# iptables -nL
Chain FORWARD (policy ACCEPT)
target prot opt source destination
DROP all -- 192.168.19.0/24 0.0.0.0/0
提示:其中“-t filter”表示该规则作用于filter表,“-A”表示新增规则,“-s”表示IP段选项,
“-j”表示指定动作。该规则表示在filter表FORWARD链上新增一条规则,发往192.168.19.0/24
网段的包采取丢弃操作。要查看某个表下的各个链的信息可以使用“iptables -nL”。
要使Linux系统成为网络防火墙,当然除了内核支持之外,还需要启用Linux的网络转发功能。如需要使系统启动时就具有该功能,可以将上面的命令写入到/etc/rc.d/rc.local文件中。
echo 1 > /proc/sys/net/ipv4/ip_forward
数据包通过表和链时需要遵循一定的顺序,当数据包到达防火墙时,如果MAC地址符合,就会由内核里相应的驱动程序接收,然后经过一系列操作,从而决定是发送给本地的程序还是转发给其他机器。数据包通过防火墙时分以下3种情况。
1.以本地为目的的包
当一个数据包进入防火墙后,如果目的地址是本机,被防火墙进行检查的顺序如表1.8所示。如果在某一个步骤数据包被丢弃,当然就不会执行后面的检查了。
表1.1 以本地为目的的包检查顺序
步骤 | 表 | 链 | 说明 |
---|---|---|---|
1 | 数据包在链路上进行传输 | ||
2 | 数据包进入网络接口 | ||
3 | mangle | PREROUTING | 这个链用来mangle数据包,如对包进行改写或做标记 |
4 | nat | PREROUTING | 这个链主要用来做DNAT |
5 | 路由判断,如包是发往本地的还是要转发的 | ||
6 | mangle | INPUT | 在路由之后,被送往本地程序之前如对包进行改写或作标记 |
7 | filter | INPUT | 所有以本地为目的的包都需要经过这个链,包的过滤规则设置在此 |
8 | 数据包到达本地程序,如服务程序或客户程序 |
2.以本地为源的包
本地应用发出的数据包,被防火墙进行检查的顺序如表1.2所示。
表1.2 以本地为源的包检查顺序
步骤 | 表 | 链 | 说明 |
---|---|---|---|
1 | 本地程序,如服务程序或客户程序 | ||
2 | 路由判断 | ||
3 | mangle | OUTPUT | 用来mangle数据包,如对包进行改写或做标记 |
4 | nat | OUTPUT | 对发出的包进行DNAT操作 |
5 | filter | OUTPUT | 对本地发出的包过滤,包的过滤规则设置在此 |
6 | mangle | POSTROUTING | 进行数据包的修改 |
7 | filter | POSTROUTING | 在这里做SNAT |
8 | 离开网络接口 | ||
9 | 数据包在链路上传输 |
3.被转发的包
需要通过防火墙转发的数据包,被防火墙进行检查的顺序如表1.3所示。
表1.3 被转发的包检查顺序
步骤 | 表 | 链 | 说明 |
---|---|---|---|
1 | 数据包在链路上传输 | ||
2 | 进入网络接口 | ||
3 | mangle | PREROUTING | mangle数据包,如对包进行改写或做标记 |
4 | nat | PREROUTING | 这个链主要用来做DNAT |
5 | 路由判断,如包是发往本地的,还是要转发的 | ||
6 | mangle | FORWARD | 包继续被发送至mangle表的FORWARD链,这是非常特殊的情况才会用到的。在这里,包被mangle。这次mangle发生在最初的路由判断之后,在最后一次更改包的目的之前 |
7 | filter | FORWARD | FORWARD包继续被发送至这条FORWARD链。只有需要转发的包才会走到这里,并且针对这些包的所有过滤也在这里进行。注意,所有要转发的包都要经过这里 |
8 | mangle | POSTROUTING | 这个链也是针对一些特殊类型的包。这一步mangle是在所有更改包的目的地址的操作完成之后做的,但这时包还在本地上 |
9 | nat | POSTROUTING | 这个链就是用来做SNAT的,不推荐在此处过滤,因为某些包即使不满足条件也会通过 |
10 | 离开网络接口 | ||
11 | 数据包在链路上传输 |
对包进行过滤时,常用的有以下3个动作。
(1)ACCEPT:一旦数据包满足了指定的匹配条件,数据包就会被ACCEPT,并且不会再去匹配当前链中的其他规则或同一个表内的其他规则,但数据仍然需要通过其他表中的链。
(2)DROP:如果包符合条件,数据包就会被丢弃掉,并且不会向发送者返回任何信息,也不会向路由器返回信息。
(3)REJECT:和DROP基本一样,区别在于除了将包丢弃并且向发送者返回错误信息。
要进一步了解各个链中规则的匹配顺序,就来学习下filter表中FORWARD链的输出,如【示例1-2】所示。
【示例1-2】
[root@node1 ~]# iptables -nvL
Chain FORWARD (policy DROP)
target prot opt source destination
ACCEPT all -- 192.168.100.0/24 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 69.147.0.0/24
ACCEPT all -- 172.16.0.0/16 0.0.0.0/0
mychain tcp -- 10.0.0.0/24 0.0.0.0 tcp dpt:80
“policy DROP”表示该链的默认规则为DROP操作。如现有一数据包。,源地址为192.168.1.58,目的地址为137.254.60.6,协议为TCP,目的端口为80.当该数据包通过FORWARD链时,从上往下开始匹配:
(1)与第1条规则:源为192.168.100.0/24,源不匹配
(2)与第2条规则:目的为69.147.0.0/24,目标不匹配。
(3)与第3条规则:源为172.16.0.0/16,源不匹配。
(4)与第4条规则:源为10.0.0.0/24,源不匹配。
由于经过匹配以上所有规则都不符合,数据包则转交给默认规则处理,由于本示例中默认的规则为DROP,因此该数据包被丢弃。
在看另一个数据包,源地址为192.168.1.58,目的地址为69.147.83.199,协议为TCP,目的端口为80。当该数据包通过FORWARD链时,从上往下开始匹配:
(1)与第一条规则:源为192.168.100.0/28,源不匹配。
(2)与第二条规则:源地址为任意(0.0.0.0/0),匹配;目的地址为69.147.0.0/24,69.147.83.199在范围内,匹配;源端口和目的端口为任意,匹配;协议为任意(all),匹配;规则链对该数据包的动作为ACCEPT,因此该数据包通过。
如果数据包的源地址为10.0.0.35,目的地址为69.147.83.199,协议为TCP,目的端口为80。当该数据包通过FORWARD链时,从上往下开始匹配,当匹配当第4条规则时匹配,动作为mychain,此时数据包会被转到用户自己定义的规则链mychain进行处理。
iptables配置实例
iptables
工具支持丰富的参数,可以IP和端口、网络接口、TCP标志位或MAC地址进行过滤,参数指定方式除传统方法外,可以支持“!”、“ALL”或“NONE”等进行参数匹配。iptables
常用参数说明如表1.3所示。
表1.3 iptables命令参数含义说明
参数 | 含义 |
---|---|
-A | 新增规则到某个规则链中,该规则将会称为规则链中的最后一条规则 |
-D | 从某个规则中删除一条规则,可以输入完整规则,或直接指定规则编号加以删除 |
-R | 替换某行规则,规则被替换后并不会改变顺序 |
-I(大写i) | 插入一条规则,原本该位置上的规则将会往后移动一个顺位 |
-L | 列出某规则链中的所有规则 |
-F | 删除规则链中的所有规则 |
-Z | 将数据包计数器归零 |
-N | 定义新的规则链 |
-X | 删除某个规则链 |
-P | 定义不符合规则的数据包的默认处理方式 |
-E | 修改某自定义规则链的名称 |
-p | 匹配通信协议类型是否相符,可以使用!运算符进行反向匹配 |
-s | 匹配数据包的来源IP,可以匹配单个IP或某个网段 |
-d | 匹配数据包的目的地IP,设定方式同上 |
-i | 匹配数据包是从哪个网络接口进入,可以使用通配字符+指定匹配范围 |
-o | 匹配数据包要从哪个网络接口发出,设定方式同上 |
--sport | 匹配数据包的源端口,可以匹配单一端口或一个范围 |
--dport | 匹配数据包的目的端口号,设定方式同上 |
--tcp-flags | 匹配TCP数据包的状态标志,如SYN、ACK、FIN等,另外可使用ALL和NONE进行匹配 |
-m | 匹配不连续的多个源端口或目的端口 |
-m | 匹配数据包来源网络接口的MAC地址,不能用于OUTPUT和POSTROUTING规则链 |
ACCEPT | 将数据包放行,进行完此处理动作后,将不再匹配其他规则,直接终端过滤程序 |
REJECT | 阻塞数据包,并传送数据包通知对方 |
DROP | 丢弃数据包不予处理,进行完此处离动作后,将不在匹配其他规则,直接中断过滤程序 |
REDIRECT | 将数据包相关信息记录在/var/log中 |
LOG | 将数据包相关信息记录在/var/log中 |
SNAT | 改写数据包来源IP为某特定IP或IP范围,可以指定port对应的范围,进行完此处理动作后,将直接跳往下一个规则链 |
DNAT | 改写数据包目的地IP为某特定IP或IP范围,可以指定port对应的范围,进行完此处理动作后,将会直接跳往下一个规则链 |
RETURN | 结束在目前规则链中的过滤程序,返回著规则链继续过滤 |
MARK | 数据包做标记,以便提供作为后续过滤的条件判断依据,进行完此处理动作后,将会继续匹配其他规则 |
1.简单应用示例
iptables
使用方法首先指定规则表,然后指定要执行的命令,接着指定参数匹配数据包的内容,最后是要采取的动作。下面通过一些示例来说明**iptables**
的使用方法,如【示例1-3】所示。
【示例1-3】
#清除所有规则
[root@node1 ~]# iptables -F
#清除nat表中的所有规则
[root@node1 ~]# iptables -t nat -F
#允许来自192.168.139.0/24连接sshd服务
[root@node1 ~]# iptables -A INPUT -p tcp -s 192.168.139.0/24 --dport 22 -j ACCEPT
#其他任何网段访问不能访问sshd服务
[root@node1 ~]# iptables -A INPUT -p tcp --dport 22 -j DROP
在上述示例中,“-F”表示清除已存在的所有规则,“-A”表示添加一条规则,“-p”指定协议为TCP,“-s”指定源地址段,如果该参数忽略或位0.0.0.0/0,则源地址表示任何地址,“-dport 指定目的端口”。包的判断顺序为首先判断第1条规则,由于允许192.168.139.0/24网段的服务器访问sshd服务,因此包可以通过;如果是其他来源的主机,由于第1条规则不符合接着判断第2条规则,策略为禁止,因此将包被丢弃。
除以上示例外,iptables
可以为每个链指定默认规则,如果包不符合现存的所有规则,则按默认规则处理,方法如【示例1-4】所示。
【示例1-4】
#清除所有规则
[root@node1 ~]# iptables -F
#设置默认规则
[root@node1 ~]# iptables -t filter -P INPUT ACCEPT
#允许来自192.168.139.0/24连接sshd服务
[root@node1 ~]# iptables -A INPUT -p tcp -s 192.168.139.0/24 --dport 22 -j ACCEPT
由于设置了默认规则,该示例的功能同示例1-3
提示:上面的所列举的示例仅仅是为了说明语法和原理,在实际使用中,还需要注意规则添加的顺序,使数据包通过的规则最少。
基于网络接口的过滤如【示例 1-5】所示。
【示例 1-5】
[root@node1 ~]# iptables -t filter -F
[root@node1 ~]# iptables -t filter -P FORWARD DROP
[root@node1 ~]# iptables -t filter -A FORWARD -p tcp -i enth2 -o enth1 --dport 80 -j ACCEPT
使用-i参数来指定数据包的来源网络接口,使用-o来指定数据包将从哪个网络接口出去。
提示:在INPUT链中不能使用-o选项,OUTPUT链中不能使用-i选项。
2.NAT设置
通常网络中的数据包从包的源地址发出直到包要发送的目的地址,整个路径经过很多不同的连接,一般情况下这些连接不会更改数据包的内容,只是原样转发。如果发出数据包的主机使用的源地址是私有网络地址,该数据包将不能再互联网上传输。要能够使用私有网络访问互联网,就必须要做NAT(Network Address Translation,网络地址转换)。
NAT分为两种不同的类型:源NAT(SNAT)和目标NAT(DNAT)。SNAT通常用于使用了私网地址的局域网络能够访问互联网。DNAT是指修改包的目标地址,端口转发、负载均衡和透明代理都属于DNAT。
再SNAT中改变源地址,如【示例1-6】所示。
【示例1-6】
#SNAT改变源地址为1.2.3.4
[root@node1 ~]# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4
#DNAT
[root@node1 ~]# iptables -t nat -A PREROUTING -p tcp -i eth2 -d 1.2.3.4 --dport 80 -j DNAT --to 192.168.3.88:80
提示:如果做SNAT只能在POSTROUTING上进行,而做DNAT只能在PREROUTING内进行。