介绍
在本实验中,你将学习如何使用 iptables(Linux 中功能强大的命令行防火墙工具)来拦截入站 ICMP 流量。你将配置一条防火墙规则,用于丢弃 ICMP 协议的数据包,该协议通常被 ping 命令用于测试网络连通性。通过在协议层控制网络访问,这是保护 Linux 系统安全的一项基础技能。
你将首先使用 nmap 进行初步的网络扫描,以评估系统的开放端口。接着,你将通过 ping 命令验证 ICMP 流量在初始状态下是允许的,从而建立基准。实验的核心部分是创建并应用一条特定的 iptables 规则,以丢弃所有入站 ICMP 数据包。最后,你将验证该规则是否生效,并通过再次尝试 ping 你的机器来测试其有效性,确认请求已被成功拦截。
使用 nmap 扫描开放的 TCP 和 UDP 端口
在这一步中,你将学习如何使用 nmap 工具扫描你自己的系统以查找开放的网络端口。网络端口是操作系统中通信的端点。当一个程序想要从网络接收信息时,它会“监听”一个特定的端口。扫描开放端口是评估机器安全性的基础第一步,因为每个开放端口都代表着攻击者潜在的入口点。
首先,你需要安装 nmap,因为它不包含在基础环境中。在安装新软件之前更新软件包列表是一个好习惯。
运行以下命令更新软件包列表:
sudo apt-get update
现在,通过运行以下命令安装 nmap:
sudo apt-get install -y nmap
你应该会看到显示 nmap 及其依赖项正在安装的输出。
接下来,你需要找到机器的 IP 地址,以便告诉 nmap 扫描什么。你可以使用 ip 命令找到它。
ip addr show
查找类似 eth0 或 ens33 的条目。你的 IP 地址将列在 inet 旁边。它看起来类似于 172.16.50.13/24。
如何从输出中识别你的 IP 地址:
- 查找状态为
state UP的接口(通常是eth0)。 - 找到以
inet开头的行(不是inet6)。 - 只取
/之前的 IP 地址部分(例如,如果你看到inet 172.16.50.13/24,你的 IP 地址就是172.16.50.13)。 - 忽略 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):规则指定了数据包的匹配标准(如协议或源地址)和目标动作(对数据包执行的操作,例如
ACCEPT或DROP)。
首先,让我们检查当前的规则集。由于 iptables 会修改内核设置,你必须使用 sudo。-L 选项列出默认 filter 表中的规则。
sudo iptables -L
你将看到三个默认链:INPUT、FORWARD 和 OUTPUT。在这个环境中,你可能会注意到 Docker 已经在 FORWARD 链中创建了一些规则,并为容器网络添加了自定义链。INPUT 和 OUTPUT 链对于常规流量仍在使用默认的 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 机器测试了拦截效果,确认请求现在已如预期般超时。



