エラーメッセージ
fatal: unable to access 'https://git.example.com/team/app.git/': SSL certificate problem: unable to get local issuer certificate
別の表記
- fatal: unable to access 'https://git.example.com/team/app.git/': SSL certificate OpenSSL verify result: unable to get local issuer certificate (20)
URL は使用しているリモートのものです。libcurl 8.22(場合によってはほかの最近のリリースも)では、理由が「SSL certificate OpenSSL verify result: unable to get local issuer certificate (20)」となります。Debian と Ubuntu の git のビルドは GnuTLS を使っており、代わりに「server verification failed: certificate signer not trusted」と出力します。
このエラーの意味
git の HTTPS トランスポートは libcurl を使っており、OpenSSL を使う libcurl が、Git サーバーが送信した最後の証明書を発行した CA を見つけられませんでした。サーバーが中間証明書を送信していないか、チェーンが git の使うバンドルに含まれていないルート(社内 CA、プロキシの CA)で終わっているかのどちらかです。Windows では、Git for Windows が Windows の証明書ストアではなく、同梱の CA ファイルで検証していることを示す典型的な症状です。
発生する理由
Git for Windows が Windows のストアではなく独自の CA ファイルで検証している
よくあるデフォルトの OpenSSL バックエンドでは、Git for Windows は同梱の ca-bundle.crt で検証します。IT 部門が Windows の証明書ストアに配布した社内のルートやプロキシのルートはこのファイルに含まれていないため、ブラウザーは動作しても clone は失敗します。
プライベート CA を使うセルフホストの Git サーバー
よくあるGitLab、Gitea、Bitbucket Data Center、Azure DevOps Server の環境では、CI のイメージや新しいマシンが信頼していない社内 CA の証明書がよく使われます。
サーバーが中間証明書を省いている
ときどきメッセージに示された発行者がパブリックな中間証明書の場合、Git サーバーまたはそのリバースプロキシは、リーフ証明書だけで設定されています。
http.sslCAInfo または GIT_SSL_CAINFO の上書き設定がバンドルを置き換えている
ときどき1 つの社内ホスト用の CA ファイルをグローバルに設定すると、すべてのリモートでデフォルトのバンドルが置き換えられるため、公開ホストで失敗するようになります(ファイルを移動した後は、その逆も起こります)。
修正方法
- 1.
Windows:git を Windows の証明書ストアに切り替える
http.sslBackend を schannel にすると、Git for Windows は Windows 自体を通じて検証し、グループポリシーで配布されたものも含め、Windows が信頼するすべてのルートを受け入れます。企業ネットワークでは、これが正攻法の修正方法です。
bash # Git for Windows: verify with the Windows certificate store, where IT deploys company roots git config --global http.sslBackend schannel git config --global --get http.sslBackend - 2.
1 つの Git ホストに限って CA を信頼する
URL 単位の http.<url>.sslCAInfo を使うと、プライベート CA がそのホストに対してのみ追加されます。GIT_SSL_CAINFO は 1 つのコマンドやジョブに適用されます。
bash git config --global http."https://git.example.com/".sslCAInfo /etc/ssl/private-ca/corp-root-ca.pem # one command or CI job only GIT_SSL_CAINFO=/etc/ssl/private-ca/corp-root-ca.pem git clone https://git.example.com/team/app.git - 3.
システムのバンドルにルートをインストールする
Linux では libcurl がデフォルトで読み込むのはシステムのバンドルなので、そこにルートを追加すると、curl やパッケージマネージャーと一緒に git も直ります。
bash # Alpine / Debian / Ubuntu cp corp-root-ca.pem /usr/local/share/ca-certificates/corp-root-ca.crt && update-ca-certificates # RHEL / Fedora cp corp-root-ca.pem /etc/pki/ca-trust/source/anchors/ && update-ca-trust - 4.
バンドルを置き換える上書き設定を探す
--show-origin を使うと、どの設定ファイルが CA のパスを設定しているかがわかります。ホスト単位にすべきだったグローバルな上書き設定は削除してください。
bash git config --show-origin --get-all http.sslCAInfo git config --show-origin --get-regexp 'http\..*\.sslcainfo' env | grep -E 'GIT_SSL_CAINFO|CURL_CA_BUNDLE|SSL_CERT_FILE' - 5.
一時的な診断:1 つのコマンドに限って検証をスキップする
-c http.sslVerify=false は診断の確認にのみ使い、グローバルな設定には決して入れないでください。認証情報が漏れるうえ、経路上にいる誰でも、取得するコードを改ざんできるようになります。
bash # Diagnostic only, for one command 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/': server verific…git over HTTPS with libcurl-gnutls (Debian, Ubuntu)curl: (60) SSL certificate problem: unable to get local issuer certificatecurl (OpenSSL backend)