我们都知道,iptables 和 netfilter 构成了 Linux 防火墙的坚实屏障,这两个技术涉及的知识点太广了,面面俱到的话足以写成一本书。但其实抓住重点核心知识的话,三张图就可以搞定了,本文就来说说这三张图。
首先,先来看看 iptables 和 netfilter 是什么关系?
iptables 和 netfilter 是一套 Linux 防火墙组合工具,共同合作完成系统的防护工作。iptables 是客户端工具,netfilter 是服务端程序,iptables 工作在用户态,netfilter 工作在内核态,用户可以通过 iptables 命令作用到服务端的 netfilter,netfilter 触发相应的回调函数(hook 机制)执行相应的防护动作。
整个调用关系如下图所示:
用户通过 iptables 下发安全规则或策略,netfilter 执行规则所对应的动作,来完成对系统的防护。netfilter 的本质就是 对报文进行规则的匹配,针对不同的规则,执行相应的动作 。
这些规则有不同的功能,也有相同的功能,在报文传输的整个过程中,有不同的作用点,有的作用在入口,有的作用在出口,有的作用在中间协议栈等等。为了方便管理这些规则集,netfilter 实现上引入了两个概念: 链(chain)和表(table) 。
表集合了相同功能的规则集,iptables 总共实现了 5 张表,但常用的只有 4 张表,我们也只重点以这 4 张表作为讲解:
•raw 表 :负责去除数据包上的连接追踪机制(iptables 默认会开启对数据包的连接追踪) •mangle 表 :负责数据包的拆解、修改、再封装等功能 •nat 表 :负责数据包的网络地址转换功能 •filter 表 :负责数据包过滤(放行、丢弃或拒绝)功能,防火墙功能的真正体现
由于在数据包传输过程中,会经历很多“关卡”,每个“关卡”都有可能匹配多种不同的规则集,也就是匹配不同的表。为了方便管理这些“关卡”,因此就有了链的概念。
链就是由多张表串联组合起来的,充当数据包进出系统的“关卡”。iptables 总共实现了 5 条链,分别是:
•PREROUTING 链 :处理刚进入系统路由前的数据包,可进行 DNAT •INPUT 链 :处理输入本地进出的数据包 •FORWARD 链 :处理转发到其他机器的数据包 •OUTPUT 链 :处理本地进出输出的数据包 •POSTROUTING 链 :处理从系统出去路由后的数据包,可进行 SNAT
这 5 条链,每一条链也并不会串联所有的表,因为每个“关卡”负责的功能不一样,可以匹配的规则自然也就不一样,下面总结下每条链的规则都可以存在哪些表中:
•PREROUTING 链 :raw, mangle, nat •INPUT 链 :mangle, nat, filter •FORWARD 链 :raw, mangle, nat, filter •OUTPUT 链 :mangle, filter •POSTROUTING 链 :mangle, nat
当然这些表的优先级也是不一样的,修改数据包的优先级肯定要比查找数据包的大,所以,从功能上说,这 4 张表的优先级分别为:
raw > mangle > nat > filter
连接追踪 raw 表是数据包刚进入就要记录的,所以优先级最高,过滤表 filter 表作为最后一道屏障,优先级是最低的。
以上梳理了 4 表 5 链之间的关系,我们可以用下面一张图来记忆它们,相信你看完,就会对 iptables 的 4 表 5 链比较清晰了。
至此,Linux 系统就通过这 4 表 5 链设置好了一道道的屏障,当网络数据包进来或者有数据包向外发出时,必然会经过这些屏障,根据预先设定的规则,就可以对这些数据包进行有效的转发或过滤。
结合第一张图,我们可以看到,netfilter 从网络层开始介入,对进出的数据包进行控制。一般的数据包处理主要经过以下三个流程:
1.到本机某进程进行处理的报文(请求报文):PREROUTING->INPUT 2.从本机转发的报文(中转报文):PREROUTING->FORWARD->POSTROUTING 3.从本机某进程发出的报文(响应报文):OUTPUT->POSTROUTING
我们可以用以下这张图来表示:
这张图一看就清楚了,不用过多解释。我们重点从代码层面来看看,首先看“入方向”,数据包从网卡接收进入网络层之后(ip_rcv
接收),会经过预先注册好的 hook 函数(NF_INET_PRE_ROUTING
),当即进入 PREROUTING 链,经由三张表(raw、mangle、nat)洗刷,合格的报文随即进入下一个阶段,这个阶段首先会经由一次路由判断,判断是进入本机进程的报文,通过 ip_local_deliver
函数,触发 hook NF_INET_LOCAL_IN
进入 INPUT 链,再通过三张表洗刷一次,最后才会往上送入传输层(udp_rcv
)。
而判断是其他主机的报文,则会通过 ip_forwad
触发 NF_INET_FORWARD
进入 FORWARD 链,完了再通过 POSTROUTING 链转发出去。
接着来看“出方向”,数据包由本地某进程发出,到达网络层,触发这里的 hook NF_INET_LOCAL_OUT
进入 OUTPUT 链,过滤之后继续通过 POSTROUTING 链发送出去。
关于以上的更多细节,可以参考 Linux 收发数据包的流程,这里我们只是提一下 iptables 在 Linux数据包收发过程中所起的作用。从图中可以看到,iptables 和 netfilter 的作用只是在网络层中,通过设置一层层的“关卡”(hook 函数)来达到过滤和修改数据包的目的。
知道每条链都含哪些表,我们就可以通过 iptables 命令为不同的表和链指定不同的规则了,从而达到控制和过滤数据包的目的。
参考:
•文章图参考 http://www.zsythink.net/archives/tag/iptables/ •https://www.cnblogs.com/marility/p/7448407.html
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8