iptables 的五表五链
2023-04-03 计算机网络
概述
iptables 是一个配置 Linux 内核防火墙的命令行工具,它基于内核的包过滤框架(packet filtering framework) netfilter, 主要用于管理数据包过滤和 NAT 规则。
如图所示:
绿色背景的方框,表示表(table), 用来管理链,Linux 支持 4 种表,包括 filter(用于过滤)、nat(用于 NAT)、mangle(用于修改分组数据) 和 raw(用于原始数据包)。
白色背景方框,表示链(chain), 用来管理具体的 iptables 规则,每个表中可以包含多条链 filter 表中,内置 INPUT、OUTPUT 和 FORWARD nat 表中,内置 PREROUTING、POSTROUTING、OUTPUT。
灰色背景方框,表示连接跟踪模块通过内核中的连接跟踪表(也就是哈希表),记录网络连接的状态,是 iptables 状态过滤(-m state)和 NAT 的实现基础。
iptables
与协议栈内有包过滤功能的 hook 交 互来完成工作。这些内核 hook 构成了 netfilter
框架。每个进入网络系统的包(接收或发送)在经过协议栈时都会触发这些 hook,
程序可以通过注册 hook 函数的方式在一些关键路径上处理网络流量。iptables
相关的内核模块在这些 hook 点注册了处理函数,因此可以通过配置 iptables
规则来使得网络流量符合防火墙规则。
理解
iptables
是学习Docker
,Kubernetes
等开源项目中网络功能实现的基础。
规则
规则
就是网络管理员预定义的条件,一般的定义为 如果数据包头符合当前条件,处理这个数据包,反之执行下一个判断条件,
规则
存储在内核空间的过滤表中,这些规则分别指定了 源地址
、目的地址
、传输协议
(如TCP、UDP、ICMP)和 服务类型
(如 HTTP、FTP 和 SMTP)等,
当数据包与 规则
匹配时,内核会执行具体的 行为
。
配置防火墙的主要工作就是添加、修改和删除规则。
行为
动作 | 描述 |
---|---|
ACCEPT | 接收数据包 |
DROP | 丢弃数据包,进行完此动作后,将直接中断检测过程,不再检测其它规则 |
REDIRECT | 将封包重新导向到另一个端口(PNAT),进行完此动作后,继续比对其它规则,这个功能可以用来实现透明代理或用来保护应用服务器 |
SNAT | 源地址转换 |
DNAT | 目的地址转换 |
MASQUERADE | IP伪装(NAT),用于 ADSL |
LOG | 日志记录 |
SEMARK | 添加 SEMARK 标记以供网域内强制访问控制(MAC) |
QUEUE | 将数据包传递到用户空间 |
REJECT | 拦截数据包,并返回数据包通知对方 |
RETURN | 防火墙停止执行当前链中的后续规则,并返回到调用链中继续检测 |
5链
链
是数据包传播的路径,每一个 链
中可以有 N 个 规则
(N >= 0)。当数据包到达一个 链
时,iptables
就会从链中第一个规则开始检测,
如果数据包满足规则所定义的条件,系统会执行具体的 行为
,否则 iptables
继续检查下一个规则。
如果数据包不符合链中任一个规则,iptables
就会根据该链预先定义的默认策略来处理数据包。
名称 | 描述 |
---|---|
INPUT | 处理接收的数据包 |
OUTPUT | 处理发送的数据包 |
FORWARD | 处理转发的数据包,常用于 网络隔离 , NAT , 负载均衡 |
PREROUTING | 修改到达且还未转发的数据包,常用于 DNAT , 端口映射 , 源地址转换 |
POSTOUTING | 修改发送前的的数据包,常用于 SNAT |
5 表
表有 N 个链,链有 N 个规则。
大部分场景仅需使用 Filter 表 和 NAT 表。
Raw 表
Raw
表用于在 连接跟踪、NAT 和路由表处理之前 对数据包进行处理,包含 2 种内置链:
- PREROUTING
- OUTPUT
因为优先级最高,所以如果使用了 Raw
表,那么在 Raw
表处理完后, 将跳过 NAT
表和 ip_conntrack
处理, 也就是避免了 连接跟踪、NAT 和路由表前置 处理。
Filter 表
Filter
是 iptables
的默认表,用于过滤数据包,如果没有定义表的情况下将使用 Filter
表,包含 3 种内置链:
- INPUT
- OUTPUT
- FORWARD
在 Filter
表中只允许对数据包进行接受,丢弃的操作,而无法对数据包进行更改。
NAT 表
NAT
用于实现网络地址转换,包含 3 种内置链:
- PREROUTING
- POSTROUTING
- OUTPUT
Mangle 表
Mangle
用于对指定数据包报头进行修改、标记或重定向,包含 5 种内置链:
- INPUT
- OUTPUT
- FORWARD
- PREROUTING
- POSTROUTING
Security 表
Security
用于给包打上 SELinux 标记,以此影响 SELinux 或其他可以解读 SELinux 安全上下文的系统处理包的行为。这些标记可以基于单个包,也可以基于连接。
表和链关系图
表的检测优先级
Raw -> Mangle -> Nat -> Filter
任何一个数据包必然经过 5 个链中的其中一个。
- 一个数据包进入网卡时,首先进入
PREROUTING
链,内核根据数据包目的 IP 判断是否需要转发 - 如果数据包是进入本机的,它就会沿着图向下移动,到达
INPUT
链,数据包到了INPUT链后,任何进程都会收到它,本机上程序可以发送数据包,这些数据包会经过OUTPUT
链,然后到达POSTROUTING
链输出 - 如果数据包是转发出去的,且内核允许转发,数据包会经过
FORWARD
链,然后到达POSTROUTING
链输出
常用命令
查看类
# 查看所有防火墙规则
$ iptables --list
# 示例输出如下
Chain DOCKER (8 references)
target prot opt source destination
ACCEPT tcp -- anywhere 172.27.0.2 tcp dpt:10010
ACCEPT tcp -- anywhere 172.22.0.2 tcp dpt:http
ACCEPT tcp -- anywhere 172.29.0.4 tcp dpt:memcached
ACCEPT tcp -- anywhere 172.17.0.2 tcp dpt:redis
ACCEPT tcp -- anywhere 172.17.0.2 tcp dpt:nginx
ACCEPT tcp -- anywhere 172.17.0.4 tcp dpt:8080
ACCEPT tcp -- anywhere 172.17.0.5 tcp dpt:mysql
ACCEPT tcp -- anywhere 172.17.0.5 tcp dpt:http
# 查看 mangle 表规则
$ iptables -t mangle --list
# 查看 nat 表规则
$ iptables -t nat --list
字段名称 | 描述 |
---|---|
target | 规则行为 |
prot | 协议 |
opt | 选项 |
source | 源 IP 地址 |
destination | 目的 IP 地址 |
操作类
# 查看说明
$ iptables --help
# 查看命令
iptables -L:查看规则链
# 规则管理命令
iptables -A:在规则链的末尾加入新规则
iptables -D:删除某个规则
iptables -I:在规则链的头部加入新规则
iptables -R:替换规则链中的规则
# 链管理命令
iptables -F:清空规则链
iptables -Z:清空规则链中的数据包计算器和字节计数器
iptables -N:创建新的用户自定义规则链
iptables -P:设置规则链中的默认策略
# 通用匹配参数
-t
对指定的表 table 进行操作
如果不指定此选项,默认的是 filter 表
-p 协议
指定规则的协议,如 tcp, udp, icmp 等,可以使用all来指定所有协议
如果不指定 -p 参数,默认的是 all 值
-s 源地址
指定数据包的源地址
参数可以使IP地址、网络地址、主机名
例如:-s 192.168.1.101 指定IP地址
例如:-s 192.168.1.10/24 指定网络地址
-d 目的地址
指定数据包的目的地址,规则和 -s 类似
-j 执行目标
指定规则匹配时如何处理数据包
可能的值是ACCEPT, DROP, QUEUE, RETURN 等
-i 输入接口
指定要处理来自哪个接口的数据包,这些数据包将进入 INPUT, FORWARD, PREROUTE 链
例如:-i eth0指定了要处理经由eth0进入的数据包
如果不指定 -i参数,那么将处理进入所有接口的数据包
如果指定 ! -i eth0,那么将处理所有经由eth0以外的接口进入的数据包
如果指定 -i eth+,那么将处理所有经由eth开头的接口进入的数据包
-o 输出
指定了数据包由哪个接口输出,这些数据包将进入 FORWARD, OUTPUT, POSTROUTING链
如果不指定-o选项,那么所有接口都可以作为输出接口
如果指定 ! -o eth0,那么将从eth0以外的接口输出
如果指定 -i eth+,那么将仅从eth开头的接口输出
# 扩展参数
-sport 源端口
针对 -p tcp 或者 -p udp,默认情况下,将匹配所有端口
可以指定端口号或者端口名称、端口范围,例如 –sport 22, –sport ssh,–sport 22:100
从性能上讲,使用端口号更好, /etc/services 文件描述了映射关系
-dport 目的端口
规则和 –sport 类似
-tcp-flags TCP 标志
针对 -p tcp
可以指定由逗号分隔的多个参数
取值范围:SYN, ACK, FIN, RST, URG, PSH, ALL, NONE
-icmp-type ICMP 标志
针对 -p icmp
icmp-type 0 表示 Echo Reply
icmp-type 8 表示 Echo
命令选项输入顺序
iptables -t 表名 <-A/I/D/R> 规则链名 [规则号] <-i/o 网卡名> -p 协议名 <-s 源IP/源子网> --sport 源端口 <-d 目标IP/目标子网> --dport 目标端口 -j 动作
示例
以下命令在生产环境中谨慎使用。
查看已添加的iptables规则
$ iptables -L -n -v
Chain INPUT (policy DROP 48106 packets, 2690K bytes)
pkts bytes target prot opt in out source destination
5075 589K ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
191K 90M ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
1499K 133M ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
4364K 6351M ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
6256 327K ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 3382K packets, 1819M bytes)
pkts bytes target prot opt in out source destination
5075 589K ACCEPT all -- * lo 0.0.0.0/0 0.0.0.0/0
清空当前的所有规则和计数
$ iptables -F # 清空所有的防火墙规则
$ iptables -X # 删除用户自定义的空链
$ iptables -Z # 清空计数
设置默认规则
$ iptables -P INPUT DROP # 配置默认的不让进
$ iptables -P FORWARD DROP # 默认的不允许转发
$ iptables -P OUTPUT ACCEPT # 默认的可以出去
开放指定端口
$ iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT # 允许本地回环接口(即运行本机访问本机)
$ iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # 允许已建立的或相关连的通行
$ iptables -A OUTPUT -j ACCEPT # 允许所有本机向外的访问
$ iptables -A INPUT -p tcp --dport 22 -j ACCEPT # 允许访问22端口
$ iptables -A INPUT -p tcp --dport 80 -j ACCEPT # 允许访问80端口
$ iptables -A INPUT -p tcp --dport 21 -j ACCEPT # 允许ftp服务的21端口
$ iptables -A INPUT -p tcp --dport 20 -j ACCEPT # 允许FTP服务的20端口
$ iptables -A INPUT -j reject # 禁止其他未允许的规则访问
$ iptables -A FORWARD -j REJECT # 禁止其他未允许的规则访问
白名单
$ iptables -A INPUT -p all -s 192.168.1.0/24 -j ACCEPT # 允许机房内网机器可以访问
$ iptables -A INPUT -p all -s 192.168.140.0/24 -j ACCEPT # 允许机房内网机器可以访问
$ iptables -A INPUT -p tcp -s 183.121.3.7 --dport 3380 -j ACCEPT # 允许 183.121.3.7 访问本机的 3380 端口
黑名单
iptables -I INPUT -s 123.45.6.7 -j DROP # 屏蔽单个 IP
iptables -I INPUT -s 123.0.0.0/8 -j DROP # 屏蔽 IP 网段 从 123.0.0.1 到 123.255.255.254
iptables -I INPUT -s 124.45.0.0/16 -j DROP # 屏蔽 IP 网段 从 123.45.0.1 到 123.45.255.254
iptables -I INPUT -s 123.45.6.0/24 -j DROP # 屏蔽 IP 网段 从 123.45.6.1 到 123.45.6.254
防止 SYN 洪水攻击
$ iptables -A INPUT -p tcp --syn -m limit --limit 5/second -j ACCEPT
小结
iptables
是一个配置 Linux 内核防火墙的命令行工具,可以根据设定的规则对网络数据包进行过滤、修改和重定向等操作,工作在 OSI 模型
中的网络层和传输层。
撰写本文过程中,笔者发现中文内容几乎说的都是 四表五链
,不知是作者刻意跳过 Security
表,还是抄袭导致的同质化太严重。
虽然 Security
表不是常用功能,但是我们不能忽略其存在。