iptables网络数据包工具使用指南,入门使用详解

本文最后更新于 2023年9月17日 上午

iptables是 Linux系统中用于管理网络包过滤的工具。它可以用来设置规则,以控制网络数据包的流动。iptables可以用于防火墙、网络地址转换(NAT)和网络包过滤等多种用途。本文章就带大家,入门iptables的使用,并配合一定样例,看看具体如何使用。

工作原理是基于内核中的netfilter模块,可以通过在不同的链中添加规则来过滤、修改或重定向网络数据包。

可以说,iptables是 Linux 系统中最常用的网络安全工具之一,在软件层面,大部份的个人服务器使用iptables对Linux服务器端口进行管理,已经足够使用了。

当然,现在有很多新的网络数据包工具,比如:iptables的继任者nftables;但是,我目前还是更习惯用iptables,也许后续再出其他工具的教程吧。

iptables 的官方文档可以在以下网址找到: https://www.netfilter.org/documentation

此外,iptables的Wiki 百科页面也提供了很多有用的信息和示例。

iptables就是防火墙?

很多人使用iptables充当Linux的网络防火墙,这样当然可以,并且大多数情况满足个人防火墙需求。

但是,实际上iptables不单单只能用于防火墙(拦截IP、封禁端口等);除了用作防火墙,iptables 还可以用于以下用途:

  1. 网络地址转换(NAT):可以使用 iptables 将一个 IP 地址转换为另一个 IP 地址,实现网络地址转换。
  2. 限制带宽:可以使用 iptables 限制特定主机或网络的带宽使用量。
  3. 端口转发:可以使用 iptables 将一个端口的流量转发到另一个端口,实现端口转发。
  4. 流量控制:可以使用 iptables 控制特定主机或网络的流量,限制其带宽使用量,实现限速等操作。
  5. 日志记录:可以使用 iptables 记录网络数据包的流向和状态,以便进行故障排除。

比如:转发tcp 8080tcp 8090:

1
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 8090

总之,iptables 是一个非常强大的工具,可以用于多种网络管理任务。

支持创作

制作教程不易,如果热心的小伙伴,想支持创作,可以加入我们的「爱发电」电圈:

当然,也欢迎在B站或YouTube上关注我们:

更多:

iptables使用前

首先,作为一个内核工具。现在iptables基本已经内置在Linux内。

  • Ubuntu从版本8.04开始,默认支持iptables;
  • Debian从版本3.1开始,默认支持iptables;
  • CentOS从版本4开始,默认支持iptables;

在比较新的Linux发行版本,iptables已经默认支持并启动。在Debian高版本上,iptables是一个独立的防火墙工具,它不依赖于systemd或其他系统初始化和进程管理器。因此,即使systemd没有提供iptables服务。

如果你的系统没有自带iptables,可以使用命令进行安装:

1
2
3
4
# Ubuntu/Debian
sudo apt install iptables
# CentOS
sudo yum install iptables

查看iptables是否运行:

1
2
# 实际上这条命令是查看filter表的状态
sudo iptables -L

iptables -L WEB_BAN_IP

如果该命令能够正常输出防火墙规则,则说明iptables已经在运行中。如果该命令无法输出规则,则说明iptables未启动。在大多数情况下,iptables会随着系统启动而自动启动,您无需手动开启。

接下来,我们就来介绍介绍iptables的使用。

基础概念

iptables是一个Linux系统下的防火墙工具,它通过定义表、链和规则来实现对网络数据包的过滤和转发控制。

每个链包含多个规则,规则是 iptables 中最基本的单位,用于匹配数据包和执行操作。每个规则都包含多个匹配条件和动作,匹配条件用于匹配数据包,动作用于执行操作,如 ACCEPT、DROP、REJECT 等。

  • 表(Table):iptables中的表是一个逻辑容器,用于存储相关联的链和规则。Linux系统中默认包含4个表,分别是filter、nat、mangle和raw。其中,filter表用于过滤数据包,nat表用于网络地址转换,mangle表用于修改数据包的特定字段,raw表用于禁止Linux内核对数据包进行处理。
  • 链(Chain):iptables中的链是一系列规则的集合,用于对数据包进行过滤和转发。Linux系统中默认包含3个链,分别是INPUT、FORWARD和OUTPUT。其中,INPUT链用于处理进入Linux系统的数据包,FORWARD链用于处理转发的数据包,OUTPUT链用于处理从Linux系统出去的数据包。用户可以自定义链,将其添加到表中。
  • 规则(Rule):iptables中的规则是用于指定对数据包的处理方式。每个规则都包含一个匹配条件和一个动作。匹配条件可以是数据包的源地址、目的地址、协议类型、端口等等,动作可以是DROP(丢弃数据包)、ACCEPT(接受数据包)、REJECT(拒绝数据包)、SNAT(源地址转换)等等。

它们的关系图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
+------------------------+
| Table |
+------------------------+
| Chain 1 |
+------------------------+
| Chain 2 |
+------------------------+
| Chain 3 |
+------------------------+
| ... |
+------------------------+
| Chain N |
+------------------------+
| ... |
+------------------------+
| Rule 1 |
+------------------------+
| Rule 2 |
+------------------------+
| Rule 3 |
+------------------------+
| ... |
+------------------------+
| Rule M |
+------------------------+

综上所述,iptables的表、链、规则之间的关系是:表是一个逻辑容器,包含了多个链和规则;链是一系列规则的集合,用于对数据包进行过滤和转发;规则是用于指定对数据包的处理方式,包含一个匹配条件和一个动作。用户可以通过定义表、链和规则来实现对网络数据包的过滤和转发控制。

iptables的数据包的流转流程可以参考下图:

数据包的流程

iptables基础命令

iptables的基础命令组成:

1
iptables [ -t 表名] 命令选项 [链名] [条件匹配] [-j 处理动作或跳转]

注: -t 表名在缺省状态下,默认为filter表,即默认 -t filter

命令选项:

  • -L: 列出一个或所有链的规则
  • -v: 显示详细信息,包括每条规则的匹配句数量和匹配字节数
  • -x: 在v的基础上,禁止自动换算单位(K,M)
  • -n: 只显示ip地址和端口号,不显示域名和服务名称
  • -I: 插入到防火墙第一条生效
  • -A: 添加链是添加到最后一条
  • -D: 删除指定链中的某一条规则,按规则序号或内容确定要删除的规则
  • -F: 清空指定链中的所有规则,默认清空表中所有链的内容
  • -X: 删除指定表中用户自定义的规则链

举个例子,我们查看iptables的全部Table(没有指定-t,实际指向filter):

1
sudo iptables -L

iptables -L

当然,如果你还想指定查找表下的某条链,你可以:

1
2
# 查找filter表下的WEB_BAN_IP链
sudo iptables -L WEB_BAN_IP

iptables -L WEB_BAN_IP

匹配条件:

  • -i: 入站请求interface(网卡)
  • -o: 出站请求interface(网卡)
  • -s: 入站源地址
  • -d: 目标地址
  • -p: 指定规则协议,如tcp, udp,icmp等,可以使用 all 来指定所有协议
  • --dport: 目的端口,数据包的目的(dport)地址是80,就是要访问我本地的80端口
  • --sport: 来源端口 数据包的来源端口是(sport)80,就是对方的数据包是80端口发送过来的。

动作

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

当然,上述的动作和匹配条件,组合我们常说的规则(规则放在表里~)。接下来,我们看看iptables的规则。

iptables规则

规则大致由两个逻辑单元组成:匹配条件和动作。

最常用的匹配条件是源地址目标地址源端口目标端口

最常用的动作有ACCEPT(接受)、DROP(丢弃)、REJECT(拒绝)。

在实际操作 iptables 的过程中,是以“表”作为操作入口的,也就是-t后跟表;以链为具体的规则。

查看链详情

上文我们说到,使用-L可以查看表的详情,加上-v参数,可以查看更多详情:

1
sudo iptables -vL

iptables -vL WEB_BAN_IP

以上字段含义:

  • Chain WEB_BAN_IP:表示规则链的名称,即WEB_BAN_IP
  • (0 references):表示该规则链当前未被引用。
  • pkts:表示匹配该规则链的数据包数量。
  • bytes:表示匹配该规则链的数据包总字节数。
  • target:表示匹配该规则链的数据包将被发送到的目标,可以是另一个规则链或一个动作(如ACCEPT、DROP、REJECT等)。
  • prot:表示匹配该规则链的数据包的协议类型,如TCP、UDP、ICMP等。
  • opt:表示匹配该规则链的数据包的选项,如TCP标志位、IP地址等。
  • in:表示匹配该规则链的数据包的输入接口。
  • out:表示匹配该规则链的数据包的输出接口。
  • source:表示匹配该规则链的数据包的源IP地址或IP地址范围。
  • destination:表示匹配该规则链的数据包的目标IP地址或IP地址范围。

可以看到,我的WEB_BAN_IP链上,已经有了数据。如何查看它们时候,还显示行标呢?

加上--line-numbers参数即可:

1
sudo iptables -vL WEB_BAN_IP --line-numbers

iptables -vL WEB_BAN_IP --line-numbers

删除链内规则

而删除就可以使用-D命令:

1
2
3
4
5
6
# 删除第2项规则
sudo iptables -D WEB_BAN_IP 2
# 删除最后1项规则
sudo iptables -D WEB_BAN_IP -1
# 删除第2到4项规则
sudo iptables -D WEB_BAN_IP 2-4

当然,你也可以模糊匹配删除:

1
2
3
4
# 删除源IP为134.122.135.178
sudo iptables -D WEB_BAN_IP -s 134.122.135.178 -j DROP
# 删除源IP为134.122.135.178且目标动作为DROP
sudo iptables -D WEB_BAN_IP -s 134.122.135.178

添加链内规则

那么我这些规则是怎么添加的呢?

实际上,我是使用脚本扫描Nginx日志,对频繁请求网站的IP进行软件层面的流量封禁。所以,禁用的语句:

1
2
# 添加来源36.248.233.107,执行目标动作为丢弃
sudo iptables -I INPUT -s 36.248.233.107 -j DROP

当然,如果你想精确一些:

1
2
# 指定36.248.233.107无法通过TCP访问443端口(丢弃匹配包)
sudo iptables -A WEB_BAN_IP -s 36.248.233.107 -p tcp --dport 443 -j DROP

-A 选项表示添加规则,-s选项指定源 IP 地址,36.248.233.107是具体的 IP 地址,-p选项指定协议类型,tcp表示TCP协议,--dport选项指定目标端口,443表示 HTTPS 默认端口,-j 选项指定目标动作,DROP表示丢弃匹配的数据包。

这条规则的作用是禁止源 IP 地址为 36.248.233.107 的主机通过 TCP 协议访问 443 端口。

是不是有小伙伴好奇,我这个WEB_BAN_IP是怎么来的?其实这个就是自定义链,接下来,我来介绍一下。

自定义iptables链

iptables中,如何自定义一个链并关联到Input内?

创建新链

使用以下命令在filter表内创建一个名为WEB_BAN_IP的新链:

1
2
3
4
# 默认filter
sudo iptables -N WEB_BAN_IP
# 你也可以指定filter
sudo -t filter -N WEB_BAN_IP

创建新的链

这个时候,这个链并没有被任何默认链进行引用;即使你现在对其增加规则,它也是不会生效的:

1
sudo iptables -vL WEB_BAN_IP

查看详情

发现:Chain WEB_BAN_IP (0 references)

所以,我们需要引用。

引用新链接

使用以下命令将新链添加到INPUT链中:

1
sudo iptables -A INPUT -j WEB_BAN_IP

没错,通常情况下,-j后面跟的是预定义的操作,例如”DROP”、”REJECT”、”ACCEPT”等。但是,也可以使用-j选项来指定自定义链的名称,以便在该链中执行更多的规则。在这种情况下,当匹配到规则时,数据包将被传递到指定的自定义链中,以便在该链中执行更多的规则。这可以帮助组织和管理iptables规则,使其更易于维护和修改。

现在,在WEB_BAN_IP链中添加规则,这些规则将在数据包到达INPUT链时执行。

1
2
3
4
# 允许22端口数据
sudo iptables -A WEB_BAN_IP -p tcp --dport 22 -j ACCEPT
# 丢弃其他数据
sudo iptables -A WEB_BAN_IP -j DROP

例如,上面的规则将允许TCP端口22的传入连接,并拒绝所有其他传入连接。

删除和清除

如果想删除mychain链及其规则,可以使用以下命令:

1
2
3
4
5
6
# 取消引用
sudo iptables -D INPUT -j WEB_BAN_IP
# 清空表
sudo iptables -F WEB_BAN_IP
# 删除表
sudo iptables -X WEB_BAN_IP

流量转发

iptables可以通过NAT表来进行流量转发,具体方法如下:

开启IP转发功能

首先需要开启Linux系统的IP转发功能,可以通过以下命令进行开启:

1
echo 1 > /proc/sys/net/ipv4/ip_forward

也可以修改/etc/sysctl.conf文件中的net.ipv4.ip_forward参数为1,使其永久生效。

添加转发规则

接下来,需要添加转发规则,将来自某个端口或IP地址的数据包转发到另一个端口或IP地址。

如果只是端口的转发,直接:

1
sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 80

这条iptables规则中各个参数的解释:

  • -t nat:这是指定iptables要操作的表,这里是”nat”表,用于网络地址转换(NAT)。
  • -A PREROUTING:这是指定要添加的规则的位置,这里是PREROUTING链。PREROUTING链用于在数据包进入路由之前修改它们的目的地IP地址。
  • -p tcp:这是指定要匹配的协议,这里是TCP协议。
  • --dport 8080:这是指定要匹配的目标端口号,这里是8080端口。
  • -j REDIRECT:这是指定要执行的动作,这里是重定向。
  • --to-port 80:这是指定重定向的目标端口号,这里是80端口。

综上所述,这条规则的作用是将进入系统的TCP协议、目标端口为8080的数据包重定向到80端口。

当然,如果你想跨网卡转发,就更复杂一些:

1
2
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to-destination <eth1 IP>:80
sudo iptables -A FORWARD -i eth0 -p tcp --dport 80 -o eth1 -j ACCEPT

第一条规则:

  • -i eth0:这是指定要匹配的输入接口,这里是eth0接口。
  • -j DNAT:这是指定要执行的动作,这里是目标地址转换(DNAT)。
  • --to-destination <eth1 IP>:80:这是指定目标地址转换的目标地址和端口号。<eth1 IP>应该替换为eth1接口的IP地址,这里是将8080端口的流量转发到eth1接口上的80端口。

综上所述,第一条规则的作用是将进入系统的TCP协议、目标端口为8080的数据包的目标地址转换为eth1接口的IP地址,并将目标端口号修改为80。

第二条规则:

  • -A FORWARD:这是指定要添加的规则的位置,这里是FORWARD链。FORWARD链用于控制转发数据包的流量。
  • -i eth0:这是指定要匹配的输入接口,这里是eth0接口。
  • -o eth1:这是指定要匹配的输出接口,这里是eth1接口。
  • -j ACCEPT:这是指定要执行的动作,这里是接受数据包。

综上所述,第二条规则的作用是允许进入系统的TCP协议、目标端口为80的数据包从eth0接口转发到eth1接口。

同时,一般端口转发和双网卡情况,发生在路由器内,在路由器内,我们还需要:

1
sudo iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE

解释一下:

  • -j MASQUERADE:指定动作为MASQUERADE,即对数据包进行源IP地址伪装(也称为SNAT),将源IP地址改为路由器的IP地址。

如果只有上述两条iptables规则,是可以将来自eth0接口的8080端口流量转发到eth1接口上的80端口的。但是,如果路由器上有其他网络接口,比如WAN口,那么在没有MASQUERADE规则的情况下,路由器上的其他网络接口将无法访问Internet。因此,通常情况下,在进行NAT转换时,都需要添加MASQUERADE规则,以便对从局域网内发出的流量进行源IP地址伪装,从而保证路由器上的其他网络接口可以正常访问Internet。

保存iptables

iptables的规则存储在内核空间(操作系统内核运行的内存空间,位于内存内)中,而不是存储在磁盘上。当你添加一条规则时,iptables 会将它添加到内核的规则表中。因此,当你重新启动系统时,iptables的规则将会丢失,因为它们没有被保存到磁盘上。

所以,我们来看看如何保存iptables的配置。

导出iptables

使用iptables-save命令,进行iptables内的规则导出:

1
sudo iptables-save > iptables-Backup

比如我这里导出:
导出iptables和导出文件的内容

这样,就导出完成了。我们在重启后,表内文件被恢复或者清空,可以用这个文件进行恢复。

恢复iptables

如何还原内,其实也十分简单,使用iptables-restore命令即可:

1
sudo iptables-restore < iptables-Backup

导入iptables恢复文件

到此,就恢复完成了。

开机自动配置

如何实现开机自动配置呢?

你可以使用自己的脚本,加入系统的启动脚本内。也可以使用iptables-persistent(CentOS上使用iptables-services)。

首先查看系统当前是否有安装iptables-persistent:

1
2
3
4
# Debian
sudo which iptables-persistent
# CentOS
sudo which iptables-services

查看是否安装

如果没有安装:

1
2
3
4
# Debian上安装iptables-presistant
sudo apt install iptables-persistent
# CentOS上安装iptables-services
sudo yum install iptables-services

Debian上安装

接下来看看如何保存。

Debian上,在安装了iptables-persistent包并配置好规则后,我们只需要保存配置到/etc/iptables/rules.v4/etc/iptables/rules.v6,这些规则会在系统启动时,由iptables-persistent自动加载。

如果是在CentOS,那么只需要在配置好规则后,使用命令sudo service iptables save即可保存配置,并在开机时候自动挂载。

END

好啦,本次的文章就到这里。虽然iptables可以为系统提供强大的安全保护,但是它也是一个非常复杂和强大的工具,需要仔细地使用。

因此,在使用iptables时,请务必小心谨慎,并确保了解正在执行的每个操作的含义和影响。

如果您想深入了解 iptables 的更多高级用法和技巧,建议查看官方文档或参考其他相关资料。



iptables网络数据包工具使用指南,入门使用详解
https://www.mintimate.cn/2023/05/20/iptablesGuide/
作者
Mintimate
发布于
2023年5月20日
许可协议