简介
在讲防火墙的时候,不得不说的是iptables,本文尽量以通俗易懂的方式描述iptables的相关概念,请耐心的读完。
防火墙分类及说明
从逻辑上讲防火墙分为主机防火墙和网络防火墙两类。
- 主机防火墙: 针对单个主机进行防护;
- 网络防火墙:往往处于网络入口或边缘,针对于网络入口进行防护,服务于防火墙背后的本地局域网。
网络防火墙和主机防火墙并不冲突,可以理解为,网络防火墙是对一个集体的防范,主机防火墙则是对个人的防范。
从物理上讲,防火墙可以分为硬件防火墙和软件防火墙。
- 硬件防火墙:在硬件级别实现部分防火墙功能,另一部分功能基于软件实现,性能高,成本高。
- 软件防火墙:应用软件处理逻辑运行于通用硬件平台之上的防火墙,性能低,成本低。
接下来我们来聊老linux的iptables。
什么是netfilter和iptables
简单点的来说:
- netfilter指整个项目,不然官网就不会叫www.netfilter.org了。
- netfilter特指内核中的netfilter框架,iptables指用户空间的配置工具。
- netfilter在协议栈中添加了5个钩子,允许内核模块在这些钩子的地方注册回调函数,这样经过钩子的所有数据包都会被注册在相应钩子上的函数所处理,包括修改数据包内容、给数据包打标记或者丢掉数据包等。
- netfilter框架负责维护钩子上注册的处理函数或者模块,以及它们的优先级。
- iptables是用户空间的一个程序,通过netlink和内核的netfilter框架打交道,负责往钩子上配置回调函数。
- netfilter框架负责在需要的时候动态加载其它的内核模块,比如ip_conntrack、nf_conntrack、NAT subsystem等。
小结:iptables工作在用户空间,是一个命令行工具,我们用这个工具来操作真正的框架,netfilter工作在内核模块。
netfilter钩子
在内核协议栈中,有5个跟netfilter有关的钩子,数据包经过每个钩子时,都会检查上面是否注册有函数,如果有的话,就会调用相应的函数处理数据包,他们的位置见下图:
- NF_IP_PRE_ROUTING: 接收的数据包刚进来,还没有经过路由选择,即还不知道数据包是要发给本机还是其它机器。
- NF_IP_LOCAL_IN: 已经经过路由选择,并且该数据包的目的IP是本机,进入本地数据包处理流程。
- NF_IP_FORWARD: 已经经过路由选择,但该数据包的目的IP不是本机,而是其它机器,进入forward流程。
- NF_IP_LOCAL_OUT: 本地程序要发出去的数据包刚到IP层,还没进行路由选择。
- NF_IP_POST_ROUTING: 本地程序发出去的数据包,或者转发(forward)的数据包已经经过了路由选择,即将交由下层发送出去。
根据上图,我们能够想象出某些常用场景中,数据包的流向:
- 本机收到目的IP是本机的数据包: NF_IP_PRE_ROUTING -> NF_IP_LOCAL_IN
- 本机收到目的IP不是本机的数据包: NF_IP_PRE_ROUTING -> NF_IP_FORWARD -> NF_IP_POST_ROUTING
- 本机发出去的数据包: NF_IP_LOCAL_OUT -> NF_IP_POST_ROUTING
注意: netfilter所有的钩子都是在内核协议栈的ip层,由于ipv4和ipv6用的是不同的ip层代码,所以iptables配置的rules只会影响ipv4的数据包,而ipv6相关的配置需要使用ip6tables。
iptables中的表
iptables用表来管理它的rule,根据rule的作用分成了好几张表,比如用来过滤数据包的filter表,用于处理地址转换的rule就会放到nat表中,如果我们自己在开发权限的时候,因为这个不需要跟用户挂钩,所以大家理解为根据不同的功能将权限给划分到不同的表里面,如果要配置某个权限就需要操作那张表是一个道理,其中rule就是应用在netfilter钩子上的函数,用来修改或者过滤数据包。目前iptables支持的表如表所示:
表名 | 用途 |
---|---|
filter | 这个表里面的规则主要用来过滤数据,用来控制让那些数据可以通过,那些数据不可以通过 |
nat | 这个表里面的rule是用来处理网络地址转换的,控制要不要进行地址转换,以及怎样修改源地址和目标地址,从容影响数据包的路由 |
mangle | 主要用来修改ip数据包头,比如修改ttl值,同时也用于给数据包添加一些标记,从而便于其它模块对数据进行处理 |
raw | 在netfilter里面有一个叫做connection tracking的功能(后面会介绍到),主要用来追踪所有的连接,而raw表里的rule的功能是给数据包打标记,从而控制哪些数据包不被connection tracking所追踪。 |
security | 里面的rule跟SELinux有关,主要是在数据包上设置一些SELinux的标记,便于跟SELinux相关的模块来处理该数据包。 |
chains
上面我们说根据不同的功能将rule放到了不同的表里面之后,这些rule会注册到哪些钩子上呢?于是iptables将表中的rule继续分类,让rule属于不同的链(chain),由chain来决定什么时候触发chain上的这些rule。
iptables里面有5个内置的chains,分别对应5个钩子:
- PREROUTING: 数据包经过NF_IP_PRE_ROUTING时会触发该chain上的rule.
- INPUT: 数据包经过NF_IP_LOCAL_IN时会触发该chain上的rule.
- FORWARD: 数据包经过NF_IP_FORWARD时会触发该chain上的rule.
- OUTPUT: 数据包经过NF_IP_LOCAL_OUT时会触发该chain上的rule.
- POSTROUTING: 数据包经过NF_IP_POST_ROUTING时会触发该chain上的rule.
每个表里面都可以包含多个chains,但并不是每个表都能包含所有的chains,因为某些表在某些chain上没有意义或者有些多余,比如说raw表,它只有在connection tracking之前才有意义,所以它里面包含connection tracking之后的chain就没有意义。(connection tracking的位置会在后面介绍到)
多个表里面可以包含同样的chain,比如在filter和raw表里面,都有OUTPUT chain,那应该先执行哪个表的OUTPUT chain呢?这就涉及到后面会介绍的优先级的问题。
提示:可以通过命令iptables -L -t nat|grep policy|grep Chain查看到nat表所支持的chain,其它的表也可以用类似的方式查看到,比如修改nat为raw即可看到raw表所支持的chain。
表链关系
根据上文提到的每个表里面都会有不同的链,不是每个链里面都会有所有的表,我们做下归类:
chain名 | 表名 |
---|---|
prerouting | raw,mangle,nat |
input | mangle,filter |
forword | mangle,filter |
output | raw,nat,filter |
postrouting | mangle,nat |
但是,我们在实际使用过程中,往往是通过表作为操作入口,对规则进行定义,所以我们将表与链的关系罗列出来。
表 | 链 |
---|---|
raw | prerouting,output |
mangle | prerouting,input,forward,output,postrouting |
nat | prerouting,output,postrouting |
filter | input,forward,output |
其实我们还需要注意,数据包经过一个链的时候会把所有的规则都执行一遍,所以需要一个优先级问题。关于优先级的定义如下图所示: | |
通过上图,我们已经知道了表中的规则可以被那些链使用,下面我们做下归纳总结,因为后面我们操作都是通过操作表来操作规则的。
表 | 链 |
---|---|
raw | prerouting,output |
mangle | prerouting,input,forward,output,postrouting |
nat | prerouting,output,postrouting |
filter | input,forward,output |
iptables中的规则
rule就是特定表的特定chain上,每条rule包含如下两部分信息
Matching
Matching就是如何匹配一个数据包,匹配条件很多,比如协议类型、源/目的IP、源/目的端口、in/out接口、包头里面的数据以及连接状态等,这些条件可以任意组合从而实现复杂情况下的匹配。详情请参考Iptables matches
targets
tartets就是找到匹配的数据包之后怎么办,常见的有如下四种:
- drop:直接将数据包丢弃,不在进行后续的处理
- reject:拒绝数据包通过,必要时会给数据发送一个响应的信息,
- accept:允许数据包通过。
- snat: 源地址转换,解决内网用户用同一个公网地址上网问题
- masquerade:是snat的一种特殊形式,适用于动态的、临时会变的ip上
- dnat: 目标地址转换
- redirect: 在本机做端口映射
当然iptables包含的targets很多很多,但并不是每个表都支持所有的targets,
rule所支持的target由它所在的表和chain以及所开启的扩展功能来决定,具体每个表支持的targets请参考Iptables targets and jumps。