端口连通性检查

从公网这边连一次看看通不通。在服务器上 nc -z localhost 能过,不代表外面连得上——云厂商的安全组、机房防火墙都在中间。

需服务端处理这个工具由服务器代为访问网络

你要检查的主机名和端口列表会发送到本站服务器,由服务器发起查询,结果只返回给这个页面。

服务器不保存查询内容,也不记录你查了什么,只按来源 IP 限制频率(每分钟 30 次,且一次检查按端口数扣额度(探 12 个端口约等于用掉 12 次))防止被当跳板刷。站上其它工具仍然全部在浏览器本机完成。

快捷选择:

例子:

只会做一次 TCP 握手。而且为了不让它变成端口扫描器,可检查的端口限于一份固定清单(页尾列出)。

「通了」和「没通」各自说明什么

做端口检查之前,值得先弄清它能回答什么。一次 TCP 握手只有三种结局:对方接受了、对方明确拒绝、对方不回应。接受说明这个端口上有程序在监听,这是唯一能确定的事——它到底是什么服务,这里并不知道,判断依据只有端口号的惯例。开放不等于安全,也开放不等于就是你以为的那个服务,这是用这个工具时最容易搞错的地方。

明确拒绝(ECONNREFUSED)其实是个好消息:它说明包走通了整条路径、到达了目标主机,只是那个端口上没有程序。所以排查时,「拒绝」和「不回应」要分开看:前者排除了网络层的问题,后者才是网络层或防火墙的问题。不回应通常是防火墙用 DROP 把包悄悄丢掉——相比回一个拒绝,丢失更难被外部判断出来,所以是默认的安全策略。

这也解释了最常见的困惑:我在服务器上连自己能通,为什么这个工具说没通?因为在机器上连本机走的是本地回环,一路上没有安全组、没有机房防火墙、没有运营商策略。从公网进来要这三样同时放行。云厂商的「安全组」尤其容易漏——它是独立于机器自身防火墙的一层,只改 iptables 而忘了安全组,症状就正好是「本机能连、公网连不上」。要让这个工具看到开放,需要网络路径上的每一层都放行。

反过来,如果这里显示开放而你以为它没开,先确认是不是反向代理或负载均衡在那里监听。CDN 和 WAF 会占用 80 和 443 并回你的源站,所以这两个端口「开放」只说明边缘节点在线,不代表源站没被藏起来。

哪些端口暴露在公网属于事故

有一类服务在暴露到公网时几乎没有抵抗能力,因为它们的设计前提是「只给自己人用」:Redis、MongoDB、Elasticsearch、Memcached、MySQL,以及 Docker 的远程管理端口。它们要么完全没有认证,要么认证是后来补上的可选功能。互联网上一直有自动化脚本在持续扫描整个 IPv4 空间寻找这些端口,从暴露到被写入挖矿程序或勒索加密,常见的间隔是几天,甚至几小时。

所以这里查到它们开放时,正确的处理不是加个密码了事,而是让它们根本不可达:绑定到内网地址、用安全组限制来源、需要外部访问时走 SSH 隧道或跳板机。密码是第二道防线,可达性才是第一道——而这道防线的检查方式,就是在别处连一次。

关于出口 IP

这个工具从我们的服务器发起连接,所以对方的日志里记录的是我们的 IP,不是你。反过来讲,你要检查的服务如果做了 IP 白名单,那白名单里得放我们的服务器,否则结果会是没有回应——这时超时并不代表你的配置错了。要让检查更贴近真实访客,更可靠的办法是在你自己的机器上用 nc、telnet 或 Test-NetConnection 连一次;这个工具的价值在于提供一个和你的网络环境无关的视角。

最后一句必要的提醒:只检查你自己有权检查的主机。对别人的主机做端口扫描,在很多地方是需要授权的行为。

可检查的端口清单

21 FTP、22 SSH、23 Telnet、25 SMTP、53 DNS、80 HTTP、110 POP3、143 IMAP、443 HTTPS、445 SMB、465 SMTPS、587 SMTP 提交、993 IMAPS、995 POP3S、1080 SOCKS、1433 SQL Server、1521 Oracle、2049 NFS、2375 Docker 远程 API、2376 Docker 远程 API(TLS)、3000 常见开发服务端口、3306 MySQL、3389 远程桌面、5000 常见开发服务端口、5432 PostgreSQL、5601 Kibana、5672 RabbitMQ、5900 VNC、6379 Redis、6443 Kubernetes API、8000 常见开发服务端口、8080 HTTP 备用端口、8081 常见开发服务端口、8443 HTTPS 备用端口、8888 常见开发服务端口、9000 常见应用端口、9090 常见管理端口、9200 Elasticsearch、9300 Elasticsearch 节点通信、11211 Memcached、27017 MongoDB

常见问题

为什么我在服务器上 nc 能连、这里却连不上?

因为这正是两个不同的位置。在机器上连本机端口,走的是本地回环,一路上没有安全组、没有机房防火墙、也没有运营商策略;从公网连进来才需要这三样都放行。云厂商的「安全组」默认只开 22 和 3389,而且它是独立于机器自身防火墙的一层——很多人只改了 iptables,却忘了安全组,于是 localhost 通、公网不通。这个工具测的就是最终用户那一侧的真实结果。

显示「开放」就说明上面跑的是我猜的那个服务吗?

不一定。这个工具只做一次 TCP 握手,不发任何应用层数据,所以它知道的仅仅是「这个端口有人接」。Redis 监听在 3306 上也是「开放」。想确认服务类型要看 banner,那需要发真实的协议数据,属于另一件事,也更容易被对方的安全设备判定为探测,所以这里刻意不做。

「被拒绝」和「没有回应」有什么区别?

区别在于对端用什么方式回绝你,而这个区别会透露不少信息。被拒绝(ECONNREFUSED)说明包到达了主机,但那个端口上没有程序监听——主机在线,端口关着。没有回应(超时)说明包被中间某处直接丢了,通常是防火墙的策略,也可能是主机不在线。所以「超时」比「被拒绝」更模糊,也往往意味着前面有一道防火墙在拦。

相关:端口号参考表

为什么只能检查常见端口?

如果放开任意端口,这个工具就变成了一个可以扫全端口的扫描器,被拿来批量扫描别人的主机只是时间问题。所以可选的端口限于一份常见服务清单,一次最多十几个。要看完整的端口号对照,站上有端口号参考表。

相关:端口号参考表

哪些端口不该对外网开放?

认准一个原则:这些服务设计时假设调用方是自己人,所以基本没有认证或只有弱认证——Redis(6379)、MongoDB(27017)、Elasticsearch(9200)、Memcached(11211)、MySQL(3306)、Docker 的远程 API(2375)。它们一旦暴露在公网,通常几天内就会被自动化脚本扫到并利用。如果这里查到它们是开放的,正确的做法不是加密码,而是收到只允许内网或跳板机访问。

这个工具会发送什么到你们服务器?

你填的主机名和端口列表。服务器据此发起 TCP 连接,只做握手,不发送任何数据。检查用的出口是我们的服务器 IP,所以对方的连接日志里会记录到我们,而不是你。