ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

GitLab HTTPS配置全攻略:从证书选型到Nginx实战部署

GitLab HTTPS配置全攻略:从证书选型到Nginx实战部署 1. 项目概述为什么你的GitLab必须上HTTPS最近在帮几个团队做代码仓库的迁移和升级发现一个挺普遍的现象很多内部部署的GitLab实例图省事或者觉得内网环境“安全”就直接跑在HTTP协议上。每次看到这种情况我都得花不少口舌去说服负责人把HTTPS给配置上。这不仅仅是浏览器地址栏里那个小锁图标好看不好看的问题它直接关系到代码资产的安全、团队协作的信任基础甚至是一些现代开发工具链比如CI/CD流水线、Webhook能否正常工作的前提。今天我就以一个踩过不少坑的过来人身份把GitLab配置HTTPS这件事从为什么、用什么、到怎么配掰开揉碎了讲清楚。无论你是刚接手一个旧的GitLab服务器还是正准备从零搭建一个新的这篇内容都能让你少走弯路一次搞定。简单来说给GitLab配置HTTPS核心就是利用Nginx作为反向代理为GitLab服务套上一层SSL/TLS加密的“铠甲”。这个过程涉及到证书的获取与配置、Nginx的配置调整以及GitLab自身的一些关键设置。听起来步骤不少但只要你理解了每个环节的作用和它们之间的联动关系操作起来其实是一条清晰的直线。我会基于最常见的、使用Let‘s Encrypt免费证书或企业购买的商业证书这两种场景把每一步的操作意图、背后的原理以及我实操中总结的“坑点”都交代明白。保证你看完就能上手配置完就能用。2. 核心思路与方案选型自签名、免费还是商业证书在动手之前我们得先想清楚用哪种SSL证书。这直接决定了后续配置的复杂度和适用场景。市面上主要就三种选择自签名证书、Let‘s Encrypt免费证书、商业SSL证书。别急着做决定我们先来盘一盘各自的优缺点和适用场景。自签名证书顾名思义就是自己给自己颁发的证书。它的最大优点是免费且完全自控生成命令一行搞定。但缺点极其明显——浏览器和绝大多数客户端如Git、curl会因为它不是由受信任的机构颁发而弹出严重的警告甚至直接拒绝连接。这基本只适用于纯内部测试、或者所有访问终端你都能够手动安装并信任该根证书的极端封闭环境。对于需要对外提供服务、或者团队成员使用不同设备的GitLab自签名证书带来的麻烦远大于它的便利我个人非常不推荐在生产环境使用。Let‘s Encrypt免费证书这是社区和个人的福音。它由国际公认的证书颁发机构CA签发完全免费且自动化程度高。通过ACME协议通常使用Certbot工具可以自动完成域名验证、证书申请和续期。它的缺点是单次有效期只有90天需要配置自动续期任务Cron Job。但考虑到其自动化工具链非常成熟这个“缺点”几乎可以忽略。这是个人项目、初创团队或预算有限场景下的首选方案。它的信任链被所有主流浏览器和操作系统内置用户访问时不会有任何安全警告。商业SSL证书向DigiCert、Sectigo、GlobalSign等商业CA购买。优点在于提供更高的保险额度、更长的有效期通常1-2年、以及OV组织验证、EV扩展验证等能增强用户信任度的证书类型。此外商业CA的技术支持通常更及时。缺点就是需要付费。对于企业级应用、对外提供服务的商业产品或者公司安全合规有明确要求的场景购买商业证书是更稳妥和专业的选择。注意无论选择哪种证书确保你的GitLab服务器有一个固定的、可公网解析的域名例如gitlab.your-company.com。使用IP地址或不可信的域名在证书申请和浏览器信任方面会遇到无法绕过的障碍。对于绝大多数场景我的建议非常明确优先使用Let‘s Encrypt。除非公司政策强制要求否则没必要在初期为商业证书付费。下面的实操演示我也会以Let‘s Encrypt为主线同时穿插说明商业证书配置时的不同点。3. 环境准备与前置条件检查磨刀不误砍柴工。在开始配置之前我们需要确保服务器环境满足基本要求并做好必要的准备工作。这能避免配置到一半才发现缺东少西的尴尬。3.1 服务器与网络环境确认首先你的GitLab应该是通过Omnibus包推荐或源码方式安装的。Omnibus包内置了Nginx管理起来最方便本文也基于此展开。你可以通过运行sudo gitlab-ctl status来确认GitLab服务是否正常运行。其次域名与DNS解析。假设你的域名是gitlab.example.com。你需要登录域名管理后台为该域名添加一条A记录指向你的GitLab服务器的公网IP地址。并确保在服务器上这个域名能正确解析到自身可以通过修改服务器的/etc/hosts文件临时测试但最终要靠公共DNS。你可以用ping gitlab.example.com和nslookup gitlab.example.com命令来验证。第三防火墙与端口。HTTPS默认使用443端口。你需要确保服务器的防火墙如firewalld、ufw或云服务商的安全组规则已经放行了80端口HTTP和443端口HTTPS的入站流量。80端口在申请Let‘s Encrypt证书时用于域名验证是必需的。# 以ufw为例开放端口 sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw reload3.2 证书获取两种路径详解证书是HTTPS的基石。这里我们分两条路走你可以根据之前的选型决定。路径一使用Certbot获取Let‘s Encrypt证书推荐Certbot是EFF电子前沿基金会维护的自动化工具能极大简化证书申请和续期流程。安装Certbot通过系统包管理器安装。以下以Ubuntu/Debian为例CentOS/RHEL请参考Certbot官网指令。sudo apt update sudo apt install certbot python3-certbot-nginx -y这里安装了Certbot及其Nginx插件后者能帮助我们自动修改Nginx配置。申请证书运行以下命令。Certbot会自动检测Nginx配置中的server_name并引导你完成申请。sudo certbot --nginx -d gitlab.example.com执行过程中Certbot会询问你的邮箱用于接收续期提醒和安全通知。要求你同意服务条款。询问是否愿意分享数据给EFF可选。最关键的一步它会尝试在/etc/nginx/sites-available/中找到对应域名的配置并自动为其添加SSL相关配置。对于全新的GitLab可能找不到这没关系我们后续会手动配置。此时Certbot依然会通过80端口完成域名验证验证你拥有该域名并将证书文件.pem保存到/etc/letsencrypt/live/gitlab.example.com/目录下。申请成功后你会看到证书和私钥的路径例如证书文件/etc/letsencrypt/live/gitlab.example.com/fullchain.pem私钥文件/etc/letsencrypt/live/gitlab.example.com/privkey.pem实操心得如果Certbot的自动配置失败了比如提示找不到Nginx配置不用担心。我们更推荐只让它负责申请证书而不自动修改配置。可以使用sudo certbot certonly --nginx -d gitlab.example.com命令这样它只申请证书不碰Nginx配置更可控。路径二配置商业SSL证书如果你购买了商业证书CA通常会通过邮件提供证书文件包。一般会包含以下几个文件your_domain.crt你的域名证书可能也叫服务器证书。your_domain.key你的私钥文件申请证书时由你生成务必保管好。ca-bundle.crt或intermediate.crt中间证书链文件可能有一个或多个。你需要将这些文件上传到服务器的一个安全目录例如/etc/gitlab/ssl/。然后将证书链与你的域名证书合并成一个fullchain.pem文件这是Nginx等软件需要的格式。sudo mkdir -p /etc/gitlab/ssl # 上传 your_domain.crt, your_domain.key, ca-bundle.crt 到此目录 # 合并证书链假设中间证书是 ca-bundle.crt sudo cat /etc/gitlab/ssl/your_domain.crt /etc/gitlab/ssl/ca-bundle.crt /etc/gitlab/ssl/fullchain.pem # 确保私钥权限安全 sudo chmod 600 /etc/gitlab/ssl/your_domain.key现在你得到了证书链文件/etc/gitlab/ssl/fullchain.pem私钥文件/etc/gitlab/ssl/your_domain.key4. 核心配置修改GitLab主配置文件这是整个配置过程的“大脑”。GitLab Omnibus包使用一个主配置文件/etc/gitlab/gitlab.rb来管理所有设置。我们需要编辑这个文件告诉GitLab“请使用HTTPS这是你的域名和证书路径”。使用你熟悉的编辑器如vim或nano打开这个文件sudo vim /etc/gitlab/gitlab.rb找到并修改以下关键配置项。注意以#开头的行是注释取消注释删除#并设置正确的值。# 1. 配置外部访问URL这是最重要的设置 external_url https://gitlab.example.com # 注意这里必须明确指定协议为 https:// # 2. 如果使用Let‘s Encrypt证书可以启用内置的自动获取和续期功能可选。 # 但鉴于我们前面可能已经手动用Certbot获取了或者使用商业证书这里通常设为false采用更可控的手动配置。 letsencrypt[enable] false # 3. 配置Nginx监听HTTPS端口并指定证书路径。 # 如果你使用的是Let‘s Encrypt且证书由Certbot管理路径通常是 nginx[ssl_certificate] /etc/letsencrypt/live/gitlab.example.com/fullchain.pem nginx[ssl_certificate_key] /etc/letsencrypt/live/gitlab.example.com/privkey.pem # 如果你使用的是上传的商业证书路径则是 # nginx[ssl_certificate] /etc/gitlab/ssl/fullchain.pem # nginx[ssl_certificate_key] /etc/gitlab/ssl/your_domain.key # 4. 强制将所有HTTP请求重定向到HTTPS提升安全性。 nginx[redirect_http_to_https] true # 5. 可选但推荐配置更安全的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 # 这个加密套件列表兼容性和安全性较好禁用了已知不安全的旧协议如SSLv3, TLSv1.0/1.1。重要提示external_url这个参数是“总开关”。一旦你将其设置为https://开头GitLab内部的许多组件如Git clone地址、API端点、Webhook配置都会自动基于这个URL生成。所以务必确保这里写对了。5. 应用配置与重启服务配置文件的修改不会立即生效需要让GitLab重新编译其运行时配置并重启相关服务。运行以下命令sudo gitlab-ctl reconfigure这个命令是GitLab Omnibus包的核心管理命令。它会解析/etc/gitlab/gitlab.rb文件。根据配置生成所有服务的实际运行配置文件包括Nginx的配置。重启受影响的服务如Nginx、GitLab Workhorse等。这个过程可能需要几分钟请耐心等待。完成后你可以检查Nginx的配置是否已更新sudo cat /opt/gitlab/embedded/conf/nginx.conf | grep -A5 -B5 server_name gitlab.example.com你应该能看到配置中包含了SSL监听listen 443 ssl以及你指定的证书路径。6. 验证与测试确保一切就绪配置完成后绝不能想当然认为成功了。必须进行系统性的验证。6.1 基础连通性测试浏览器访问直接在浏览器中输入https://gitlab.example.com。你应该能看到GitLab的登录界面并且浏览器地址栏显示安全锁标志。点击锁标志可以查看证书的详细信息确认颁发给Subject是你的域名且由受信任的机构颁发。命令行工具测试使用curl命令可以更细致地检查。curl -I https://gitlab.example.com你应该看到返回的HTTP状态码是200 OK或302 Found重定向到登录页。如果遇到SSL证书错误可能是证书配置不正确或域名不匹配。 更严格的测试可以检查SSL握手详情openssl s_client -connect gitlab.example.com:443 -servername gitlab.example.com /dev/null 2/dev/null | openssl x509 -noout -dates -subject这个命令会输出证书的有效期和主题信息确认证书是否有效且对应你的域名。6.2 Git操作测试HTTPS配置的最终目的是为了安全地使用Git。我们需要测试克隆和推送。克隆仓库在另一台机器上尝试使用HTTPS URL克隆一个项目。git clone https://gitlab.example.com/username/your-project.git系统会提示你输入GitLab的用户名和密码。如果克隆成功说明HTTPS基础通道是通的。配置凭据存储避免每次输入密码频繁输入密码很麻烦。推荐使用Git的凭据缓存或者配置SSH密钥虽然本文讲HTTPS但这是最佳实践补充。凭据缓存git config --global credential.helper cache # 设置缓存时间例如1小时3600秒 git config --global credential.helper cache --timeout3600使用个人访问令牌更安全在GitLab用户设置中生成一个具有read_repository和write_repository权限的Personal Access Token。克隆或推送时密码栏输入这个令牌即可。令牌可以替代密码且权限可细粒度控制更安全。6.3 检查后台服务与日志如果上述测试失败查看日志是定位问题的第一步。检查Nginx错误日志sudo tail -f /var/log/gitlab/nginx/error.log尝试访问时观察这个日志的输出。常见的错误如“SSL handshake failed”可能指向证书或密钥文件格式错误、权限问题。检查GitLab服务状态sudo gitlab-ctl status确保所有服务特别是nginx、gitlab-workhorse都是run状态。7. 高级配置与优化要点基本的HTTPS通了但要让服务更健壮、更安全还需要一些优化。7.1 配置HTTP严格传输安全HSTSHSTS是一种安全策略机制告诉浏览器在未来一段时间内通过max-age指定只能通过HTTPS访问该网站即使用户手动输入http://也会被强制跳转。这能有效防止SSL剥离攻击。在/etc/gitlab/gitlab.rb中启用nginx[hsts_max_age] 63072000 # 单位秒这里设置约为2年 nginx[hsts_include_subdomains] false # 谨慎设置为true除非你确定所有子域名都支持HTTPS修改后再次运行sudo gitlab-ctl reconfigure。警告一旦启用HSTS并设置了较长的max-age在证书失效或想临时回退到HTTP时会非常困难。建议先在测试环境验证生产环境可先设置一个较短的时间如300秒。7.2 配置OCSP装订OCSP StaplingOCSP在线证书状态协议用于实时检查证书是否被吊销。默认情况下浏览器需要额外向CA的OCSP服务器发起查询这会增加延迟并泄露用户隐私。OCSP装订让Nginx在TLS握手时就将CA返回的OCSP响应“装订”到证书上一并发送给客户端解决了上述问题。在/etc/gitlab/gitlab.rb中配置nginx[ssl_stapling] true nginx[ssl_stapling_verify] true # 通常不需要手动指定解析器但若在内网无DNS可能需要设置 # nginx[resolver] [8.8.8.8, 8.8.4.4]配置后可以用命令验证装订是否生效openssl s_client -connect gitlab.example.com:443 -servername gitlab.example.com -status /dev/null 2/dev/null | grep -A2 OCSP response如果看到OCSP Response Status: successful则表示配置成功。7.3 证书自动续期针对Let‘s EncryptLet‘s Encrypt证书90天过期手动续期不可行。我们需要配置自动化。Certbot安装时通常会自动创建一个定时任务cron job位于/etc/cron.d/certbot。你可以检查并确认它存在且有效。其内容通常是每天运行两次certbot renew命令。关键点certbot renew命令只会检查证书是否快过期默认到期前30天如果是才会真正续期。续期成功后需要重启Nginx来加载新证书。我们需要确保GitLab的Nginx在证书更新后能自动重启。Certbot提供了--deploy-hook参数来实现这一点。编辑Certbot的续期配置文件位置可能因系统而异常见于/etc/letsencrypt/renewal/gitlab.example.com.conf确保其中有类似如下配置# 在 [renewalparams] 部分 renew_hook systemctl reload nginx但GitLab Omnibus包管理自己的Nginx更可靠的做法是使用一个通用的部署钩子脚本。我们可以创建一个脚本sudo vim /etc/letsencrypt/renewal-hooks/deploy/reload-gitlab-nginx.sh内容为#!/bin/bash sudo /opt/gitlab/embedded/sbin/nginx -t sudo gitlab-ctl hup nginx然后赋予执行权限sudo chmod x /etc/letsencrypt/renewal-hooks/deploy/reload-gitlab-nginx.sh这样每次证书成功续期后Certbot都会执行这个脚本在检查Nginx配置语法无误后优雅地重启GitLab的Nginx服务。你可以手动测试续期流程模拟不会真的续期未过期的证书sudo certbot renew --dry-run如果看到“The dry run was successful”输出说明自动续期配置正确。8. 故障排查与常见问题实录即使按照步骤操作也可能会遇到问题。这里我整理了几个最常见的“坑”及其解决方法。8.1 浏览器提示“不安全”或证书错误症状访问HTTPS地址浏览器显示红色警告如“您的连接不是私密连接”。可能原因与排查证书域名不匹配证书是为www.example.com颁发的但你访问的是example.com。检查external_url和证书的Common Name (CN) 或 Subject Alternative Names (SAN) 是否完全一致。Let‘s Encrypt证书的SAN可以通过openssl x509 -in /etc/letsencrypt/live/gitlab.example.com/fullchain.pem -text -noout | grep -A1 Subject Alternative Name查看。证书链不完整浏览器无法构建完整的信任链。确保nginx[ssl_certificate]指向的是包含中间证书的fullchain.pem文件而不是单独的cert.pem。可以用SSL检测工具如SSL Labs的SSL Test在线诊断。系统时间不正确证书验证依赖于准确的时间。如果服务器时间偏差过大快或慢几天会导致证书被判定为无效或过期。使用date命令检查并通过NTP同步时间sudo timedatectl set-ntp true。8.2 Git clone/push over HTTPS 失败症状git clone或git push时失败提示SSL certificate problem或unable to access ‘https://.../‘。可能原因与排查自签名证书未受信任如果你错误地使用了自签名证书需要在客户端机器上手动信任它。对于Git可以临时设置git config --global http.sslVerify false极度不推荐用于生产环境仅作临时调试。正确做法是将自签名证书的CA根证书安装到客户端的受信任根证书存储区。GitLab Runner或CI/CD作业中的证书问题如果你的GitLab Runner执行器是Shell类型或运行在Docker容器内它可能不包含系统的根证书库。需要在Runner服务器或Docker镜像中安装ca-certificates包如apt-get install -y ca-certificates。网络代理问题公司网络可能对HTTPS流量进行了拦截并使用了自签名的中间人证书。你需要联系IT部门获取该代理的根证书并配置到Git或系统环境中。8.3 Nginx启动失败或配置错误症状运行sudo gitlab-ctl reconfigure后Nginx服务无法启动或sudo gitlab-ctl status显示nginx状态为failed。可能原因与排查证书文件权限问题Nginx进程通常以gitlab-www用户运行需要能够读取证书和私钥文件。检查权限sudo ls -la /etc/letsencrypt/live/gitlab.example.com/确保私钥privkey.pem权限为600-rw-------证书文件为644。/etc/letsencrypt/archive/和/etc/letsencrypt/live/目录的权限也应该是755。配置语法错误在reconfigure之前可以先测试Nginx配置sudo /opt/gitlab/embedded/sbin/nginx -t -p /var/opt/gitlab/nginx -c /var/opt/gitlab/nginx/conf/nginx.conf这个命令会输出具体的错误行和原因比如拼写错误、缺少分号等。端口冲突443端口可能被其他程序如Apache另一个Nginx实例占用。使用sudo netstat -tulpn | grep :443查看。8.4 混合内容警告Mixed Content症状浏览器地址栏锁标志是黄色的提示“网站包含不安全内容”。可能原因与排查这是因为GitLab页面中如README.md里的图片、用户上传的头像等有些资源的链接仍然使用的是http://协议。这通常是由于早期通过HTTP上传的资源其链接被硬编码在数据库或页面中。某些第三方集成或自定义配置错误。解决首先确保external_url是https://。其次可以尝试在/etc/gitlab/gitlab.rb中强制GitLab使用HTTPS生成所有URLgitlab_rails[gitlab_https] true gitlab_rails[gitlab_host] gitlab.example.com然后运行sudo gitlab-ctl reconfigure并sudo gitlab-ctl restart。对于已存在的HTTP资源链接GitLab通常会自动处理但某些情况可能需要手动清理缓存或更新资源。配置GitLab的HTTPS就像给自家的金库换上一把符合国际标准的安全锁。它不再是“可选项”而是现代软件开发和运维的“必选项”。整个过程的核心在于理解证书、Nginx、GitLab三者之间的关系证书提供身份凭证和加密基础Nginx作为门户负责SSL终结和请求转发GitLab则专注于应用逻辑。只要理清这个链条按步骤仔细操作遇到问题根据日志按图索骥最终都能成功。我个人的体会是自动化是关键。尤其是使用Let‘s Encrypt时一定要把Certbot的自动续期和GitLab Nginx的重载钩子配置好这能省去未来无数的手动维护成本。另外在每次大的配置变更前养成先sudo gitlab-ctl reconfigure再sudo gitlab-ctl restart的习惯而不是直接重启因为reconfigure会确保配置文件的正确性。最后别忘了在一切配置完成后用SSL Labs等在线工具做一次全面的安全扫描它会给你一个评分并指出潜在的弱点如支持的加密套件强度、是否启用HSTS等根据报告进行微调能让你的GitLab服务更加坚固。
返回列表