GitLab HTTPS配置实战:从SSL证书到Nginx反向代理完整指南
2026/8/24 5:28:21 网站建设 项目流程

1. 从HTTP到HTTPS:为什么你的GitLab必须升级?

如果你还在用HTTP访问你的GitLab,那感觉就像把公司代码库的钥匙挂在办公室门口的信箱上——理论上只有你知道,但任何一个路过的人都有可能顺手牵羊。HTTP协议下,所有数据,包括你的用户名、密码、API令牌,甚至每一次代码推送的内容,都是以明文形式在网络中裸奔。这绝不是危言耸听,尤其是在内网环境中,很多人误以为“内网就是安全的”,从而放松了警惕。实际上,内网嗅探、中间人攻击(MITM)的风险同样存在。HTTPS的核心价值,就是为这趟“裸奔”套上一件加密的“防护服”,通过SSL/TLS协议,在客户端(你的浏览器或Git客户端)和服务器(你的GitLab实例)之间建立一条加密通道,确保数据的机密性和完整性。

对于GitLab这种承载着团队核心知识产权(源代码)和协作流程(CI/CD)的平台,启用HTTPS不是“锦上添花”,而是“安全基线”。没有它,你无法放心地通过Web界面管理项目,更无法安全地让CI/CD Runner与GitLab通信。很多人在初次搭建GitLab时,为了图省事跳过了HTTPS配置,结果在后续集成CI/CD、配置Webhook或者使用高级功能时,会遇到一堆令人头疼的“SSL证书验证失败”错误。与其亡羊补牢,不如在搭建之初就一步到位。

本指南将带你完整走通GitLab的HTTPS配置流程。我们将聚焦于最常见的场景:使用Nginx作为反向代理,并为它配置一个有效的SSL证书。无论你是使用自签名证书在测试环境快速验证,还是为生产环境申请并部署受信任的CA(证书颁发机构)签发的证书,核心原理和步骤都是相通的。我会基于多年的运维经验,不仅告诉你每一步怎么做,更会解释为什么这么做,以及过程中可能遇到的“坑”和避坑技巧。

2. 配置前的核心准备:证书、域名与Nginx角色

在动手修改任何配置文件之前,我们必须把“地基”打好。这个阶段准备工作的充分与否,直接决定了后续配置是顺风顺水还是一路坎坷。

2.1 SSL证书的获取与选择

SSL证书是HTTPS的基石。你可以把它理解为一本由权威机构(或你自己)签发的“数字护照”,里面包含了你的服务器域名、公钥以及签发机构的数字签名。浏览器或Git客户端会用它来验证服务器的身份并建立加密连接。

1. 自签名证书:

  • 是什么:自己充当CA,为自己签发证书。成本为零,随时可生成。
  • 适用场景:内部测试、开发环境、或者短期内无法绑定公网域名的内网服务。
  • 缺点:不受客户端(浏览器、Git、各种SDK)信任。首次访问时,客户端会抛出严重的警告,需要手动确认并添加例外。这对于自动化工具(如CI/CD Runner)来说是致命的,因为它们无法像人一样去点击“继续前往不安全网站”。
  • 生成命令示例(使用OpenSSL)
    # 生成一个有效期10年的RSA私钥 openssl genrsa -out gitlab.example.com.key 2048 # 使用该私钥创建证书签名请求(CSR),这里需要交互式输入信息,其中Common Name(CN)必须填写你访问GitLab使用的域名 openssl req -new -key gitlab.example.com.key -out gitlab.example.com.csr # 自签名,生成证书文件 openssl x509 -req -days 3650 -in gitlab.example.com.csr -signkey gitlab.example.com.key -out gitlab.example.com.crt

    注意:对于现代浏览器和工具,仅crtkey可能不够。你可能还需要生成一个包含Subject Alternative Name (SAN)的证书,以兼容性更好。更推荐使用一条命令生成包含SAN的自签名证书,但这需要额外的配置文件。

2. 受信任的CA签发证书:

  • 是什么:由全球或区域受信的CA(如Let‘s Encrypt, DigiCert, GlobalSign等)签发的证书。
  • 适用场景:任何面向公网或需要被广泛信任的生产环境。
  • 优点:被所有主流浏览器和操作系统信任,无安全警告。
  • 获取方式
    • 商业购买:从证书服务商处购买,通常提供保险和更长的有效期(1-2年)。
    • 免费申请Let‘s Encrypt是目前最流行的免费、自动化证书颁发机构。它通过ACME协议验证你对域名的控制权(例如,在服务器上放置特定文件或添加DNS解析记录),然后签发有效期为90天的证书。可以通过certbot等工具自动完成申请和续期。对于公有云用户,阿里云、腾讯云等也提供一年期的免费单域名证书。

选择建议:对于生产环境,无脑选择Let‘s Encrypt或其他受信CA证书。自签名证书仅用于临时测试,并务必清楚其局限性。

2.2 域名的正确绑定

无论使用哪种证书,一个关键前提是:你必须有一个确定的域名(或主机名)来访问你的GitLab服务器,并且这个域名要与SSL证书中的“Common Name (CN)”或“Subject Alternative Name (SAN)”完全匹配。

  • 公网场景:你需要拥有一个域名(例如gitlab.yourcompany.com),并将其A记录或CNAME记录解析到你的服务器公网IP。
  • 纯内网场景:你需要在内部DNS服务器上为GitLab服务器创建一个主机记录(例如gitlab.internal),或者,更常见的做法是,在所有需要访问该GitLab的客户端机器的/etc/hosts(Linux/macOS)或C:\Windows\System32\drivers\etc\hosts(Windows)文件中添加一条记录,例如:192.168.1.100 gitlab.internal证书中的域名必须与你在浏览器地址栏或Git远程仓库地址中输入的域名一致

2.3 理解GitLab与Nginx的关系

这是很多初学者困惑的地方。GitLab本身内置了一个轻量级的Web服务器(Unicorn或Puma)来处理Ruby on Rails应用,同时它也捆绑了一个Nginx。在默认的Omnibus安装包中,这个捆绑的Nginx被配置为直接为GitLab服务。

当我们配置HTTPS时,实际上主要是在配置这个Nginx。有两种架构模式:

  1. 使用捆绑的Nginx(推荐给大多数用户):直接修改GitLab的配置文件,管理起来最方便,所有配置集中在一处。
  2. 使用独立安装的Nginx作为反向代理:你可以在服务器上先安装一个Nginx,然后让它代理到GitLab内置应用服务器(监听在某个如127.0.0.1:8080的端口)上。这种方式更灵活,比如你可以在同一台服务器上用同一个Nginx代理多个Web服务。但配置稍复杂,需要同时维护Nginx和GitLab两边的配置。

本指南将以使用GitLab捆绑的Nginx为标准路径进行讲解,因为这是Omnibus安装包下的最佳实践,能减少不必要的复杂度。

3. 基于Omnibus安装包的HTTPS核心配置实战

假设你已经通过Omnibus包(如gitlab-cegitlab-ee)在Linux服务器上安装好了GitLab,并且目前通过HTTP(如http://gitlab.example.com)可以正常访问。现在我们要将其切换为HTTPS。

3.1 放置SSL证书文件

首先,将你的证书文件(.crt.pem文件)和私钥文件(.key文件)放到服务器上。GitLab Omnibus包期望的默认位置是/etc/gitlab/ssl/目录。你需要以root或有sudo权限的用户操作。

sudo mkdir -p /etc/gitlab/ssl sudo chmod 700 /etc/gitlab/ssl # 将你的证书和私钥文件复制到此目录,并确保命名规范 # 通常使用你的域名作为文件名前缀,例如: sudo cp /path/to/your/gitlab.example.com.crt /etc/gitlab/ssl/ sudo cp /path/to/your/gitlab.example.com.key /etc/gitlab/ssl/ # 设置严格的权限,私钥必须只有root可读 sudo chmod 600 /etc/gitlab/ssl/gitlab.example.com.key

关键细节与避坑

  • 目录权限/etc/gitlab/ssl目录权限设为700,私钥文件权限设为600,这是安全硬性要求,过宽的权限可能导致Nginx启动失败并报错。
  • 文件命名:Omnibus GitLab的Nginx配置默认会查找以gitlab.example.com命名的证书和密钥。如果你使用其他域名,需要稍后在配置中明确指定路径。
  • 证书链:如果你的CA提供的是中级证书(Intermediate CA Certificate),你需要将你的域名证书和中级证书合并成一个文件。通常顺序是:你的证书在上,中级证书在下。你可以用文本编辑器合并,或使用cat命令:
    cat gitlab.example.com.crt intermediate.crt > /etc/gitlab/ssl/gitlab.example.com.crt
    私钥文件(.key)不需要合并。

3.2 修改GitLab主配置文件

核心配置都在/etc/gitlab/gitlab.rb这个文件中。这是一个Ruby语法格式的配置文件,我们需要修改其中的相关参数。

sudo vim /etc/gitlab/gitlab.rb

找到并修改或添加以下配置项:

# 1. 配置外部访问URL,必须使用HTTPS协议 external_url 'https://gitlab.example.com' # 2. 告诉GitLab我们使用内置的Nginx并启用SSL nginx['enable'] = true nginx['redirect_http_to_https'] = true # 自动将HTTP请求重定向到HTTPS nginx['ssl_certificate'] = "/etc/gitlab/ssl/gitlab.example.com.crt" nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/gitlab.example.com.key" # 3. (可选但推荐)配置更强的SSL协议和加密套件,禁用不安全的旧协议 nginx['ssl_protocols'] = "TLSv1.2 TLSv1.3" nginx['ssl_ciphers'] = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384" # 上述加密套件列表是一个兼顾安全性和兼容性的示例,你可以根据需求调整。 # 4. (重要)如果证书是自签名的,需要禁用客户端证书验证,否则GitLab内置服务(如Workhorse)会报错 # 对于自签名证书,必须设置: gitlab_rails['gitlab_https'] = true gitlab_rails['gitlab_ssh_host'] = 'gitlab.example.com' # SSH克隆地址,通常与域名相同或不同端口 # 关键设置:绕过SSL验证(仅限自签名证书环境) gitlab_rails['gitlab_ssl_verify'] = false # 对于受信任的CA证书,则不需要设置 `gitlab_ssl_verify` 为 false,或者可以设为 true。

配置解析与经验谈

  • external_url:这是最重要的配置。它不仅决定了用户访问的链接,还会影响GitLab内部生成的仓库克隆地址(HTTPS和SSH)。一旦这里改成https://,GitLab的所有链接生成、Webhook回调地址等都会基于HTTPS。
  • nginx['redirect_http_to_https']:强烈建议开启。这样即使用户输入了http://,也会被301重定向到https://,确保流量始终加密。
  • 自签名证书的特殊处理gitlab_rails['gitlab_ssl_verify'] = false这一行至关重要。GitLab由多个组件构成(Rails, Workhorse, GitLab Shell等),它们内部会通过HTTP/HTTPS进行通信。当使用自签名证书时,这些组件间的SSL握手会失败,因为对方不信任你的自签名CA。设置为false是告诉这些组件“不要验证对方证书的有效性”。在生产环境使用受信证书时,绝不应该设置此项为false
  • 关于加密套件:我提供的ssl_ciphers示例禁用了老旧的、不安全的算法(如SSLv3, TLSv1.0/1.1,以及RC4, DES等),优先使用前向保密(Forward Secrecy)的ECDHE套件。你可以使用在线工具(如SSL Labs的测试)来检查你的配置安全性。

3.3 应用配置并重启服务

修改完gitlab.rb后,需要运行GitLab的重配置命令,它会根据这个文件生成所有组件的实际配置文件(包括Nginx的配置文件),并重启相关服务。

sudo gitlab-ctl reconfigure

这个命令会运行一段时间,屏幕上会滚动大量输出,显示它正在配置什么服务。请耐心等待其完成。

3.4 验证配置是否生效

  1. 检查Nginx配置:生成的Nginx配置文件通常在/var/opt/gitlab/nginx/conf/gitlab-http.conf。你可以查看其中是否包含了正确的ssl_certificatessl_certificate_key路径,以及listen 443 ssl;这样的指令。

    sudo grep -n “ssl_certificate” /var/opt/gitlab/nginx/conf/gitlab-http.conf
  2. 检查服务状态:确保所有GitLab核心服务运行正常。

    sudo gitlab-ctl status

    重点关注nginx,gitlab-workhorse,puma等服务是否都是run状态。

  3. 浏览器访问:打开浏览器,访问https://gitlab.example.com。如果使用受信证书,你应该能看到绿色的锁标志。如果使用自签名证书,你会看到“不安全连接”的警告,需要手动点击“高级”->“继续前往”才能访问(这是预期行为)。

  4. 检查克隆地址:登录GitLab,进入任意项目,查看仓库的克隆地址。HTTPS克隆地址应该显示为https://gitlab.example.com/username/project.git

4. 配置后的关键调整与故障排查

配置生效只是第一步,要让整个GitLab生态在HTTPS下顺畅工作,还需要注意以下几个关键点。

4.1 Git客户端配置调整

服务器启用HTTPS后,本地Git客户端克隆或推送代码时,可能会遇到证书验证问题。

  • 对于受信CA证书:通常无需任何配置,Git(使用curl或OpenSSL后端)会自动信任系统信任库中的CA。
  • 对于自签名证书:Git会报错SSL certificate problem: self signed certificate。你有几种选择:
    1. 临时跳过验证(不推荐用于脚本或自动化)
      git -c http.sslVerify=false clone https://gitlab.example.com/xxx/xxx.git
    2. 全局关闭SSL验证(极不推荐,存在安全风险)
      git config --global http.sslVerify false
    3. 将自签名证书添加到Git的信任列表(推荐):将你的.crt文件导出为PEM格式(如果还不是),然后将其添加到Git的专用CA包或系统CA包中。具体步骤因操作系统和Git版本而异。例如,在Linux上,你可以将证书复制到/usr/local/share/ca-certificates/然后运行sudo update-ca-certificates。更通用的方法是配置Git使用特定的CA包文件:
      git config --global http.sslCAInfo /path/to/your/self-signed-cert.pem

4.2 容器化环境(Docker)的特殊考量

如果你使用Docker运行GitLab,HTTPS配置的逻辑是相似的,但路径和方式略有不同。

  1. 挂载证书:在运行docker run命令时,你需要将宿主机上的证书目录挂载到容器内的/etc/gitlab/ssl目录。

    docker run -d \ --hostname gitlab.example.com \ -p 443:443 -p 80:80 -p 22:22 \ --name gitlab \ --restart always \ -v /your/host/path/ssl:/etc/gitlab/ssl \ -v /your/host/path/gitlab/config:/etc/gitlab \ -v /your/host/path/gitlab/logs:/var/log/gitlab \ -v /your/host/path/gitlab/data:/var/opt/gitlab \ gitlab/gitlab-ce:latest

    注意,你需要确保宿主机/your/host/path/ssl目录下已经放置了正确命名的证书和密钥文件。

  2. 修改配置:你可以进入容器内部修改/etc/gitlab/gitlab.rb,但更好的做法是在宿主机修改挂载的配置文件(/your/host/path/gitlab/config/gitlab.rb),然后在容器内执行gitlab-ctl reconfigure

  3. 环境变量:GitLab的Docker镜像也支持通过环境变量GITLAB_OMNIBUS_CONFIG来传递配置,可以在docker run命令中直接设置,避免进入容器修改。例如:

    -e GITLAB_OMNIBUS_CONFIG="external_url 'https://gitlab.example.com/'; nginx['redirect_http_to_https'] = true;"

4.3 常见故障与排查思路

即使按照步骤操作,也可能会遇到问题。以下是一些常见故障及排查方法:

  • Nginx启动失败,报错SSL_CTX_use_PrivateKeyBIO_new_file

    • 可能原因1:证书或密钥文件路径错误,或Nginx进程没有读取权限。
    • 排查:检查gitlab.rbnginx['ssl_certificate']nginx['ssl_certificate_key']的路径是否正确。使用sudo ls -la检查文件是否存在,以及密钥文件权限是否为600
    • 可能原因2:证书和密钥不匹配。
    • 排查:使用OpenSSL命令验证:
      openssl x509 -noout -modulus -in /etc/gitlab/ssl/gitlab.example.com.crt | openssl md5 openssl rsa -noout -modulus -in /etc/gitlab/ssl/gitlab.example.com.key | openssl md5
      两次命令输出的MD5值必须完全一致。
  • 可以HTTPS访问网页,但Git克隆/推送失败

    • 可能原因:GitLab内部组件(如Workhorse)通信问题,特别是自签名证书环境下gitlab_ssl_verify未设置为false
    • 排查:检查/var/log/gitlab/gitlab-workhorse/current/var/log/gitlab/nginx/current日志,看是否有SSL验证相关的错误。确认gitlab.rb中已正确设置gitlab_rails['gitlab_ssl_verify'] = false(自签名证书)并已执行reconfigure
  • HTTPS访问正常,但CI/CD Runner注册或连接失败

    • 可能原因:Runner在向GitLab API发起请求时,同样遇到了证书信任问题。
    • 排查:如果是自签名证书,在注册Runner时,可以使用--tls-ca-file参数指定CA证书文件:
      sudo gitlab-runner register -n \ --url https://gitlab.example.com \ --registration-token YOUR_PROJECT_TOKEN \ --tls-ca-file /path/to/your-ca.crt
      对于已注册的Runner,可以在其配置文件(/etc/gitlab-runner/config.toml)中对应的[[runners]]部分添加tls-ca-file = "/path/to/your-ca.crt"
  • HTTP到HTTPS重定向不工作或出现重定向循环

    • 可能原因:负载均衡器或前置代理(如云服务商的SLB、自己搭建的HAProxy)已经处理了SSL,并以HTTP协议将请求转发给后端的GitLab Nginx。此时,GitLab Nginx看到的是HTTP请求,但又配置了重定向到HTTPS,导致循环。
    • 解决方案:在这种情况下,需要告诉GitLab Nginx,它虽然收到的是HTTP请求,但外部用户实际使用的是HTTPS。在gitlab.rb中设置:
      nginx['listen_port'] = 80 nginx['listen_https'] = false # 不在这个Nginx上处理HTTPS nginx['redirect_http_to_https'] = false # 关闭重定向,因为SSL已在外部终结 # 关键:设置代理协议头,让GitLab知道原始请求是HTTPS nginx['proxy_set_headers'] = { "X-Forwarded-Proto" => "https", "X-Forwarded-Ssl" => "on" }
      同时,你需要在你的前置代理上正确设置这些HTTP头。

配置HTTPS的过程,本质上是一个理解Web通信安全模型和GitLab内部架构的过程。每一步配置背后都有其安全性和功能性的考量。我强烈建议在生产环境部署前,先在测试环境中完整演练一遍,并尝试模拟各种客户端(浏览器、Git命令行、CI Runner)的连接,确保万无一失。毕竟,代码仓库的安全,怎么重视都不为过。

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

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

立即咨询