为 Linux 软件包安装配置 SSL
Tier: 基础版,专业版,旗舰版
Offering: 私有化部署
Linux 软件包支持 SSL 配置的几种常见用例。
这些配置说明适用于极狐GitLab 19.2 及更高版本。如果您正在配置极狐GitLab 19.1 及更早版本,请将 gitlab_rails['nginx'] 替换为顶层 nginx 键。例如,将 gitlab_rails['nginx']['redirect_http_to_https'] 替换为 nginx['redirect_http_to_https']。使用顶层 nginx 键可以工作,但已弃用。
默认情况下,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 集成
如果 external_url 使用 HTTPS 协议设置且未配置其他证书,则默认启用 Let's Encrypt。
先决条件:
- 端口 80 和 443 必须可供运行验证检查的公共 Let's Encrypt 服务器访问。该验证 不适用于非标准端口。 如果环境是私有的或隔离的,certbot(Let's Encrypt 使用的工具)提供了一种 手动方法 来安装 Let's Encrypt 证书。
要启用 Let's Encrypt:
-
编辑 /etc/gitlab/gitlab.rb 并添加或更改以下条目:
ruby1## GitLab instance 2external_url "https://gitlab.example.com" # Must use https protocol 3letsencrypt['contact_emails'] = ['foo@email.com'] # Optional 4 5## Container Registry (optional), must use https protocol 6registry_external_url "https://registry.example.com" 7#registry['nginx']['ssl_certificate'] = "path/to/cert" # Must be absent or commented out 8 9## GitLab Pages (optional), must use https protocol 10pages_external_url "https://pages.example.com" 11gitlab_pages['namespace_in_path'] = true # Required to enable single-domain sites- 证书每 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# Renew every 7th day of the month at 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 向 go-crond 传递 CLI 参数:
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 服务器的服务包括:
要将极狐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# Separate multiple domains with commas 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/ sudo chmod 644 /etc/gitlab/ssl/gitlab.example.com.crt sudo chmod 600 /etc/gitlab/ssl/gitlab.example.com.key在示例中,主机名是 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:
rubygitlab_rails['nginx']['ssl_password_file'] = '/etc/gitlab/ssl/key_file_password.txt' -
重新配置极狐GitLab:
shellsudo gitlab-ctl reconfigure -
可选。如果您使用防火墙,则可能需要打开端口 443 以允许入站 HTTPS 流量:
shell1# UFW example (Debian, Ubuntu) 2sudo ufw allow https 3 4# lokkit example (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:
rubygitlab_rails['nginx']['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:
rubygitlab_rails['nginx']['ssl_certificate'] = "/mnt/gitlab/ssl/gitlab.crt" gitlab_rails['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,并为 SSL 终止配置 NGINX。 但是,如果您将极狐GitLab 配置为在反向代理或外部负载均衡器后面运行, 某些环境可能希望在极狐GitLab 应用程序外部终止 SSL。
要防止捆绑的 NGINX 处理 SSL 终止:
-
编辑 /etc/gitlab/gitlab.rb:
rubygitlab_rails['nginx']['listen_port'] = 80 gitlab_rails['nginx']['listen_https'] = false -
重新配置极狐GitLab:
shellsudo gitlab-ctl reconfigure
外部负载均衡器可能需要访问返回 200 状态代码的极狐GitLab 端点 (对于需要登录的安装,根 页面会返回 302 重定向到登录页面)。在这种情况下,建议利用 健康检查端点。
其他捆绑组件,如容器镜像仓库或 GitLab Pages, 对代理 SSL 使用类似的策略。使用 https:// 设置特定组件的 *_external_url,并在该组件的配置键下配置 nginx 设置。例如, 极狐GitLab 容器镜像仓库使用 registry['nginx']:
-
编辑 /etc/gitlab/gitlab.rb:
rubyregistry_external_url 'https://registry.example.com' registry['nginx']['listen_port'] = 80 registry['nginx']['listen_https'] = false相同的格式可用于 Pages(gitlab_pages['nginx'])。
-
重新配置极狐GitLab:
shellsudo gitlab-ctl reconfigure -
可选。您可能需要配置反向代理或负载均衡器以将某些标头(例如 Host、X-Forwarded-Ssl、X-Forwarded-For、 X-Forwarded-Port)转发到极狐GitLab。如果您忘记 此步骤,您可能会看到不正确的重定向或错误,例如 “422 Unprocessable Entity”或“Can't verify CSRF token authenticity”。
某些云提供商服务(例如 AWS Certificate Manager (ACM))不允许 下载证书。这阻止了它们在极狐GitLab 实例上用于终止。 如果希望在此类云服务和极狐GitLab 之间使用 SSL, 则必须在极狐GitLab 实例上使用另一个证书。
使用自定义 SSL 密码套件
默认情况下,Linux 软件包 使用 SSL 密码套件,这些密码套件是在 https://gitlab.com 上测试以及 GitLab 社区贡献的各种最佳实践的组合。
要更改 SSL 密码套件:
-
编辑 /etc/gitlab/gitlab.rb:
rubygitlab_rails['nginx']['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:
rubygitlab_rails['nginx']['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 协议的更多信息,请查看 NGINX HTTP/2 白皮书。
如果无法更改密码套件,您可以禁用 HTTP/2 支持:
-
编辑 /etc/gitlab/gitlab.rb:
rubygitlab_rails['nginx']['http2_enabled'] = false -
重新配置极狐GitLab:
shellsudo gitlab-ctl reconfigure
HTTP/2 设置仅适用于极狐GitLab 主应用程序,不适用于其他服务, 例如 GitLab Pages 和容器镜像仓库。
启用双向 SSL 客户端认证
要要求 Web 客户端使用受信任的证书进行认证,您可以 启用双向 SSL:
-
编辑 /etc/gitlab/gitlab.rb:
rubygitlab_rails['nginx']['ssl_verify_client'] = "on" gitlab_rails['nginx']['ssl_client_certificate'] = "/etc/pki/tls/certs/root-certs.pem" -
可选。您可以配置 NGINX 在决定客户端没有有效证书之前应验证证书链的深度(默认为 1)。 编辑 /etc/gitlab/gitlab.rb:
rubygitlab_rails['nginx']['ssl_verify_depth'] = "2" -
重新配置极狐GitLab:
shellsudo gitlab-ctl reconfigure
配置 HTTP 严格传输安全 (HSTS)
HSTS 设置仅适用于极狐GitLab 主应用程序,不适用于其他服务, 例如 GitLab Pages 和容器镜像仓库。
HTTP 严格传输安全 (HSTS) 默认启用,它告知浏览器 它们只应使用 HTTPS 联系网站。浏览器即使只访问过极狐GitLab 实例一次, 也会记住不再尝试不安全的连接, 即使用户明确输入纯 HTTP URL(http://)。纯 HTTP URL 会被浏览器自动重定向到 https:// 变体。
默认情况下,max_age 设置为两年,这是浏览器记住 仅通过 HTTPS 连接的时间。
要更改 max age 值:
-
编辑 /etc/gitlab/gitlab.rb:
rubygitlab_rails['nginx']['hsts_max_age'] = 63072000 gitlab_rails['nginx']['hsts_include_subdomains'] = false将 max_age 设置为 0 会禁用 HSTS。
-
重新配置极狐GitLab:
shellsudo gitlab-ctl reconfigure
有关 HSTS 和 NGINX 的更多信息,请参阅 https://blog.nginx.org/blog/http-strict-transport-security-hsts-and-nginx。
安装自定义公共证书
某些环境会为各种任务连接到外部资源,极狐GitLab 允许这些连接使用 HTTPS,并支持使用自签名证书的连接。 极狐GitLab 有自己的 ca-cert 捆绑包,您可以通过将 单个自定义证书放入 /etc/gitlab/trusted-certs 目录来添加证书。然后它们 会被添加到捆绑包中。它们使用 openssl rehash 命令添加,该命令 仅适用于 单个证书。
Linux 软件包附带官方的 Mozilla 受信任根证书颁发机构集合,用于验证证书真实性。
对于使用自签名证书的安装,Linux 软件包 提供了一种管理这些证书的方法。有关其工作原理的更多技术细节, 请参阅本页底部的 详细信息。
要安装自定义公共证书:
-
从您的私钥证书生成 PEM 或 DER 编码的公共证书。
-
仅将公共证书文件复制到 /etc/gitlab/trusted-certs 目录。 如果您有多节点安装,请确保将证书复制到所有节点。
- 配置极狐GitLab 使用自定义公共证书时,默认情况下,极狐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 软件包通过使用 openssl rehash 工具,将添加到 /etc/gitlab/trusted-certs/ 的任何证书符号链接到 /opt/gitlab/embedded/ssl/certs 来管理自定义证书。例如,假设我们将 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 故障排除指南。