如何在Mac上检查开放端口:lsof、netstat和nc

使用lsof -i :3000、netstat和nc在Mac上检查开放端口。涵盖本地端口检查和远程主机测试,并附有真实的命令输出示例。

您运行了rails server但页面无法加载,或者您尝试连接远程服务器却没有任何响应。第一个问题永远是:这个端口真的开着吗?

在Mac上检查端口状态只需一条命令。关键是要知道:检查自己的Mac还是检查远程主机,应该使用不同的命令。

检查本机开放端口

这是开发者最常遇到的情况。您的开发服务器应该运行在3000端口,但浏览器说无法连接。这个端口根本在监听吗?

lsof -i :端口(最快的答案)

lsof -i :3000

如果有程序在监听,您会看到如下输出:

COMMAND   PID   USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
ruby     8421  aaron  13u  IPv4 0x3f8a2b4c      0t0  TCP *:3000 (LISTEN)

如果输出为空,说明没有任何程序绑定到该端口。要么您的Rails服务器没有运行,要么它启动在了其他端口上。

检查8080端口:

lsof -i :8080

检查80端口(需要sudo,因为这是特权端口):

sudo lsof -i :80

lsof -i | grep LISTEN(一次看到所有端口)

要查看Mac当前正在监听的所有端口:

lsof -i | grep LISTEN

输出显示所有拥有开放监听端口的进程:

ruby      8421  aaron  13u  IPv4  TCP *:3000 (LISTEN)
node      9102  aaron  21u  IPv6  TCP *:8080 (LISTEN)
postgres  1234  aaron   5u  IPv4  TCP localhost:5432 (LISTEN)

注意localhost:5432*:3000的区别。Postgres只接受来自同一台机器的连接,而Rails接受来自网络中任何地方的连接。当您试图从另一台设备连接时,这个区别至关重要。

如果您想要不带主机名查找的数字端口(更快):

lsof -i -n -P | grep LISTEN

netstat -an | grep LISTEN

netstat以不同格式提供类似的视图:

netstat -an | grep LISTEN

输出如下:

tcp4       0      0  *.3000                 *.*                    LISTEN
tcp4       0      0  127.0.0.1.5432         *.*                    LISTEN
tcp6       0      0  *.8080                 *.*                    LISTEN

端口前面的地址告诉您监听的接口。*.3000表示所有接口(可从网络访问),127.0.0.1.5432表示仅本机。

当您需要一个没有进程名称的简单列表时,netstat很有用。当您需要知道哪个应用拥有哪个端口时,lsof更好用。

结果含义

LISTEN输出中有内容:端口已开放且有进程占用它。如果您仍然无法连接,问题在其他地方(防火墙、IP地址错误、身份验证)。

lsof无输出/netstat中没有内容:没有任何程序在该端口上监听。服务要么没有运行,要么启动在了不同的端口上。

输出显示127.0.0.1localhost:服务只接受本地连接,您无法从同一网络中的其他机器或手机访问它。

检查远程主机的端口

当您需要测试一台您不控制的服务器上的端口是否开放时,无法使用lsof。您需要实际尝试连接,看看会发生什么。

nc -zv(正确的工具)

nc -zv hostname 443

如果端口开放:

Connection to hostname port 443 [https] succeeded!

如果端口关闭(没有程序在监听):

nc: connectx to hostname port 80 (tcp) failed: Connection refused

如果端口被过滤(防火墙丢弃数据包):

nc: connectx to hostname port 25 (tcp) failed: Operation timed out

“Connection refused"意味着服务器可达但该端口上没有程序。“Operation timed out"意味着防火墙可能在数据包到达之前就将其丢弃了。

实际示例:

# 我的服务器上HTTPS是否正常工作?
nc -zv myserver.com 443

# 这台机器上SSH是否开放?
nc -zv 192.168.1.100 22

# 从这台机器能连接到数据库端口吗?
nc -zv db.internal 5432

您也可以同时检查多个端口:

nc -zv hostname 80 443 8080

结果解读

结果 含义
Connection succeeded 端口开放,有程序在监听
Connection refused 端口关闭,没有程序在监听
Operation timed out 防火墙正在阻止连接
Name or service not known 主机名无法解析(DNS问题)

如果端口连接成功但服务仍然无法使用,问题在应用层:凭据错误、协议不匹配、应用拒绝了连接。

常见端口参考

调试时,以下端口最常出现:

  • 22(SSH):无法SSH连接?先检查这个。
  • 80(HTTP)和443(HTTPS):Web服务器无响应。
  • 3000、3001、8000、8080:常见的开发服务器端口。Rails默认使用3000,许多Node应用使用8080。
  • 5432(PostgreSQL)、3306(MySQL)、27017(MongoDB):数据库连接问题。
  • 25(SMTP):应用无法发送邮件?通常被ISP和云服务商封锁。

安全:您的Mac暴露了哪些端口?

从安全角度来看,偶尔运行lsof -i | grep LISTEN是值得的。每个监听端口都是潜在的入口点。在笔记本电脑上,您通常希望开放端口越少越好。

意外开放端口的常见原因:

  • 仍在运行的开发服务器(Rails、Node、Webpack)
  • Docker将端口映射到宿主机
  • 启用了远程桌面或屏幕共享
  • AirPlay接收器
  • 运行后台服务的第三方应用

如果您看到无法识别的内容,从lsof输出中获取PID并查找:

ps aux | grep <PID>

使用macOS防火墙

macOS防火墙控制外部什么可以连接到您的Mac。在"系统设置 > 网络 > 防火墙”(或某些版本中的"系统设置 > 隐私与安全性 > 防火墙”)中查看。

开启防火墙后,其他机器无法访问您Mac上的监听服务,除非您明确允许。您的Mac仍然可以发起对外的连接。

如果您的本地开发服务器在浏览器中加载正常,但无法从同一网络中的手机访问,防火墙很可能是原因所在。

图形界面选项:NetUtil的端口扫描器

如果您不想输入命令,NetUtil内置了端口扫描器。输入主机名和端口范围,它会以表格形式显示哪些端口是开放的。这是Apple在macOS Monterey中移除"网络实用工具"后,其端口扫描器功能的直接替代品。

对于日常调试,一旦掌握了终端命令会更快。lsof -i :3000多练几次之后,打起来只需几个按键。对于偶尔的检查,或者需要扫描远程服务器上的一系列端口时,图形工具可以节省时间。

快速参考

检查Mac是否在特定端口上监听:

lsof -i :3000

查看Mac正在监听的所有端口:

lsof -i | grep LISTEN

使用netstat的同等命令:

netstat -an | grep LISTEN

检查远程端口是否开放:

nc -zv hostname 443

Mac上的端口状态告诉您服务是否在运行;远程主机上的端口状态告诉您该服务是否可以访问。这是两个不同的问题,对应两个不同的工具。