Nginx代理到内网网站,反向代理实战案例
当公网用户需要访问部署在内网服务器上的网站,而内网机器没有公网IP时,用Nginx做反向代理是最常见的做法。
本文以一个实际场景为例:公网Nginx服务器(1.2.3.4)接收请求,转发到内网Web服务器(192.168.1.100:8080),带你从零完成配置、排错和验证。
开始前的环境确认
操作前,请确保以下条件已满足:
- 一台可公网访问的服务器,已安装Nginx(本文以Nginx 1.20+为例,实际版本以
nginx -v输出为准)。 - 一台内网Web服务器,运行着你的网站,假设监听
192.168.1.100:8080。 - 公网服务器能ping通内网服务器,或者至少能通过内网IP和端口访问到Web服务。
- 拥有公网服务器的root或sudo权限。
先在公网服务器上测试连通性:
curl -I http://192.168.1.100:8080
如果返回HTTP/1.1 200 OK或类似成功状态,说明网络层没问题。
如果超时或被拒绝,请先检查防火墙、安全组或路由,这一步不通过,后面配置Nginx也没用。
配置Nginx反向代理
在公网服务器上,进入Nginx配置目录。
通常主配置文件是/etc/nginx/nginx.conf,站点配置可以放在/etc/nginx/conf.d/下。
新建一个配置文件,比如/etc/nginx/conf.d/proxy_internal.conf:
server {
listen 80;
server_name your-public-domain.com; # 替换为你的域名或公网IP
location / {
proxy_pass http://192.168.1.100:8080;
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;
}
}
关键参数说明:
proxy_pass:指定内网Web服务器的地址和端口,注意末尾不要多加斜杠,除非你有路径重写需求。proxy_set_header Host $host:把原始请求的Host头传给后端,避免后端生成错误的跳转链接。X-Real-IP和X-Forwarded-For:让后端能获取真实客户端IP,便于日志分析。
保存后,检查配置语法并重载Nginx:
nginx -t
systemctl reload nginx
如果nginx -t输出syntax is ok和test is successful,说明配置没问题。
容易踩坑的几个地方
即使配置看起来正确,实际运行中也可能遇到问题。
下面这几个坑最常见:
- 内网服务器防火墙未放行:公网服务器能ping通内网IP,但端口被防火墙拦截。在内网服务器上执行
iptables -L -n或firewall-cmd --list-all检查,确保8080端口允许来自公网服务器内网IP的访问。 - SELinux阻止Nginx发起网络连接:如果公网服务器是CentOS/RedHat,SELinux可能阻止Nginx连接后端。临时测试可执行
setenforce 0,但生产环境建议用setsebool -P httpd_can_network_connect 1放行。 - 后端返回502 Bad Gateway:通常是Nginx无法连接到
192.168.1.100:8080。回到第一步,在公网服务器上用curl或telnet 192.168.1.100 8080确认连通性。 - 页面能打开但样式丢失或跳转异常:检查后端网站是否使用了绝对路径(如
http://192.168.1.100:8080/style.css)。如果有,需要在Nginx里做sub_filter替换,或者修改后端配置使用相对路径。
另外,如果内网网站需要HTTPS,公网Nginx可以配置SSL证书,然后proxy_pass仍然用HTTP连内网,这样能减少内网服务器的证书管理负担。
验证代理是否生效
配置完成后,从公网客户端访问你的域名或公网IP:
curl -I http://your-public-domain.com
观察返回的HTTP状态码和响应头。
如果返回200 OK,并且页面内容与直接访问内网网站一致,说明反向代理成功。
还可以查看Nginx访问日志,确认请求被正确转发:
tail -f /var/log/nginx/access.log
日志中应该出现客户端公网IP、请求路径以及后端返回的状态码。
如果看到502、504等错误码,结合上文避坑部分逐项排查。
最后,在内网Web服务器上查看其访问日志,应该能看到来自公网Nginx服务器内网IP的请求记录,这进一步证明代理链路已打通。
常见疑问
问:内网网站有多个域名,怎么用同一个Nginx代理?
可以在同一个server块里配置多个server_name,或者为每个域名单独写server块,分别指向不同的后端。
问:代理后网站获取到的客户端IP都是Nginx服务器的内网IP,怎么办?
确保配置了proxy_set_header X-Real-IP $remote_addr;和X-Forwarded-For,然后后端程序需要从这些请求头中读取真实IP,而不是直接取REMOTE_ADDR。
问:Nginx代理到内网网站时,上传大文件失败怎么处理?
在location块中增加client_max_body_size 100m;(按需调整大小),并适当增加proxy_read_timeout和proxy_send_timeout的值。
按照以上步骤操作后,你应该已经成功用Nginx反向代理打通了公网到内网网站的访问。
如果遇到其他报错,优先检查网络连通性、防火墙规则和Nginx错误日志,大部分问题都能快速定位。