エラーメッセージ
fatal: unable to access 'https://git.example.com/team/app.git/': server verification failed: certificate signer not trusted. (CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none)
別の表記
- server verification failed: certificate signer not trusted. (CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none)
- server certificate verification failed. CAfile: none CRLfile: none
URL は使用しているリモートのものです。古い Debian と Ubuntu のリリース(libcurl 7.x)では、より短い「server certificate verification failed. CAfile: none CRLfile: none」が出力されます。この「CAfile: none」は、CA ファイルが明示的に設定されておらず、システムのバンドルが使われたことを示すだけです。
このエラーの意味
git の HTTPS トランスポート(Debian と Ubuntu では GnuTLS を使ってビルドされた libcurl)が、Git サーバーの証明書を検証できませんでした。チェーン内のどの証明書も、読み込んでいるバンドル内の CA にたどり着きません。「certificate signer not trusted」は、発行者が不明であることを GnuTLS 流に表現したものです。認証情報やリポジトリについては、まだ何もチェックされていません。
発生する理由
社内の証明書を使うセルフホストの GitLab、Gitea、Bitbucket
よくあるセルフホストの Git サーバーには、社内 CA が発行した証明書がよく使われます。開発者のノート PC にはデバイス管理を通じてそのルートが入っていますが、Linux コンテナー、CI ランナー、WSL のディストリビューションには通常入っていません。
Git サーバーが中間証明書を送信していない
よくあるGitLab、Gitea、およびその前段のリバースプロキシは、リーフ証明書だけで設定されていることがよくあります。ブラウザーは欠けている部分を補いますが、GnuTLS は補いません。
TLS を検査するプロキシが Git ホストとの間にある
ときどきgithub.com や gitlab.com からの clone が社内ネットワークでのみ失敗する場合、通信はプロキシによって再署名されており、そのプロキシのルートがマシンのバンドルに含まれていません。
イメージに CA バンドルがない
ときどきgit はインストールされているものの ca-certificates が含まれていない slim 版のイメージでは、HTTPS のリモートがすべて失敗します。
修正方法
- 1.
Git サーバーが送信する証明書を確認する
リーフ証明書しか表示されない場合は、サーバーを修正してください。チェーンが社内のルートやプロキシのルートで終わっている場合は、そのルートをクライアントにインストールしてください。
bash openssl s_client -connect git.example.com:443 -servername git.example.com -showcerts </dev/null 2>/dev/null \ | grep -E '^ *[0-9]+ s:|^ *i:' - 2.
1 つの Git サーバーに限って CA を信頼する
http.<url>.sslCAInfo を使うと、独自の CA の適用範囲を 1 つのホストに限定できるため、公開リモートでは引き続きシステムのバンドルが使われます。GIT_SSL_CAINFO は、1 つのコマンドや CI ジョブに対して同じことを行います。
bash # Trust the company CA for this server only; other remotes keep the system bundle git config --global http."https://git.example.com/".sslCAInfo /etc/ssl/private-ca/corp-root-ca.pem git ls-remote https://git.example.com/team/app.git - 3.
システムのバンドルにルートを追加する
update-ca-certificates でルート証明書をインストールすると、git、curl、wget、パッケージマネージャーの問題が一度に解決します。Docker イメージでは Dockerfile の中で、CI ではランナーのイメージで行ってください。
bash sudo cp corp-root-ca.pem /usr/local/share/ca-certificates/corp-root-ca.crt sudo update-ca-certificates # git, curl and wget read /etc/ssl/certs/ca-certificates.crt - 4.
サーバー運営者:完全なチェーンを設定する
Git サーバーの Web フロントエンドが使う証明書ファイルには、リーフ証明書と、それに続くすべての中間証明書が含まれていなければなりません。
text # GitLab Omnibus (/etc/gitlab/gitlab.rb): the .crt file must contain leaf + intermediates nginx['ssl_certificate'] = "/etc/gitlab/ssl/git.example.com.crt" # then: sudo gitlab-ctl reconfigure - 5.
一時的な診断:1 つのコマンドに限って検証をスキップする
1 つのコマンドに -c http.sslVerify=false を付けると、問題が信頼だけであることを確認できます。これをグローバルに設定すると、接続を傍受できる誰にでも認証情報とコードが渡ってしまいます。
bash # Diagnostic only, for one command: never set http.sslVerify=false globally git -c http.sslVerify=false ls-remote https://git.example.com/team/app.git
関連するエラー
fatal: unable to access 'https://git.example.com/team/app.git/': SSL certificat…git over HTTPS with libcurl + OpenSSL (Git for Windows default, macOS Homebrew, Alpine, RHEL)fatal: unable to access 'https://git.example.com/team/app.git/': SSL certificat…git over HTTPS with libcurl + OpenSSL (Git for Windows default, macOS Homebrew, Alpine, RHEL)curl: (60) SSL certificate problem: unable to get local issuer certificatecurl (OpenSSL backend)ERROR: The certificate of 'api.example.com' is not trusted.GNU Wget built with GnuTLS (Debian, Ubuntu before 22.04 used it too)