soarli

生产环境实战:GitLab 穿透 Nginx 反向代理获取用户真实 IP 的完整指南
在企业级生产环境中,我们很少会将 GitLab 直接暴露在公网上。通常的标准架构是:用户的请求首先到达防火墙或云厂...
扫描右侧二维码阅读全文
23
2026/04

生产环境实战:GitLab 穿透 Nginx 反向代理获取用户真实 IP 的完整指南

在企业级生产环境中,我们很少会将 GitLab 直接暴露在公网上。通常的标准架构是:用户的请求首先到达防火墙或云厂商的负载均衡器,然后进入系统内部的 Nginx / Traefik 等反向代理服务器,最后才转发给 Docker 容器内部的 GitLab 服务。

这种架构虽然极大地提升了系统的安全性和扩展性,但也带来了一个经典的运维痛点——“IP 丢失”

一、 为什么需要获取真实 IP?(痛点分析)

如果在配置了反向代理后你不做任何额外的网络穿透设置,你会发现 GitLab 后台的审计日志、用户的登录历史中,清一色记录的都是反向代理服务器的内网 IP(或者是 Docker 网关的 IP,例如 172.x.x.x192.168.x.x)。

这在生产环境中是不可接受的,主要会引发以下三大致命风险:

  1. 审计追溯失效:一旦发生代码泄露或恶意删库,管理员查看日志时根本无法定位到真正的操作源头。
  2. 防爆破机制误伤:GitLab 内置了 Rack Attack 机制用于防止密码暴力破解。如果检测到某个 IP 频繁密码错误,会自动封禁该 IP。由于所有请求看起来都来自同一个“代理 IP”,一旦有黑客扫描,GitLab 会直接把代理 IP 封杀,导致全公司所有人都无法登录
  3. 异地登录告警失效:系统无法判断用户是否处于异常地理位置,无法触发相应的安全验证。

要解决这个问题,我们需要在“代理端”和“应用端”同时进行配置,建立一条传递真实 IP 的信任链。

二、 原理简述:信任链的建立

当用户的请求通过多层代理时,标准的做法是将用户的真实公网 IP 附加在 HTTP Header(请求头)中,最常用的字段是 X-Forwarded-ForX-Real-IP

然而,仅仅让代理服务器附带这个 Header 是不够的。出于安全考虑,GitLab 默认是不信任这些 Header 的(因为恶意用户也可以伪造这些 Header)。因此,我们必须在 GitLab 中明确声明:“我信任这几个内网 IP 作为我的代理服务器,当请求从它们发来时,请提取 Header 中的真实 IP。”

三、 第一步:配置反向代理(Nginx 端)

首先,我们必须确保 Nginx 在将请求转发给 GitLab Docker 容器时,把真实的客户端 IP 塞进了 HTTP 请求头中。

打开你的 Nginx 配置文件(通常在 /etc/nginx/conf.d/ 目录下),在处理 GitLab 转发的 location / 块中,添加或确认存在以下配置:

location / {
    # 将请求转发给内部的 GitLab 容器
    proxy_pass http://127.0.0.1:8088; 
    
    # 核心:将真实 IP 和协议等信息传递给后端的 GitLab
    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 https;
}

配置完成后,执行 sudo systemctl reload nginx 让代理配置生效。

四、 第二步:配置 GitLab 信任网段(GitLab 端)

接下来是核心环节,我们需要修改 GitLab 的配置文件,让它学会读取代理服务器传来的 Header。

由于我们使用 Docker 部署,挂载的配置文件路径通常为 /mnt/gitlabdata/config/gitlab.rb。使用 Vim 等编辑器打开它:

sudo vim /mnt/gitlabdata/config/gitlab.rb

在文件中添加以下四项核心配置(如果是首次配置,建议直接加在文件末尾):

# 1. 配置 GitLab 核心应用 (Rails) 的受信任代理列表
# 我们直接填入局域网和 Docker 默认的私有网段,确保极佳的兼容性。
# 无论你的 Docker 网桥 IP 怎么变,都在这个信任范围内。
gitlab_rails['trusted_proxies'] = ['127.0.0.1', '192.168.0.0/16', '172.16.0.0/12', '10.0.0.0/8']

# 2. 配置 GitLab 内置 Nginx 的受信任代理列表(与上方保持一致)
nginx['real_ip_trusted_addresses'] = ['127.0.0.1', '192.168.0.0/16', '172.16.0.0/12', '10.0.0.0/8']

# 3. 指定提取真实 IP 时使用的 Header 字段
# 对应我们在前端 Nginx 中设置的 proxy_set_header X-Forwarded-For
nginx['real_ip_header'] = 'X-Forwarded-For'

# 4. 开启递归解析
# 如果用户的请求经过了 CDN (如 Cloudflare) -> Nginx -> GitLab 多层代理,
# 开启此选项可以逐层剥离代理 IP,精准拿到最原始的客户端公网 IP。
nginx['real_ip_recursive'] = 'on'

CIDR 网段解释:

  • 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 是 IANA 规定的三大私有局域网网段。Docker 容器的默认网关(通常是 172.17.0.1 等)被完美包含在 172.16.0.0/12 中。这种写法既安全,又省去了每次容器重建后 IP 变动带来的维护烦恼。

五、 第三步:重启与验证

保存配置文件并退出后,由于修改了网络底层的监听与信任逻辑,我们需要重启 GitLab 容器:

sudo docker restart gitlab

等待 2-5 分钟 GitLab 完全启动后,我们可以进行最终的验证:

  1. 断开当前设备的 WIFI,使用手机的 4G/5G 移动网络,或者使用与服务器不在同一个局域网的电脑。
  2. 登录你的 GitLab 账号。
  3. 点击右上角头像,进入 Preferences (偏好设置)。
  4. 在左侧菜单栏点击 Authentication log (认证日志)。

此时,查看列表中最新的一条登录记录。如果你看到的 IP Address 列显示的是一串公网 IP,而不是你服务器的内网 172.x / 192.x 地址,那么恭喜你,你的 GitLab 已经成功穿透了反向代理,具备了真正的生产级安全审计能力!

最后修改:2026 年 04 月 23 日 03 : 47 AM

发表评论