没有理想的人不伤心

Linux - 搞懂iptables

2022/10/13
2
0

image.png

iptables

参考博客:《一篇搞懂》系列之一 —— iptables - 知乎 (zhihu.com)

iptables 是 linux 中的防火墙工具,用于管理网络流量,配置内核提供的 IPv4 和 IPv6 包过滤功能,

iptables 组成:表<–链<–规则

  • 表 table: 将处理同一类型的数据包规则聚合在一起。内核中内置有4 张表,分别是raw manglenatfilter。每一张表都只包含同一类型的数据包规则,比如nat 表只包含与网络地址转换相关的规则。
  • 链 chain:每一张表包含若干,其规定了相关规则在什么时候执行。内核中内置有5 条链,分别对应 netfilter 提供的 5 个 Hook 点。能够让管理员在数据包传输过程中的某一个点通过相关规则控制数据包的走向。INPUTOUTPUTFORWARDPREROUTINGPOSTROUTING
  • 规则 rule:规则存在于中,每一条包含若干规则。当被调用时,数据包处理函数将按照顺序依次匹配对应链中的所有规则。每条规则都由匹配部分+动作部分组成,如果数据包满足匹配规则,则会执行相关动作对数据包进行处理。

iptables 的作用:

  1. 定义规则来过滤数据包,允许或拒绝特定来源、目的地或端口的网络流量。
  2. 网络地址转化 NAT,实现内外网之间的通信
  3. 通过 mangle 表,可以实现对数据包的修改,如更改 TTL 值、优先级等。

优先级:

表的优先级:由高到低排列为,**raw -> mangle -> nat -> filter**

规则优先级:某一规则触发的优先级,首先取决于链所在的位置,其次通过包含了该 chain 类型的 table 中所对应的实际的 chain 下的规则进行规则匹配和动作执行

raw table

raw 表提供的功能很简单:提供且仅提供一个让数据包绕过连接跟踪的框架。

iptables 提供一个有状态的防火墙,基于 netfilter 上建立了连接跟踪的特性,即 connection tracking,简称 conntrack。iptables 在处理数据包时都会依赖之前已经判断过的数据包。例如一条 NAT 记录,在第一次处理过后就会被存储在 conntrack 的哈希表中,下次有相同的数据包,则复用处理结果

mangle table

mangle 表提供 **修改数据包 IP 头部** 的功能,例如,修改数据包的 TTL 等。此外,mangle 表中的规则还可以对数据包打一个 仅在内核内有效的标记(mark),后续对于该数据包的处理可以用到这些标记。

nat table

用于网络地址转换(NAT),当数据包进入协议栈后,nat 表中的相关规则将决定是否修改以及如何修改数据包的源/目标地址,从而改变数据包被路由的行为。nat 表通常用于将数据包路由到外部网络无法直接访问到的局域网络中。

filter table

filter 表是 iptables 中最常用的表,用来 **判断一个数据包是否可以通过**。在防火墙领域,filter 表提供的功能通常被称为“过滤”包。这个表提供了防火墙的一些常见功能。Filter 表负责的主要是和主机自身相关的数据包处理手段,是真正负责主机防火墙功能的一张表。

security table

security 表的作用是 **给数据包打上 SELinux 标记**。SELinux 以及可以解读 SELinux 安全上下文的系统在处理由 security 表做了标记的数据包时,行为会相应做出改变。

内核中内置的 5 条链分别对应 netfilter 提供的 5 个 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 触发。

链位于表中

五条内置链和五个内置表的包含关系

Tables PREROUTING INPUT FORWARD OUTPUT POSTROUTING
raw
mangle
nat
filter
security

filter 表中有三条链:input、forward 和 output。

  • input:用来过滤进入主机的数据包;
  • forward:负责转发流经主机的数据包,起到转发的作用,和 NAT 关系很大。想要主机支持转发需要设置相关内核参数:net.ipv4.ip_forward=1
  • output:用来处理从主机发出去的数据包。

nat 表中有三条链:prerouting,postrouting 和 output。

  • prerouting:在数据包到达 netfilter 系统时,在进行路由判断之前执行该链上的规则,作用是改变数据包的目的地址、目的端口等,起到 DNAT 的作用;
  • postrouting:数据包发出时,当数据包经过了路由判断后执行该链上的规则,作用是改变数据包的源地址、源端口等,起到 SNAT 的作用;
  • output:用来处理从主机发出去的数据包。

规则

规则是最终影响数据包的地方,一条有效的规则必须由匹配规则+动作目标组成:

  • 匹配规则:提供了需要执行对应动作的目标匹配机制,通常可以匹配协议类型、目的地址、源地址、目的端口、源端口、目的网段、源网段、接收数据包的网卡、发送数据包的网卡、协议头、连接状态等。
  • 动作目标:又称为 target。是数据包满足匹配规则时触发的相应的动作。Target 分为两种类型:终止目标和非终止目标。

终止目标

linux 内核提供如下的终止目标动作

动作 含义
ACCEPT 允许数据包通过
DROP 直接丢弃数据包,不给任何回应信息,这时候客户端
会感觉自己的请求没有响应,过了超时时间才会有反应。
REJECT 拒绝数据包通过,必要时会给数据发送端一个响应的信息,客户端刚请求就会收到拒绝的信息
SNAT 源地址转换,解决内网用户用同一个公网地址上网的问题
MASQUERADE 是 SNAT 的一种特殊形式,适用于动态的、临时会变的 ip 上
DNAT 目标地址转换
REDIRECT 在本机做端口映射
LOG 在/var/log/messages 文件中记录日志信息(其实就是写入系统日志,通过 dmesg 也可以看到),然后将数据包传递给下一条规则,也就是说除了记录日志以外不对数据包做任何其他操作,仍然让下一条规则去匹配

特殊的非终止目标(jumping target)

Linux 内核内置的链只有 5 条,且这 5 条链是 netfilter hooks 触发的唯一方式。那如果我想在不影响其他链的情况下使用自己定义的链,该如何操作呢?这时就可以在内置链上配置一个 Jumping Target。实际上这里指定的就是我自定义的链的名字。例如下面的配置:

[root@localhost ~]# iptables -L
Chain INPUT(policy ACCEPT)
target     prot opt source               destination
KUBE-FIREWALL  all  --  anywhere             anywhere

Chain KUBE-FIREWALL(2 references)
target     prot opt source               destination
DROP       all  --  anywhere             anywhere             /* kubernetes firewall for dropping marked packets */ mark match 0x8000/0x8000

上面的配置中,INPUT 链的 target 为一条自定义的名为 KUBE-FIREWALL 的链,这样,从 INPUT 入口进入的数据包将会沿着链到达 KUBE-FIREWALL 链,然后将所有带有 0x8000/0x8000标记的包丢弃。

数据包处理流程

考虑最常用的 filter 和 nat 两张表

1726128636229-44b93877-f3c2-416e-b7b4-d02c4cc280da.png

数据流入

  1. 当数据包流入网卡进入 netfliter 系统中时,首先对数据包进行 DNAT,将公网地址转换成局域网地址;
  2. 进行路由判断:
  3. 如果目的地址为本机地址,则进行包过滤;
  4. 如果目的地址不为本机地址,则准备进行包转发,经过 filter 表中 forward 链的规则匹配后,如果允许对目的地址进行转发,则进行包转发;
  5. 通过 Nat 表中 PostRouting 链的规则查看当前数据包的转发是否要做 SNAT,处理完成后发出数据包。 值得注意的是,当数据包流入后,经过路由选择发现不是发给 Local 的包,则会通过 FORWARD 链直接到达 POSTROUTING 链,而不会再走 OUTPUT 链。

数据流出

  1. 当数据包从本机准备发出时,会先经过 Nat 表的 output 链进行规则检查;
  2. 随后,会经过 Filter 表的 output 链进行规则检查;
  3. 最后根据 Nat 表中 PostRouting 链的规则查看当前数据包的发出是否要做 SNAT,处理完成后发出数据包。

完整的数据包处理流程

1726128883663-37bc9d5b-7daf-4886-89fd-8c8a78e9820b.png

iptables 命令

基础命令

  • 查看使用手册:man iptables

  • 查看详细参数使用手册:man iptables-extensions

  • 查看 filter 表中的所有链和规则: iptables -nL --line-numbers

-n:将主机信息(IP 地址,端口等)以数字的形式打印出来。默认会以 hostname 等方式打印出来; -L:显示规则链中已有的条目; --line-numbers:显示条目序号。