在 Linux 中使用 iptables 拦截 ICMP 流量

CompTIABeginner
立即练习

介绍

在本实验中,你将学习如何使用 iptables(Linux 中功能强大的命令行防火墙工具)来拦截入站 ICMP 流量。你将配置一条防火墙规则,用于丢弃 ICMP 协议的数据包,该协议通常被 ping 命令用于测试网络连通性。通过在协议层控制网络访问,这是保护 Linux 系统安全的一项基础技能。

你将首先使用 nmap 进行初步的网络扫描,以评估系统的开放端口。接着,你将通过 ping 命令验证 ICMP 流量在初始状态下是允许的,从而建立基准。实验的核心部分是创建并应用一条特定的 iptables 规则,以丢弃所有入站 ICMP 数据包。最后,你将验证该规则是否生效,并通过再次尝试 ping 你的机器来测试其有效性,确认请求已被成功拦截。

这是一个引导实验,提供了逐步的指令来帮助你学习和练习。请仔细遵循说明完成每个步骤并获得实践经验。历史数据表明,这是一个初学者级别的实验,完成率为 99%。它获得了学习者 98% 的好评率。

使用 nmap 扫描开放的 TCP 和 UDP 端口

在这一步中,你将学习如何使用 nmap 工具扫描你自己的系统以查找开放的网络端口。网络端口是操作系统中通信的端点。当一个程序想要从网络接收信息时,它会“监听”一个特定的端口。扫描开放端口是评估机器安全性的基础第一步,因为每个开放端口都代表着攻击者潜在的入口点。

首先,你需要安装 nmap,因为它不包含在基础环境中。在安装新软件之前更新软件包列表是一个好习惯。

运行以下命令更新软件包列表:

sudo apt-get update

现在,通过运行以下命令安装 nmap

sudo apt-get install -y nmap

你应该会看到显示 nmap 及其依赖项正在安装的输出。

接下来,你需要找到机器的 IP 地址,以便告诉 nmap 扫描什么。你可以使用 ip 命令找到它。

ip addr show

查找类似 eth0ens33 的条目。你的 IP 地址将列在 inet 旁边。它看起来类似于 172.16.50.13/24

如何从输出中识别你的 IP 地址:

  1. 查找状态为 state UP 的接口(通常是 eth0)。
  2. 找到以 inet 开头的行(不是 inet6)。
  3. 只取 / 之前的 IP 地址部分(例如,如果你看到 inet 172.16.50.13/24,你的 IP 地址就是 172.16.50.13)。
  4. 忽略 IP 为 127.0.0.1 的回环接口(lo)。

在本实验的后续部分,我们将使用 <your_IP_address> 作为你实际 IP 地址的占位符。

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:16:3e:04:c3:1d brd ff:ff:ff:ff:ff:ff
    altname enp0s5
    altname ens5
    inet 172.16.50.13/24 metric 100 brd 172.16.50.255 scope global dynamic eth0
       valid_lft 1892159940sec preferred_lft 1892159940sec
    inet6 fe80::216:3eff:fe04:c31d/64 scope link
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:1d:45:49:f8 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever

现在你已经准备好进行第一次扫描了。让我们从扫描开放的 TCP(传输控制协议)端口开始。TCP 是一种面向连接的协议,用于许多常见服务,如 SSH(端口 22)和 HTTP(端口 80)。nmap 中的 -sT 选项执行 TCP 连接扫描。

重要提示: 请将 <your_IP_address> 替换为你从上一步中找到的实际 IP。例如,如果你的 IP 是 172.16.50.13,命令将是 nmap -sT 172.16.50.13

替换 <your_IP_address> 并运行命令:

nmap -sT <your_IP_address>

输出将列出处于“开放(open)”状态的端口。你的系统默认情况下可能会开放 SSH 端口(22),并且可能在其他端口上运行着其他服务。

Starting Nmap 7.80 ( https://nmap.org ) at 2025-07-01 14:08 CST
Nmap scan report for iZrj93qpoj98oqswu96cqfZ (172.16.50.13)
Host is up (0.00013s latency).
Not shown: 997 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
3000/tcp open  ppp
3001/tcp open  nessus

Nmap done: 1 IP address (1 host up) scanned in 0.06 seconds

接下来,让我们扫描 UDP(用户数据报协议)端口。UDP 是一种无连接协议,用于 DNS(端口 53)和 DHCP(端口 67/68)等服务。UDP 扫描可能比 TCP 扫描更慢且更不可靠。使用 sudo 可以为 UDP 扫描提供更好的结果。-sU 选项告诉 nmap 执行 UDP 扫描。

请记住:<your_IP_address> 替换为你上一步中的实际 IP 地址。

替换 <your_IP_address> 并运行命令:

sudo nmap -sU <your_IP_address>

输出可能会将端口显示为 open|filtered。这意味着 nmap 无法确定端口是开放的还是防火墙拦截了扫描。这是 UDP 扫描的常见结果。

Starting Nmap 7.80 ( https://nmap.org ) at 2025-07-01 14:09 CST
Nmap scan report for iZrj93qpoj98oqswu96cqfZ (172.16.50.13)
Host is up (0.0000060s latency).
Not shown: 998 closed ports
PORT     STATE         SERVICE
68/udp   open|filtered dhcpc
5353/udp open|filtered zeroconf

Nmap done: 1 IP address (1 host up) scanned in 1.29 seconds

通过完成这些扫描,你已成功识别了机器上正在监听网络连接的服务。

使用 ping 验证初始网络连通性

在这一步中,你将在实施任何防火墙规则之前,使用 ping 命令验证你的系统是否对网络请求有响应。ping 命令向目标主机发送 ICMP(互联网控制消息协议)“回显请求(echo request)”数据包。如果主机可达且配置为响应,它将发回一个“回显应答(echo reply)”数据包。这是测试基础网络连通性的基本方法。

在我们创建防火墙规则来拦截此类流量之前,必须先确认该流量目前是被允许的。这可以确保稍后我们测试规则时,能够确定是规则导致了拦截,而不是某些预先存在的网络问题。

我们将 ping“回环(loopback)”地址 127.0.0.1。这个特殊的 IP 地址始终指向你自己的机器,允许你在不需要外部连接甚至不需要知道机器分配的 IP 地址的情况下测试本地网络栈。

为了仅发送四个数据包然后停止,我们将使用 -c 4 选项。这很重要,因为如果没有它,ping 将持续运行,直到你手动使用 Ctrl+C 停止它。

打开终端并运行以下命令:

ping -c 4 127.0.0.1

你应该会看到显示发送了四个数据包并接收了四个数据包的输出,这表明你的系统正在正确响应 ICMP 请求。

PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.045 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.055 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.052 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.053 ms

--- 127.0.0.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3070ms
rtt min/avg/max/mdev = 0.045/0.051/0.055/0.003 ms

0% packet loss(0% 丢包)这一行确认了连接工作正常。既然你已经建立了基准,现在就可以配置防火墙规则来拦截这种特定类型的通信了。

创建 iptables 规则以丢弃 ICMP 数据包

在这一步中,你将使用 iptables 配置一条简单的防火墙规则。iptables 是 Linux 内核中管理网络数据包过滤规则的标准命令行工具。我们将创建一条规则来拦截你之前用 ping 命令测试过的 ICMP 流量。

iptables 通过表(tables)、链(chains)和规则(rules)系统工作。

  • 表(Tables):针对特定用途的链的集合。最常用的表是 filter,它是默认表,用于数据包过滤。
  • 链(Chains):按顺序检查的规则列表。对于入站流量,使用 INPUT 链。
  • 规则(Rules):规则指定了数据包的匹配标准(如协议或源地址)和目标动作(对数据包执行的操作,例如 ACCEPTDROP)。

首先,让我们检查当前的规则集。由于 iptables 会修改内核设置,你必须使用 sudo-L 选项列出默认 filter 表中的规则。

sudo iptables -L

你将看到三个默认链:INPUTFORWARDOUTPUT。在这个环境中,你可能会注意到 Docker 已经在 FORWARD 链中创建了一些规则,并为容器网络添加了自定义链。INPUTOUTPUT 链对于常规流量仍在使用默认的 ACCEPT 策略。

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy DROP)
target     prot opt source               destination
DOCKER-USER  all  --  anywhere             anywhere
DOCKER-ISOLATION-STAGE-1  all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
DOCKER     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain DOCKER (1 references)
target     prot opt source               destination

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere
RETURN     all  --  anywhere             anywhere

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
target     prot opt source               destination
DROP       all  --  anywhere             anywhere
RETURN     all  --  anywhere             anywhere

Chain DOCKER-USER (1 references)
target     prot opt source               destination
RETURN     all  --  anywhere             anywhere

现在,让我们添加一条规则来拦截入站 ICMP 数据包。我们将向 INPUT 链追加(-A)一条新规则。

该命令的构成如下:

  • sudo iptables:管理防火墙的命令。
  • -A INPUT:向 INPUT 链追加一条规则。
  • -p icmp:此规则适用于使用 icmp 协议的数据包。
  • -j DROP:如果数据包匹配,则跳转到 DROP 目标,这将静默丢弃数据包而不发送任何响应。

运行以下命令创建规则:

sudo iptables -A INPUT -p icmp -j DROP

如果成功,此命令不会产生任何输出。你现在已经指示内核防火墙丢弃来自任何源的所有入站 ICMP 数据包。

验证防火墙规则并测试拦截效果

在最后一步中,你将确认新的防火墙规则已成功添加,然后通过再次尝试 ping 你的系统来测试其效果。这种验证过程在网络管理中至关重要,以确保安全策略得到正确实施。

首先,让我们再次查看规则列表以查看新添加的内容。通过运行与之前相同的命令,你可以看到防火墙的当前状态。

sudo iptables -L

你现在应该能看到 INPUT 链下列出了你的新规则。输出清楚地显示,匹配 icmp 协议的数据包将被发送到 DROP 目标。

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
DROP       icmp --  anywhere             anywhere

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

既然你已经确认规则已就绪,让我们来测试一下。运行你在步骤 2 中使用的相同 ping 命令。

ping -c 4 127.0.0.1

这一次,你将看不到任何答复。命令会似乎挂起几秒钟,然后退出。输出将显示 100% packet loss(100% 丢包)。这是预期的行为,因为内核的防火墙现在正按照你的指示,静默丢弃入站的 ICMP 数据包。

PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.

--- 127.0.0.1 ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 3055ms

你已成功拦截了 ICMP 流量!你使用 iptables 创建的规则不是持久性的,在系统重启后会被清除。不过,了解如何手动删除规则是一个好习惯。你可以使用 -D(删除)标志,并指定与添加时完全相同的规则来完成此操作。

让我们删除该规则以恢复连通性。

sudo iptables -D INPUT -p icmp -j DROP

为了确认规则已消失且连通性已恢复,最后运行一次 ping

ping -c 2 127.0.0.1

ping 现在应该会成功,确认你已成功删除了防火墙规则。

PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.048 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.058 ms

--- 127.0.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1024ms
rtt min/avg/max/mdev = 0.048/0.053/0.058/0.005 ms

总结

在本实验中,你学习了如何在 Linux 系统上进行初步的网络侦察。你首先在识别机器 IP 地址后,安装了 nmap 工具来扫描开放的 TCP 和 UDP 端口。随后,你通过使用 ping 命令建立了网络连通性基准,确认系统能够成功接收并响应 ICMP 流量。

实验的核心涉及使用 iptables 防火墙工具来操作网络流量。你构建并应用了一条特定的规则到 INPUT 链,以“丢弃(DROP)”所有入站 ICMP 数据包,从而有效地拦截了 ping 等工具。为了完成整个流程,你通过列出当前的 iptables 规则集验证了新规则是否生效,并通过再次尝试 ping 机器测试了拦截效果,确认请求现在已如预期般超时。