☰
Nginx域名访问后台管理系统实战:从IP端口到HTTPS反向代理
2026/10/13 1:15:54 网站建设 项目流程

如果你也正在给后台管理系统做访问入口改造,想把原来那串"IP:端口"换成好记的域名,那么这篇文章就是围绕"使用域名访问后台管理系统(Nginx)"的一份实战记录。我这次改造的背景很简单:后台系统一直挂在 192.168.x.x:8080 上,开发同学自己随手能背出来,但每次换环境、加新人、问题排查都要重新翻文档;更麻烦的是,登录密码还是明文走HTTP,心里始终不踏实。后来我用一个后台管理域名把入口收口到Nginx,再配上HTTPS,整个访问体验和安全性都上了个台阶。

这篇文章适合正在部署后台系统的开发、运维,也适合第一次碰Nginx但想把事情做规范的同学。我尽量不堆配置,而是把链路拆开讲,说清楚每一步为什么这样选、不这么做会遇到什么坑。下面所有配置都是可以直接复制改一改就能用的。

1. 为什么后台管理系统一定要走域名而不是裸IP加端口

1.1 裸IP加端口在真实业务里的三种痛点

先说说我一直坚持让后台管理系统走域名的原因。最直接的一个问题就是记忆和分享成本。IP 加端口这种东西本质上是给机器看的,不是给人看的。一个人面对一台服务器的时候还好,一旦后台系统要交接、要给别人开权限、要让财务或者运营也进去看数据,那串 192.168.x.x:8080 就会被复制到各种地方,多一个字符少一个字符都看不出来,出了问题你都不知道访问的到底是不是那个环境。

第二个痛点是端口会越开越多。今天上一个监控系统占 8080,明天内部工具占 9090,后天日志平台又占 5601。时间一长,服务器上到底开了哪些端口、哪个端口对应哪个系统,全靠一张快过期的 Excel 表。而且端口全部暴露在防火墙上,外部扫描一眼就能看到你在跑什么服务,安全上也不体面。

第三个痛点是IP一旦变化,所有入口跟着失效。后端服务换个机器、机房迁移、IP重新规划,这些都是说不准哪天就来的事。如果业务方只记住了 IP:端口,环境一变就彻底找不到入口。域名则把"用户访问的地址"和"后端真实地址"彻底解耦,IP 变了,域名不动,Nginx 里改一行转发目标就恢复。

1.2 域名访问给后台管理带来的四个便利

域名带来的便利不是锦上添花,而是实打实的管理收益。首先是可读性。admin.你的域名 和 192.168.x.x:8080 放在一起,谁更容易被记住、更不容易被写错,一目了然。给新人发链接的时候,也不用再反复叮嘱"前面还有一段是 http://"。

其次是可以用 server_name 做二级域名分流。你完全可以把订单后台、用户后台、运维平台分别挂到不同的子域名下,Nginx 根据域名把请求分发到不同后端。这样所有入口都收口在同一个公网IP上,只开放 80/443 两个端口,后台端口不再暴露,维护面也小很多。

再者是后端迁移对使用者完全透明。后端应用从物理机换到容器、从 A 机器换到 B 机器,只要把 Nginx 的 proxy_pass 改一下并 reload,用户访问的域名还是那个,收藏夹里的地址也不会失效。这个迁移成本几乎是零。

最后是让上 HTTPS 成为顺理成章的事。证书绑定的是域名,不是IP,没有域名你连正规证书都申请不了。后台管理系统承载的是账号密码和管理操作,这类系统在公网上裸奔HTTP,风险确实有点高。

1.3 什么时候可以暂时不折腾域名

当然,也有一种情况暂时可以不折腾:系统只在你的笔记本上本地跑,或者在一个完全封闭的内网里,只有你一个人用,IP 也长期不变。这种情况折腾域名确实收益不大。但只要系统要交给别人用,或者要放到公网服务器上,我建议还是别偷懒,域名加Nginx这套组合早配早省心。

2. 把"域名访问后台系统"整条链路拆开看

2.1 浏览器输入域名之后发生了什么

想配置不出错,先得在脑子里建立一条完整的请求链路。假设你在浏览器地址栏输入 admin.example.com,整个过程是这样的:首先浏览器向DNS服务器查询 admin.example.com 对应哪个IP;然后把HTTP请求发到这个IP的 80 或 443 端口;服务器上Nginx收到请求后,根据请求头里的 Host 字段去匹配配置好的 server_name;匹配成功后,Nginx 作为反向代理把请求转发给实际运行后台服务的端口;后端处理完返回响应,Nginx 再原样带回给浏览器。

这条链路里最关键的一个认知变化是:从用户的角度看,后台系统的地址变成了域名,浏览器永远只和 Nginx 建立连接;而你的后端应用可以安心地监听在 127.0.0.1 上,外部完全碰不到它。原来直接暴露在公网上的 8080 端口,相当于从入口链路上消失了。

2.2 端口规划与监听地址:我给这次改造画的表

动手之前,建议先把规划写清楚,避免临时东改一处西改一处。下面是我这次改造用的规划,你可以照着替换成自己的实际地址:

角色地址与端口说明
DNS A记录admin.example.com -> 服务器公网IP负责把域名解析到服务器
Nginx监听0.0.0.0:80 / 0.0.0.0:443对外只暴露这两个端口
后端应用监听127.0.0.1:8080仅有Nginx能访问,外部不可达
前端静态资源/data/www/admin前后端分离时由Nginx直接读取
HTTPS证书/etc/nginx/cert/admin.example.com.pem证书私钥存放在服务器指定目录

这里特别提醒一下监听地址。很多后台服务默认监听 0.0.0.0,也就是所有网卡都可达。如果它监听在 127.0.0.1,只有本机Nginx能转发到它,跳到公网的安全风险直接小一截。如果后端和Nginx不在同一台机器,那就监听在内网网卡地址,并确认防火墙只允许Nginx所在机器访问。

2.3 理解 proxy_pass 的路径拼接规则

Nginx新手最常见的配置困惑就是 proxy_pass 后面到底要不要带斜杠。这直接决定了转发给后端时路径是原样还是被改写。当 proxy_pass 后面不带 URI 时,比如 proxy_pass http://127.0.0.1:8080;,Nginx 会把原始请求的完整URI原样转发给后端,例如请求 /api/user 转给后端还是 /api/user。

当 proxy_pass 后面带了路径或斜杠时,情况就变了,例如 proxy_pass http://127.0.0.1:8080/;,Nginx 会把 location 匹配到的前缀拿掉,再把剩余部分拼到代理地址后面。假设 location 是 /api/,请求来了 /api/user,转发给后端的实际路径就成了 /user。这个特性常常被用来做前缀剥离,比如前端只认识 /api,后端接口却是 /v1/user。用错的话,后端会返回一堆 404,页面白屏,你还以为是后端挂了。

3. 第一个能直接复用的Nginx配置:先跑通HTTP域名访问

3.1 动手前先确认三件事

配置Nginx之前,别急着写文件,先把环境摸清楚。第一,确认后端服务已经正常监听在 127.0.0.1:8080。在服务器上执行 ss -lntp | grep 8080,能看到 LISTEN 状态基本就没问题;再执行 curl http://127.0.0.1:8080,如果后端有响应,说明可以进入下一步。第二,确认Nginx已经安装并且正在运行,执行 nginx -v 看版本,执行 systemctl status nginx 看运行状态。第三,登录你的域名管理控制台,先把 A 记录加上,指向这台服务器的公网IP,TTL 可以设短一点,比如 600 秒,方便测试期调整。

这一步很多新手会跳过,结果配置写完发现后端其实监听在别的端口,白白排查半天。我自己的习惯是先用 curl 验证后端通,再动Nginx,顺序永远别反。

3.2 最基础的 server 块,以及每行配置的含义

先给一个最简配置,目标是把 HTTP 跑通:

server { listen 80; server_name admin.example.com; location / { proxy_pass http://127.0.0.1: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; } }

这段配置里,listen 80 表示Nginx监听80端口,接收 HTTP 请求;server_name admin.example.com 告诉Nginx,只有当请求头里的 Host 是这个域名时,才走这个 server 块。这也是同一台服务器上放多个域名的基础,Nginx 靠它区分站点。

关键在下面四行 proxy_set_header。Host $host 是把浏览器请求里的域名透传给后端。很多后端框架会拿 Host 去生成绝对链接,如果不传,后端看到的 Host 可能就是 127.0.0.1:8080,生成的跳转地址、重置密码链接、Cookie 作用域全都会错。X-Real-IP 和 X-Forwarded-For 是为了让后端知道真实访客IP,不然日志里全是 127.0.0.1,你根本无法分辨谁在访问。X-Forwarded-Proto 则是告诉后端用户用的是 HTTP 还是 HTTPS,后面配 HTTPS 时尤其重要。

3.3 加域名解析:A记录与本地 hosts 速验

配置写好后,去域名控制台添加 A 记录,主机记录填 admin,记录值填服务器公网IP。添加后可以通过 nslookup admin.example.com 或在线DNS工具确认解析是否生效。如果当前还没有域名,或者想绕过DNS立刻测试,可以改本地 hosts 文件,在 /etc/hosts(Windows 是 C:\Windows\System32\drivers\etc\hosts)里加一行:

服务器公网IP admin.example.com

提示:hosts 只对当前设备生效,适合测试Nginx配置用。域名在多个客户端都能访问,最终还是要靠 DNS 解析。

加完 hosts 后,打开浏览器访问 http://admin.example.com,如果能看到后台登录页,说明 Nginx 这一层已经通了。

3.4 前后端分离时的静态资源与 history 路由处理

刚才的配置能跑通后台系统,但如果你的后台是前后端分离的项目,一般不建议让后端应用同时承担静态文件响应,更合理的做法是让 Nginx 直接读前端构建产物,接口再反代给后端接口服务。配置可以这样写:

server { listen 80; server_name admin.example.com; root /data/www/admin; index index.html; location /api/ { proxy_pass http://127.0.0.1:8080/; } location / { try_files $uri $uri/ /index.html; } }

root 指向前端打包后的目录,比如 Vue 或同类框架构建出来的 dist 上传到 /data/www/admin。location /api/ 这段把接口请求转发给后端,注意我用的 proxy_pass 带了尾部斜杠,意思是把 /api/ 前缀剥掉再转发,这样后端就不用额外加一层 /api 前缀。如果后端本来就有 /api 前缀,那就不要带斜杠,写成 proxy_pass http://127.0.0.1:8080;。

最后那行 try_files 也很关键。现代前端框架多数是 history 路由,访问后台某个子页面时,URL 是 /user/list 这种真实路径,但服务器上并不存在这个文件。try_files 的作用是先找真实文件,找不到就回退到 /index.html,把路由控制权交回前端框架。不写这行,你一刷新子页面就 404。这个坑我见过太多次了。

3.5 nginx -t 与平滑重载

配置文件写完后,别直接 restart,先检查语法:

nginx -t

只要输出显示 syntax is ok 和 test is successful,就可以平滑重载:

systemctl reload nginx

nginx -s reload 也能达到同样效果。注意 reload 和 restart 的区别:reload 是让Nginx重新读配置,已经建立的连接继续走旧配置,新连接走新配置,对正在使用的用户影响极小;restart 则会瞬间断开所有连接。后台管理系统虽然用户量不大,但养成用 reload 的习惯没有坏处。

4. 从HTTP升级到HTTPS:证书申请与Nginx配置要点

4.1 后台管理系统的密码不该在链路上裸奔

如果后台管理域名要面向公网,那 HTTPS 基本是必须的。原因很简单,登录时输入的账号密码如果走 HTTP,就是明文在网络上传输,中间任何一个环节被截获都能直接看到。尤其后台管理系统的账号通常权限高,一旦被拿到,后果不是开玩笑的。

另外,现代浏览器对非 HTTPS 页面会直接标"不安全",对用户心理也有负面影响。免费证书已经很成熟,给一个后台管理子域名申请证书的成本几乎为零,实在没有理由不走 HTTPS。

4.2 免费证书申请与放置流程

证书申请的大致流程是:在证书服务商处申请一张 DV 域名证书,绑定 admin.example.com,然后通过 DNS 添加一条 TXT 记录,或者在你的网站根目录放一个验证文件,用来证明你确实拥有这个域名。验证通过后,你会拿到两个文件:一个是证书文件(通常以 .pem 或 .crt 结尾),一个是私钥文件(以 .key 结尾)。

拿到文件后,放到统一目录,比如 /etc/nginx/cert/ 下面,然后收紧权限:

mkdir -p /etc/nginx/cert chmod 600 /etc/nginx/cert/admin.example.com.key

注意:私钥文件等同于密码,别传到代码仓库,别共享到群里,服务器上建议限制只有 root 能读。漏私钥等于前面所有安全措施白做。

4.3 HTTPS server 配置与 HTTP 自动跳转

证书文件放好后,在同一个 server 配置里加一组 HTTPS 监听:

server { listen 443 ssl; server_name admin.example.com; ssl_certificate /etc/nginx/cert/admin.example.com.pem; ssl_certificate_key /etc/nginx/cert/admin.example.com.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; location / { proxy_pass http://127.0.0.1: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; } }

如果希望用户访问 http://admin.example.com 时自动跳到 https,不用加额外页面,单独写一个 80 端口的 server 块做跳转:

server { listen 80; server_name admin.example.com; return 301 https://$host$request_uri; }

这里有一点我要特别提醒:regarding HSTS 响应头,也就是 Strict-Transport-Security。它告诉浏览器"以后这个域名只能用 HTTPS",一旦下发,浏览器会在你设定的时间范围内强制走 HTTPS。这个头很有用,但如果你的证书续期流程还不稳定,或者还在频繁回滚 HTTP,我建议先不要加,或者把 max-age 设得短一些,比如 3600,等稳定了再加长。否则证书到期没续上,用户浏览器还会强行 HTTPS,连降级访问的机会都没有。

4.4 证书续期与自动化:别等过期那天

DV 证书有效期通常只有三个月,到期没续真的会有人打电话问你系统怎么打不开了。建议直接配自动续期。现在主流 ACME 客户端都支持签发免费证书,并且可以通过 crontab 定时任务自动续期。大致思路是:每月定时执行一次续期命令,续期成功后执行 nginx -s reload 让新证书生效:

0 3 1 * * /usr/bin/某acme客户端续期命令 --renew-hook "nginx -s reload"

这句话的意思是每月的凌晨3点执行一次续期检查,续期成功就重载Nginx。具体命令以你用的工具为准,但套路就是这样。配好自动续期后,平时基本可以不用管证书,偶尔瞄一眼到期时间就行。

5. 从IP切到域名后必踩的坑:Cookie、跨域与WebSocket

5.1 登录失效的元凶:Cookie 的 Domain 和 SameSite

我这次改造遇到的最棘手问题,不是Nginx配置,而是切到域名后登录状态保不住。现象是登录跳转成功,但刷新一下又回到登录页,看了后台日志发现用户确实认证通过了,但浏览器并没有把登录凭证保存下来。

排查后发现原因是后端在返回 Set-Cookie 时,Cookie 的 Domain 被写死成了旧IP。浏览器接收到一个和当前域名不匹配的 Cookie,会直接拒绝存储。解决办法是改后端配置,把 Cookie 的 Domain 改成空,让它跟随当前请求域名生成;或者改成 admin.example.com。如果后端不方便改,也可以看下应用框架有没有类似"信任代理"的开关,开启后 Cookie 会按请求里的 Host 生成。

另一个容易忽略的是 SameSite 属性。很多后台系统会被嵌入到内部办公平台里用 iframe 打开,如果 Cookie 的 SameSite 是比较严格的模式,在跨站 iframe 场景下 Cookie 可能不会携带,导致登录失效。这种问题不一定和域名切换直接相关,但切域名后更容易被暴露出来。遇到这种场景,需要检查后端 Set-Cookie 的 SameSite 设置,必要时改成兼容方式。

5.2 同域代理是最省心的跨域方案

在域名改造前,前端页面可能部署在一个域名,接口服务在另一个IP上,开发调试时天天遇到跨域报错。切到域名并由 Nginx 反代之后,前端页面和接口路径天然同域,跨域问题直接消失。这也是我坚持让接口和前端共用同一个域名的原因。

但在某些场景下,后端接口可能还要给别的系统用,比如从另一个管理平台通过接口拉数据,这时就会涉及 CORS。Nginx 侧加响应头也能处理:

add_header Access-Control-Allow-Origin "https://other.example.com" always;

不过我要提醒一句:如果后端应用本身也配置了 CORS,两层都加会造成响应头重复或者冲突。最好确认一下策略边界,Nginx 管好域名层,应用层该管业务就管业务,别两个地方都写。最省心的原则仍然是一个域名,同域访问,不加跨域头。

5.3 WebSocket 连接在反向代理下的升级配置

后台管理系统里如果带有实时告警、在线日志查看、流水推送这类功能,通常会有 WebSocket 长连接。Nginx 默认的 HTTP 代理配置不会自动处理协议升级,你会发现页面能打开,但实时推送一直连不上。

需要在 location 里加上协议升级的头:

location /ws/ { proxy_pass http://127.0.0.1:8080; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 3600s; }

这里解释一下原理:WebSocket 连接建立前,客户端会通过 HTTP 请求头里的 Upgrade 字段发起协议切换;Nginx 要原样把这个请求透传给后端,就必须关掉默认的 proxy_http_version 1.0,改用 1.1,并显式传递 Upgrade 和 Connection 头。最后那行 proxy_read_timeout 也很重要,默认 60 秒没有数据就会被判定超时断开,长连接场景下建议拉长时间,否则日志看一会儿就断线。

5.4 页面白屏、接口 404:排查"写死IP和端口"的埋雷

域名改造最隐蔽的坑,是前端代码或者后端配置里把之前的 IP:端口写死了。常见情况有两种:一种是前端代码的接口地址写的是 http://192.168.x.x:8080/api,无论你在地址栏输入哪个域名,页面加载后真正发请求的还是那个IP,一旦IP访问权限收紧,接口立刻全挂,表现就是页面白屏,控制台一片红。

另一种是后端生成的回调链接写死了IP,常见于重置密码邮件、单点登录回调、文件下载地址等。这类问题的排查顺序我建议是:先在浏览器 F12 的 Network 面板看请求发到哪个地址,然后在前端源码里全局搜索之前的IP串。全部改成相对路径或者根据当前请求域名动态拼接,才是根治方案。

5.5 重定向循环和"请求被重定向到 http"

还有一个很不起眼但很折磨人的问题:用户访问 https 域名后,登录成功,后端却把请求重定向到 http 地址,浏览器又强制跳回 https,来回几次直接报重定向次数过多。根因是后端不知道自己其实是在 HTTPS 后面。它看到请求是 HTTP 就认为不安全,于是生成一个跳转让它换成 HTTPS,可实际上浏览器已经在用 HTTPS 了。

解决方式就在前面反复提到的 X-Forwarded-Proto $scheme。只要 Nginx 把原始协议传给后端,后端再配合框架的"信任代理"相关开关,就能正确识别用户使用的是 HTTPS。需要注意的是,信任代理接口有安全边界,不要无条件信任外部传入的 X-Forwarded-* 头,只要保证只有 Nginx 能直连后端端口即可。

6. 切换前后的验证清单与回滚预案

6.1 先验证 Nginx 转发,再动客户端

我习惯在浏览器配置之前,先用命令行把链路验证完整。验证分三层。第一层验证 Nginx 对域名的匹配是否正常,在服务器本机执行:

curl -H "Host: admin.example.com" http://127.0.0.1/

这一步不会真的走 DNS,而是手动指定 Host,直接打到 Nginx 上。如果返回的是后台页面内容,说明 server_name 匹配成功。如果返回的是默认站点页面,说明你的 server 块没生效,多半是配置没加载或 server_name 写错。

第二层验证域名解析和公网链路:

curl -I http://admin.example.com curl -kI https://admin.example.com

curl -k 的意思是跳过证书校验,用来确认证书路径放好后 HTTPS 端口能不能正常响应。如果看到 HTTP/1.1 301 这样的返回,说明跳转配置起了作用;如果直接 200,说明服务正常。第三层验证转发是否到达后端,打开Nginx访问日志 tail -f /var/log/nginx/access.log,再访问一次域名,能看到对应请求记录就说明整条链路完整。

6.2 浏览器与客户端侧检查清单

命令行验证通过后,一定要在真实浏览器里走一遍完整流程。我建议用无痕窗口,避免旧 Cookie 干扰。清单大致是这样:

  • 打开 https://admin.example.com,确认地址栏不出现"不安全"警告。
  • 输入用户名密码登录,确认登录成功后刷新页面,登录态还在。
  • 按 F12 打开 Network 面板,确认页面所有请求都是 https 开头,且 API 请求域名一致。
  • 检查控制台有没有被浏览器拦截的混合内容,比如 HTTPS 页面里加载了 HTTP 资源。
  • 换个网络环境,或者用手机连一下,确认 DNS 解析对所有人都生效,而不只是你本机。
  • 如果有 WebSocket 功能,打开对应页面确认连接状态是已连接,并且能收到实时推送。

其中混合内容拦截要重点留意。有些页面看起来一切正常,但某些图标、字体或附件下载地址还是 http,浏览器会直接拦截,表现就是资源加载不出来。这个在切换时最容易被漏掉。

6.3 回滚预案:域名不可用时怎样快速恢复入口

计划再好也要有退路。我强烈建议:域名切换初期,别急着把原来的 IP:端口 访问方式关掉,防火墙端口也先保留。等域名方案跑稳了,比如连续几天无人报障,再逐步收紧暴露面。这不是拖泥带水,而是给自己的容错空间。

Nginx 配置层面的回滚,最稳妥的办法是用独立配置文件。每个站点一个文件,比如 /etc/nginx/conf.d/admin.example.com.conf,改之前先复制一份备份:

cp /etc/nginx/conf.d/admin.example.com.conf /etc/nginx/conf.d/admin.example.com.conf.bak

配置出了问题,直接执行 nginx -t 检查,再根据情况回滚:

cp /etc/nginx/conf.d/admin.example.com.conf.bak /etc/nginx/conf.d/admin.example.com.conf nginx -t && systemctl reload nginx

如果问题出在 DNS 还没生效,而你又在赶时间,可以在需要访问的机器上临时加 hosts 记录,跳过 DNS 直接解析到目标服务器。证书如果暂时有问题,则先把 80 跳到 443 的那段配置注释掉,回退到 HTTP 先恢复业务,等证书处理好再切回去。记住,回滚要快、要简单,不要在用户已经报障的时候还做复杂的验证。

这次改造下来,我最大的体会是:Nginx 的配置本身并不算复杂,真正花时间的,是让后端应用感知到"环境变了"。Cookie 的域名、回调地址、重定向协议判断,这些问题每一个都足以让域名切换看起来像是个大型翻车现场。最后分享一个习惯:把每个站点的 Nginx 配置独立拆成一个文件,命名带域名,改之前先备份,再小的改动也走"检查、备份、写入、reload"这套流程。靠这个习惯,我在好几次手滑的时候都只用几十秒就完成了回滚,希望你也能用上。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询