修复 Nginx 'Connection Refused' 错误:实用故障排除指南

通过检查服务状态、监听端口、防火墙、配置和上游服务,排除 Nginx 连接被拒绝的错误。

修复 Nginx 'Connection Refused' 错误:实用故障排除指南

当尝试访问 Nginx 后端服务时遇到 'Connection Refused' 错误是一种常见但令人沮丧的情况。与 'Timeout' 错误(暗示网络延迟或丢包)不同,'Connection Refused' 错误是明确的:操作系统立即拒绝了连接尝试,因为没有应用程序在指定的 IP 地址和端口上主动监听。

这种立即拒绝将问题定位到几个关键区域:服务已关闭、防火墙在本地阻止了流量,或者配置将流量引导至不存在的端口。本指南提供了一种系统性的四阶段方法,用于诊断和解决 'Connection Refused' 错误,确保您能够快速恢复服务连接。

第一阶段:检查 Nginx 服务器状态(主要监听器)

连接被拒绝的最基本原因是 Nginx 服务本身未运行或配置不当。

1. 验证 Nginx 服务状态

使用系统的服务管理器(通常是 systemd)确认 Nginx 是否处于活动状态并正在运行。此处失败是主要监听端口(通常是 80 或 443)上拒绝的直接原因。

sudo systemctl status nginx

预期输出(成功): 查找 Active: active (running)

可操作修复: 如果状态显示 inactivefailed,请尝试启动服务并检查日志以获取失败详情。

sudo systemctl start nginx
sudo journalctl -xe | grep nginx

2. 确认活动监听端口

使用 ss(套接字统计)或 netstat 工具验证 Nginx 是否实际绑定到预期的 IP 地址和端口(例如,0.0.0.0:80 或 127.0.0.1:8080)。

# 使用 ss(现代 Linux 发行版首选)
sudo ss -tuln | grep 80

# 使用 netstat
sudo netstat -tuln | grep 80

如果您没有看到与 Nginx 关联的进程(PID)下列出预期的端口(例如 :80:443),则意味着 Nginx 绑定失败,很可能是由于配置错误或其他服务已占用该端口。

提示: 如果其他服务占用了该端口,您必须停止该服务,或修改 Nginx 配置以监听其他可用端口。

第二阶段:防火墙和网络配置

如果 Nginx 正在运行并在本地监听,则连接被拒绝可能发生在服务外部,通常是由于防火墙规则阻止了入站流量。

1. 检查本地服务器防火墙

确保 Nginx 监听的端口(例如 80、443)已明确允许通过主机防火墙(UFW、firewalld 或 iptables)。

UFW 示例(Ubuntu/Debian)

sudo ufw status verbose
# 如果已关闭,请允许端口:
sudo ufw allow 'Nginx Full'
# 或具体地:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

Firewalld 示例(CentOS/RHEL)

sudo firewall-cmd --list-all
# 如果已关闭,请添加服务:
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

2. 验证云提供商安全组

如果您的服务器托管在云环境中(AWS EC2、Azure VM、GCP Compute Engine),连接被拒绝可能源于虚拟网络的安全层。

  • AWS 安全组 (SG): 检查关联的 SG,并确保入站规则允许来自源 IP 地址(通常为公共访问的 0.0.0.0/0)的端口 80 和 443 流量。
  • Azure 网络安全组 (NSG): 验证入站端口规则。

第三阶段:Nginx 配置验证

不正确的配置指令可能导致 Nginx 尝试监听不可用的端口或 IP,从而导致启动失败和随后的连接被拒绝。

1. 检查 listen 指令

检查您的主配置文件(通常是 /etc/nginx/nginx.conf)以及任何相关的服务器块(通常在 /etc/nginx/conf.d//etc/nginx/sites-enabled/ 中)。确保 listen 指令正确。

正确配置的 listen 块示例:

server {
    listen 80;
    listen [::]:80;
    server_name example.com;
    # ... 其他指令
}

如果 Nginx 配置为仅监听 127.0.0.1(本地主机),但您尝试使用公共 IP 访问它,则连接将被拒绝。

2. 运行配置语法检查

在重新启动 Nginx 之前,始终验证配置语法。解析错误将阻止服务启动,从而导致拒绝。

sudo nginx -t

如果测试失败,请修复识别出的错误,重新运行测试,然后重新加载或重新启动 Nginx。

sudo systemctl reload nginx

第四阶段:故障排除反向代理(上游)问题

如果 Nginx 在端口 80/443 上成功运行,但访问特定路径(/api/)导致 'Connection Refused',则问题出在 Nginx 和 后端服务(上游)之间。

在这种情况下,Nginx 接受了初始连接,但当它尝试代理请求时,与后端的连接被拒绝。错误日志将确认这一点。

1. 检查 Nginx 错误日志

在尝试失败连接后立即检查 Nginx 错误日志(通常是 /var/log/nginx/error.log)。查找与 proxy_pass 指令相关的消息,特别是提到连接错误的消息。

tail -f /var/log/nginx/error.log

您可能会看到类似以下条目:

[error] connect() failed (111: Connection refused) while connecting to upstream

2. 验证后端服务状态

这是代理场景中最常见的修复方法:后端应用程序(例如 Node.js、Python Gunicorn、Apache)已关闭或未在 Nginx 期望的位置监听。

可操作步骤:

a. 检查后端服务状态: 确认后端应用程序正在运行。

b. 验证后端监听端口: 在托管后端的服务器上使用 ss -tuln 确认应用程序正在监听 Nginx 的 proxy_pass 指令中指定的 IP/端口。

3. 直接测试后端连接

使用 curltelnet 从 Nginx 服务器测试到后端的连接,以隔离问题(远离 Nginx)。

假设您的 proxy_pass 设置为 http://127.0.0.1:8080

# 从 Nginx 服务器测试到后端端口的连接
curl -v http://127.0.0.1:8080

# 或使用 telnet
telnet 127.0.0.1 8080
  • 如果 curltelnet 失败: 后端服务肯定是问题所在(它未监听或其内部防火墙阻止了 127.0.0.1 访问)。
  • 如果 curltelnet 成功: 问题可能出在您的 proxy_pass 指令中的细微错误(例如,缺少分号、主机名解析不正确或协议不匹配——HTTP 与 HTTPS)。

常见的 proxy_pass 错误

确保 proxy_pass 中的 IP 地址与后端实际绑定的地址匹配。如果后端绑定到特定 IP(例如 192.168.1.10:8080),但 Nginx 使用 localhost:8080,则如果绑定是限制性的,连接将失败。

关键故障排除步骤的最终检查

  1. 系统检查: Nginx 是否正在运行(systemctl status nginx)?
  2. 端口检查: Nginx 是否在正确的 IP/端口上监听(ss -tuln)?
  3. 防火墙检查: 入站端口是否在主机防火墙(UFW、iptables)上打开?
  4. 配置检查: nginx -t 是否通过,并且 listen 指令是否正确?
  5. 代理检查(如果适用): 上游服务是否正在运行并在 proxy_pass 中定义的精确 IP/端口上监听?使用 curl 直接测试连接。

按顺序进行检查:监听器、端口、防火墙、配置,然后上游。该路径使您专注于连接被拒绝的确切位置。