- 启用 Let’s Encrypt 集成
- 手动配置 HTTPS
- 配置反向代理或负载均衡器 SSL 终止
- 使用自定义 SSL 密码
- 配置 HTTP/2 协议
- 启用 2-way SSL 客户端身份验证
- 配置 HTTP Strict Transport Security(HSTS)
- 安装自定义公共证书
- 极狐GitLab 和 SSL 的工作实现细节
- 故障排除
为 Linux 软件包安装配置 SSL
Linux 包支持 SSL 配置的几种常见用例。
默认情况下,HTTPS 未启用。要启用 HTTPS,您可以:
- 使用 Let’s Encrypt 免费的自动 HTTPS。
- 使用您自己的证书手动配置 HTTPS。
下表显示了每个极狐GitLab 服务支持的方法。
服务 | 手动 SSL | Let’s Encrypt |
---|---|---|
极狐GitLab Instance Domain | 是 | 是 |
Container Registry | 是 | 是 |
Mattermost | 是 | 是 |
极狐GitLab Pages | 是 | No |
启用 Let’s Encrypt 集成
如果 external_url
设置为 HTTPS 协议且未配置其他证书,则默认启用 Let’s Encrypt。
先决条件:
- 运行验证检查的公共 Let’s Encrypt 服务器必须可以访问端口
80
和443
。验证不适用于非标准端口。如果环境是私有的或隔离的,certbot(Let’s Encrypt 使用的工具)提供了安装 Let’s Encrypt 证书的手动方法。
要启用 Let’s Encrypt:
-
编辑
/etc/gitlab/gitlab.rb
并添加或更改以下条目:## GitLab instance external_url "https://gitlab.example.com" # Must use https protocol letsencrypt['contact_emails'] = ['foo@email.com'] # Optional ## Container Registry (optional), must use https protocol registry_external_url "https://registry.example.com" #registry_nginx['ssl_certificate'] = "path/to/cert" # Must be absent or commented out ## Mattermost (optional), must use https protocol mattermost_external_url "https://mattermost.example.com"
- 证书每 90 天到期一次。当到期日期临近时,您为
contact_emails
指定的电子邮件地址会收到警报。 - 极狐GitLab 实例是证书上的主域名。Container Registry 等其他服务作为备用域名添加到同一个证书中。在上面的示例中,主域名是
gitlab.example.com
,Container Registry 域名是registry.example.com
。您不需要设置通配符证书。
- 证书每 90 天到期一次。当到期日期临近时,您为
-
重新配置极狐GitLab:
sudo gitlab-ctl reconfigure
如果 Let’s Encrypt 无法颁发证书,请参阅故障排除部分以获取可能的解决方案。
自动更新证书
默认安装会在每月第 4 天的午夜后安排更新。
在哪一分钟更新由 external_url
中的值确定,帮助在上游 Let’s Encrypt 服务器上分配负载。
要明确设置更新时间:
-
编辑
/etc/gitlab/gitlab.rb
:# 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:
sudo gitlab-ctl reconfigure
要禁用自动更新:
-
编辑
/etc/gitlab/gitlab.rb
:letsencrypt['auto_renew'] = false
-
重新配置极狐GitLab:
sudo gitlab-ctl reconfigure
手动更新证书
使用以下任一命令手动更新 Let’s Encrypt 证书:
sudo gitlab-ctl reconfigure
sudo gitlab-ctl renew-le-certs
仅当证书即将到期时,前面的命令才会生成更新。 如果在更新期间遇到错误,考虑上行速率限制。
使用 Let’s Encrypt 以外的 ACME 服务器
您可以使用 Let’s Encrypt 以外的 ACME 服务器,并将极狐GitLab 配置为使用它来获取证书。提供自己的 ACME 服务器的服务有:
要将极狐GitLab 配置为使用自定义 ACME 服务器:
-
编辑
/etc/gitlab/gitlab.rb
并设置 ACME 端点:external_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 速率限制。
默认值:
https://acme-staging-v02.api.letsencrypt.org/directory https://acme-v02.api.letsencrypt.org/directory
-
重新配置极狐GitLab:
sudo gitlab-ctl reconfigure
向证书添加备用域
您可以将备用域(或主备用名称)添加到 Let’s Encrypt 证书中。 如果您想使用捆绑的 NGINX 作为其他后端应用程序的反向代理,这会很有用。
备用域的 DNS 记录必须指向极狐GitLab 实例。
要将备用域添加到 Let’s Encrypt 证书中:
-
编辑
/etc/gitlab/gitlab.rb
并添加备用域:# Separate multiple domains with commas letsencrypt['alt_names'] = ['another-application.example.com']
-
重新配置极狐GitLab:
sudo gitlab-ctl reconfigure
为主要的极狐GitLab 应用程序生成的 Let’s Encrypt 证书将包括指定的备用域。生成的文件位于:
- 对于密钥:
/etc/gitlab/ssl/gitlab.example.com.key
- 对于证书:
/etc/gitlab/ssl/gitlab.example.com.crt
手动配置 HTTPS
要启用 HTTPS:
- 编辑
/etc/gitlab/gitlab.rb
:-
将
external_url
设置为您的域名。请注意 URL 中的https
:external_url "https://gitlab.example.com"
-
禁用 Let’s Encrypt 集成:
letsencrypt['enable'] = false
极狐GitLab 尝试在每次重新配置时更新任何 Let’s Encrypt 证书。如果您打算使用自己手动创建的证书,则必须禁用 Let’s Encrypt 集成,否则证书可能会由于自动更新而被覆盖。
-
-
创建
/etc/gitlab/ssl
目录并在那里复制您的密钥和证书:sudo 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
文件受密码保护,当您重新配置极狐GitLab 时,NGINX 不会要求输入密码。在这种情况下,Linux 软件包安装会静默失败,没有错误消息。要指定密钥文件的密码,请将密码存储在文本文件中(例如,
/etc/gitlab/ssl/key_file_password.txt
),并将以下内容添加到/etc/gitlab/gitlab.rb
:nginx['ssl_password_file'] = '/etc/gitlab/ssl/key_file_password.txt'
-
重新配置极狐GitLab:
sudo gitlab-ctl reconfigure
-
可选。如果您使用防火墙,则可能必须打开端口 443 以允许入站 HTTPS 流量:
# UFW example (Debian, Ubuntu) sudo ufw allow https # lokkit example (RedHat, CentOS 6) sudo lokkit -s https # firewall-cmd (RedHat, Centos 7) sudo firewall-cmd --permanent --add-service=https sudo systemctl reload firewalld
如果您要更新现有证书,请遵循不同的流程。
将 HTTP
请求重定向到 HTTPS
默认情况下,当您指定以 https
开头的 external_url
时,NGINX 不再侦听端口 80 上未加密的 HTTP 流量。要将所有 HTTP 流量重定向到 HTTPS:
-
编辑
/etc/gitlab/gitlab.rb
:nginx['redirect_http_to_https'] = true
-
重新配置极狐GitLab:
sudo gitlab-ctl reconfigure
更改默认 HTTPS 端口
如果您需要使用默认端口 (443) 以外的 HTTPS 端口,请将其指定为 external_url
的一部分:
-
编辑
/etc/gitlab/gitlab.rb
:external_url "https://gitlab.example.com:2443"
-
重新配置极狐GitLab:
sudo 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
文件放在目录中:sudo 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
:nginx['ssl_certificate'] = "/mnt/gitlab/ssl/gitlab.crt" nginx['ssl_certificate_key'] = "/mnt/gitlab/ssl/gitlab.key"
-
重新配置极狐GitLab:
sudo gitlab-ctl reconfigure
更新 SSL 证书
如果您的 SSL 证书的内容已更新,但没有对 /etc/gitlab/gitlab.rb
进行配置更改,则重新配置极狐GitLab 不会影响 NGINX。相反,您必须使 NGINX 优雅地重新加载现有配置和新证书:
sudo 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
:nginx['listen_port'] = 80 nginx['listen_https'] = false
-
重新配置极狐GitLab:
sudo gitlab-ctl reconfigure
外部负载均衡器可能需要访问返回 200
状态码的极狐GitLab 端点(对于需要登录的安装实例,根页面返回 302
重定向到登录页面)。在这种情况下,建议利用健康检查端点。
其他捆绑的组件,如 Container Registry、极狐GitLab Pages 或 Mattermost,对代理 SSL 使用类似的策略。使用 https://
设置特定组件的 *_external_url
,并在 nginx[...]
配置前加上组件名称。例如,Container Registry 配置以 registry_
为前缀:
- 编辑
/etc/gitlab/gitlab.rb
:
registry_external_url 'https://registry.example.com'
registry_nginx['listen_port'] = 80
registry_nginx['listen_https'] = false
相同的格式可用于 Pages(pages_
前缀)和 Mattermost(mattermost_
前缀)。
-
重新配置极狐GitLab:
sudo gitlab-ctl reconfigure
-
可选。您可能需要配置反向代理或负载均衡器以将某些 headers(例如
Host
、X-Forwarded-Ssl
、X-Forwarded-For
、X-Forwarded-Port
)转发到极狐GitLab(和 Mattermost,如果您使用)。如果您忘记了这一步,您可能会看到不正确的重定向或错误,例如 “422 Unprocessable Entity” 或 “Can’t verify CSRF token authenticity”。
某些云提供商服务,例如 AWS Certificate Manager (ACM),并非都下载证书。这可以防止它们被用来终止极狐GitLab 实例。如果此类云服务和极狐GitLab 之间需要 SSL,则必须在极狐GitLab 实例上使用另一个证书。
使用自定义 SSL 密码
要更改 SSL 密码:
-
编辑
/etc/gitlab/gitlab.rb
:nginx['ssl_ciphers'] = "CIPHER:CIPHER1"
-
重新配置极狐GitLab:
sudo gitlab-ctl reconfigure
要启用 ssl_dhparam
指令:
-
生成
dhparams.pem
:openssl dhparam -out /etc/gitlab/ssl/dhparams.pem 2048
-
编辑
/etc/gitlab/gitlab.rb
:nginx['ssl_dhparam'] = "/etc/gitlab/ssl/dhparams.pem"
-
重新配置极狐GitLab:
sudo 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
:nginx['http2_enabled'] = false
-
重新配置极狐GitLab:
sudo gitlab-ctl reconfigure
启用 2-way SSL 客户端身份验证
要要求 Web 客户端使用受信任的证书进行身份验证,您可以启用 2-way SSL:
-
编辑
/etc/gitlab/gitlab.rb
:nginx['ssl_verify_client'] = "on" nginx['ssl_client_certificate'] = "/etc/pki/tls/certs/root-certs.pem"
-
可选。您可以配置 NGINX,在确定客户端没有有效证书之前验证证书链的深度(默认为
1
)。编辑/etc/gitlab/gitlab.rb
:nginx['ssl_verify_depth'] = "2"
-
重新配置极狐GitLab:
sudo gitlab-ctl reconfigure
配置 HTTP Strict Transport Security(HSTS)
HTTP Strict Transport Security(HSTS)默认启用,它通知浏览器他们应该只使用 HTTPS 联系网站。当浏览器访问极狐GitLab 实例一次时,它会记住不再尝试不安全的连接,即使用户明确输入纯 HTTP URL (http://
)。浏览器会自动将纯 HTTP URL 重定向到 https://
变体。
默认情况下, max_age
设置为两年,这是浏览器记住只通过 HTTPS 连接的时间。
要更改最大 age 值:
-
编辑
/etc/gitlab/gitlab.rb
:nginx['hsts_max_age'] = 63072000 nginx['hsts_include_subdomains'] = false
Setting
max_age
to0
disables HSTS. -
重新配置极狐GitLab:
sudo gitlab-ctl reconfigure
有关 HSTS 和 NGINX 的更多信息,请参阅 https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/。
安装自定义公共证书
一些环境连接到外部资源以执行各种任务。Linux 软件包允许这些连接使用 HTTPS,并支持使用自签名证书的连接。极狐GitLab 有自己的 ca-cert 包,您可以通过将各个自定义证书放在 /etc/gitlab/trusted-certs
目录中来添加证书,然后将它们添加到捆绑包中,它们是使用 openssl 的 c_rehash
方法添加的,该方法仅适用于单个证书。
极狐GitLab 附带了官方的 CAcert.org 可信根证书颁发机构集合,用于验证证书的真实性。
c_rehash
依赖需要一个 perl 解释器来正确地符号链接证书。Perl 目前未捆绑在 Omnibus GitLab 中。- 从您的私钥证书生成 PEM 或 DER 编码的公共证书。
- 仅将公共证书文件复制到
/etc/gitlab/trusted-certs
目录中。默认情况下,系统期望找到一个以您的极狐GitLab URL 为标题的证书,扩展名为.crt
。 例如,如果您的服务器地址是https://gitlab.example.com
,则证书应命名为gitlab.example.com.crt
。要指定不同的路径和文件名,您可以更改默认 SSL 证书位置。如果您使用多节点安装实例,请确保在所有节点中复制证书。 -
重新配置极狐GitLab:
sudo 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 软件包通过使用 c_rehash 将添加到 /etc/gitlab/trusted-certs/
的任何证书链接到 /opt/gitlab/embedded/ssl/certs
来管理自定义证书。例如,假设我们将 customcacert.pem
添加到 /etc/gitlab/trusted-certs/
:
$ sudo ls -al /opt/gitlab/embedded/ssl/certs
total 272
drwxr-xr-x 2 root root 4096 Jul 12 04:19 .
drwxr-xr-x 4 root root 4096 Jul 6 04:00 ..
lrwxrwxrwx 1 root root 42 Jul 12 04:19 7f279c95.0 -> /etc/gitlab/trusted-certs/customcacert.pem
-rw-r--r-- 1 root root 263781 Jul 5 17:52 cacert.pem
-rw-r--r-- 1 root root 147 Feb 6 20:48 README
证书的指纹为 7f279c95
,它链接到自定义证书。
当我们发出 HTTPS 请求时会发生什么?让我们以一个简单的 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”目录中,这些变量不是必需的。但是,如果由于某种原因需要设置它们,它们可以定义为环境变量。例如:
gitlab_rails['env'] = {"SSL_CERT_FILE" => "/usr/lib/ssl/private/customcacert.pem"}
故障排除
请查看我们的 SSL 故障排除指南。