服务器上程序已经跑起来了,浏览器却打不开页面,多半是端口没放行。第一次用阿里云 ECS 的人,很容易卡在这一步。这篇文章用一个真实的排查过程,把阿里云开放端口的思路和操作讲清楚。

一个常见的卡壳场景
小王在阿里云买了一台 Linux 服务器,用 Node.js 写了个小网站,监听 3000 端口。他在服务器上执行 curl localhost:3000,返回正常。但用自己电脑的浏览器输入公网 IP 加端口,页面一直转圈,最后超时。他先检查程序,没有问题;又看了系统防火墙,也是关闭的。最后问题出在阿里云控制台的安全组上,3000 端口根本没有放行。
这种情况很典型。云服务器的外部流量要先过云平台的安全组,进入系统后还要再过一次系统防火墙。两层都放行,外网才能访问。只配了其中一层,就会出现“程序明明在跑,外面就是连不上”的情况。
安全组是什么
安全组可以理解成挂在服务器外面的门卫。它按规则判断哪些入站流量可以进来,哪些直接挡在外面。大多数入站端口默认是关闭的,常见的只有 22(SSH)等少数端口。所以服务要对外提供访问,就得主动把对应端口加进规则里。
还有一点要注意:同一个安全组可以绑定多台实例。改一次规则,所有绑定它的服务器都会受影响。改之前最好先确认这个安全组还被哪些机器在用。
添加入方向规则的步骤
以 ECS 为例,流程大致如下:
- 登录阿里云控制台,进入“云服务器 ECS”,在左侧“网络与安全”下找到“安全组”。
- 点击目标安全组进入详情页,切换到“入方向”标签。
- 点击“手动添加”,填写端口范围。单个端口写成 3000/3000,一段端口可以写成 8000/8100。
- 授权对象填写允许访问的 IP 段,具体怎么填见下一节。
- 保存后,到服务器里检查系统防火墙是否也放行了这个端口。
第 5 步最容易被忽略。如果系统是 CentOS 或 Alibaba Cloud Linux 这类默认用 firewalld 的,可以执行 firewall-cmd –permanent –add-port=3000/tcp,再执行 firewall-cmd –reload 让它生效。如果是 Ubuntu 上的 ufw,执行 ufw allow 3000/tcp 即可。命令执行完,用 firewall-cmd –list-ports 或 ufw status 确认一下端口已经在列表里。
授权对象怎么填
不少人图省事,把授权对象直接填成 0.0.0.0/0,意思是全世界任何 IP 都能访问。给公开网站开放 80 或 443,这样做通常没问题。但如果开放的是 MySQL 的 3306 或 Redis 的 6379,风险就大了。这类端口一旦暴露在公网,很容易被扫描器盯上,遭到暴力破解,甚至中勒索病毒。
更稳妥的做法是只允许自己常用的出口 IP 访问。小王后来把 3000 端口的授权对象改成了办公室的公网 IP 段,调试没有影响,外人也进不来。如果你的 IP 经常变化,可以考虑先用 SSH 隧道做中转,把服务端口留在本机访问,而不是图方便全部放开。
端口开了还是不通怎么办
按下面的顺序排查,通常能很快找到原因。
- 先确认程序在监听哪个地址。在服务器上执行 ss -tlnp,如果本地地址显示为 127.0.0.1:3000,说明服务只接受本机连接,外部访问不到。把监听地址改成 0.0.0.0,或者干脆不指定主机,让程序监听所有网卡。
- 再检查安全组规则。协议、端口和授权对象三项都要对得上,尤其要注意授权的 IP 段有没有写错。改完规则后一般很快生效,如果还不通,稍等片刻再测。
- 最后检查系统防火墙,以及宝塔之类面板自带的拦截规则。面板里的防火墙和系统防火墙是两套,很容易只改了一个。
从自己电脑测试时,可以用 curl -I http://公网IP:3000 看有没有响应,也可以用 nc -vz 公网IP 3000 直接判断端口是否连通。连接被拒绝,一般是程序没在监听;一直超时,多半是安全组或防火墙在拦。两种现象指向的排查方向不同,分开看能省不少时间。
小王最后卡在第一条。他的 Node.js 代码写的是 app.listen(3000, ‘127.0.0.1’),只允许本机访问。改成不指定主机,或者指定 0.0.0.0 之后,外网才真正能访问。
小结
阿里云开放端口要做两件事:在安全组里添加入方向规则,在服务器系统防火墙里也放行。授权对象尽量收窄,数据库之类的敏感端口不要直接暴露在公网。动手前先想清楚哪些人需要访问,再去配置规则,既省事,也更安全。