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

エラーメッセージ

x509: certificate is valid for example.com, not api.example.com

2 つの名前には、失敗ごとに実際の値が入ります。先に証明書がカバーする名前、次にクライアントが要求した名前です。

Go crypto/x509 — HostnameError from VerifyHostname / TLS dials

このエラーの意味

TLS 接続は証明書を読み取れるところまでは進みましたが、証明書のサブジェクト代替名(SAN)のどれも、クライアントが接続したホスト名と一致しません。エラーには両方の名前が示されるため、食い違いはすぐにわかります。証明書がカバーしているのは X で、要求したのは Y です。なお、現在の検証では SAN だけが使われ、従来のコモンネームフィールドは無視されます。

発生する理由

修正方法

  1. 1.

    実際に使うすべての名前を含めて再発行する

    発行時にすべてのホスト名を SAN として追加してください。現時点でカバーされている名前は、現在の SAN リストを調べると確認できます。

    bash
    echo | openssl s_client -connect host:443 -servername api.example.com 2>/dev/null \
      | openssl x509 -noout -ext subjectAltName
    # request with SANs:
    openssl req -new -key key.pem -out req.csr \
      -subj "/CN=example.com" -addext "subjectAltName=DNS:example.com,DNS:api.example.com"
  2. 2.

    名前で接続するか、ServerName を明示的に設定する

    ネットワーク上のアドレスを証明書の名前と別にしなければならない場合(VIP、ポートフォワード、サイドカー)は、どの ID(証明書上の名前)を期待しているかを TLS に伝え、検証が本来の役割を果たすようにしてください。

    go
    conn, err := tls.Dial("tcp", "10.0.0.5:443", &tls.Config{
        ServerName: "api.example.com",   // matched against SANs, sent as SNI
    })

関連するエラー

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