假设你在服务器上装好了Nginx,用systemctl start nginx启动后没有任何报错,systemctl status nginx也显示绿色的active (running)。但打开浏览器访问服务器公网IP或者域名,页面一直转圈最后提示连接超时。这时候你会不会怀疑Nginx装坏了?其实大部分情况下Nginx进程都在正常运行,问题出在网络链路的某一个环节。这篇文章带你一步步排查“启动成功但访问不到”的典型原因,建议新手从头到尾跟着操作一遍。

第一步:确认Nginx到底监听了哪个端口和地址
Nginx的配置文件里有一个关键指令叫listen,它决定了Nginx在哪个IP地址和端口上接收请求。很多Linux发行版自带的Nginx默认配置可能写成listen 80 default_server;,这表示监听所有IPv4地址的80端口。但有些系统里会出现listen [::]:80 default_server;,这个写法只监听IPv6地址。如果你通过IPv4访问服务器,自然连不上。
最直接的办法是用ss或者netstat命令查看实际监听情况。执行ss -tlnp | grep nginx,输出结果里会显示类似0.0.0.0:80或者[::]:80。如果只看到[::]:80,说明Nginx只绑定了IPv6,IPv4访问会被拒绝。解决办法是在配置文件的server块中同时添加两条listen指令:listen 80;和listen [::]:80;,然后执行nginx -t测试配置无误后nginx -s reload重载。
还有一种情况是端口被其他进程占用,Nginx启动时会报错,但有时用systemctl start启动时错误信息不会直接显示。可以用ss -tlnp | grep :80看看80端口是不是被Apache、Tomcat或者某个Docker容器占用了。如果端口冲突,要么停掉占用进程,要么改Nginx监听其他端口比如8080,同时记得防火墙和安全组也要同步放行新端口。
第二步:检查系统防火墙和云服务器安全组
服务器本地的防火墙是第二个高频故障点。CentOS 7/8使用firewalld,Ubuntu使用ufw。很多新手安装完Nginx后没有主动放行80端口,而firewalld默认策略是拒绝外部访问。在CentOS上可以执行firewall-cmd --list-all查看当前放行的端口和服务,如果ports和services里都没有80,就需要执行firewall-cmd --permanent --add-port=80/tcp然后firewall-cmd --reload。Ubuntu下用ufw status查看,执行ufw allow 80/tcp放行。
需要注意的是,即使本地防火墙放行了,云服务器还有一层平台侧的安全组。以阿里云、腾讯云、AWS为例,所有实例都默认绑定一个安全组,安全组是独立于操作系统防火墙的。你需要在云控制台找到对应实例的安全组规则,添加入方向规则:协议选择TCP,端口填写80(如果Nginx监听8080就填8080),授权对象一般填0.0.0.0/0表示对所有IP开放。很多开发者排查了半天服务器内部配置,最后发现是安全组没放行,教训深刻。
排查顺序建议从外到内:先确认云安全组有没有放行端口,再检查操作系统防火墙,最后看Nginx本身的监听地址。可以用telnet 服务器公网IP 80从本地测试连通性,如果连接失败,大概率是安全组或防火墙拦截;如果连接成功但页面无响应,才需要进一步检查Nginx配置。
第三步:配置文件语法错误和站点根目录权限
Nginx启动时如果配置文件有语法错误,systemctl start nginx会直接失败,但有些情况下语法错误不会导致启动失败,比如重复定义server_name或者location块写法不规范。这时Nginx进程虽然运行,但访问对应站点时可能返回404、403或者500错误,而不是打不开页面。所以任何时候修改完配置,都要先执行nginx -t做语法测试,看到syntax is ok和test is successful再执行nginx -s reload。
另一个容易被忽视的问题是站点根目录的权限。比如配置文件里写了root /home/user/www;,但Nginx运行用户通常是nginx或者www-data,而/home/user目录默认权限是750,其他用户没有读和执行权限。这样Nginx worker进程无法读取目录下的index.html文件,访问时会返回403 Forbidden。解决办法是确保从根目录开始的每一级目录都有o+x权限,或者把站点目录移动到/var/www并设置合适的属主。
排查权限问题可以查看Nginx错误日志,通常位于/var/log/nginx/error.log。执行tail -f /var/log/nginx/error.log然后重新访问页面,日志里会明确提示Permission denied、No such file or directory或者directory index of ... is forbidden。根据日志提示调整目录权限或者修正root路径即可。
第四步:SELinux策略拦截导致无法访问
在CentOS/RHEL系统上,SELinux默认处于Enforcing模式,它会严格限制进程对文件系统的访问。即使文件权限正确、防火墙放行,Nginx仍然可能因为SELinux上下文不对而无法读取站点文件。典型表现是访问页面返回403 Forbidden,错误日志里出现permission denied但文件权限明明没问题。
快速验证方法是临时把SELinux调成宽容模式:执行setenforce 0,然后重新访问页面。如果页面正常了,就说明是SELinux搞的鬼。不建议长期关闭SELinux,正确做法是设置正确的文件上下文类型。对于站点目录,应该设置成httpd_sys_content_t类型,执行semanage fcontext -a -t httpd_sys_content_t "/var/www/html(/.*)?"然后restorecon -Rv /var/www/html。如果没有semanage命令,需要先安装policycoreutils-python-utils包。
此外还要注意Nginx的worker进程是否有权限访问网络端口,SELinux的httpd_can_network_connect布尔值默认为off,当Nginx作为反向代理连接后端服务时可能会被拦截。如果只是提供静态文件不需要开启,但做负载均衡或代理时需要执行setsebool -P httpd_can_network_connect 1永久开启。
以上四个步骤覆盖了绝大多数“Nginx启动成功但页面访问不到”的场景。排查时按照从网络层到应用层的顺序:先看端口监听(Nginx自身),再看安全组和防火墙(网络链路),然后检查配置语法和文件权限(应用配置),最后处理SELinux(系统安全策略)。每完成一步都记得重新测试访问,避免同时改太多东西导致无法定位问题。新手最容易忽略的是云安全组和SELinux,这两个环节在本地虚拟机环境很少遇到,一上云就暴露出来。记住:服务状态是active running只代表进程活着,不代表对外可达,端口、防火墙、权限、SELinux任何一个环节卡住都会导致访问失败。