如何在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.1或localhost:服务只接受本地连接,您无法从同一网络中的其他机器或手机访问它。
检查远程主机的端口
当您需要测试一台您不控制的服务器上的端口是否开放时,无法使用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上的端口状态告诉您服务是否在运行;远程主机上的端口状态告诉您该服务是否可以访问。这是两个不同的问题,对应两个不同的工具。