本文へスキップ
ecdsa.com
Go crypto/tlsGo

エラーメッセージ

remote error: tls: bad certificate

Go のサーバーは「http: TLS handshake error from <client>: remote error: tls: bad certificate」とログに記録します。OpenSSL ベースのクライアントは、同じ拒否に対して別のアラート(TLS 1.2 では unknown_ca)を送信するため、サーバー側に記録されるテキストはクライアントの TLS ライブラリによって異なります。

Go crypto/tls — TLS alert 42 received from the peer; typically logged by a Go server whose certificate a Go client rejected

このエラーの意味

ピアが TLS アラート 42(bad_certificate)を送信しました。Go サーバーのログ(「http: TLS handshake error from …: remote error: tls: bad certificate」)に出ている場合は、クライアントがサーバーの証明書を拒否したことを意味します。Go のクライアントは、検証に失敗するとその理由(不明な認証局、期限切れ、名前の不一致)を問わずこのアラートを送信します。Go のクライアントで出ている場合は、相互 TLS でサーバーがクライアント証明書を拒否したことを意味します。本当の理由は、アラートを送信した側でしか確認できません。

発生する理由

修正方法

  1. 1.

    拒否しているクライアントを特定し、そのエラーを確認する

    ログに記録されたクライアントのアドレスから、どのサービスを調べればよいかがわかります。そのサービスのエラーに、実際の検証失敗の内容が示されています。

    bash
    # The log line names the client; its own error message says why it rejected the certificate
    journalctl -u myservice | grep 'remote error: tls: bad certificate' | grep -oE 'from [0-9a-f.:]+' | sort | uniq -c
  2. 2.

    信頼される完全なチェーンを送信する

    すべてのクライアントが信頼する CA が発行した、フルチェーンの PEM ファイルを Go サーバーに設定してください。

    go
    // Serve the full chain: leaf first, then intermediates, in one PEM file
    log.Fatal(http.ListenAndServeTLS(":443", "fullchain.pem", "server.key", nil))
  3. 3.

    Kubernetes:webhook の caBundle を確認する

    caBundle には、webhook のサーバー証明書を発行した CA が含まれていなければなりません。cert-manager の CA インジェクターを使うと、両者が同期された状態に保たれます。

    bash
    # Kubernetes webhooks: the API server verifies the webhook's certificate with caBundle
    kubectl get validatingwebhookconfiguration my-webhook -o jsonpath='{.webhooks[0].clientConfig.caBundle}' \
      | base64 -d | openssl x509 -noout -subject -enddate

関連するエラー

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