为 Linux 软件包安装配置 SSL
- Tier: 基础版,专业版,旗舰版
- Offering: 私有化部署
Linux 软件包支持几个常见的 SSL 配置用例。
默认情况下,HTTPS 是未启用的。要启用 HTTPS,您可以:
- 使用 Let's Encrypt 免费自动化 HTTPS。
- 使用您自己的证书手动配置 HTTPS。
如果您使用代理、负载均衡器或其他外部设备来终止极狐GitLab 主机名的 SSL,请参阅 外部、代理和负载均衡器 SSL 终止。
下表显示了每种极狐GitLab 服务支持的方法。
OpenSSL 3 升级
从 版本 17.7 开始,极狐GitLab 使用 OpenSSL 3。一些较旧的 TLS 协议和密码套件,或者较弱的 TLS 证书可能与 OpenSSL 3 的默认设置不兼容。
在升级到极狐GitLab 17.7 之前,请使用 OpenSSL 3 指南 来识别和评估您的外部集成的兼容性。
升级到极狐GitLab 17.7 后,您可以使用以下命令验证极狐GitLab 是否正在使用 OpenSSL 3:
shell/opt/gitlab/embedded/bin/openssl version
启用 Let's Encrypt 集成
Let's Encrypt 在默认情况下启用,如果 external_url 使用 HTTPS 协议设置并且没有配置其他证书。
前提条件:
- 端口 80 和 443 必须对运行验证检查的公共 Let's Encrypt 服务器可访问。
要启用 Let's Encrypt:
-
编辑 /etc/gitlab/gitlab.rb 并添加或更改以下条目:
ruby1## 极狐GitLab 实例 2external_url "https://gitlab.example.com" # 必须使用 https 协议 3letsencrypt['contact_emails'] = ['foo@email.com'] # 可选 4 5## 容器注册表(可选),必须使用 https 协议 6registry_external_url "https://registry.example.com" 7#registry_nginx['ssl_certificate'] = "path/to/cert" # 必须缺失或被注释掉 8 9## Mattermost(可选),必须使用 https 协议 10mattermost_external_url "https://mattermost.example.com"- 证书每 90 天过期。您为 contact_emails 指定的电子邮件地址会在到期日期临近时收到警报。
- 极狐GitLab 实例是证书上的主要域名。其他服务,例如容器注册表,被添加为相同证书的备用域名。在上面的例子中,主域名是 gitlab.example.com,容器注册表域名是 registry.example.com。您不需要设置通配符证书。
-
重新配置极狐GitLab:
shellsudo gitlab-ctl reconfigure
如果 Let's Encrypt 未能颁发证书,请参阅 故障排除部分 以获取潜在解决方案。
自动更新证书
默认安装计划在每月的第 4 天午夜后进行更新。分钟数由 external_url 的值决定,以帮助分散上游 Let's Encrypt 服务器的负载。
要显式设置更新时间:
-
编辑 /etc/gitlab/gitlab.rb:
ruby# 每月第 7 天 12:30 更新 letsencrypt['auto_renew_hour'] = "12" letsencrypt['auto_renew_minute'] = "30" letsencrypt['auto_renew_day_of_month'] = "*/7" -
重新配置极狐GitLab:
shellsudo gitlab-ctl reconfigure
只有在证书过期 30 天时才会更新证书。例如,如果您设置为每月 1 日 00:00 更新,而证书在 31 日过期,那么证书将在更新之前过期。
自动更新由 go-crond 管理。如果需要,可以通过编辑 /etc/gitlab/gitlab.rb 来传递 CLI 参数给 go-crond:
rubycrond['flags'] = { 'log.json' = true, 'server.bind' = ':8040' }
要禁用自动更新:
-
编辑 /etc/gitlab/gitlab.rb:
rubyletsencrypt['auto_renew'] = false -
重新配置极狐GitLab:
shellsudo gitlab-ctl reconfigure
手动更新证书
使用以下任一命令手动更新 Let's Encrypt 证书:
shellsudo gitlab-ctl reconfigure
shellsudo gitlab-ctl renew-le-certs
前面的命令仅在证书接近过期时生成更新。
使用非 Let's Encrypt 的 ACME 服务器
您可以使用非 Let's Encrypt 的 ACME 服务器,并配置极狐GitLab 使用该服务器获取证书。一些提供自己 ACME 服务器的服务包括:
- ZeroSSL
- Buypass
- SSL.com
- step-ca
要配置极狐GitLab 使用自定义 ACME 服务器:
-
编辑 /etc/gitlab/gitlab.rb 并设置 ACME 端点:
rubyexternal_url 'https://example.com' letsencrypt['acme_staging_endpoint'] = 'https://ca.internal/acme/acme/directory' letsencrypt['acme_production_endpoint'] = 'https://ca.internal/acme/acme/directory'如果自定义 ACME 服务器提供,请使用暂存端点。首先检查暂存端点以确保 ACME 配置正确,然后再提交请求到 ACME 生产环境。在进行配置时避免 ACME 速率限制。
默认值为:
plaintexthttps://acme-staging-v02.api.letsencrypt.org/directory https://acme-v02.api.letsencrypt.org/directory -
重新配置极狐GitLab:
shellsudo gitlab-ctl reconfigure
将备用域名添加到证书中
默认情况下,极狐GitLab 设置证书的通用名称(CN)和主题备用名称(SAN)为 external_url 中指定的主机名。
您可以将额外的备用域名(或主题备用名称)添加到 Let's Encrypt 证书中。如果您希望使用 捆绑 NGINX 作为 其他后端应用程序的反向代理,这可能很有帮助。
备用域名的 DNS 记录必须指向极狐GitLab 实例。external_url 主机名必须包含在主题备用名称列表中。
要将备用域名添加到您的 Let's Encrypt 证书中:
-
编辑 /etc/gitlab/gitlab.rb 并添加备用域名:
ruby# 用逗号分隔多个域名 letsencrypt['alt_names'] = ['gitlab.example.com', 'another-application.example.com'] -
重新配置极狐GitLab:
shellsudo gitlab-ctl reconfigure
生成的主要极狐GitLab 应用程序的 Let's Encrypt 证书将包含指定的备用域名。生成的文件位于:
- /etc/gitlab/ssl/gitlab.example.com.key 用于密钥。
- /etc/gitlab/ssl/gitlab.example.com.crt 用于证书。
手动配置 HTTPS
NGINX 配置指示浏览器和客户端在接下来的 365 天内仅通过安全连接与您的极狐GitLab 实例进行通信,使用 HSTS。请参阅 配置 HTTP 严格传输安全性 以获取更多配置选项。如果启用 HTTPS,您必须在未来至少 24 个月内为您的实例提供安全连接。
要启用 HTTPS:
-
编辑 /etc/gitlab/gitlab.rb:
-
将 external_url 设置为您的域名。注意 URL 中的 https:
rubyexternal_url "https://gitlab.example.com" -
禁用 Let's Encrypt 集成:
rubyletsencrypt['enable'] = false极狐GitLab 尝试在每次重新配置时续订任何 Let's Encrypt 证书。如果您计划使用自己手动创建的证书,则必须禁用 Let's Encrypt 集成,否则证书可能会由于自动更新而被覆盖。
-
-
创建 /etc/gitlab/ssl 目录并将您的密钥和证书复制到那里:
shellsudo mkdir -p /etc/gitlab/ssl sudo chmod 755 /etc/gitlab/ssl sudo cp gitlab.example.com.key gitlab.example.com.crt /etc/gitlab/ssl/在示例中,主机名是 gitlab.example.com,所以 Linux 软件包安装会查找名为 /etc/gitlab/ssl/gitlab.example.com.key 的私钥和名为 /etc/gitlab/ssl/gitlab.example.com.crt 的公共证书文件。如果您愿意,您可以 使用不同的位置和证书名称。
您必须使用完整的证书链,以正确的顺序,防止客户端连接时出现 SSL 错误:首先是服务器证书,然后是所有中间证书,最后是根 CA。
-
可选项。如果 certificate.key 文件受到密码保护,NGINX 在重新配置极狐GitLab 时不会询问密码。在这种情况下,Linux 软件包安装会无声地失败,不会显示错误消息。
要为密钥文件指定密码,请将密码存储在文本文件中(例如 /etc/gitlab/ssl/key_file_password.txt),并将以下内容添加到 /etc/gitlab/gitlab.rb 中:
rubynginx['ssl_password_file'] = '/etc/gitlab/ssl/key_file_password.txt' -
重新配置极狐GitLab:
shellsudo gitlab-ctl reconfigure -
可选项。如果您正在使用防火墙,可能需要打开端口 443 以允许入站 HTTPS 流量:
shell1# UFW 示例(Debian,Ubuntu) 2sudo ufw allow https 3 4# lokkit 示例(RedHat,CentOS 6) 5sudo lokkit -s https 6 7# firewall-cmd(RedHat,Centos 7) 8sudo firewall-cmd --permanent --add-service=https 9sudo systemctl reload firewalld
如果您正在更新现有证书,请遵循 不同的过程。
将 HTTP 请求重定向到 HTTPS
默认情况下,当您指定 https 开头的 external_url 时,NGINX 不再监听端口 80 上的未加密 HTTP 流量。要将所有 HTTP 流量重定向到 HTTPS:
-
编辑 /etc/gitlab/gitlab.rb:
rubynginx['redirect_http_to_https'] = true -
重新配置极狐GitLab:
shellsudo gitlab-ctl reconfigure
此行为在使用 Let's Encrypt 集成 时默认启用。
更改默认 HTTPS 端口
如果您需要使用默认端口(443)以外的 HTTPS 端口,请在 external_url 中指定:
-
编辑 /etc/gitlab/gitlab.rb:
rubyexternal_url "https://gitlab.example.com:2443" -
重新配置极狐GitLab:
shellsudo gitlab-ctl reconfigure
更改默认 SSL 证书位置
如果您的主机名是 gitlab.example.com,Linux 软件包安装默认情况下会查找名为 /etc/gitlab/ssl/gitlab.example.com.key 的私钥和名为 /etc/gitlab/ssl/gitlab.example.com.crt 的公共证书。
要设置 SSL 证书的不同位置:
-
创建一个目录,给予适当的权限,并将 .crt 和 .key 文件放置在目录中:
shellsudo mkdir -p /mnt/gitlab/ssl sudo chmod 755 /mnt/gitlab/ssl sudo cp gitlab.key gitlab.crt /mnt/gitlab/ssl/您必须使用完整的证书链,以正确的顺序,防止客户端连接时出现 SSL 错误:首先是服务器证书,然后是所有中间证书,最后是根 CA。
-
编辑 /etc/gitlab/gitlab.rb:
rubynginx['ssl_certificate'] = "/mnt/gitlab/ssl/gitlab.crt" nginx['ssl_certificate_key'] = "/mnt/gitlab/ssl/gitlab.key" -
重新配置极狐GitLab:
shellsudo gitlab-ctl reconfigure
更新 SSL 证书
如果您的 SSL 证书内容已更新,但对 /etc/gitlab/gitlab.rb 没有进行配置更改,则重新配置极狐GitLab 不会影响 NGINX。相反,您必须让 NGINX 重新加载现有配置和新证书:
shellsudo gitlab-ctl hup nginx sudo gitlab-ctl hup registry
配置反向代理或负载均衡器 SSL 终止
默认情况下,如果 external_url 包含 https://,Linux 软件包安装会自动检测是否使用 SSL,并配置 NGINX 进行 SSL 终止。然而,如果您配置极狐GitLab 在反向代理或外部负载均衡器后运行,某些环境可能希望在极狐GitLab 应用程序之外终止 SSL。
要阻止捆绑的 NGINX 处理 SSL 终止:
-
编辑 /etc/gitlab/gitlab.rb:
rubynginx['listen_port'] = 80 nginx['listen_https'] = false -
重新配置极狐GitLab:
shellsudo gitlab-ctl reconfigure
外部负载均衡器可能需要访问极狐GitLab 端点,该端点返回 200 状态码(对于需要登录的安装,根页面返回 302 重定向到登录页面)。在这种情况下,建议利用 健康检查端点。
其他捆绑组件,如容器注册表、极狐GitLab Pages 或 Mattermost,使用类似的策略进行代理 SSL。使用 https:// 设置特定组件的 *_external_url,并在 nginx[...] 配置前加上组件名称前缀。例如,极狐GitLab 容器注册表配置以 registry_ 为前缀:
-
编辑 /etc/gitlab/gitlab.rb:
rubyregistry_external_url 'https://registry.example.com' registry_nginx['listen_port'] = 80 registry_nginx['listen_https'] = false同样的格式可以用于 Pages(pages_ 前缀)和 Mattermost(mattermost_ 前缀)。
-
重新配置极狐GitLab:
shellsudo gitlab-ctl reconfigure -
可选项。您可能需要配置反向代理或负载均衡器以转发某些头(例如 Host、X-Forwarded-Ssl、X-Forwarded-For、X-Forwarded-Port)到极狐GitLab(如果使用 Mattermost,则也需要)。如果您忘记此步骤,可能会看到不正确的重定向或错误,例如 "422 Unprocessable Entity" 或 "Can't verify CSRF token authenticity"。
某些云提供商服务,例如 AWS 证书管理器(ACM),不允许下载证书。这阻止了它们在极狐GitLab 实例上使用来终止 SSL。如果需要在这种云服务和极狐GitLab 之间使用 SSL,则必须在极狐GitLab 实例上使用其他证书。
使用自定义 SSL 密码
默认情况下,Linux 软件包使用 SSL 密码,这些密码是通过在 https://JihuLab.com 上进行测试和由极狐GitLab 社区贡献的各种最佳实践组合而来的。
要更改 SSL 密码:
-
编辑 /etc/gitlab/gitlab.rb:
rubynginx['ssl_ciphers'] = "CIPHER:CIPHER1" -
重新配置极狐GitLab:
shellsudo gitlab-ctl reconfigure
要启用 ssl_dhparam 指令:
-
生成 dhparams.pem:
shellopenssl dhparam -out /etc/gitlab/ssl/dhparams.pem 2048 -
编辑 /etc/gitlab/gitlab.rb:
rubynginx['ssl_dhparam'] = "/etc/gitlab/ssl/dhparams.pem" -
重新配置极狐GitLab:
shellsudo gitlab-ctl reconfigure
配置 HTTP/2 协议
默认情况下,当您指定您的极狐GitLab 实例通过 HTTPS 可访问时,HTTP/2 协议也会启用。
Linux 软件包设置与 HTTP/2 协议兼容的所需 SSL 密码。
如果您指定自己的 自定义 SSL 密码,而其中一个密码在 HTTP/2 密码黑名单中,当您尝试访问您的极狐GitLab 实例时,浏览器中会出现 INADEQUATE_SECURITY 错误。在这种情况下,请考虑从密码列表中删除有问题的密码。只有在您有非常特定的自定义设置时才需要更改密码。
如果更改密码不是一个选项,您可以禁用 HTTP/2 支持:
-
编辑 /etc/gitlab/gitlab.rb:
rubynginx['http2_enabled'] = false -
重新配置极狐GitLab:
shellsudo gitlab-ctl reconfigure
HTTP/2 设置仅适用于主要极狐GitLab 应用程序,而不适用于其他服务,如极狐GitLab Pages、容器注册表和 Mattermost。
启用双向 SSL 客户端认证
要要求 Web 客户端使用可信证书进行身份验证,您可以启用双向 SSL:
-
编辑 /etc/gitlab/gitlab.rb:
rubynginx['ssl_verify_client'] = "on" nginx['ssl_client_certificate'] = "/etc/pki/tls/certs/root-certs.pem" -
可选项。您可以配置在证书链中 NGINX 应验证的深度,然后决定客户端没有有效证书(默认值为 1)。编辑 /etc/gitlab/gitlab.rb:
rubynginx['ssl_verify_depth'] = "2" -
重新配置极狐GitLab:
shellsudo gitlab-ctl reconfigure
配置 HTTP 严格传输安全性(HSTS)
HSTS 设置仅适用于主要极狐GitLab 应用程序,而不适用于其他服务,如极狐GitLab Pages、容器注册表和 Mattermost。
HTTP 严格传输安全性(HSTS)默认启用,它通知浏览器它们应该只使用 HTTPS 联系网站。当浏览器访问极狐GitLab 实例时,即使用户显式输入一个简单的 HTTP URL(http://),它也会记住不再尝试不安全的连接。简单的 HTTP URL 会自动由浏览器重定向到 https:// 变体。
默认情况下,max_age 设置为两年,这是浏览器记住仅通过 HTTPS 连接的时间。
要更改最大年龄值:
-
编辑 /etc/gitlab/gitlab.rb:
rubynginx['hsts_max_age'] = 63072000 nginx['hsts_include_subdomains'] = false设置 max_age 为 0 禁用 HSTS。
-
重新配置极狐GitLab:
shellsudo gitlab-ctl reconfigure
安装自定义公共证书
一些环境连接到外部资源进行各种任务,极狐GitLab 允许这些连接使用 HTTPS,并支持使用自签名证书的连接。极狐GitLab 有自己的 ca-cert 捆绑包,您可以通过将单个自定义证书放入 /etc/gitlab/trusted-certs 目录中来添加证书。然后它们会被添加到捆绑包中。它们是使用 openssl 的 c_rehash 方法添加的,该方法仅适用于 单个证书。
Linux 软件包附带官方 Mozilla 受信任根认证机构的集合,用于验证证书的真实性。
对于使用自签名证书的安装,Linux 软件包提供了一种管理这些证书的方法。有关其工作原理的更多技术细节,请参阅此页面底部的 详细信息。
要安装自定义公共证书:
-
从您的私钥证书生成 PEM 或 DER 编码的公共证书。
-
仅将公共证书文件复制到 /etc/gitlab/trusted-certs 目录中。如果您有多节点安装,请确保在所有节点中复制证书。
- 在配置极狐GitLab 使用自定义公共证书时,默认情况下,极狐GitLab 期望找到一个以 .crt 扩展名命名的证书。例如,如果您的服务器地址是 https://gitlab.example.com,则证书应命名为 gitlab.example.com.crt。
- 如果极狐GitLab 需要连接到使用自定义公共证书的外部资源,请将证书存储在 /etc/gitlab/trusted-certs 目录中,并使用 .crt 扩展名命名文件。您不必根据相关外部资源的域名命名文件,但使用一致的命名方案会有所帮助。
要指定不同的路径和文件名,您可以 更改默认 SSL 证书位置。
-
重新配置极狐GitLab:
shellsudo gitlab-ctl reconfigure
使用自定义证书链
由于已知问题,如果使用自定义证书链,服务器、中间和根证书 必须 放入 /etc/gitlab/trusted-certs 目录中的单独文件中。
这适用于极狐GitLab 本身或极狐GitLab 必须连接的外部资源使用自定义证书链的情况。
例如,对于极狐GitLab 本身,您可以使用:
- /etc/gitlab/trusted-certs/example.gitlab.com.crt
- /etc/gitlab/trusted-certs/example.gitlab.com_intermediate.crt
- /etc/gitlab/trusted-certs/example.gitlab.com_root.crt
对于极狐GitLab 必须连接的外部资源,您可以使用:
- /etc/gitlab/trusted-certs/external-service.gitlab.com.crt
- /etc/gitlab/trusted-certs/external-service.gitlab.com_intermediate.crt
- /etc/gitlab/trusted-certs/external-service.gitlab.com_root.crt
极狐GitLab 和 SSL 的工作原理的详细信息
Linux 软件包包含其自己的 OpenSSL 库,并将所有已编译的程序(例如 Ruby、PostgreSQL 等)链接到此库。此库编译为在 /opt/gitlab/embedded/ssl/certs 中查找证书。
Linux 软件包通过将添加到 /etc/gitlab/trusted-certs/ 的任何证书符号链接到 /opt/gitlab/embedded/ssl/certs 来管理自定义证书,使用 c_rehash 工具。例如,假设我们将 customcacert.pem 添加到 /etc/gitlab/trusted-certs/:
shell1$ sudo ls -al /opt/gitlab/embedded/ssl/certs 2 3total 272 4drwxr-xr-x 2 root root 4096 Jul 12 04:19 . 5drwxr-xr-x 4 root root 4096 Jul 6 04:00 .. 6lrwxrwxrwx 1 root root 42 Jul 12 04:19 7f279c95.0 -> /etc/gitlab/trusted-certs/customcacert.pem 7-rw-r--r-- 1 root root 263781 Jul 5 17:52 cacert.pem 8-rw-r--r-- 1 root root 147 Feb 6 20:48 README
这里我们看到证书的指纹是 7f279c95,它链接到自定义证书。
当我们发出 HTTPS 请求时会发生什么?让我们看一个简单的 Ruby 程序:
ruby#!/opt/gitlab/embedded/bin/ruby require 'openssl' require 'net/http' Net::HTTP.get(URI('https://www.google.com'))
这就是幕后的工作原理:
- "require openssl" 行导致解释器加载 /opt/gitlab/embedded/lib/ruby/2.3.0/x86_64-linux/openssl.so。
- Net::HTTP 调用然后尝试读取 /opt/gitlab/embedded/ssl/certs/cacert.pem 中的默认证书捆绑包。
- 进行 SSL 协商。
- 服务器发送其 SSL 证书。
- 如果发送的证书被捆绑包覆盖,则 SSL 成功完成。
- 否则,OpenSSL 可以通过搜索与其指纹匹配的文件来验证其他证书。例如,如果证书的指纹是 7f279c95,OpenSSL 将尝试读取 /opt/gitlab/embedded/ssl/certs/7f279c95.0。
注意,OpenSSL 库支持定义 SSL_CERT_FILE 和 SSL_CERT_DIR 环境变量。前者定义要加载的默认证书捆绑包,而后者定义要搜索更多证书的目录。如果您已将证书添加到 trusted-certs 目录,则不应该需要这些变量。然而,如果因为某些原因您需要设置它们,它们可以作为 环境变量定义。例如:
rubygitlab_rails['env'] = {"SSL_CERT_FILE" => "/usr/lib/ssl/private/customcacert.pem"}
故障排除
请参阅我们的 SSL 故障排除指南。