服务器上的程序已经跑起来了,本地却打不开网站或接口,这种情况在阿里云上很常见。多数时候是端口没有放行。本文先说明外部请求会经过哪些关卡,再讲安全组怎么配,最后用两个案例演示排错顺序。

一、外部请求要过哪几道关
从公网进来的请求,通常依次经过下面几层。任何一层拦截,外部看到的现象都是连接超时或被拒绝,所以要逐层确认。
- 安全组:控制哪些IP可以访问哪些端口,多数问题出在这里。
- 网络ACL:实例在专有网络里,且子网配置了ACL时,子网层还会再过滤一次。
- 系统防火墙:Linux上常见的是firewalld和ufw,Windows上是Windows防火墙。装了防火墙却忘了放行端口,请求同样进不来。
- 应用的监听地址:程序只监听127.0.0.1时,只有服务器本机能连上。安全组配得再对,外部也访问不到。
二、在安全组中开放端口
进入阿里云控制台,依次打开“云服务器ECS”“网络与安全”“安全组”,找到实例绑定的安全组,在“入方向”页签点击“添加安全组规则”。表单里有五项需要填写:
- 授权策略:选“允许”。
- 协议类型:网站、SSH等服务用TCP。DNS和部分游戏、视频服务用UDP。协议选错,端口开了也不通。
- 端口范围:开放单个端口时填成80/80,连续多个端口时填成8000/8100这样的区间。
- 授权对象:填允许访问的IP或网段,例如办公网出口IP 203.0.113.10/32。
- 优先级:数值越小越先匹配,可选范围是1到100。多条规则互相冲突时,先看这个数字。
保存后规则一般不用重启实例就能生效。新建的安全组默认只允许同组实例之间互访,外部要用的端口必须手动添加规则。
如果网站前面挂了负载均衡SLB,还要在SLB的监听配置里加上对应端口。安全组只作用于后端ECS,对SLB的监听没有效果。只改安全组,通过SLB地址访问时依然会失败。
三、管理端口不要对全网开放
授权对象填0.0.0.0/0,意味着全网任何地址都能访问。网站的80和443这样开通常没有问题。但SSH的22、远程桌面的3389、MySQL的3306、Redis的6379如果也全网开放,风险很高。自动化扫描程序会持续尝试弱口令,数据库直接暴露在公网上最容易被盯上。
更稳妥的做法是:管理端口只允许运维人员的固定办公IP访问;数据库只允许同一专有网络里应用服务器的内网IP访问。开发人员需要远程调试数据库时,可以走SSH隧道,不必为此开放公网端口。
四、案例一:Node.js服务部署后访问超时
某团队在ECS上部署了一个内部接口,服务监听3000端口。在服务器上执行curl localhost:3000能拿到返回结果,但从本地浏览器访问公网IP加3000端口,一直超时。
排查分三步:
- 执行ss -tlnp | grep 3000查看监听地址。结果显示进程绑定在127.0.0.1:3000上,外部请求进不来。把代码中的监听地址改为0.0.0.0,让服务接受外部连接。
- 在安全组入方向添加TCP 3000规则,授权对象填办公网出口IP。
- 再从外部访问,返回正常。
这个案例里有两个独立的问题。只改安全组,服务仍然连不上。只改监听地址,请求仍会被安全组拦下。两处都要检查。
五、案例二:数据库端口遭到爆破尝试
某电商团队为了远程调试方便,把MySQL的3306端口在安全组中授权给0.0.0.0/0。几天后,数据库日志里出现大量登录失败记录,来源IP分散在多个国家。
团队随后做了三件事。第一,把3306的授权对象改成应用服务器所在的内网网段。第二,为数据库账号设置强密码,并只授予必要的权限。第三,开发人员改用SSH隧道连接数据库调试。端口只向确实需要它的地址开放。服务只在内网使用时,就不该开到公网。
六、排错清单
按下面顺序检查,大部分问题可以很快定位。
- 确认服务的监听地址:在服务器上执行ss -tlnp,看端口绑定的是0.0.0.0还是127.0.0.1。
- 检查系统防火墙:用ufw的同学执行sudo ufw status,用firewalld的同学执行firewall-cmd –list-all,确认端口已放行。
- 从外部测试TCP连通性:在本地执行telnet 公网IP 端口,或nc -vz 公网IP 端口。连通时显示Connected。超时通常说明被安全组或防火墙拦截;连接被直接拒绝,多半是服务没有在该端口监听。
- 逐条核对安全组规则:检查协议、端口范围和授权对象。IP最容易填错,比如漏写/32,或把网段写反。
- 确认出口IP没有变化:办公网或家庭宽带如果是动态IP,IP一变,原来的白名单就失效,表现为突然连不上。