文章目录
- [Nginx 反向代理实战:解决 IPv6 报错与跨网段访问指南](#Nginx 反向代理实战:解决 IPv6 报错与跨网段访问指南)
-
- [📖 文档概述](#📖 文档概述)
- [🎯 核心目标](#🎯 核心目标)
- [🛠️ 实施步骤详解](#🛠️ 实施步骤详解)
-
- [第一步:修复 IPv6 解析报错](#第一步:修复 IPv6 解析报错)
- 第二步:配置反向代理 (Server Block)
- 第三步:验证与调试 (关键技巧)
- [第四步:DNS 解析与端口误区排查](#第四步:DNS 解析与端口误区排查)
-
- [1. DNS 解析设置](#1. DNS 解析设置)
- [2. ⚠️ 常见误区:端口号问题](#2. ⚠️ 常见误区:端口号问题)
- [🔍 故障排查清单 (Checklist)](#🔍 故障排查清单 (Checklist))
- [📚 核心知识总结](#📚 核心知识总结)
- [🚀 进阶建议](#🚀 进阶建议)
Nginx 反向代理实战:解决 IPv6 报错与跨网段访问指南
⚠️ 隐私提示:本文档中的所有 IP 地址、域名均为示例占位符。在实际部署时,请将其替换为您真实的配置信息,切勿直接将包含真实内网 IP 的配置文件截图发布到公共网络。
📖 文档概述
本文档记录了如何通过 Nginx 将公网域名请求代理到公司内部网络服务的完整过程。重点解决了 IPv6 解析导致的连接超时 问题,并详细阐述了 端口映射 与 DNS 解析 的核心原理。适用于需要将内网开发/测试环境暴露给公网访问的场景。
🎯 核心目标
- 场景 :用户通过公网域名(如
app.example.com)访问部署在公司内网的 Web 服务(如192.168.x.x:3000)。 - 架构 :
- 入口:云服务器(公网 IP,运行 Nginx)。
- 出口:公司内网服务器(内网 IP,运行实际业务)。
- 动作:Nginx 作为反向代理,转发请求并返回结果。
- 关键难点 :
- Nginx 默认尝试 IPv6 解析域名,若网络环境不支持 IPv6 会导致
connect() failed (101: Network is unreachable)。 - 用户容易混淆"代理端口"与"源服务端口",导致访问失败。
- Nginx 默认尝试 IPv6 解析域名,若网络环境不支持 IPv6 会导致
🛠️ 实施步骤详解
第一步:修复 IPv6 解析报错
在 CentOS/RHEL 等现代 Linux 发行版中,Nginx 默认可能优先尝试 IPv6 解析。如果服务器或上游网络不支持 IPv6,代理请求会失败。
解决方案 :在 nginx.conf 的 http 块中强制指定 DNS 解析器并关闭 IPv6。
配置文件路径 :/etc/nginx/nginx.conf
nginx
http {
# ... 其他配置 ...
# 【关键配置】指定 DNS 服务器并禁用 IPv6
# 语法:resolver <dns_ip> [ipv6=off];
# 建议替换为您所在区域稳定的公共 DNS (如 114.114.114.114 或 8.8.8.8)
resolver 114.114.114.114 8.8.8.8 ipv6=off;
# ... 其他配置 ...
include /etc/nginx/conf.d/*.conf;
}
操作命令:
bash
# 1. 测试配置语法
sudo nginx -t
# 2. 重载配置生效
sudo systemctl reload nginx
💡 知识点 :
ipv6=off参数告诉 Nginx 在解析域名时只获取 A 记录(IPv4),忽略 AAAA 记录(IPv6),从而避免不必要的网络尝试和超时。
第二步:配置反向代理 (Server Block)
创建独立的配置文件,将特定域名流量转发到内网 IP。
配置文件路径 :/etc/nginx/conf.d/<your-project>.conf
nginx
server {
listen 80;
# 替换为您的真实公网域名
server_name app.example.com;
location / {
# 替换为您的真实内网服务 IP 和端口
# 注意:此处填写的是 Nginx 能访问到的内网地址,不要写公网地址
proxy_pass http://<Inner_IP>:<Inner_Port>;
# 传递真实用户 IP 给后端(重要!否则后端日志全是 Nginx IP)
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 优化长连接支持(可选,针对 WebSocket 或大文件)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
操作命令:
bash
sudo nginx -t && sudo systemctl reload nginx
第三步:验证与调试 (关键技巧)
在修改 DNS 之前,先在服务器本地验证 Nginx 配置是否正确,避免外部干扰。
测试命令:
bash
# 模拟外部请求,强制指定 Host 头,访问本地 127.0.0.1 (即 Nginx 监听口)
# 请将 <your-domain.com> 替换为您的真实域名
curl -I -H "Host: app.example.com" http://127.0.0.1
结果分析:
- ✅ HTTP/1.1 200 OK:配置成功,Nginx 已成功从内网拉取数据。
- ❌ 502 Bad Gateway:Nginx 无法连接内网 IP(检查防火墙、路由、内网服务状态)。
- ❌ 404 Not Found :域名匹配错误,检查
server_name。
第四步:DNS 解析与端口误区排查
1. DNS 解析设置
确保域名服务商处,app.example.com 的 A 记录 指向 云服务器的公网 IP。
- 验证命令:
ping app.example.com - 预期结果:返回云服务器公网 IP。
2. ⚠️ 常见误区:端口号问题
- 错误做法 :访问
http://app.example.com:<Inner_Port>- 原因 :
:<Inner_Port>是内网服务的端口,云服务器通常未开放此端口,且 Nginx 也未监听此端口。
- 原因 :
- 正确做法 :访问
http://app.example.com(默认 80 端口)- 原理 :用户访问 80 端口 -> Nginx 接收 -> Nginx 内部 转发请求到内网的
<Inner_Port>端口 -> 返回结果给用户。用户无需知道内网端口。
- 原理 :用户访问 80 端口 -> Nginx 接收 -> Nginx 内部 转发请求到内网的
🔍 故障排查清单 (Checklist)
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| connect() failed (101: Network is unreachable) | Nginx 尝试 IPv6 连接 | 添加 resolver ... ipv6=off 配置 |
| 502 Bad Gateway | 云服务器无法连通内网 IP | 检查云服务器安全组出方向、公司防火墙、内网服务是否存活 |
| 404 Not Found | 域名不匹配 | 检查 server_name 拼写,确认 Host 头传递 |
| 页面空白/加载失败 | 前端资源路径错误 | 检查前端代码中 API 请求地址是否为相对路径,或配置了错误的绝对地址 |
| 访问 : 不通 | 端口概念混淆 | 去掉 URL 中的端口号,直接访问域名 |
📚 核心知识总结
-
反向代理 (Reverse Proxy):
- 充当"中间人",客户端只与 Nginx 交互,不知道后端真实存在。
- 好处:隐藏内网结构、统一入口、负载均衡、SSL 终止。
-
Resolver 指令:
- 当
proxy_pass使用域名而非 IP 时,Nginx 需要 DNS 解析。 - 在生产环境中,显式配置
resolver并关闭 IPv6 是最佳实践,能避免大量隐蔽的网络超时问题。
- 当
-
Host 头传递:
proxy_set_header Host $host;至关重要。如果不加,后端服务收到的 Host 可能是内网 IP,导致某些框架(如 Django, SpringBoot, Vite)拒绝服务或重定向错误。
-
端口映射逻辑:
- 外部端口 (80/443):面向公众,由 Nginx 监听。
- 内部端口 (3000/8080/5173):面向内网,由业务服务监听。
- 两者不需要一致,Nginx 负责桥接。
🚀 进阶建议
- 启用 HTTPS :使用 Let's Encrypt (
certbot) 免费证书,将 HTTP 强制跳转到 HTTPS,提升安全性。 - 日志监控 :定期检查
/var/log/nginx/error.log,监控upstream连接状态。 - 高可用 :如果内网服务有多台,可在
upstream块中配置多台服务器实现负载均衡。