- 有用的 OpenSSL 调试命令
- 常见的 SSL 错误
- 证书导致重新配置失败
- 丢失或跳过自定义证书
- 未检测到自定义证书
- Let’s Encrypt 证书由未知机构签署
- 重新配置时 Let’s Encrypt 失败
- 在极狐GitLab 中使用内部 CA 证书
- X.509 键值不匹配错误
- 将极狐GitLab Runner 与配置有内部 CA 证书或自签名证书的极狐GitLab 实例一起使用
- 镜像使用自签名 SSL 证书的远端极狐GitLab 仓库
- 由于内部证书或自签名证书的原因,无法执行 Git 操作
- SSL_connect 版本号错误
schannel: SEC_E_UNTRUSTED_ROOT
- 升级到 OpenSSL 3
故障排除
此页面包含使用极狐GitLab 时可能遇到的常见 SSL 相关错误和场景列表,作为 SSL 文档的主要补充:
有用的 OpenSSL 调试命令
有时,通过直接在源中查看 SSL 证书链,可以更好地了解它是有帮助的。这些命令是用于诊断和调试的标准 OpenSSL 工具库的一部分。
-
通过 HTTPS 执行与主机的测试连接。将
HOSTNAME
替换为您的极狐GitLab URL(不包括 HTTPS),并将port
替换为提供 HTTPS 连接的端口(通常为 443):echo | /opt/gitlab/embedded/bin/openssl s_client -connect HOSTNAME:port
echo
命令向服务器发送一个空请求,导致它关闭连接而不是等待额外的输入。您可以使用相同的命令来测试远程主机(例如,托管外部仓库的服务器),方法是将HOSTNAME:port
替换为远程主机的域名和端口号。此命令的输出显示证书链、服务器提供的任何公共证书,以及验证或连接可能发生的错误。这样可以快速检查 SSL 设置的任何直接问题。
-
使用
x509
以文本形式查看证书的详细信息。 请务必将/path/to/certificate.crt
替换为证书的路径:/opt/gitlab/embedded/bin/openssl x509 -in /path/to/certificate.crt -text -noout
例如,极狐GitLab 会自动从 Let’s Encrypt 获取证书并将其放置在
/etc/gitlab/ssl/hostname.crt
。您可以使用带有该路径的x509
命令来快速显示证书的信息(例如,主机名、颁发者、有效期等)。如果证书存在问题,将会出现错误。
-
从服务器获取证书并对其进行解码。这结合了上述两个命令来获取服务器的 SSL 证书并将其解码为文本:
echo | /opt/gitlab/embedded/bin/openssl s_client -connect HOSTNAME:port | /opt/gitlab/embedded/bin/openssl x509 -text -noout
常见的 SSL 错误
-
SSL certificate problem: unable to get local issuer certificate
此错误表示客户端无法获取根 CA。要解决此问题,您可以尝试新人在客户端上连接的服务器的根 CA,或修改证书 使得在您尝试连接的服务器上显示完整的链式证书。
建议使用完整的证书链,以防止客户端连接时出现 SSL 错误。完整的证书链顺序应首先包含服务器证书,然后是所有中间证书,最后是根 CA。 -
unable to verify the first certificate
此错误表明服务器提供了不完整的证书链。要修复此错误,您需要用完整链式证书替换服务器的证书。 完整的证书链顺序应首先包含服务器证书,然后是所有中间证书,最后是根 CA。
如果您是在使用系统 OpenSSL 应用而不是/opt/gitlab/embedded/bin/openssl
应用时遇到了此错误,请确保您在操作系统级别更新了 CA 证书以便修复此问题。 -
certificate signed by unknown authority
此错误表明客户端不信任证书或 CA。要修复此错误,连接到服务器的客户端需要信任证书或 CA。
-
SSL certificate problem: self signed certificate in certificate chain
此错误表明客户端不信任证书或 CA。要修复此错误,连接到服务器的客户端需要信任证书或 CA。
-
x509: certificate relies on legacy Common Name field, use SANs instead
此错误表明必须在证书中配置 SANs(subjectAltName)。
证书导致重新配置失败
ERROR: Not a certificate: /opt/gitlab/embedded/ssl/certs/FILE. Move it from /opt/gitlab/embedded/ssl/certs to a different location and reconfigure again.
检查 /opt/gitlab/embedded/ssl/certs
并删除除 README.md
之外的任何不是有效 X.509 证书的文件。
gitlab-ctl reconfigure
构造从自定义公共证书的 subject 哈希命名的链接,并将它们放在 /opt/gitlab/embedded/ssl/certs/
中。/opt/gitlab/embedded/ssl/certs/
中损坏的链接将被自动删除。存储在 /opt/gitlab/embedded/ssl/certs/
中的 cacert.pem
和 README.md
以外的文件将被移动到 /etc/gitlab/trusted-certs/
中。丢失或跳过自定义证书
GitLab versions 8.9.0, 8.9.1, and 8.9.2 all mistakenly used the
/etc/gitlab/ssl/trusted-certs/
directory. This directory is safe to remove if it
is empty. If it still contains custom certificates then move them to /etc/gitlab/trusted-certs/
and run gitlab-ctl reconfigure
.
如果没有在 /opt/gitlab/embedded/ssl/certs/
中创建链接,你会看到运行gitlab-ctl reconfigure
后出现 “Skipping cert.pem
” 消息,这意味着可能存在以下四个问题之一:
-
/etc/gitlab/trusted-certs/
中的文件是链接 - 该文件不是有效的 PEM 或 DER 编码的证书
- Perl 未安装在 c_rehash 正确链接证书所需的操作系统上
- 证书包含字符串
TRUSTED
使用以下命令测试证书的有效性:
/opt/gitlab/embedded/bin/openssl x509 -in /etc/gitlab/trusted-certs/example.pem -text -noout
/opt/gitlab/embedded/bin/openssl x509 -inform DER -in /etc/gitlab/trusted-certs/example.der -text -noout
无效的证书文件会产生以下输出:
unable to load certificate
140663131141784:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:701:Expecting: TRUSTED CERTIFICATE
测试 c_rehash
是否由于缺少 perl 解释器而没有链接证书:
$ /opt/gitlab/embedded/bin/c_rehash /etc/gitlab/trusted-certs
bash: /opt/gitlab/embedded/bin/c_rehash: /usr/bin/perl: bad interpreter: No such file or directory
如果您看到此消息,则需要使用发行版的包管理器安装 perl。
如果您检查证书本身,请查找字符串 TRUSTED
:
-----BEGIN TRUSTED CERTIFICATE-----
...
-----END TRUSTED CERTIFICATE-----
如果像上面的例子一样,然后尝试删除字符串 TRUSTED
并再次运行 gitlab-ctl reconfigure
。
未检测到自定义证书
如果在执行 gitlab-ctl reconfigure
命令后:
- 在
/opt/gitlab/embedded/ssl/certs/
中没有创建链接; - 您已将自定义证书放在
/etc/gitlab/trusted-certs/
中;并且 - 您未看到任何跳过的或链接的自定义证书消息
您可能会遇到 Linux 软件包安装认为已添加自定义证书的问题。
要解决,请删除受信任的证书目录哈希:
rm /var/opt/gitlab/trusted-certs-directory-hash
然后再次运行gitlab-ctl reconfigure
。重新配置应现在检测并链接您的自定义证书。
Let’s Encrypt 证书由未知机构签署
Let’s Encrypt 集成的初始实现仅使用证书,而不是完整的证书链。
从 10.5.4 开始,就已经开始使用完整的证书链了。对于已经在使用证书的安装,在续订逻辑指示证书即将到期之前不会发生切换。要尽快强制执行,请运行以下命令:
rm /etc/gitlab/ssl/HOSTNAME*
gitlab-ctl reconfigure
其中 HOSTNAME 是证书的主机名。
重新配置时 Let’s Encrypt 失败
重新配置时,Let’s Encrypt 可能会在以下常见情况下失败:
-
如果您的服务器无法访问 Let’s Encrypt 验证服务器,Let’s Encrypt 可能会失败,反之亦然:
letsencrypt_certificate[gitlab.domain.com] (letsencrypt::http_authorization line 3) had an error: RuntimeError: acme_certificate[staging] (/opt/gitlab/embedded/cookbooks/cache/cookbooks/letsencrypt/resources/certificate.rb line 20) had an error: RuntimeError: [gitlab.domain.com] Validation failed for domain gitlab.domain.com
如果您由于 Let’s Encrypt 而在重新配置极狐GitLab 时遇到问题确保您的端口 80 和 443 已打开并可访问。
-
您的域名的证书颁发机构授权 (CAA) 记录不允许 Let’s Encrypt 为您的域名颁发证书。在重新配置输出中查找以下错误:
letsencrypt_certificate[gitlab.domain.net] (letsencrypt::http_authorization line 5) had an error: RuntimeError: acme_certificate[staging] (/opt/gitlab/embedded/cookbooks/cache/cookbooks/letsencrypt/resources/certificate.rb line 25) had an error: RuntimeError: ruby_block[create certificate for gitlab.domain.net] (/opt/gitlab/embedded/cookbooks/cache/cookbooks/acme/resources/certificate.rb line 108) had an error: RuntimeError: [gitlab.domain.com] Validation failed, unable to request certificate
-
如果您使用的是例如
gitlab.example.com
之类的测试域名,但没有证书,您将看到上面显示的unable to request certificate
。在这种情况下,通过在/etc/gitlab/gitlab.rb
中设置letsencrypt['enable'] = false
来禁用 Let’s Encrypt。 -
Let’s Encrypt 实施速率限制,位于顶级域。如果您使用云提供商的主机名作为
external_url
,例如*.cloudapp.azure.com
,Let’s Encrypt 将对azure.com
实施限制,这可能会使证书创建不完整。这种情况下,您可以尝试手动更新 Let’s Encrypt 证书:
sudo gitlab-ctl renew-le-certs
在极狐GitLab 中使用内部 CA 证书
使用内部 CA 证书配置极狐GitLab 实例后,您可能无法使用各种 CLI 工具访问它。您可能会遇到以下问题:
-
curl
失败:curl "https://gitlab.domain.tld" curl: (60) SSL certificate problem: unable to get local issuer certificate More details here: https://curl.haxx.se/docs/sslcerts.html
-
使用Rails 控制台进行的测试也失败:
uri = URI.parse("https://gitlab.domain.tld") http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true http.verify_mode = 1 response = http.request(Net::HTTP::Get.new(uri.request_uri)) ... Traceback (most recent call last): 1: from (irb):5 OpenSSL::SSL::SSLError (SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get local issuer certificate))
- 从此极狐GitLab 实例设置镜像时,显示错误
SSL certificate problem: unable to get local issuer certificate
。 -
openssl
在指定证书路径时有效:/opt/gitlab/embedded/bin/openssl s_client -CAfile /root/my-cert.crt -connect gitlab.domain.tld:443
如果您有上述问题,请将证书添加到 /etc/gitlab/retrustedcerts
,然后运行 sudo-gitlab-ctl-reconfigure
。
X.509 键值不匹配错误
使用证书包配置实例后,NGINX 可能会显示以下错误消息:
SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch
此错误消息表示您提供的服务器证书和密钥不匹配。您可以通过运行以下命令,然后比较输出来确认这一点:
openssl rsa -noout -modulus -in path/to/your/.key | openssl md5
openssl x509 -noout -modulus -in path/to/your/.crt | openssl md5
下面是匹配密钥和证书之间的 md5 输出示例。注意匹配的 md5 哈希:
$ openssl rsa -noout -modulus -in private.key | openssl md5
4f49b61b25225abeb7542b29ae20e98c
$ openssl x509 -noout -modulus -in public.crt | openssl md5
4f49b61b25225abeb7542b29ae20e98c
这是一个具有不匹配密钥和证书的相反输出,它显示不同的 md5 哈希:
$ openssl rsa -noout -modulus -in private.key | openssl md5
d418865077299af27707b1d1fa83cd99
$ openssl x509 -noout -modulus -in public.crt | openssl md5
4f49b61b25225abeb7542b29ae20e98c
如果两个输出与前面的示例不同,则证书和密钥之间存在不匹配。请与 SSL 证书的提供商联系以获得进一步支持。
将极狐GitLab Runner 与配置有内部 CA 证书或自签名证书的极狐GitLab 实例一起使用
除了在极狐GitLab 中使用内部 CA 证书中遇到的错误之外,您的 CI 流水线可能会陷入 Pending
状态。在运行程序日志中,您可能会看到以下错误消息:
Dec 6 02:43:17 runner-host01 gitlab-runner[15131]: #033[0;33mWARNING: Checking for jobs... failed
#033[0;m #033[0;33mrunner#033[0;m=Bfkz1fyb #033[0;33mstatus#033[0;m=couldn't execute POST against
https://gitlab.domain.tld/api/v4/jobs/request: Post https://gitlab.domain.tld/api/v4/jobs/request:
x509: certificate signed by unknown authority
请遵循极狐GitLab Runner 的自签名证书或自定义证书颁发机构中的详细信息。
镜像使用自签名 SSL 证书的远端极狐GitLab 仓库
将本地极狐GitLab 实例配置为从远端镜像仓库时,从使用自签名证书的远端极狐GitLab 实例中,您可能会在用户界面中看到 SSL certificate problem: self signed certificate
错误消息。
通过检查以下情况,可以确认问题的原因:
-
curl
失败:$ curl "https://gitlab.domain.tld" curl: (60) SSL certificate problem: self signed certificate More details here: https://curl.haxx.se/docs/sslcerts.html
-
使用 Rails 控制台进行测试也会失败:
uri = URI.parse("https://gitlab.domain.tld") http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true http.verify_mode = 1 response = http.request(Net::HTTP::Get.new(uri.request_uri)) ... Traceback (most recent call last): 1: from (irb):5 OpenSSL::SSL::SSLError (SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get local issuer certificate))
要解决此问题,请执行以下操作:
- 将远端极狐GitLab 实例的自签名证书添加到本地实例上的
/etc/GitLab/trusted certs
目录中,然后按照安装自定义公共证书的说明,运行sudo GitLab ctl reconfigure
。 - 如果您使用 Helm Charts 安装本地极狐GitLab 实例,您可以向您的极狐GitLab 实例添加自签署证书。
当尝试从使用自签名证书的远端极狐GitLab 实例镜像仓库时,还可能会收到另一条错误消息:
2:Fetching remote upstream failed: fatal: unable to access 'https://gitlab.domain.tld/root/test-repo/':
SSL: unable to obtain common name from peer certificate
在这种情况下,问题可能与证书本身有关:
- 验证您的自签名证书是否缺少通用名称(common name)。如果是,请重新生成有效证书。
- 将证书添加到
/etc/gitlab/trusted certs
。 - 运行
sudo gitlab ctl reconfig
。
由于内部证书或自签名证书的原因,无法执行 Git 操作
如果您的极狐GitLab 实例使用的是自签名证书,或者证书由内部证书颁发机构(CA)签名,则在尝试执行 Git 操作时可能会遇到以下错误:
$ git clone https://gitlab.domain.tld/group/project.git
Cloning into 'project'...
fatal: unable to access 'https://gitlab.domain.tld/group/project.git/': SSL certificate problem: self signed certificate
$ git clone https://gitlab.domain.tld/group/project.git
Cloning into 'project'...
fatal: unable to access 'https://gitlab.domain.tld/group/project.git/': server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none
要解决此问题,请执行以下操作:
- 如果可能,对所有 Git 操作使用 SSH remote。这被认为更安全,使用更方便。
- 如果必须使用 HTTPS remote,可以尝试以下操作:
-
将自签名证书或内部根CA证书复制到本地目录(例如,
~/.ssl
),并配置 Git 以信任您的证书:git config --global http.sslCAInfo ~/.ssl/gitlab.domain.tld.crt
-
在 Git 客户端中禁用 SSL 验证。这是一项临时措施,因为它可能被视为安全风险。
git config --global http.sslVerify false
-
SSL_connect 版本号错误
错误配置可能导致:
-
gitlab rails/exceptions_json.log
条目包含:"exception.class":"Excon::Error::Socket","exception.message":"SSL_connect returned=1 errno=0 state=error: wrong version number (OpenSSL::SSL::SSLError)", "exception.class":"Excon::Error::Socket","exception.message":"SSL_connect returned=1 errno=0 state=error: wrong version number (OpenSSL::SSL::SSLError)",
-
gitlab-workhorse/current
包含:http: server gave HTTP response to HTTPS client http: server gave HTTP response to HTTPS client
-
gitlab-rails/sidekiq.log
或sidekiq/current
包含:message: SSL_connect returned=1 errno=0 state=error: wrong version number (OpenSSL::SSL::SSLError) message: SSL_connect returned=1 errno=0 state=error: wrong version number (OpenSSL::SSL::SSLError)
其中一些错误来自 Excon Ruby gem,可能是在极狐GitLab 被配置为向仅提供 HTTP 的远端服务器发起 HTTPS 会话的情况下产生的。
一种情况是您正在使用对象存储,不在 HTTPS 下提供服务。极狐GitLab 配置错误,并尝试 TLS 握手,但对象存储以普通 HTTP 响应。
schannel: SEC_E_UNTRUSTED_ROOT
如果您在 Windows 上,并收到以下错误:
Fatal: unable to access 'https://gitlab.domain.tld/group/project.git': schannel: SEC_E_UNTRUSTED_ROOT (0x80090325) - The certificate chain was issued by an authority that is not trusted."
您必须指定 Git 应使用OpenSSL:
git config --system http.sslbackend openssl
或者,您可以通过运行以下命令忽略 SSL 验证:
git config --global http.sslVerify false
升级到 OpenSSL 3
从 17.7 开始,极狐GitLab 将使用 OpenSSL 3。一些老旧的 TLS 协议和密码套件,抑或针对外部集成的较弱 TLS 证书可能会和 OpenSSL 不兼容。
随着升级到 OpenSSL 3:
- 对于所有进入或者出去的 TLS 链接都需要 TLS 1.2 或者更高版本。
- TLS 证书必须最少要有 112 位的安全码。短于 2048 位的 RSA、DSA 和 DH key 以及短于 224 位的 ECC key 都将被禁止。
您可能会遇到以下错误信息:
- 当 TLS 链接使用比 TLS 1.2 低的版本时会遇到
no protocols available
。 - 当 TLS 证书的安全码少于 112 位时会遇到
certificate key too weak
。 - 当请求一个旧版本密码套件时会遇到
unsupported cipher algorithm
。
使用 OpenSSL 3 指南来识别和获取您的外部集成兼容信息。