在 Linux 中检查开放端口:使用 nmap、netcat 与 Bash

无论你是在排查网络连接问题,还是配置防火墙,了解 Linux 系统上哪些端口处于开放状态都至关重要。

本指南介绍在 Linux 系统上检查开放端口的命令行工具,包括 nmapnetcatnc)、telnet,以及使用 /dev/tcp 的纯 Bash 方法。

什么是开放端口

监听端口是应用程序正在监听的网络端口。你可以使用 ssnetstat 命令列出监听端口。

开放端口是接受来自远程主机传入数据包的网络端口。一个端口是否开放,取决于防火墙配置以及绑定到该端口的服务。

例如,如果你运行一个监听 80 和 443 端口的 Web 服务器,且防火墙允许到这些端口的流量,那么这些端口对外部就是开放的。

开放端口可能带来安全风险,因为每个端口都可能被攻击者用来入侵系统。只保留需要的端口开放,其余一律关闭。

使用 nmap 检查开放端口

nmap 是一款功能强大的网络扫描工具,可以扫描单个主机和大型网络范围。它已包含在大多数 Linux 发行版的软件仓库中。

如果系统已安装,nmap 通常是最全面的端口扫描工具。除了基本的开放/关闭结果,它还能识别端口背后的服务与操作系统。

警告:仅扫描你拥有或已获得书面授权测试的主机。未经授权的扫描可能违反你所在网络的合理使用策略或当地法律。

以下命令扫描远程主机上的所有 TCP 端口:

nmap -sT -p- 10.10.8.8

-sT 标志指示 nmap 扫描 TCP 连接,-p- 扫描全部 65535 个端口。请将 10.10.8.8 替换为你目标主机的 IP 地址或主机名。

Starting Nmap 7.95 ( https://nmap.org ) at 2026-03-01 21:00 CET
Nmap scan report for 10.10.8.8
Host is up (0.0012s latency).
Not shown: 65533 closed tcp ports (conn-refused)
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

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

上面的输出显示目标系统上只有 22 和 80 端口是开放的。STATE 列显示每个端口是开放、关闭还是被过滤。

要扫描 UDP 端口,使用 -sU 代替 -sT

sudo nmap -sU -p- 10.10.8.8

扫描全部 65535 个端口需要一些时间,而大多数情况下你只关心常见的服务端口。要只扫描 80 端口,使用:

nmap -p 80 10.10.8.8
Starting Nmap 7.95 ( https://nmap.org ) at 2026-09-01 14:12 CEST
Nmap scan report for 10.10.8.8
Host is up (0.0011s latency).

PORT   STATE SERVICE
80/tcp open  http

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

STATE 列是阅读重点。open 表示有服务接受了连接,closed 表示没有服务监听,filtered 通常表示防火墙丢弃了探测包。

欲了解更多信息,可查看 nmap 手册页了解所有可用选项:man nmap

使用 netcat 检查开放端口

netcat(或称 nc)是一款命令行工具,可以通过 TCP 或 UDP 跨网络连接读写数据。当 nmap 不可用时,它很适合做快速的端口检查。

使用 netcat 你可以扫描单个端口或一段端口范围。要扫描 20-80 范围内的开放 TCP 端口,运行:

nc -z -v 10.10.8.8 20-80

-z 选项指示 nc 仅扫描开放端口而不发送任何数据,-v 开启详细输出。出现 succeeded 的行表示该端口是开放的。

输出类似如下:

nc: connect to 10.10.8.8 port 20 (tcp) failed: Connection refused
nc: connect to 10.10.8.8 port 21 (tcp) failed: Connection refused
Connection to 10.10.8.8 22 port [tcp/ssh] succeeded!
...
Connection to 10.10.8.8 80 port [tcp/http] succeeded!

要只显示开放的端口,用 grep 命令过滤结果:

nc -z -v 10.10.8.8 20-80 2>&1 | grep succeeded
Connection to 10.10.8.8 22 port [tcp/ssh] succeeded!
Connection to 10.10.8.8 80 port [tcp/http] succeeded!

要扫描 UDP 端口,传入 -u 标志:

nc -z -v -u 10.10.8.8 20-80 2>&1 | grep succeeded

由于 UDP 没有连接握手,一个未返回错误的探测并不能保证端口一定开放。UDP 结果应视为尽力而为(best-effort)。

提示:2>&1 将标准错误重定向到标准输出,这是必需的,因为 nc 把结果打印到 stderr 而非 stdout。

使用 telnet 检查远程服务器上的单个端口

当你需要测试远程服务器上的单个 TCP 端口时,telnet 可以建立连接并告诉你该端口是否接受连接。

telnet 10.10.8.8 22

如果端口开放,telnet 会完成连接并把原始会话交给你。按 Ctrl+] 返回 telnet> 提示符。

Trying 10.10.8.8...
Connected to 10.10.8.8.
Escape character is '^]'.
SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.5

Ctrl+] 返回 telnet> 提示符,然后输入 quit 关闭会话。

当端口上没有服务监听,或防火墙直接拒绝数据包时,连接会立即失败:

Trying 10.10.8.8...
telnet: Unable to connect to remote host: Connection refused

如果 telnet 一直停留在 Trying 行直到超时,说明没有建立 TCP 连接,这通常意味着防火墙正在丢弃数据包。

在依赖此方法之前,有两点局限值得了解:telnet 只支持 TCP,因此无法测试 UDP 端口,而且它不会告诉你端口背后监听的是什么服务。

使用 Bash /dev/tcp 检查开放端口

另一种检查特定 TCP 端口是否开放的方法是使用 Bash 的 /dev/tcp 伪设备。它除了 Bash 本身外不需要任何额外工具。

当你打开这个伪设备时,Bash 会尝试与指定的主机和端口建立 TCP 连接。如果连接成功,文件描述符被打开;如果失败,Bash 报错。

Bash 也支持 /dev/udp/HOST/PORT,但仅打开一个 UDP 套接字并不能确认有服务在监听,因此它在可达性检查中用处不大。

下面的 if..else 语句检查 kernel.org 的 443 端口是否开放:

if timeout 5 bash -c '</dev/tcp/kernel.org/443 &>/dev/null'

then

  echo "Port is open"

else

  echo "Port is closed"

fi
Port is open

伪设备的默认连接超时时间非常长,因此用 timeout 命令把等待时间限制在 5 秒。你可以根据网络情况调整该值。

要检查一段端口范围,使用 for 循环:

for PORT in {20..80}; do

  timeout 1 bash -c "</dev/tcp/10.10.8.8/$PORT &>/dev/null" && echo "port $PORT is open"

done
port 22 is open
port 80 is open

检查防火墙允许的端口

扫描可以告诉你客户端能到达什么,但它无法识别设备自身的防火墙规则。要查看防火墙本身允许哪些端口,需要查询正在使用的防火墙管理器。

在配置了 ufw 的 Ubuntu 及其他系统上,用以下命令查看其状态和规则:

sudo ufw status

firewalld 处于活动状态时,先找出绑定到入站接口的区域,再列出该区域允许的服务和端口:

sudo firewall-cmd --get-active-zones

sudo firewall-cmd --zone=public --list-all

public 替换为你系统上显示的活动区域。同时查看 servicesports 两行,了解允许了什么。

如果防火墙由 nftables 直接管理,检查完整规则集:

sudo nft list ruleset

仅在维护旧的 iptables 规则集时才使用 iptablesiptables 命令显示当前规则:

仅凭防火墙规则并不能证明端口可达,因为服务可能并未运行,因此请将其与主动扫描结合使用。

故障排查

nmap: command not found —— nmap 并非默认安装在所有发行版上。请从你的包管理器安装它(例如,在基于 Debian 的系统上执行 sudo apt install nmap)。

nc 不可用或行为不同 —— 某些发行版把 ncat(来自 nmap 项目)作为 nc 提供,或完全省略 nc。用 nc -h 检查你拥有的是哪个变体。

nmap 将端口显示为 filtered 而非 openclosed —— filtered 状态表示数据包被丢弃且未获响应,通常是防火墙所为。它并不能确认是否有服务在监听。

UDP 扫描结果不可靠 —— UDP 扫描天生就不如 TCP 可靠,因为没有握手来确认响应。请用应用层测试来验证重要的 UDP 端口。

nc -z 显示端口开放但服务不可达 —— 端口在本地处于监听状态,但你与主机之间的防火墙仍可能阻止它。请将 nc 与远程扫描结合使用以确认。

速查表

如需可打印的速查表,参见 nmap 速查表与 netcat 速查表(下方表格已汇总常用命令)。

CommandDescription
nmap -sT -p- HOST扫描主机上的所有 TCP 端口
sudo nmap -sU -p- HOST扫描主机上的所有 UDP 端口
nmap -p PORT HOST检查单个 TCP 端口的状态
nc -z -v HOST PORT_RANGE使用 netcat 扫描一段 TCP 端口范围
nc -z -v -u HOST PORT_RANGE使用 netcat 探测一段 UDP 端口范围
nc -z -v HOST PORT_RANGE 2>&1 | grep succeeded仅显示开放的端口
telnet HOST PORT测试远程服务器上的单个 TCP 端口
timeout 5 bash -c '使用 Bash 测试单个 TCP 端口
sudo ufw status显示 ufw 状态与规则
sudo firewall-cmd --get-active-zones查找活动的 firewalld 区域
sudo firewall-cmd --zone=ZONE --list-all列出 firewalld 区域的规则
sudo nft list ruleset检查完整的 nftables 规则集

常见问题

监听端口和开放端口有什么区别?监听端口已绑定到某个服务并等待连接。开放端口是指从网络可以到达的端口,这要求既有正在监听的服务,也有允许该流量的防火墙规则。

如何检查自己机器上某个特定端口是否开放?使用 ss -tlnp | grep :PORT 在本地列出监听端口,或用 nmap -sT -p PORT localhost 从回环接口扫描。

不安装 nmap 也能扫描端口吗?可以。对 TCP 使用 nc -z -v HOST PORT_RANGE,对单个端口使用 Bash /dev/tcp,如本指南前面所示。

扫描端口需要 root 吗?TCP 连接扫描(nmap -sT)和 nc 以普通用户身份即可工作,但 UDP 扫描(-sU)以及用 ss -p 读取进程名通常需要 root 权限。

总结

使用 nmap 进行全面端口扫描,netcat 做快速范围检查,telnet 测试单个端口,在没有安装任何工具时用 Bash /dev/tcp。将扫描与防火墙检查结合起来,才能完整掌握系统上哪些端口可达。

下一条

没有了