25 多个最常见的 iptables 命令和示例

Linux 系统安全:深入了解 iptables 防火墙

对于使用 Linux 操作系统的用户而言,保护设备安全至关重要。Linux 提供了多种安全工具,其中 iptables 是一个功能强大的命令行防火墙,它具备高度的灵活性和卓越的保护能力。

然而,由于 iptables 是一个命令行工具,初学者可能需要一些时间来熟悉它的用法。

本文将通过实际示例,为系统管理员和 Linux 学习者详细介绍常见的 iptables 命令,帮助大家快速掌握这一重要工具。

什么是 iptables?

iptables 是 Linux 系统内置的软件防火墙。它允许用户创建并定义规则,从而直接或间接地控制网络流量。通过 iptables,您可以设定规则来允许或阻止特定端口、源 IP 地址、网络接口等的流量。

当规则被定义后,所有流量都必须经过这些规则的检查。例如,对于每一个新的连接,iptables 会检查是否存在与该连接匹配的预定义规则。如果存在,则应用该规则。如果没有匹配的规则,则会执行默认规则。

要使用 iptables,您需要使用以下命令:

$ iptables -L -n -v 

该命令的参数含义如下:

  • -L:列出所有规则。
  • -n:以数字格式显示输出,提高性能。
  • -v:以详细格式显示输出。

如果直接运行不带任何参数的 iptables 命令,系统会返回以下提示信息:

iptables v1.8.7 (nf_tables): no command specified

Try `iptables -h' or 'iptables --help' for more information.

如果出现类似“找不到命令 iptables”的错误,则需要手动安装它。使用以下命令在您的 Linux 发行版上安装 iptables

$ sudo apt-get install iptables

如果您的系统中已预装 iptables,则会看到类似如下的输出:

#output
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
iptables is already the newest version (1.8.7-1ubuntu5).
iptables set to manually installed.
0 upgraded, 0 newly installed, 0 to remove, and 35 not upgraded.

什么是防火墙?

防火墙是保护系统、网络和个人计算机的最基本安全措施之一。它可以是基于硬件或软件的,其核心是通过规则来实现保护。

大多数防火墙都具有高度可定制性,允许用户创建和编辑规则。例如,通过端口扫描可以帮助过滤掉来自互联网的数据包。此外,您还可以根据源 IP 地址或网络接口来允许或阻止特定的服务。

Linux 系统内置了 iptables 防火墙,您也可以使用其他独立的 Linux 防火墙来增强系统的安全性。

为什么需要 iptables 来配置防火墙?

既然有像 ufwfirewalld 这样优秀的命令行防火墙替代工具,为什么还要使用 iptables 呢?此外,还有一些简单易用且功能更丰富的独立 Linux 防火墙可供选择。

那么,iptables 在配置防火墙方面的优势是什么呢?原因包括:

  • 它提供了极高的灵活性,您可以直接在数据包级别设置规则。
  • 一旦掌握了其工作原理,iptables 相对容易使用。
  • 它可以直接有效地阻止不必要的网络流量。
  • 它还可以将数据包重定向到备用 IP 地址。
  • 它有助于保护您的系统免受拒绝服务 (DoS) 攻击。
  • 以及更多!

了解 iptables 架构及其与 Netfilter 的关系

为了更深入地理解 iptables,我们需要了解它的架构。首先,这将帮助我们理清 iptables 的不同组件。然后,我们可以利用这些组件来编写防火墙规则。

在讨论 iptables 时,我们不可避免地会提到 Netfilter。您可以将 Netfilter 视为 iptables 的“大哥”。它构建于 iptables 之上,提供了更丰富的功能来管理防火墙。实际上,iptables 是 Netfilter 实现强大防火墙功能的一种手段。

iptables 是 Netfilter 内核级钩子的命令行界面。这些钩子可以与 Linux 网络堆栈交互,从而影响最深层次的数据包处理。

那么,iptables 的架构是怎样的呢?

表 (Tables)

iptables 架构始于“表”。表负责规则的组织。每个表都根据其所做的决策类型进行分类。简单来说,表通过特定方式处理数据包,简化了整个数据包的处理流程。

iptables 提供了以下不同的表:

  • filter 表:用于指定数据包过滤的决策类型。它决定数据包是否应该到达目的地。
  • nat 表:用于指定地址转换的决策类型。数据包的路由在此处根据 NAT 网络确定。如果数据包无法访问 NAT,它会跳过并尝试搜索非 NAT 网络。
  • mangle 表:管理数据包的特殊处理需求。例如,您可以配置它来修改数据包的标头信息,如 TTL 值。
  • raw 表:允许您处理 iptables 防火墙的状态方面。通过此表,您可以在 Linux 内核开始跟踪其状态之前,根据数据包的“状态”来路由它们。它主要用于标记数据包,无论连接跟踪系统是否处理它们。如果数据包未被跟踪,则将其设置为 NOTRACK 目标。

链 (Chains)

在“表”中,我们有“链”。

链在数据包旅程的不同阶段执行深入的数据包检查。例如,您可以在数据包到达端口或网络接口时检查它们。这使您可以在数据包被发送到系统进程之前做出决策。

和表类似,您也会得到不同的链,包括:

  • PREROUTING 链:处理刚刚到达网络接口的数据包。
  • INPUT 链:处理传入的连接请求。处理完成后,数据包将被传递给本地进程。
  • OUTPUT 链:处理由本地进程产生的数据包。
  • FORWARD 链:管理不适用于本地系统的数据包。它充当其他目标系统(如路由器)的载体。
  • POSTROUTING 链:处理即将通过网络接口离开的数据包。

并非所有链都适用于每个表。例如,FORWARD 链仅在 manglefiltersecurity 表中可用。同样,POSTROUTING 链在 manglenat (SNAT) 上可用。只有 OUTPUT 链在所有表中都可用。

目标 (Target)

接下来是“目标”。当数据包到达时,它会通过链来寻找最匹配的规则。如果符合规则,则会执行相关的操作,然后将数据包移动到目标,最终决定数据包的命运。

在许多情况下,数据包可能不符合任何规则。这时,默认策略(目标)就发挥作用了。

目标可以是 ACCEPTDROPREJECT。这些是决定数据包命运的终止目标。

  • ACCEPT:接受数据包。
  • DROP:丢弃数据包,使发送方无法得知系统是否存在。
  • REJECT:拒绝数据包。

此外,还有一些非终止目标,主要用于存储有关数据包的信息。

最常见的 iptables 命令及示例

在开始执行 iptables 命令之前,请确保:

  • 您具有运行命令的管理权限。如果命令因权限不足而失败,请在命令前添加 sudo
  • 本文并非关于如何在 Ubuntu 上配置 iptables 的教程。
  • 我们将使用适用于 IPv4 的 iptables 命令。如果您要使用 IPv6,请使用 ip6tables

检查 iptables 状态

要检查当前的 iptables 状态,请运行以下命令:

$ iptables -L -n -v
#output

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)

 pkts bytes target  prot opt in  out  source   destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)

 pkts bytes target  prot opt in  out  source   destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)

 pkts bytes target  prot opt in  out  source   destination

上面的输出包含了大量的信息,但也暗示了一个未激活的防火墙。因为目前所有链都设置为接受,并且没有任何规则。

您需要开始添加规则来激活防火墙。

向链中添加规则

添加规则时,它始终附加到链中。因此,您必须使用 -A(追加)选项。其语法如下:

$ sudo iptables - A

但是,当您运行此命令时,它会返回以下错误:

iptables v1.8.7 (nf_tables): option "-A" requires an argument

Try `iptables -h' or 'iptables --help' for more information.

以下是一些可用于添加规则的参数:

  • -i:代表接口。在此,您可以指定要为其添加规则的接口,如 ppp0eth0 等。
  • -p:代表协议。在此,您可以指定用于过滤数据包的协议,如 ICMPTCPUDP 等。如果希望规则适用于所有协议,请使用 all
  • -s:表示源地址,指定流量的来源(可以是 IP 地址或主机名)。
  • --dportdport 代表目标端口,指定数据包的目标端口号。
  • --j:表示目标 (TARGET) 参数,指定目标名称,如 ACCEPTDROPRETURN

编写命令时,必须按照以下顺序:

$ sudo iptables -A <chain-name> -i <interface-name> - p <protocool-name> - s <source> --dport <port no.> -j <target>

保存对 iptables 的更改

添加规则后,可以使用 iptables -save 命令保存更改。

$ sudo iptables -save

输出如下所示:

[email protected]:~$ sudo iptables-save
# Generated by iptables-save v1.8.7 on Sun May 14 13:37:34 2023
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 392 -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -o lo -j ACCEPT
COMMIT
# Completed on Sun May 14 13:37:34 2023

手动持久化规则

默认情况下,iptables 不会自动保存规则。因此,如果重启计算机,所有规则都将被删除。您需要使用以下命令来确保不必重新配置 iptables

对于 IPv4 规则,请运行:

$ sudo iptables-save > /etc/iptables/rules.v4

对于 IPv6 规则,请运行:

$ sudo iptables-save > /etc/iptables/rules.v6

自动持久化规则

要使规则在重启后仍然存在并自动应用,您需要安装 iptables-persistent 包。

请使用以下命令进行安装:

$ sudo apt-get install iptables-persistent

系统会弹出窗口,请按回车键选择 <Yes>

如果您使用的是 IPv4 表,则会显示 IPv4 规则。如果您使用的是 IPv6,则会显示相应的窗口。

注意:该软件包仅加载您保存的 iptables 规则。因此,无论何时更改 iptables,都需要使用 iptables -save 命令保存。

重启后重新加载规则

保存规则后,您必须使用以下命令恢复它们:

$ sudo iptables-restore < /etc/iptables/rules.v4

以及

$ sudo iptables-restore < /etc/iptables/rules.v6

在本地主机上启用流量/启用环回

要在本地主机上启用流量,请使用以下命令:

$ sudo iptables -A INPUT -i lo -j ACCEPT

其中,lo 代表所有本地主机通信的环回接口。

同样,我们可以允许数据包通过环回接口离开:

$ sudo iptables -A OUTPUT -o lo -j ACCEPT

要检查规则的变化,请运行 iptables -L -n -V 命令:

#output
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
  pkts bytes target  prot opt in  out  source  destination
    0  0 ACCEPT all -- lo  *  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 0 packets, 0 bytes)
  pkts bytes target  prot opt in  out  source  destination

在特定端口上启用流量

您可以在特定端口上启用 ACCEPTREJECT 流量。

例如,SSL、HTTP 和 SSH 端口对于应用程序的正常运行至关重要。您可以向 ACCEPT 数据包添加规则,确保这些端口按预期工作。

对于 SSL,请运行以下命令:

$ sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

对于 HTTP,请运行以下命令:

$ sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT

允许 eth0 接口上的所有 HTTP 流量:

$ iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
$ iptables -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT

对于 SSH,请运行以下命令:

$ sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

允许 eth0 接口上的所有传入 SSH 流量:

$ iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
$ iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT

另一个示例是为您的自定义应用程序在特定端口上启用端口流量。假设您的自定义应用使用端口 233。

要打开此端口的连接,请运行:

$ sudo iptables -A INPUT -p tcp --dport 233 -j ACCEPT

同样,您也可以使用 REJECT 目标选项禁用特定端口的连接。

让我们阻止端口 392 的所有连接:

$ sudo iptables -A INPUT -p tcp --dport 392 -j REJECT

要检查规则是否生效,请运行 iptables -L -n -v 命令:

#output
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
  pkts bytes target  prot opt in  out  source  destination
  0 0 ACCEPT tcp -- *  *  0.0.0.0/0  0.0.0.0/0 tcp dpt:22
  0 0 ACCEPT tcp -- *  *  0.0.0.0/0  0.0.0.0/0 tcp dpt:80
  0 0 ACCEPT tcp -- *  *  0.0.0.0/0  0.0.0.0/0 tcp dpt:443
  0 0 ACCEPT tcp -- *  *  0.0.0.0/0  0.0.0.0/0 tcp dpt:233
  0 0 REJECT tcp -- *  *  0.0.0.0/0  0.0.0.0/0 tcp dpt:392 reject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
  pkts bytes target  prot opt in  out  source  destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
  pkts bytes target  prot opt in  out  source  destination
 0 0 ACCEPT all -- * lo  0.0.0.0/0  0.0.0.0/0

删除现有规则

要删除现有规则,请运行以下命令:

$ iptables -F

或者

$ iptables --flush

注意:如果您尚未保存规则,则它们将永久丢失,无法使用 iptables -restore 恢复。

删除带有行号的规则

要删除特定规则,您需要获取带有行号的规则列表:

$ sudo iptables -L --line-numbers
#output
Chain INPUT (policy ACCEPT)
num target  prot opt source  destination
1 ACCEPT tcp -- anywhere  anywhere tcp dpt:ssh
2 ACCEPT tcp -- anywhere  anywhere tcp dpt:http
3 ACCEPT tcp -- anywhere  anywhere tcp dpt:https
4 ACCEPT tcp -- anywhere  anywhere tcp dpt:233
5 REJECT tcp -- anywhere  anywhere tcp dpt:392 reject-with icmp-port-unreachable

如果要删除 INPUT 链中的第 4 条规则,请运行以下命令:

$ sudo iptables -D INPUT 4

然后,再次运行 iptables -n -v -L 命令:

#output
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
  pkts bytes target  prot opt in  out  source  destination
  0 0 ACCEPT tcp -- *  *  0.0.0.0/0  0.0.0.0/0 tcp dpt:22
  0 0 ACCEPT tcp -- *  *  0.0.0.0/0  0.0.0.0/0 tcp dpt:80
  0 0 ACCEPT tcp -- *  *  0.0.0.0/0  0.0.0.0/0 tcp dpt:443
  0 0 REJECT tcp -- *  *  0.0.0.0/0  0.0.0.0/0 tcp dpt:392 reject-with icmp-port-unreachable

仅显示 INPUT 或 OUTPUT 链规则

要仅显示 INPUT 链规则,请运行以下命令:

$ sudo iptables -L INPUT -n -v --line-numbers
#ouput
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target  prot opt in  out  source  destination
1 0 0 ACCEPT tcp -- *  *  0.0.0.0/0  0.0.0.0/0 tcp dpt:22
2 0 0 ACCEPT tcp -- *  *  0.0.0.0/0  0.0.0.0/0 tcp dpt:80
3 0 0 ACCEPT tcp -- *  *  0.0.0.0/0  0.0.0.0/0 tcp dpt:443
4 0 0 REJECT tcp -- *  *  0.0.0.0/0  0.0.0.0/0 tcp dpt:392 reject-with icmp-port-unreachable

如果您只想查看 OUTPUT 链规则,请运行:

$ sudo iptables -L OUTPUT -n -v --line-numbers
#output
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target  prot opt in  out  source  destination
1 0 0 ACCEPT all -- * lo  0.0.0.0/0  0.0.0.0/0

启动/停止/重启防火墙

如果您使用的是 RHEL/Fedora Linux 或 CentOS,则可以通过运行命令来启动、停止或重启防火墙。

$ service iptables stop
$ service iptables start
$ service iptables restart

您也可以使用 systemctl 命令。

但是,这些命令不适用于 Ubuntu。

在特定位置插入规则

如果要将规则插入到特定位置,必须使用以下命令。

首先,检查规则:

$ sudo iptables -L INPUT -n --line-numbers
#output
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT tcp -- 0.0.0.0/0  0.0.0.0/0 tcp dpt:22
2 ACCEPT tcp -- 0.0.0.0/0  0.0.0.0/0 tcp dpt:80
3 ACCEPT tcp -- 0.0.0.0/0  0.0.0.0/0 tcp dpt:443
4 REJECT tcp -- 0.0.0.0/0  0.0.0.0/0 tcp dpt:392 reject-with icmp-port-unreachable

如果在 2 和 3 之间插入规则,请运行以下命令:

$ sudo iptables -I INPUT 3 -s 252.32.1.2 -j DROP

现在,检查更新后的规则:

#output
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT tcp -- 0.0.0.0/0  0.0.0.0/0 tcp dpt:22
2 ACCEPT tcp -- 0.0.0.0/0  0.0.0.0/0 tcp dpt:80
3 DROP all -- 252.32.1.2 0.0.0.0/0
4 ACCEPT tcp -- 0.0.0.0/0  0.0.0.0/0 tcp dpt:443
5 REJECT tcp -- 0.0.0.0/0  0.0.0.0/0 tcp dpt:392 reject-with icmp-port-unreachable

阻止传入流量但允许传出流量

您需要输入以下命令来阻止所有传入流量:

$ iptables -P INPUT DROP
$ iptables -P FORWARD DROP
$ iptables -P OUTPUT ACCEPT
$ iptables -A INPUT -m state --state NEW,ESTABLISHED -j ACCEPT
$ iptables -L -v -n

这样,您可以 ping 或下载数据包,但会阻止任何未知的传入流量。

阻止特定 IP 地址

要阻止特定 IP 地址,请运行以下命令:

$ iptables -A INPUT -s 14.23.59.9 -J DROP

您也可以定义一个变量来存储要阻止的 IP 地址,然后运行命令:

BLOCK_THE_IP = “a.b.c.d”

然后运行:

$ iptables -A INPUT -s “BLOCK_THE_IP” -j DROP

注意:将“abcd”更改为您要阻止的 IP 地址。

允许系统从外部 ping

您可以允许外部用户 ping 您的服务器,以使您的网络可被发现:

$ sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
$ sudo iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT

允许内部网络与外部网络对话

运行以下命令,允许内部网络(如 eth0)连接到外部网络(如 eth1):

$ sudo iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT

允许出站 DNS

要允许 DNS 连接到您的服务器,请运行以下命令:

$ iptables -A OUTPUT -p udp -o eth0 --dport 53 -j ACCEPT
$ iptables -A INPUT -p udp -i eth0 --sport 53 -j ACCEPT

允许来自特定网络的 Rsync

如果您使用 Rsync 命令,并希望通过特定网络启用它,请运行以下命令:

iptables -A INPUT -i eth0 -p tcp -s 192.168.101.0/24 --dport 873 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 873 -m state --state ESTABLISHED -j ACCEPT

阻塞端口

运行以下命令来阻止特定端口的传入请求:

iptables -A INPUT -p tcp --dport 80 -j DROP
iptables -A INPUT -i eth1 -p tcp --dport 80 -j DROP

阻止到特定 IP 地址的传出流量

您可以通过运行以下命令来阻止流向任何 IP 地址的流量:

$ host -t a techblik.com.com

# 输出

techblik.com.com 的地址是 172.66.40.93

要阻止流向此特定 IP 地址的传出流量,请运行以下命令:

iptables -A OUTPUT -d 72.66.40.93 -j DROP

同样,您也可以屏蔽 Instagram、Twitter 和 Facebook 等社交媒体平台。

通过运行以下命令查找社交媒体 IP 地址:

$ host -t a social-media-web-adrress.com

例如,对于 Instagram,它将是:

$ host -t a www.instagram.com

现在,您需要找到该特定社交媒体平台的 IP 地址的 CIDR:

$ whois 185.89.219.11 | grep CIDR

注意:您可能需要通过运行 sudo apt-get install whois 来安装 whois 包。

现在,按以下格式输入 CIDR 值:

$ iptables - A OUTPUT -p tcp -d CIDR-value -j DROP

注意:确保相应地更改 CIDR 值。

允许或阻止 ICMP Ping 请求

要允许或阻止 ICMP ping 请求,请运行以下命令:

$ iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
$ iptables -A INPUT -i eth1 -p icmp --icmp-type echo-request -j DROP

打开特定范围的端口

要打开一系列端口,请运行以下命令:

$ iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 8933: 8500 -j ACCEPT

列出 NAT 规则

要列出 NAT 规则,请运行以下命令:

$ sudo iptables -t nat -L -n -v

或者

$ sudo iptables -t nat -v -L -n --line-number

重置数据包计数器

要检查当前的 iptables 计数器:

$ sudo iptables -L -n -v

要重置或清除计数器,请运行以下命令:

$ sudo iptables -Z
$ sudo iptables -L -n -v

仅重置 INPUT 链计数器,请运行:

$ iptables -Z INPUT

要重置特定规则的计数器