网站打不开?先别改代码——安全组与网络排查入门

举报
辣椒酱来了 发表于 2026/11/07 00:29:42 2026/11/07
【摘要】 一、先建立一个正确的排查顺序一个请求从你的浏览器到服务器上的进程,要穿过三道关卡。任何一道没过,你都看不到页面。你的浏览器 │ ├─ ① 安全组 ────────── 云平台层,在服务器外面 │ 没放行 → 连接超时 │ ├─ ② 系统防火墙 ────── 操作系统层,在服务器里面 │ ...

一、先建立一个正确的排查顺序

一个请求从你的浏览器到服务器上的进程,要穿过三道关卡。任何一道没过,你都看不到页面。

你的浏览器
    │
    ├─ ① 安全组 ────────── 云平台层,在服务器外面
    │                      没放行 → 连接超时
    │
    ├─ ② 系统防火墙 ────── 操作系统层,在服务器里面
    │                      没放行 → 连接被拒绝
    │
    └─ ③ 服务监听地址 ──── 进程层,网卡绑在哪
                           只听 127.0.0.1 → 外部连不上

三层必须按顺序查,从外到内。 反过来查会浪费大量时间——你会反复改 Nginx 配置,而问题其实在安全组。

判断该从哪层入手,最有效的方法是看失败的具体表现:

浏览器表现 大概率卡在
转了十几秒,最后「无法访问此网站」/ 连接超时 ① 安全组
立刻显示「连接被拒绝」 ② 防火墙,或 ③ 服务没启动
服务器上 curl 127.0.0.1:80 正常,外部不行 ① 或 ②
服务器上 curl 127.0.0.1:80 正常,但 curl 内网IP:80 不行 ③ 监听地址

这张表能省掉大部分瞎试。「超时」和「拒绝」是两种完全不同的信号:超时说明包被静默丢弃(安全组),拒绝说明包到了机器但被明确回绝(防火墙或没有进程监听)。

二、第一层:安全组

2.1 它是什么

安全组是云平台的虚拟防火墙,作用于实例的网卡,在操作系统之前生效。也就是说,即使你把服务器里的 firewalld 全关了,安全组不放行,外部一样进不来。

这是新手最容易忽略的一层,因为它是「云上的东西」,不在你登录后的那个系统里。

规则按方向分两类:

  • 入方向:别人访问你。默认是拒绝的。
  • 出方向:你访问别人。默认是允许的。

新建的云服务器,入方向通常是空的——意思是任何外部访问都不允许。所以刚装好的服务,除非你主动加规则,否则一定访问不了。

2.2 怎么加一条规则

两种入口,效果一样:

  • 从实例进:ECS 控制台 → 点进实例 → 「安全组」标签页 → 配置规则
  • 从 VPC 进:虚拟私有云控制台 → 访问控制 → 安全组 → 选中实例所属的安全组 → 入方向规则 → 添加规则

添加时要填四个字段:

字段 填什么 说明
优先级 1~100,数字越小越优先 没特殊要求就填 1
协议端口 TCP + 80(或直接写 80) 也可以写范围 8000-8010
源地址 0.0.0.0/0 表示允许所有 IPv4 来源
描述 自己看的备注,如「网站 HTTP」 以后回来看得懂

填完保存,规则立即生效,不需要重启服务器。

0.0.0.0/0 的含义是「任何来源」。对公开网站这是必要的,但要清楚它意味着整个互联网都能扫到这个端口。如果只是自己临时用,更安全的做法是填自己的公网 IP 加 /32,例如 1.2.3.4/32。

2.3 三个最容易错的地方

第一,ping 不通不等于服务器挂了。

ping 走的是 ICMP 协议,不是 TCP。安全组里如果没有 ICMP 规则,ping 一定不通,但网站在 80 端口上照样能访问。想验证网络通不通,别用 ping,直接测目标端口:

telnet 你的公网IP 80
# 或者
curl -I http://你的公网IP

第二,出方向规则不要随手删。

有人为了「安全」把出方向也设成拒绝,结果服务器连不上外网——apt install 装不了包、curl 拉不到东西、NTP 对不了时间,然后开始怀疑网络故障。出方向保持默认允许即可。

第三,注意 80 和 443 要分别放行。

只加了 443,用 http:// 访问依然不通。反过来只加 80,https:// 也不通。两个都要加。

2.4 快速验证是不是安全组的问题

用换端口法:把服务临时改到 8080 端口,安全组放行 8080,然后访问 http://IP:8080。

  • 8080 能通、80 不通 → 说明 80 被挡了(安全组没放行,或者域名未备案被拦截)
  • 两个都不通 → 说明问题不在端口,继续往下查防火墙和服务

这个方法的好处是不用改任何配置就能定位问题层次。

三、第二层:系统防火墙

安全组放行之后,包进到了机器里,接下来遇到的是操作系统自己的防火墙。

先看它到底开没开:

# CentOS / openEuler / 华为云 EulerOS
systemctl status firewalld

# Ubuntu / Debian
ufw status

firewalld 的临时与永久

这是最容易踩的坑。firewalld 有「运行时」和「永久」两套配置:

# 临时放行(立即生效,但 reload 或重启后消失)
firewall-cmd --add-port=80/tcp

# 永久放行(写进配置,需要 reload 才生效)
firewall-cmd --add-port=80/tcp --permanent
firewall-cmd --reload

# 查看当前生效的规则
firewall-cmd --list-all

只加 --permanent 不 reload,规则不会生效;只加临时规则不 --permanent,重启就丢。 两个坑都极其常见,表现都是「明明加了规则,还是不通」。

正确的做法永远是:--permanent + --reload 一起用。

ufw 的区别

ufw 简单一些,allow 就是永久的:

ufw status
ufw allow 80/tcp
ufw allow 443/tcp

改完立即生效,不用 reload。

一个务实的建议

如果你在排查阶段,可以临时关掉防火墙做验证,确认问题层次后再打开并精确放行:

systemctl stop firewalld    # 临时停止,重启后会恢复

但不要长期关着。关防火墙相当于把第二层防线整个撤掉,只剩安全组一层。

四、第三层:服务本身

安全组通了、防火墙放行了,还是访问不了,那就剩最后一个可能:服务没有监听在对外网卡上。

4.1 127.0.0.1 和 0.0.0.0 的区别

这是新手最常撞的墙,而且它的表现很有欺骗性——在服务器上 curl localhost 完全正常,所以你不会怀疑服务。

# 只允许本机访问:外部永远连不上
listen 127.0.0.1:80;

# 监听所有网卡:外部可以访问
listen 80;
# 等价于 listen 0.0.0.0:80;

同样的坑在其他语言里也有:

语言/框架 默认监听 要改成
Flask app.run() → 127.0.0.1 app.run(host='0.0.0.0')
Django runserver → 127.0.0.1 runserver 0.0.0.0:8000
Node/Express app.listen(3000) → 所有网卡 一般无需改
Spring Boot 默认所有网卡 一般无需改

判断方法就是看它到底听在哪。

4.2 一条命令看监听地址

ss -lntp | grep ':80'

输出大概是:

LISTEN 0  511  127.0.0.1:80  0.0.0.0:*  users:(("nginx",pid=1234,fd=6))

重点看 Local Address 那一列:

  • 127.0.0.1:80 → 只有本机能连,外部一定失败
  • 0.0.0.0:80 → 所有网卡都听,正常
  • 192.168.x.x:80 → 只听内网网卡,公网访问不了

如果这里没有输出,说明根本没有进程在监听这个端口,回到上一步确认服务是否真的启动了。

4.3 服务启动了却立刻退出

systemctl status 显示 active (running) 但几秒后变 failed,或者 activating 卡住,要看日志:

journalctl -u nginx -n 50 --no-pager

常见原因:端口被占用(Address already in use)、配置文件语法错误、证书文件路径不对导致启动失败。

查端口被谁占了:

ss -lntp | grep ':80'
# 或者
lsof -i :80

五、两个容易漏掉的前提

三层都排查过了还是不通,先别怀疑自己——有两件事在「三层」之外,但同样常见。

5.1 服务器根本没绑公网 IP

创建云服务器时如果没有勾选「分配弹性公网 IP」,这台机器就只有内网地址。你在控制台看到的那串 192.168.x.x 是内网 IP,在家里、在公司都访问不到——它只在同一个 VPC 内部有效。

判断方法很直接:打开实例列表,看「弹性公网 IP」这一列。空的就是没绑。

没绑也能补:在实例详情里绑定一个 EIP,或者在 VPC 控制台申请一个弹性公网 IP 再绑定到实例。绑完立刻可用,不用重启。

这里有个容易混淆的点:内网 IP 和公网 IP 是两套地址,服务只需要监听 0.0.0.0 就能同时接受两边访问,不需要为公网单独配置。

5.2 域名没备案,请求到不了服务器

如果你是用域名访问(而不是 IP),并且服务器在中国大陆,那么域名必须完成备案。没备案的域名,请求会在到达你的服务器之前就被拦掉。

这个现象特别好认:用 IP 访问正常,换成域名就超时。 因为 IP 直连不受备案约束,域名会。

遇到这种情况,不用再查安全组和防火墙了——问题在网络链路上游,跟你服务器里的任何配置都无关。备案的完整流程在另一篇里单独讲。

六、一张排查表

把上面三层压缩成一张表,下次遇到直接照着走:

现象 最可能的原因 一条命令验证
浏览器转圈后超时 安全组没放行 telnet IP 端口 看是否超时
立刻「连接被拒绝」 防火墙拦了,或服务没起 ss -lntp | grep :端口
本机 curl 通,外部不通 监听地址是 127.0.0.1 ss -lntp | grep :端口
内网 IP 通,公网 IP 不通 没绑弹性公网 IP 控制台看 EIP 列是否为空
加域名超时,用 IP 正常 域名未备案被拦 换 IP 访问看是否恢复
加了规则还是不通 firewalld 少了 --reload firewall-cmd --list-all
ping 不通但网站能开 安全组没放 ICMP 属正常现象,不用管
昨天能开今天不能 安全组被改 / 服务挂了 systemctl status + 安全组规则

七、小结

排查这类问题,靠的不是经验,是顺序。

从外到内三层:安全组 → 系统防火墙 → 服务监听地址。每层都有明确的判断方法,而且失败表现本身就在告诉你卡在哪一层——超时是安全组,拒绝是防火墙或缺进程,本机通外部不通是监听地址。

新手最常犯的错,不是不会配,而是顺序反了:一上来就怀疑代码、反复改配置、重装服务,把时间花在根本没出问题的地方。

下次再遇到「打不开」,先别动代码。打开终端,敲那条 ss -lntp | grep :80。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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