GitLab HTTPS配置实战:从SSL证书到Nginx反向代理完整指南

📅 2026/8/24 5:28:28
GitLab HTTPS配置实战:从SSL证书到Nginx反向代理完整指南
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 NameCN必须填写你访问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注意对于现代浏览器和工具仅crt和key可能不够。你可能还需要生成一个包含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/hostsLinux/macOS或C:\Windows\System32\drivers\etc\hostsWindows文件中添加一条记录例如192.168.1.100 gitlab.internal。证书中的域名必须与你在浏览器地址栏或Git远程仓库地址中输入的域名一致。2.3 理解GitLab与Nginx的关系这是很多初学者困惑的地方。GitLab本身内置了一个轻量级的Web服务器Unicorn或Puma来处理Ruby on Rails应用同时它也捆绑了一个Nginx。在默认的Omnibus安装包中这个捆绑的Nginx被配置为直接为GitLab服务。当我们配置HTTPS时实际上主要是在配置这个Nginx。有两种架构模式使用捆绑的Nginx推荐给大多数用户直接修改GitLab的配置文件管理起来最方便所有配置集中在一处。使用独立安装的Nginx作为反向代理你可以在服务器上先安装一个Nginx然后让它代理到GitLab内置应用服务器监听在某个如127.0.0.1:8080的端口上。这种方式更灵活比如你可以在同一台服务器上用同一个Nginx代理多个Web服务。但配置稍复杂需要同时维护Nginx和GitLab两边的配置。本指南将以使用GitLab捆绑的Nginx为标准路径进行讲解因为这是Omnibus安装包下的最佳实践能减少不必要的复杂度。3. 基于Omnibus安装包的HTTPS核心配置实战假设你已经通过Omnibus包如gitlab-ce或gitlab-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 验证配置是否生效检查Nginx配置生成的Nginx配置文件通常在/var/opt/gitlab/nginx/conf/gitlab-http.conf。你可以查看其中是否包含了正确的ssl_certificate和ssl_certificate_key路径以及listen 443 ssl;这样的指令。sudo grep -n “ssl_certificate” /var/opt/gitlab/nginx/conf/gitlab-http.conf检查服务状态确保所有GitLab核心服务运行正常。sudo gitlab-ctl status重点关注nginx,gitlab-workhorse,puma等服务是否都是run状态。浏览器访问打开浏览器访问https://gitlab.example.com。如果使用受信证书你应该能看到绿色的锁标志。如果使用自签名证书你会看到“不安全连接”的警告需要手动点击“高级”-“继续前往”才能访问这是预期行为。检查克隆地址登录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。你有几种选择临时跳过验证不推荐用于脚本或自动化git -c http.sslVerifyfalse clone https://gitlab.example.com/xxx/xxx.git全局关闭SSL验证极不推荐存在安全风险git config --global http.sslVerify false将自签名证书添加到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.pem4.2 容器化环境Docker的特殊考量如果你使用Docker运行GitLabHTTPS配置的逻辑是相似的但路径和方式略有不同。挂载证书在运行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目录下已经放置了正确命名的证书和密钥文件。修改配置你可以进入容器内部修改/etc/gitlab/gitlab.rb但更好的做法是在宿主机修改挂载的配置文件/your/host/path/gitlab/config/gitlab.rb然后在容器内执行gitlab-ctl reconfigure。环境变量GitLab的Docker镜像也支持通过环境变量GITLAB_OMNIBUS_CONFIG来传递配置可以在docker run命令中直接设置避免进入容器修改。例如-e GITLAB_OMNIBUS_CONFIGexternal_url https://gitlab.example.com/; nginx[redirect_http_to_https] true;4.3 常见故障与排查思路即使按照步骤操作也可能会遇到问题。以下是一些常见故障及排查方法Nginx启动失败报错SSL_CTX_use_PrivateKey或BIO_new_file可能原因1证书或密钥文件路径错误或Nginx进程没有读取权限。排查检查gitlab.rb中nginx[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的连接确保万无一失。毕竟代码仓库的安全怎么重视都不为过。