iptables 原理概述_iptables内核架构-程序员宅基地

技术标签: 网络  运维  linux  

References

在这里插入图片描述

一、iptables 和 netfilter

iptables 是 Linux 上最常用的防火墙工具。其底层是基于与 Linux 内核网络协议栈所提供的包过滤 hook 从而实现的。而负责提供这些 hook 的就是 Netfilter 框架。

每个进入网络系统的包(接收或发送)在经过协议栈时都会触发这些 hook,程序可以通过注册 hook 函数的方式在一些关键路径上处理网络流量。而 Linux 上的防火墙功能正是基于 iptables 所提供的接口,在这些 hook 点上注册了处理函数,从而可以实现对应的防火墙规则。

综上所述,即 Netfilter 是 Linux 内核提供的一个框架,而 iptables 是基于此框架实现的一个内核模块,同时我们也应该注意到,iptables 并不是唯一基于 Netfilter 实现的内核模块,同样基于 Netfilter 实现的还有例如 IPVS 模块等。

二、Network Hook

netfilter 提供了 5 个 hook 点。包经过这些点时会触发内核模块在这里注册的处理函数。触发哪个 hook 取决于包的方向(ingress/egress)、包的目的地址、包在上一个 hook 点是被丢弃还是拒绝等。

下面几个 hook 是内核协议栈中已经定义好的:

  • NF_IP_PRE_ROUTING:接收到的包进入协议栈后立即触发此 hook,在进行任何路由判断(将包发往哪里)之前;
  • NF_IP_LOCAL_IN:接收到的包经过路由判断,如果目的是本机,将触发此 hook;
  • NF_IP_FORWARD:接收到的包经过路由判断,如果目的是其他机器,将触发此 hook;
  • NF_IP_LOCAL_OUT:本机产生的准备发送的包,在进入协议栈之后立即触发此 hook;
  • NF_IP_POST_ROUTING:本机产生的准备发送的包或者转发的包,在经过路由判断之后,将触发此 hook。

在 hook 点上注册处理函数时必须提供优先级,以便 hook 被触发时能按照优先级顺序调用处理函数。这使得多个模块(或者同一模块的多个实例)可以在同一 hook 点注册,并且有确定的处理顺序。

三、iptables 表和链

iptables 使用表(tables)来组织规则,根据规则的应用场景从而划分到不同的表中。例如某条规则是用来做网络地址转换的,那这条规则会被划分到 nat 表中,如果某条规则是用来判断过滤数据包,那么这条规则则是属于 filter 表的。

同时,在每个表内部,规则被进一步组织成链(chains)。表是由它们所持有的规则的应用场景定义的,而内置链表示触发它们的 netfilter 钩子,即链决定何时触发这些规则。

下面可以看出,内置的 chain 名字和 netfilter hook 名字是一一对应的:

  • PREROUTING:由 NF_IP_PRE_ROUTING hook 触发;
  • INPUT:由 NF_IP_LOCAL_IN hook 触发;
  • FORWARD:由 NF_IP_FORWARD hook 触发;
  • OUTPUT:由 NF_IP_LOCAL_OUT hook 触发;
  • POSTROUTING:由 NF_IP_POST_ROUTING hook 触发。

四、table 类型

先来看看 iptables 提供的 table 类型,这些 tables 是按规则类型区分的。

4.1 filter table:过滤(放行/拒绝)

filter table 是最常用的表之一,用于判断是否允许一个包通行。

在防火墙的概念中,这通常被称作包“过滤”(“filtering” packets),这个 table 提供了防火墙的一些常见功能。

4.2 nat table:网络地址转换

nat 表用于实现网络地址转换规则。

当包进入协议栈的时候,这些规则决定是否以及如何修改包的源/目的地址,以改变包被路由时的行为。nat 表通常用于将包修改后路由到原先的包无法直接访问的网络。

4.3 mangle table:修改 IP 头

mangle 表用来对 IP 包的 IP 头进行修改,例如可以修改包的 TTL,增加或减少可以经过的跳数。

这个表还可以用来对包打上内核内置的标记,以便后续的表或其他网络工具根据标记进行处理。这个标记不会修改 IP 包本身,只是做了个标签,而且只在内核处理过程中有效。

4.4 raw table:contrack 相关

iptables 是有状态的,即 iptables 对数据包有连接追踪(connection tracking)机制(对于 contrack 的进一步探讨看第七小节),而 raw 是用来去除这种最终机制的,主要是为了提高效率使用的。

raw本身的含义是指“原生的”、“未经过加工 的”,符合 raw 表所对应规则的数据包将会跳过一些检查,这样就可以提高效率;

4.5 security table:打 SELinux 标记

最不常用的表(通常,我们说 iptables 只有 4 张表,security 表是后面新加入的特性),用于在数据包上应用 SELiunx。

五、表与链之间的关联

前面已经讨论了 table 和 chain,接下来我们探讨每个 table 里都有哪些 chain。同时,我们还将关注注册到同一 hook 上的不同 chain 的优先级。例如:mangle、raw、nat 这三个表中都有 PREROUTING chain,那么应该按照什么顺序调用它们呢?

5.1 表关联的链以及链的执行顺序

下面的表格展示了 table 和 chain 的关系。横向是 table,纵向是 chain,Y 表示这个 table 里面有这个 chain。例如,第二行表示 raw table 有 PRETOUTINGOUTPUT 两 个 chain。具体到每列,从上倒下的顺序就是 netfilter hook 触发的时候,(对应 table 的)chain 被调用的顺序。

有几点需要说明一下。在下面的图中,nat 表被细分成了 DNAT (修改目的地址) 和 SNAT(修改源地址),以更方便地展示他们的优先级。另外,我们添加了路由决策点 和连接跟踪点,以使得整个过程更完整全面:

Tables↓/Chains→ PREROUTING INPUT FORWARD OUTPUT POSTROUTING
(routing decision)
raw
(connection tracking enabled)
mangle
nat (DNAT)
(routing decision)
filter
security
nat (SNAT)

当一个包触发 netfilter hook 时,处理过程将沿着列从上向下执行。 触发哪个 hook(列)和包的方向(ingress/egress)、路由判断、过滤条件等相关。

在这里插入图片描述

特定事件会导致 table 的 chain 被跳过。例如,只有每个连接的第一个包会去匹配 NAT 规则,对这个包的动作会应用于此连接后面的所有包。到这个连接的应答包会被自动应用反方向的 NAT 规则。

5.2 自定义 chain

除了上述我们提到的 chain 外,iptables 也支持创建自定义的链。用户定义的 chain 可以看作是对调用它的 chain 的扩展。例如,用户定义的 chain 在结 束的时候,可以返回 netfilter hook,也可以继续跳转到其他自定义 chain。

向用户自定义 chain 添加规则和向内置的 chain 添加规则的方式是相同的。不同的地方在于, 用户定义的 chain 只能通过从另一个规则跳转(jump)到它,因为它们没有注册到 netfilter hook

用户自定义的链中的规则和系统预定义的 5 条链里的规则没有区别。犹豫自定义的链没有与 netfilter 里的 hook 进行绑定,所以它不会自定触发,只能从其他链的规则中跳转过来,也就是后续 iptables 规则中提到的 JUMP 动作。

这种设计使框架具有强大的分支功能,使得管理员可以组织更大更复杂的网络规则。

六、iptables 规则

每一条 iptables 规则都包涵匹配和动作两部分。

6.1 匹配

规则的匹配部分指定数据包必须满足的条件,以便执行相关的操作(或“目标”)。

匹配系统非常灵活,可以通过附加的 iptables 接口进行定义。规则可以根据协议类型、目标或源地址、目标或源端口、目标或源网络、输入或输出接口、报头或连接状态等条件进行匹配。可以将这些规则组合起来创建复杂的规则集,以区分不同的流量。

6.2 动作

那么数据包匹配完之后该怎么办,常见的有以下几种操作:

  • DROP:直接将数据丢弃,不再进行后续的处理;
  • REJECT:给客户端发挥一个 connection refused 或 destination unreachable 包文;
  • QUEUE:将数据包放入用户空间的队列,供用户空间的程序处理;
  • RETURN:跳出当前链,该链里的后续规则不再执行;
  • ACCEPT:同意数据包通过,继续执行后续的规则;
  • JUMP:跳转到其他用户自定义的链继续执行。

七、iptables 和 conntrack

在讨论 raw 表和匹配连接状态的时候,我们介绍了构建在 netfilter 之上的 连接跟踪(conntrack)系统。conntrack 系统使得 iptables 基于连接上下文而不是单个包来做出规则判断, 给 iptables 提供了有状态操作的功能。

conntrack 系统将包和已有的连接进行比较,如果包所属的连接已经存在就更新连接状态, 否则就创建一个新连接。如果 raw 表的某个 chain 对包标记为目标是 NOTRACK, 那这个包会跳过连接跟踪系统。

7.1 什么是 conntrack

Connection tracking(“contrack”)是 Linux 内核提供的一个重要特性,用来支持 Linux 内核对逻辑网络连接或流进行跟踪,识别组成每个流的所有数据包,从而能够对这些数据包进行一致性的处理。

Contrack 是 Linux 上一些功能的底层技术支撑:

  • NAT 就依赖着 Contrack 技术,所以在做 NAT 时,才能将同一连接上的所有包打到同一目标网络去。例如:在 Kubernetes 中,当一个 Pod 访问 Service 时,kube-proxy 的负载均衡会利用 NAT 将请求转发到特定的 Pod 上去。这个时候就需要 contrack 保证来自同一请求的所有包都转发到特定的 Pod 上,也不会被转发到 Service 所代理的其他 Pod 上。

  • 有状态防火墙。比如 calico 就依赖 connection tracking 提供的信息精准地将本机允许通过的流量列入放行名单中,而只阻止那些来自不允许通过的流量。如果没有这个,就无法区分连接的状态。例如现在一个 Pod 不允许主动对外访问,但是允许外部的 Pod 访问它,这个时候如果没有 conntrack,就无法识别哪些数据包是该 Pod 响应的,哪些数据包是该 Pod 主动对外访问的。

此外,conntrack 通常可以提高性能(减少CPU和数据包延迟),因为只有连接中的第一个数据包需要经过完整的网络堆栈处理才能确定如何处理它。

7.2 连接的状态

conntrack 系统中的状态有以下几种:

  • NEW:如果到达的包关联不到任何已有的连接,但包是合法的,就为这个包创建一个新的连接。对面向连接(connection-aware)的协议如 TCP 以及非面向连接的(connectionless)的协议例如 UDP 都适用;
  • ESTABLISHED:当一个连接收到应答方向的合法包时,状态就从 NEW 变成 ESTABLISHED 。对于 TCP,这个合法包就是 SYN/ACK 包;对于 UDP/ICMP 来说,则是原地址与目的地址的 IP 与原包相反的包;
  • RELATED:包不属于已有的连接,但是和已有的连接有一定关系。这可能是辅助连接(helper connection),例如 FTP 数据传输连接,活着是其他协议试图建立连接时的 ICMP 应答包;
  • INVALID:包不属于已有连接,并且因为某些原因不能用来创建一个新连接,例如无法识别、无法路由等;
  • UNTRACKED:如果在 raw 表中标记为目标是 UNTRACKED,这个包将不会进入 contrack 系统;
  • SNAT:包的源地址被 NAT 修改之后会进入的虚拟状态,conntrack 系统根据此在收到反向包时对地址做反向转换;
  • DNAT:包的目的地址被 NAT 修改之后会进入的虚拟状态,conntrack 系统根据此在收到反向包时对地址做反向转换。

这些状态可以定位到连接生命周期内部,程序员可以据此编写出更加细粒度、适用范围更大、更安全的规则。

八、总结

Netfilter 包过滤框架和 iptables 防火墙是 Linux 服务器上大部分防火墙解决方案的基础。Netfilter 的内核 hook 和协议栈之间联系紧密,提供了对数据包经过系统时的强大控制功能。 iptables 基于这些功能提供了一个灵活的、可扩展的、将策略需求应用到内核的方案。理解了这些不同模块是如何联系到一起的,就可以更高效地对数据包进行控制。篇文章,了解一下Markdown的基本语法知识。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Allen_Adolph/article/details/129817038

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签