云服务器控制台里已经添加了入站规则,浏览器、curl 或客户端仍然连不上对应端口,这类问题通常不只涉及安全组。公网请求要经过公网 IP、云侧访问控制、虚拟网卡、系统防火墙和应用监听等环节,其中任何一层没有接通,外部访问都会超时或被拒绝。
排查时可以把链路拆开验证:应用是否真的在监听,服务器本机能否访问,数据包是否到达网卡,最后再回到安全组、公网入口和客户端网络。这样比反复添加放行规则更容易找到故障点。

一、先根据报错判断问题落在哪一层
从外部电脑测试目标端口:
curl -v --connect-timeout 5 http://服务器公网IP:8080/
nc -vz -w 5 服务器公网IP 8080
Windows PowerShell 可以使用:
Test-NetConnection 服务器公网IP -Port 8080
常见结果可以这样理解:
| 现象 | 更值得优先检查的方向 |
|---|---|
Connection refused / 连接被拒绝 |
请求通常已经到达主机,但端口没有进程监听,或主机明确拒绝连接 |
| 一直等待后超时 | 安全组、系统防火墙、路由、公网入口或运营商网络可能丢弃了数据包 |
| TCP 已连接,但返回 403、404、502 或 TLS 错误 | 网络链路基本已通,应检查域名、反向代理、证书和应用配置 |
| 同一内网可以访问,公网不通 | 公网 IP、安全组来源范围、NAT、负载均衡或互联网边界策略更可疑 |
报错只能帮助缩小范围,不能单独作为结论。最稳妥的办法仍是从服务器内部向外逐层检查。
二、确认应用确实监听了目标端口
在 Linux 云服务器上执行:
sudo ss -lntup
sudo ss -lntup '( sport = :8080 )'
ss 的 -l 参数只显示监听套接字,-n 保留数字端口,-t 和 -u 分别查看 TCP、UDP,-p 用于显示关联进程。
检查结果时,监听地址和端口同样重要:
127.0.0.1:8080
0.0.0.0:8080
[::]:8080
如果服务只监听 127.0.0.1:8080,它只能接受本机回环接口的请求。要让外部网络直接访问,应用通常需要监听服务器网卡地址、0.0.0.0,或按实际 IPv6 需求监听 [::]。修改监听地址前,应先确认该服务是否适合暴露到公网。
端口没有出现在监听列表时,继续检查服务状态和日志:
sudo systemctl status your-service --no-pager
sudo journalctl -u your-service -n 100 --no-pager
如果使用 Docker,还要确认容器端口已经发布到宿主机:
docker ps --format 'table {{.Names}}\t{{.Ports}}'
仅在容器内部监听端口,而没有通过 -p 或 Compose 的 ports 映射到宿主机,外部请求同样无法进入。
三、在服务器本机验证应用,而不是直接改安全组
假设应用监听 8080 端口,可以分别测试回环地址和服务器网卡地址:
curl -v http://127.0.0.1:8080/
hostname -I
curl -v http://服务器内网IP:8080/
本机回环访问失败,说明问题还在应用进程、监听端口或应用依赖,不需要继续修改云端规则。本机回环可用、内网 IP 不可用,通常要检查监听地址或系统防火墙。
如果服务依赖域名或虚拟主机,直接请求 IP 可能得到默认站点或 404。可以临时带上正确的 Host 请求头:
curl -v -H 'Host: example.com' http://127.0.0.1:8080/
HTTPS 服务还要确认实际启用的是 TLS 端口,不能把 HTTP 请求发到 HTTPS 监听端口。
四、检查系统防火墙所在区域和实际规则
云安全组与 Linux 主机防火墙是两套控制层。安全组允许流量,不代表 firewalld、UFW 或 nftables 一定允许。
使用 firewalld 的系统可以先看运行状态、活动区域和现有规则:
sudo firewall-cmd --state
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --zone=public --list-all
确认网卡属于哪个 zone,再向正确区域添加端口。以下示例把 8080/TCP 加入 public 区域:
sudo firewall-cmd --zone=public --add-port=8080/tcp
sudo firewall-cmd --permanent --zone=public --add-port=8080/tcp
sudo firewall-cmd --reload
第一条修改运行时规则,第二条写入永久配置。只添加运行时规则,重启 firewalld 或服务器后可能失效;只写永久规则但没有重新加载,也不会立即进入当前运行配置。
Ubuntu 常见的 UFW 可以这样检查:
sudo ufw status verbose
sudo ufw status numbered
需要放行时,尽量限定来源地址:
sudo ufw allow proto tcp from 203.0.113.10 to any port 8080
不要为了测试直接长期关闭主机防火墙,也不要把数据库、缓存、管理面板等高风险端口开放给 0.0.0.0/0。更稳妥的做法是临时只允许自己的公网 IP,验证完成后再整理规则。
五、回到云控制台核对安全组的五个细节
安全组规则看起来“已经放行”,仍可能选错对象或匹配到更高优先级的规则。逐项核对:
- 实例是否绑定了这组规则。 同一账号、同一地域可能有多个名称相近的安全组,规则改对了,实例却绑定了另一组。
- 协议是否一致。 TCP 和 UDP 是不同协议。DNS、游戏服务、VPN 或实时通信可能使用 UDP,不能只放行同号 TCP 端口。
- 端口是否写对。 控制台规则应对应应用实际监听的端口,不要只根据文档默认端口判断。
- 来源范围是否包含当前客户端。 家庭宽带、手机热点、公司出口或代理会改变公网出口 IP。只允许旧 IP 时,新网络会被拒绝。
- 优先级和多安全组顺序是否冲突。 以腾讯云为例,规则按优先级匹配,实例绑定多个安全组时也存在匹配顺序。更高优先级的拒绝规则可能先命中。
安全组是否有状态、多个安全组如何合并、规则冲突时如何处理,会因云平台和产品而异。应以当前厂商文档及控制台说明为准,不能把某一家云平台的规则直接套到另一家。
六、确认服务器具备真正的公网入口
有安全组放行规则,不等于实例一定能从互联网被直接访问。还要确认访问目标和网络架构:
- 实例是否绑定公网 IPv4、IPv6 或弹性公网 IP;
- 公网 IP 是否仍绑定在当前实例或当前网卡;
- 域名 A、AAAA 记录是否指向了正确地址;
- 前面是否还有负载均衡、云防火墙、WAF 或 NAT 网关;
- 负载均衡监听端口、后端端口和健康检查是否一致;
- 私网实例是否只有出站 NAT,而没有配置入站映射或公网负载均衡。
尤其要注意:能在服务器里访问互联网,只能说明出站链路可用,不能证明公网客户端能够反向访问这台实例。
可以从本地检查域名当前解析结果:
nslookup example.com
dig +short A example.com
dig +short AAAA example.com
如果域名同时有 A 和 AAAA 记录,而 IPv6 链路没有配置完整,部分客户端可能优先尝试 IPv6 后失败。此时应分别测试 IPv4 和 IPv6,确认问题是否只出现在某一种协议栈。
七、用抓包判断数据包究竟有没有到达服务器
前面的配置都看不出问题时,抓包能把云外和云内迅速分开。以 TCP 8080 为例:
sudo tcpdump -ni any tcp port 8080
然后从外部客户端重新连接一次:
- 完全看不到入站 SYN:问题更可能位于安全组、公网 IP、路由、负载均衡、云防火墙或客户端出口;
- 能看到 SYN,但服务器没有返回 SYN-ACK:继续检查监听进程、主机防火墙和本机路由;
- TCP 三次握手完成,随后出现 HTTP 或 TLS 错误:网络端口已经接通,应转向反向代理和应用层;
- 服务器发出了 SYN-ACK,但客户端收不到:检查回程路由、策略路由、非对称路径和上游网络策略。
抓包可能包含业务 IP、端口和载荷信息。生产环境应限制过滤范围和持续时间,排查完成后及时停止。
八、修复后要从内外两侧重新验证
修改配置后,至少完成以下验证:
sudo ss -lntup '( sport = :8080 )'
curl -v http://127.0.0.1:8080/
curl -v http://服务器内网IP:8080/
再从真正的外部网络测试公网地址和域名。不要只在同一台服务器上请求自己的公网 IP,因为部分云网络会经过不同的回流路径,结果不能代表真实互联网客户端。
最后收紧为了排查临时添加的规则,只保留必要协议、端口和来源;记录安全组、主机防火墙、监听地址以及公网入口之间的对应关系。以后再次出现端口不通,可以沿着同一条路径检查:监听进程、本机访问、主机防火墙、云侧访问控制、公网入口、外部客户端。
参考资料
- 腾讯云:安全组概述
- Linux man-pages:ss(8)
- firewalld:Open a Port or Service
- Ubuntu Server documentation:Firewall
- NGINX:ngx_http_core_module listen 指令
资料核验日期:2026年9月8日




