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

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

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

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


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

相关推荐
b***74883 小时前
前端的未来不是框架之争,而是数字体验能力的全面竞争
前端
Lunar*3 小时前
[开源] 纯前端实现楼盘采光模拟工具:从2D规划图到3D日照分析
前端·3d
白兰地空瓶3 小时前
一行 npm init vite,前端工程化的世界就此展开
前端·vue.js·vite
LYFlied3 小时前
【每日算法】LeetCode 23. 合并 K 个升序链表
前端·数据结构·算法·leetcode·链表
xiaoxue..3 小时前
LeetCode 第 15 题:三数之和
前端·javascript·算法·leetcode·面试
狂炫冰美式3 小时前
《预言市场进化论:从罗马斗兽场,到 Polymarket 的 K 线图》
前端·后端
码力巨能编3 小时前
Markdown 作为 Vue 组件导入
前端·javascript·vue.js
私人珍藏库3 小时前
[吾爱大神原创工具] FlowMouse - 心流鼠标手势 v1.0【Chrome浏览器插件】
前端·chrome·计算机外设
旧梦吟3 小时前
脚本网页 地球演化
前端·算法·css3·html5·pygame