SSLのトラブルシューティング

このページでは、GitLabで作業中に遭遇する可能性のある、SSLに関連する一般的なエラーやシナリオのリストを掲載します。メインの SSL ドキュメントに追加する役割を果たします:

便利な OpenSSL デバッグ・コマンド

時々、SSL 証明書チェーンをソースから直接見ることで、より良いイメージを得るのに役立つことがあります。これらのコマンドは診断やデバッグのためのツールで、標準の OpenSSL ライブラリの一部です。

note
GitLabには、すべてのGitLabライブラリがリンクされる独自のカスタムコンパイル版OpenSSLが含まれています。このOpenSSLバージョンを使って以下のコマンドを実行することが重要です。
  • HTTPSでホストへのテスト接続を行います。HOSTNAME を GitLab の URL(HTTPS を除く)に置き換え、port を HTTPS 接続を提供するポート(通常は 443)に置き換えてください:

     echo | /opt/gitlab/embedded/bin/openssl s_client -connect HOSTNAME:port
    

    echo コマンドはサーバーに NULL リクエストを送り、追加の入力を待たずに接続を閉じます。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エラー

  1. SSL certificate problem: unable to get local issuer certificate

    このエラーは、クライアントがルートCAを取得できないことを示しています。これを解決するには、クライアントで接続しようとしているサーバーのルートCAを信頼するか、接続しようとしているサーバーの証明書を修正して、完全な連鎖証明書を提示します。

    note
    クライアントが接続する際のSSLエラーを防ぐために、証明書チェーンを完全に使用することをお勧めします。完全な証明書チェーンの順番は、最初にサーバー証明書、次にすべての中間証明書、最後にルートCAとなります。
  2. unable to verify the first certificate

    このエラーは、サーバによって不完全な証明書チェーンが提示されていることを示しています。このエラーを修正するには、サーバーの証明書を完全な証明書チェーンで置き換える必要があります。完全な証明書チェーンの順序は、最初にサーバ証明書、次にすべての中間証明書、最後にルートCAで構成される必要があります。

  3. certificate signed by unknown authority

    このエラーは、クライアントが証明書または CA を信頼していないことを示しています。このエラーを修正するには、サーバーに接続するクライアントが証明書または CA を信頼する必要があります。

  4. SSL certificate problem: self signed certificate in certificate chain

    このエラーは、クライアントが証明書または CA を信頼していないことを示しています。このエラーを修正するには、サーバーに接続するクライアントが証明書または CA を信頼する必要があります。

  5. x509: certificate relies on legacy Common Name field, use SANs instead

    このエラーは、証明書にSAN(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 をチェックし、有効な X.509 証明書でないREADME.md 以外のファイルを削除します。

note
gitlab-ctl reconfigure を実行すると、カスタム公開証明書のサブジェクト・ハッシュから命名されたシンボリックリンクが構築され、そのシンボリックリンクが に格納されます/opt/gitlab/embedded/ssl/certs/。 .内の壊れたシンボリックリンクは /opt/gitlab/embedded/ssl/certs/自動的に削除されます。/opt/gitlab/embedded/ssl/certs/ に格納されているcacert.pem およびREADME.md 以外のファイルは、/etc/gitlab/trusted-certs/ に移動されます。

カスタム証明書の欠落またはスキップ

GitLab バージョン 8.9.0, 8.9.1および 8.9.2はすべて誤って/etc/gitlab/ssl/trusted-certs/ ディレクトリを使用していました。このディレクトリは、空であれば削除しても安全です。まだカスタム証明書が含まれている場合は、/etc/gitlab/trusted-certs/ に移動し、gitlab-ctl reconfigureを実行してください。

/opt/gitlab/embedded/ssl/certs/ にシンボリックリンクが作成されず、gitlab-ctl reconfigure を実行した後に “Skippingcert.pem” というメッセージが表示された場合、4つのイシューのうちの1つが考えられます:

  1. /etc/gitlab/trusted-certs/ のファイルはシンボリックリンクです。
  2. ファイルが有効な PEM または DER エンコード証明書ではありません。
  3. c_rehashが証明書を正しくシンボリックリンクするために必要なPerlがオペレーション・システムにインストールされていません。
  4. 証明書には文字列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
    
  •    cannot load certificate
       PEM_read_bio_X509_AUX() failed (SSL: error:0909006C:PEM routines:get_name:no start line:Expecting: TRUSTED CERTIFICATE)
    

いずれの場合も、証明書の先頭と末尾が以下のもの以外である場合:

-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----

GitLabと互換性がありません。証明書をコンポーネント(サーバー、中間、ルート)ごとに分けて、互換性のある PEM 形式に変換しなければなりません。

perl インタプリタがないためにc_rehash が証明書をシンボリックリンクしていないかテストするには:

$ /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

  1. /opt/gitlab/embedded/ssl/certs/ にシンボリックリンクが作成されない場合;
  2. /etc/gitlab/trusted-certs/ にカスタム証明書を配置しました。
  3. カスタム証明書のメッセージがスキップまたはシンボリックリンクされていない場合。

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 が失敗する一般的なシナリオがあります:

  1. サーバーが 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を開いてアクセスできるようにしてください。

  2. あなたのドメインの認証局認可(CAA) レコードが、Let’s Encryptにあなたのドメインの証明書を発行することを許可していません。reconfigureの出力で以下のエラーを探してください:

    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
    
  3. gitlab.example.com のようなテストドメインを証明書なしで使用している場合、上記のunable to request certificate エラーが表示されます。その場合は、/etc/gitlab/gitlab.rbletsencrypt['enable'] = false を設定し、Let’s Encrypt を無効にします。

Let’s Debug診断ツールを使用してドメインをテストできます。Let’s Encrypt 証明書をイシューできない原因を突き止めるのに役立ちます。

GitLabで内部CA証明書を使用する場合

GitLabインスタンスに内部CA証明書を設定した後、様々な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/trusted-certs に追加してから、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

前の例のように2つの出力が異なる場合は、証明書と鍵の不一致です。SSL証明書のプロバイダーにお問い合わせください。

内部CA証明書または自己署名証明書で設定されたGitLabインスタンスでGitLab Runnerを使用する場合

内部CA証明書をGitLabで使うで述べたエラーに加え、CIパイプラインがPending 。Runner のログには以下のエラーメッセージが表示されるかもしれません:

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

Self-signed certificates or custom Certification Authorities for 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インスタンスから自己署名証明書をローカルのGitLabインスタンスの/etc/gitlab/trusted-certs ディレクトリに追加し、カスタム公開証明書をインストールする手順に従ってsudo gitlab-ctl reconfigure
  • ローカルのGitLabインスタンスがHelm Chartを使ってインストールされた場合は、自己署名証明書を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

この場合は、証明書そのものに問題がある可能性があります:

  1. 自己署名証明書にコモンネームがないことを確認してください。コモンネームがない場合は、有効な証明書を再生成してください。
  2. 証明書を/etc/gitlab/trusted-certs に追加します。
  3. sudo gitlab-ctl reconfigure を実行してください。

内部証明書または自己署名証明書が原因で 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リモートを使ってください。この方がセキュリティが高く、使いやすいと考えられています。
  • どうしても HTTPS リモートを使いたい場合は、次のようにしてください:
    • 自己署名証明書あるいは内部ルート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検証を無視することもできます:

caution
グローバル・レベルでこのオプションを無効にするとセキュリティ上の問題が発生する可能性があるため、SSLを無視する場合は注意してください。このオプションは、トラブルシューティングを行う_場合にのみ_使用し、その後すぐにSSL検証を再開してください。
git config --global http.sslVerify false