最近在折腾家里那台NAS的时候,被几个问题轮番折腾到半夜:想统一用域名和HTTPS访问各类服务,结果有的服务是HTTP、有的要WebSocket长连接,还有几个套件的路径映射怎么配都别扭。折腾完这一圈,最大的感受是,Nginx反向代理这块属于典型的“配一次、能跑好几年”的活,但前提是第一次就得把原理和细节搞清楚,不然日后每加一个服务就要重新踩一遍坑。
这篇文章就把我实测过的一套完整方案拆开讲透:包含HTTP强制跳HTTPS、WebSocket长连接穿透、NAS多服务转发,以及部署后怎么验证、怎么排查。文章里有完整可抄的配置,也有配置背后为什么要这么写的逻辑。不管你是刚接触Nginx的小白,还是已经在生产环境里跑Nginx的运维,只要你用Nginx代理过带WebSocket的服务、给NAS套件配过子路径,这篇文章里应该都有你用得上的东西。
1. 为什么要在前面加一层Nginx:三个不解决就反复踩坑的场景
先说点实在的。很多人一开始觉得反向代理是“大厂才需要的东西”,自己家里一台NAS、几个服务,直接IP加端口访问不就行了?理论上确实行,但只要你手里的服务超过三个,这套“原始方案”就会开始暴露问题,而且问题全是连续性的:端口记不住、HTTPS证书没法统一、服务地址一变就全乱套。
1.1 服务多了之后,端口号就是第一个失控的地方
假设你有一台群晖或者自己攒的飞牛NAS,上面跑着文件管理、下载工具、家庭相册、离线下载、监控面板,每个服务一个端口。今天要用下载工具,得记住8080是它;明天看监控,得记住9000是它。如果还有一台云服务器上挂着API服务,又是另一个IP加端口。这还只是“知道地址”的问题。
更麻烦的是,很多服务默认监听在HTTP上,直接把端口暴露到公网的话,等于把明文流量铺在网络上让人看。长期用下来,你还会遇到“某个服务不知道为什么就是连不上”的排查地狱:是端口冲突?是防火墙拦了?是服务进程挂了?没有统一入口的时候,每排查一个问题都要从头捋一遍网络链路。
反向代理解决的就是这一整层问题:所有外部请求统一打到Nginx的80/443端口,由Nginx按域名或路径把流量分发到内网不同服务的实际IP和端口上。对外你只需要记住一个入口地址,服务怎么变端口、怎么换机器,对内改动就行,外部无感。
1.2 HTTPS只在网关做一次,比每个服务各搞一套省心得多
第二个痛点来自HTTPS。现在越来越多场景要求强制HTTPS:有些API回调要求必须是HTTPS地址、PWA应用要求安全上下文、现代浏览器的很多高级特性也需要HTTPS才开放。如果直接访问NAS的HTTP端口,这些问题会一个接一个冒出来。
你可以给每个服务都单独配证书,但这种做法在现实里很难维持:证书续期要挨个处理,每个服务的监听端口还要改,内网服务之间互相调用时证书校验又是一堆破事。最常见的首选方案是在Nginx这一层统一终结HTTPS:证书只装一份在Nginx上,外部用HTTPS和Nginx通信,Nginx和内部服务之间走内网HTTP。这样证书的管理半径被压缩到一个入口里面,后续再加服务时不需要再动证书。
1.3 路径区分:一个入口访问多个应用
还有一类需求是“同一个域名下,用路径区分服务”。比如 https://my.domain.com/ 是NAS主界面,https://my.domain.com/download/ 是下载工具,https://my.domain.com/photos/ 是相册。Nginx通过location块来匹配不同的路径前缀,再把请求转发给不同的后端服务。
这种方式最典型的应用场景就是NAS:群晖的Web服务、套件中心里的各种套件,很多都希望挂在同一个反代域名下面。但路径转发恰恰是Nginx配置里最容易被忽略“末尾斜杠”差异的地方,一个斜杠的差别就能导致404或者页面样式全丢。这个我在第5章里会专门拆开说。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 先把最简反向代理跑通:从安装到第一份可用的server块
不管后面要做多复杂的配置,第一步永远是先让Nginx跑起来,并且能成功代理一个最简单的服务。
2.1 安装Nginx:发行版仓库里的就够用了
在Debian/Ubuntu系统上安装Nginx非常简单:
bash复制sudo apt update
sudo apt install -y nginx
安装完后,systemctl status nginx 看一下状态,默认配置文件在 /etc/nginx/nginx.conf,主配置文件里一般会引入 /etc/nginx/conf.d/*.conf 或者 /etc/nginx/sites-enabled/*(视发行版而定)。我习惯把每个站点独立成一个文件放在 conf.d 下面,比如 conf.d/reverse-proxy.conf,这样结构清晰,改一个服务不会影响其他配置。
CentOS/RHEL系统上用yum/dnf装也一样,路径略有差异,但核心配置语法一致。
提示:如果你用的系统自带Nginx版本太老(比如CentOS 7带的1.20左右),建议配一下Nginx官方源装新版,老版本对HTTP/2、WebSocket支持的默认参数有些跟不上,后续配起来总是差口气。
2.2 最小可用的server块配置
假设你的NAS内网IP是 192.168.1.100,Web界面跑在 5000 端口,现在想让外部通过 https://home.example.com 访问它。一个最基础的配置是这样:
nginx复制server {
listen 80;
server_name home.example.com;
location / {
proxy_pass http://192.168.1.100:5000;
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;
}
}
这段配置的核心就是这个 location / 块:所有匹配到的请求都会被Nginx转发给 http://192.168.1.100:5000。加上的三个proxy_set_header是常规操作,它们的作用是让后端服务知道原始的域名、客户端真实IP、以及原始请求是HTTP还是HTTPS。很多后端程序在生成链接时依赖这些头信息,不设置的话会出现页面里跳转到内网IP、或者误判为HTTP请求之类的问题。
写
