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

エラーメッセージ

remote error: tls: unknown certificate authority

Go のサーバーは「http: TLS handshake error from <client>: remote error: tls: unknown certificate authority」とログに記録します。ecdsa.com のテストでは、同じ証明書を TLS 1.3 で拒否した OpenSSL 3.5 クライアントについて、Go 1.27 のサーバーは代わりに「local error: tls: bad record MAC」と記録しました。また、Go クライアントは bad_certificate を送信します(「remote error: tls: bad certificate」と記録されます)。

Go crypto/tls — TLS alert 48 (unknown_ca) received from the peer, e.g. an OpenSSL-based client rejecting a Go server's certificate

このエラーの意味

ピアが TLS アラート 48(unknown_ca)を送信しました。受け取った証明書から、自身が信頼する CA までのチェーンを構築できなかったということです。Go サーバーのログに出ている場合は、クライアント(OpenSSL ベースのもの:curl、Python、Ruby、PHP、プロキシとしての nginx)が TLS 1.2 のハンドシェイク中にサーバーの証明書を拒否したことを意味します。Go クライアントで出ている場合は、相互 TLS でサーバーがクライアント証明書を拒否したことを意味します。

発生する理由

修正方法

  1. 1.

    サーバーが返すチェーンをクライアント側から確認する

    リーフ証明書しか送信されていない場合は、ファイルを修正してください。チェーンがプライベートなルートで終わっている場合は、そのルートをクライアントにインストールしてください。

    bash
    openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null \
      | grep -E '^ *[0-9]+ s:|^ *i:|Verify return code'
  2. 2.

    Go サーバーでフルチェーンを送信する

    ListenAndServeTLS(または tls.LoadX509KeyPair)に渡す PEM ファイルに、リーフ証明書とその中間証明書を含めてください。

    go
    // Leaf + intermediates in one file; Go sends every certificate in it
    srv := &http.Server{Addr: ":443"}
    log.Fatal(srv.ListenAndServeTLS("fullchain.pem", "server.key"))
  3. 3.

    プライベートルートをクライアントにインストールする

    社内サービスの場合は、そのサーバーを呼び出すシステムとコンテナーに社内のルートを配布してください。

    bash
    # Private CA: install the root on the clients (Debian/Ubuntu example)
    sudo cp corp-root-ca.pem /usr/local/share/ca-certificates/corp-root-ca.crt && sudo update-ca-certificates

関連するエラー

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