65、【Ubuntu】【Gitlab】拉出内网 Web 服务:Gitlab 配置审视(九)

【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除

背景

上篇 blog
【Ubuntu】【Gitlab】拉出内网 Web 服务:Gitlab 配置审视(八)

分析了安全的 default_server 配置,然后继续分析了 server 块中的 location 配置项,下面继续

Nginx 配置审视

上篇 blog 分析到了配置项 proxy_set_header Host $host; 的作用是把原始请求的 Host 头传递给后端服务,很多 Web 框架会检查 Host 头来生成绝对 URL(重定向场景)

下面就这个重定向场景再详细展开分析下,比如用户登录后的重定向,假设系统架构如下

  • 用户在浏览器输入 http://192.168.1.100/login
  • Nginx 监听 80 端口,并反向代理到 http://localhost:8080
  • 后端是个 Web 应用

登录时,用户提交用户名和密码,后端验证成功后,想把用户重定向到首页 /dashboard,那么问题来了,后端该怎么写这个重定向响应?按照有没有 Host 头划分,有两种情况:

  • 第一种,没 Host 头 :此时后端不知道用户是通过 192.168.1.100 访问的,它可能以为自己直接暴露在 localhost:8080(也就是以为用户直接访问的 localhost:8080),于是返回
bash 复制代码
HTTP/1.1 302 Found
Location: http://localhost:8080/dashboard

然后浏览器跳转到 http://localhost:8080/dashboard,对于私人使用的端口映射远程服务器,这样当然没问题,但是如果是要提供给更多人使用的公用服务器,这么做就有问题了,此时用户会看到无法访问此网站,因为 localhost 是回环地址**,公用场景下,客户端一般不会把自己端口映射出去**,这时用户访问 http://localhost:8080/dashboard,就相当于访问自己的回环地址,那样当然就没有服务了

  • 第二种,有 Host 头 :当 Nginx 设置了 proxy_set_header Host $host;,此时后端收到的请求头包含 Host: 192.168.1.100,于是后端知道,用户是通过 192.168.1.100 访问的,所以生成重定向
bash 复制代码
HTTP/1.1 302 Found
Location: http://192.168.1.100/dashboard

此时浏览器就能正确跳转到 http://192.168.1.100/dashboard

OK,分析完 proxy_set_header Host $host;,继续看下一个

  • proxy_set_header X-Real-IP $remote_addr;:表示将真实客户端 IP 传递给后端,$remote_addr 是 Nginx 变量,表示直接连接 Nginx 的客户端 IP (注意和 $host 区别,$host 表示服务端的域名,remote_addr 表示客户端的 IP),此时后端通过 X-Real-IP 头就能知道真实用户 IP,否则后端看到的来源 IP 永远是 127.0.0.1(本机地址),因为是 Nginx 本地应用在访问后端
  • proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;:用于记录请求经过的代理链 ,如果客户端没发 X-Forwarded-For,那么 $proxy_add_x_forwarded_for 就设为 $remote_addr,表示客户端 IP;如果客户端已经发了(比如 X-Forwarded-For: A, B),就追加当前 IP 上去,最后 X-Forwarded-For 可能呈现为
bash 复制代码
X-Forwarded-For: client-ip, proxy1-ip, proxy2-ip

后端可以通过这个 X-Forwarded-For 追踪原始用户 IP(尤其在多层代理时)

  • proxy_set_header X-Forwarded-Proto $scheme:让后端知道原始请求用的是什么协议(比如 HTTP 还是 HTTPS),这里 $scheme 是 Nginx 变量,值为 http 或 https ,比如有这么一个场景,用户通过 HTTPS 访问 Nginx(比如 https://example.com),但 Nginx 和后端之间走的是 HTTP 协议,此时后端不知道原始请求是 HTTPS,就可能生成 http://... 的链接,会导致混合内容高级或登录失败,通过 $scheme 的传递,可以让用户知道原始请求的协议,进而生成正确的安全链接

最后总结一下,location 字段定义如下功能

  • 请求转发 :proxy_pass 到 localhost:8080
  • 保留原始域名 :Host $host
  • 传递真实 IP :X-Real-IP + X-Forwarded-For
  • 传递原始协议 :X-Forwarded-Proto $scheme

这套反向代理配置适用于大多数 Web 应用


OK,本篇先到这里,如有疑问,欢迎评论区留言讨论,祝各位功力大涨,技术更上一层楼!!!更多内容见下篇 blog

相关推荐
lovingsoft13 分钟前
Chrome Lighthouse 详解
前端·chrome
Qlly23 分钟前
全栈工程师怎么接需求?从一句「加个功能」聊到能开发、能验收
前端·后端
马可家的菠萝27 分钟前
你的微信“文件传输助手”,是不是已经成了第二个网盘?
前端·后端·架构
略略略啦27 分钟前
Vibe Coding 基于Spec DD和TDD的实践指南
前端
shmily麻瓜小菜鸡1 小时前
前端实现图片与PDF文字识别敏感信息打码方案
前端·pdf·状态模式
打工仔折腾 AI1 小时前
LangChain 工具调用实战:从 Tool 定义到 Agent 执行链路拆解
java·前端·人工智能·后端·python·langchain·ai agent 实战
东风微鸣1 小时前
一次断电引发的血案:Ubuntu 26.04 升级中断后的完整救援实录
数据库·ubuntu·postgresql
汉堡大王95271 小时前
单次输出拉到100万Token:拆完 Gemini 4 Argon 的续写协议,才看懂谷歌这7个月在憋什么
前端·人工智能·后端
看浪的路人1 小时前
第9讲:大模型应用监控与可观测性——OpenTelemetry + Prometheus + Grafana 全链路追踪
java·前端·spring
Victor Zhong1 小时前
llama.cpp 部署大模型到 Ubuntu 台式机 SOP
linux·ubuntu·llama