本文へスキップ
ecdsa.com
git over HTTPS with libcurl-gnutls (Debian, Ubuntu)Git

エラーメッセージ

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 流に表現したものです。認証情報やリポジトリについては、まだ何もチェックされていません。

発生する理由

修正方法

  1. 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. 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. 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. 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. 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

関連するエラー

署名エラーデータベースをすべて見る