服务明明在跑,端口也开着,外网就是连不上,我一层层查下去才找到原因

举报
yd_242783495 发表于 2026/11/09 14:45:38 2026/11/09
【摘要】 新服务部署到华为云 ECS 上,本地 curl 能通,外网死活连不上。顺着监听地址、防火墙、安全组一层层查,最后发现问题出在最不起眼的地方。把排查顺序和每一步的命令都记下来了。

上周往一台华为云 ECS 上布了个小服务,部署完在机器上 curl localhost:8080,返回正常。换台电脑从外网访问,浏览器一直转圈,最后超时。当时第一反应是服务没起好,但本地明明是通的,这就很别扭了。

这种“本地通、外网不通”的毛病,我后来总结出一个排查顺序:先看服务到底在监听哪个地址,再看本机防火墙,最后看云上的安全组。按这个顺序查,基本不会绕路。下面就是我那天实际走的步骤。

第一步:服务到底在监听谁

本地能通只能证明进程活着,说明不了它在对外提供服务。先看监听状态:

ss -tlnp | grep 8080

输出是这样的:

LISTEN 0  128  127.0.0.1:8080  0.0.0.0:*  users:(("myapp",pid=1234,fd=9))

问题就摆在这儿了:127.0.0.1:8080。服务只绑了回环地址,外网的包根本到不了它。curl localhost:8080 能通,纯粹是因为请求压根没出本机。

这是很多框架和脚手架的默认行为,图省事默认绑 localhost,开发机上没问题,一上服务器就翻车。修法是改配置,让服务绑 0.0.0.0:

# 比如很多服务是这样的启动参数或配置文件
# 启动时指定 --host 0.0.0.0,或在配置文件里把 host 改成 0.0.0.0

改完重启,再看一眼监听状态,确认变成 0.0.0.0:8080:

ss -tlnp | grep 8080
# LISTEN 0  128  0.0.0.0:8080  0.0.0.0:*  users:(("myapp",pid=2345,fd=9))

我当时以为这就完了,结果外网还是连不上。说明后面还有关卡。

第二步:本机防火墙有没有放行

监听地址对了,包到网卡这一层还可能被本机防火墙拦住。这台机器用的是 firewalld:

# 看 8080 在不在放行列表里
firewall-cmd --list-ports

# 看当前 zone 的放行情况
firewall-cmd --list-all

--list-ports 里果然没有 8080。加上:

# --permanent 写进持久配置,--add-port 只影响当前运行时
firewall-cmd --permanent --add-port=8080/tcp
firewall-cmd --reload
firewall-cmd --list-ports

这里有个容易踩的坑:firewall-cmd --add-port 不加 --permanent,当时生效,机器一重启就没了;只加 --permanent 不 reload,配置写进去了但当前不生效。我以前就吃过这个亏,服务好好的,重启机器之后又“神秘失联”。所以上面两条要一起跑,跑完再 --list-ports 确认一次。

如果机器用的是 iptables 而不是 firewalld,查法换成:

iptables -L INPUT -n --line-numbers | grep 8080

没放行的话补一条规则,同样注意保存持久化,不然重启丢规则。

加完防火墙,我从另一台机器 telnet 了一下,还是不通。这时候基本能确定,问题在云平台那一层。

第三步:安全组,才是云服务器最常卡住的地方

云服务器和自家机房的机器不一样,流量进 ECS 之前,还要过一道安全组。在华为云控制台找到这台 ECS,点进安全组,看入方向规则:

  • 有没有放行 8080/tcp
  • 规则的源地址是不是 0.0.0.0/0,还是只放了某个内网网段
  • 优先级和方向有没有配反(入方向和出方向别看串了)

我那台就是安全组里只有 22 和 80 端口,8080 压根没放。加一条入方向规则:协议 TCP,端口 8080,源地址 0.0.0.0/0,保存后立刻生效,不用重启机器。

加完再测,外网终于通了。整件事从头到尾,服务本身一点毛病没有,三道关卡各拦了一次。

一个小工具:分不清卡在哪一层的时候

后来我养成一个习惯,排查这类问题先分层测,省得瞎猜:

# 本机测:服务本身有没有问题
curl -v http://127.0.0.1:8080/health

# 内网另一台机器测:过不过本机防火墙
curl -v http://<内网IP>:8080/health

# 外网测:过不过安全组
curl -v http://<公网IP>:8080/health

三层测下来,断在哪一步就查哪一层。第一步不通查监听地址和进程,第二步不通查防火墙,第三步不通查安全组。这比上来就改配置、重启服务要省事得多。

还有个办法是抓包确认包到底到没到机器:

# 在服务器上抓 8080 端口的包,另一边从外网发起请求
tcpdump -i any port 8080 -n -c 20

如果 tcpdump 里能看到外网 IP 的 SYN 包,说明包到了机器,是本机拦的;如果什么都没有,问题在安全组那一层。这个办法在分不清责任的时候特别管用。

我踩过的几个坑,顺手记下来

  • 框架默认绑 127.0.0.1:开发机没问题,上服务器就翻车。部署完第一件事就是 ss -tlnp 看监听地址。
  • firewalld 规则没持久化:当时好了,重启丢了。--permanent 和 --reload 要成对出现。
  • 安全组只放了 22 和 80:新服务换个端口,安全组不跟着改,等于没部署。
  • 拿 curl localhost 当验收:本地通不代表对外通,验收一定要从外网测一次。
  • 端口被别的进程占了:服务启动时报 Address already in use,但旧进程还在跑,curl 返回的可能是旧服务。ss -tlnp 看一眼 pid 再动手。

现在我每次部署新服务,都按“监听地址、防火墙、安全组、外网实测”这个顺序走一遍,几分钟的事,能省掉一下午的折腾。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。