Featured image of post Linux运维 01:Mac 判断服务器端口连通性方法大全(nc / curl / telnet / nmap)

Linux运维 01:Mac 判断服务器端口连通性方法大全(nc / curl / telnet / nmap)

ping 不通 ≠ 端口不通,telnet 连上没字 ≠ 不通:Mac 上判断单个端口连通性与扫描整台服务器开放端口的完整方法集,附内网服务器实扫案例。

环境:macOS(Apple Silicon),无需安装任何软件即可完成 90% 的排查 场景:服务器部署了服务,想确认"端口到底通不通"“这台机器上还开了哪些端口” 读者定位:收藏当手册,用到时按目录查


一、先建立两个认知(不懂这两个,必误判)

1.1 ping 不通 ≠ 端口不通

ping 走的是 ICMP 协议,而业务端口走的是 TCP 协议,两者互不相干。 很多服务器和内网防火墙会直接丢弃 ICMP 包,造成"ping 100% 丢包但 80 端口网页开得好好的"。

结论:不要用 ping 判断服务是否存活,要用 TCP 探测。

1.2 连上没字 ≠ 不通(“谁先说话"问题)

不同协议的"开场白"方向不一样:

协议类型代表服务连接建立后
服务器先说话SSH(22)、MySQL(3306)、FTP(21)立刻推送 banner(版本信息)
客户端先说话HTTP(80/8080…)、Redis(6379)一言不发,等你先发请求

所以用 telnet 测 HTTP 端口,连上后一片空白、光标干等——这不是不通,是正常等待。输入 GET / HTTP/1.0 再按两次回车,响应立刻就出来了。

真实案例:浏览器能打开 http://10.36.35.43:8083/login,但 telnet 10.36.35.43 8083 “没响应”。用 nc 验证:TCP 秒连,手动发一行 GET 请求立刻返回 HTTP/1.1 200 OK——端口一直是通的,只是 HTTP 服务不主动打招呼。


二、判断单个端口是否通

方法 1:nc(macOS 自带,首选)

1
2
nc -vz 10.36.35.43 22
# -v 显示详情  -z 只探测不传数据  -G 2 可指定超时秒数

三种结果,语义完全不同,要能读懂:

输出含义
Connection to ... succeeded!✅ 通,且有服务在监听
failed: Connection refused主机可达,但端口没服务监听(服务没起/监听别的端口)
failed: Operation timed out包被防火墙丢了,或主机不可达(不是"没服务”)

方法 2:curl(HTTP 服务最方便)

1
2
curl -sI -m 5 http://10.36.35.43:8080      # 看状态行 + Server 头
curl -v telnet://10.36.35.43:22            # 冷门招:telnet:// 协议能测任意 TCP 端口,还能拿到 SSH banner

方法 3:bash 内置 /dev/tcp(零依赖应急)

1
bash -c '(echo > /dev/tcp/10.36.35.43/22) 2>/dev/null && echo 通 || echo 不通'

无需任何外部命令,是 bash 自身的特性。缺点是超时不可控(防火墙丢包场景会等很久),日常还是 nc 好用。

⚠️ 踩坑(实测):zsh 下直接跑会得到"假阴性"。/dev/tcp 是 bash 独有的伪设备,zsh 不认识——它把 /dev/tcp/10.36.35.43/22 当普通文件路径,重定向失败的报错又被 2>/dev/null 吞掉,于是端口明明是通的也输出"不通"。macOS 从 Catalina 起默认 shell 就是 zsh,所以必须套一层 bash -c '...'。验证:curl -v telnet://IP:端口 能拿到 banner 而 /dev/tcp 报不通时,先想想自己当前在哪个 shell 里。

方法 4:telnet(新版 macOS 需自行安装)

1
2
brew install telnet
telnet 10.36.35.43 22

看到 Connected to ... 就说明 TCP 通了。后面有没有字,取决于 1.1 节说的"谁先说话"。

方法 5:nmap(装了的话)

1
nmap -Pn -p 22,80,443 10.36.35.43

-Pn 很重要:nmap 默认先 ping 探测主机死活,ping 不通直接跳过扫描。内网服务器经常禁 ping(见 1.1),不加 -Pn 会得出"主机 down"的错误结论。

方法 6:浏览器

HTTP/HTTPS 服务最直接:http://IP:端口 能打开页面就是通的。但注意它只对 Web 服务有效。


三、扫描整台服务器:哪些端口是开的

方法 1:nmap(标准答案)

1
2
3
4
5
6
7
brew install nmap

nmap -Pn 10.36.35.43              # top 1000 常用端口(最常用)
nmap -Pn -F 10.36.35.43           # top 100,更快
nmap -Pn -p- 10.36.35.43          # 全端口 1-65535(慢,几分钟)
nmap -Pn -sV 10.36.35.43          # 顺带识别服务版本
nmap -Pn -T4 --open 10.36.35.43   # 加速 + 只显示开放的

方法 2:nc + xargs 并发(不装任何东西的应急方案)

1
2
3
4
5
echo "21 22 23 25 53 80 110 143 443 445 465 587 993 995 1080 1433 1521 2181 \
2375 3000 3306 3389 4000 5000 5432 5672 5900 6379 8000 8006 8007 8080 8081 \
8086 8090 8443 8848 8888 9000 9001 9042 9090 9092 9200 9300 10000 11211 15672 27017" \
  | tr ' ' '\n' \
  | xargs -P 20 -I{} sh -c 'nc -z -G 2 10.36.35.43 {} >/dev/null 2>&1 && echo "OPEN {}"'

原理:nc -z 逐端口试探 TCP 握手,xargs -P 20 并发 20 个,50 个常见端口十几秒扫完。 想扫全端口就换成 seq 1 65535 | xargs -P 50 ...,慢但可行。

注意列表覆盖:上面的清单是手挑的常见端口,像 8083 这种非典型端口就不会命中——扫不到不代表没开,只代表"不在清单里"。要穷举就上 nmap -p-。

方法 3:masscan(海量端口,需 sudo)

1
2
brew install masscan
sudo masscan -p1-65535 10.36.35.43 --rate=1000

异步发包,全端口几十秒扫完。适合大网段,单机用 nmap 足矣。


四、识别端口上跑的是什么服务(banner grabbing)

端口通只是第一步,抓 banner 才知道上面跑的是谁:

1
2
3
4
5
6
7
8
9
# SSH / MySQL:连上就读(服务器先说话)
nc -w 2 10.36.35.43 22 < /dev/null | head -1        # SSH-2.0-OpenSSH_8.8
nc -w 2 10.36.35.43 3306 < /dev/null | strings | head -1   # 5.7.44

# Redis:发 PING 看回应(客户端先说话)
printf 'PING\r\n' | nc -w 2 10.36.35.43 6379        # -NOAUTH Authentication required.

# HTTP:HEAD 请求
curl -sI -m 5 http://10.36.35.43:80                 # Server: nginx/1.13.12

一条命令全搞定的懒人方案:nmap -Pn -sV 目标IP。


五、实战案例:扫描内网服务器 10.36.35.43

用方法三·2 的 nc 并发扫描 + 方法四的 banner 抓取,实测结果:

端口服务识别详情
22SSHOpenSSH 8.8
80HTTPnginx/1.13.12,首页 200
443开放但未知TCP 通,不回应 HTTPS 握手
3306MySQL5.7.44(版本号 banner 直接暴露)
6379Redis有密码(NOAUTH)
8080/8081HTTP根路径 404,未暴露 Server 头
8083HTTPnginx 反代的前端登录页(后补扫发现)

顺带两个安全观察:

  • MySQL 版本号在 banner 里裸奔——等于告诉攻击者该打哪些 CVE,3306 应只对需要的网段开放
  • nginx 1.13.12 是 2017 年的版本,已知漏洞不少(如 CVE-2017-7529),正式服务建议升级

六、速查表

需求命令
测单个端口nc -vz IP 端口
测 HTTP 服务curl -sI -m 5 http://IP:端口
任意 TCP 端口看 bannercurl -v telnet://IP:端口 或 nc -w 2 IP 端口
扫常用端口nmap -Pn IP(无 nmap 时用 nc+xargs 脚本)
扫全端口nmap -Pn -p- IP
识别服务版本nmap -Pn -sV IP
ping 不通还想扫nmap 务必加 -Pn

合规提醒:端口扫描只用于自己的服务器或获得明确授权的目标。对陌生主机扫描在多数公司和云厂商守则里属于攻击行为。

使用 Hugo 构建
主题 Stack 由 Jimmy 设计