修复 Nginx“连接被拒绝”错误:实用的故障排除指南

不要让“连接被拒绝”错误阻碍您的服务。本综合指南提供了专家级的、可操作的步骤,用于排除 Nginx 连接故障。了解如何系统地诊断常见原因,包括 Nginx 服务未激活、限制性的本地和云防火墙,以及配置错误的代理设置。我们详细介绍了基本命令——从检查服务状态和活动端口(使用 `ss`、`systemctl`)到验证代理连通性(使用 `curl`)——确保您能够快速查明根本原因并恢复完整的服务器功能。

62 浏览量

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

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

这种立即拒绝将问题指向几个关键领域:服务已停止、防火墙在本地阻止了流量,或者配置将流量导向了一个不存在的端口。本指南提供了一个系统的、分为四个阶段的方法来诊断和解决“Connection Refused”错误,确保您能够快速恢复服务连接。


阶段 1:检查 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(socket statistics)或 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 配置以监听不同的可用端口。

阶段 2:防火墙和网络配置

如果 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): 检查关联的安全组,并确保入站规则允许来自源 IP 地址(通常是 0.0.0.0/0 用于公共访问)的流量通过端口 80 和 443。
  • Azure 网络安全组 (NSG): 验证入站端口规则。

阶段 3: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;
    # ... other directives
}

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

2. 运行配置语法检查

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

sudo nginx -t

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

sudo systemctl reload nginx

阶段 4:排查反向代理(上游)问题

如果 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 直接测试连接。

通过遵循这一系统化的过程,您可以快速识别“Connection Refused”错误是由于服务停止、限制性防火墙还是配置错误的反向代理设置造成的,从而最大程度地减少停机时间并高效恢复访问。