subjectAltNameが設定されていない証明書はChromeで NET::ERR_CERT_COMMON_NAME_INVALID エラー

開発環境用に自己署名のSSL証明書を使っているサイトにChromeでアクセスしたら、
「この接続ではプライバシーが保護されません NET::ERR_CERT_COMMON_NAME_INVALID」というエラーになった。

自己署名証明書(Self-signed certificate)だが、クライアント側はMacではキーチェーンアクセスに登録してx.509基本ポリシーを「常に信頼」にしているし、Windowsでは「コンピューター証明書の管理」で「信頼されたルート証明機関」に登録してある。
CN(Common Name)とアクセスしているホスト名も一致している。

Chrome以外のブラウザでは問題ない。
Chromeでも問題なくアクセスできていたが、急にエラーになるようになった。

エラーメッセージに「このサーバーのセキュリティ証明書は[missing_subjectAltName]から発行されています。」とあるので、証明書にsubjectAltNameが設定されていないことが関係しているようだ。

原因

Chrome 58 以降で、ドメイン名と証明書の照合にcommonNameが使われず、subjectAlternativeNameのみを使用するようになった。(ただし、Chrome 65 までは、EnableCommonNameFallbackForLocalAnchorsを設定すればcommonNameを使用できるらしい。)

https://support.google.com/chrome/a/answer/7391219?hl=en

解決方法

subjectAltNameを設定した自己署名証明書を作成する

openssl.cnfをコピーしたファイルにsubjectAltNameを設定して証明書作成時に指定する。

  1. openssl.cnfをコピー(下記はRedHat系の例。openssl.cnfの場所は環境によって読み替える。Ubuntuは/etc/ssl/openssl.cnf、MacPortsなら/opt/local/etc/openssl/openssl.cnf)
    $ cp /etc/pki/tls/openssl.cnf my-server.example.com.cnf
    
  2. コピーした設定ファイルのreqセクションのx509_extensionsがv3_caになっているので、v3_caセクションにsubjectAltNameを追加すればよさそうだ。
    $ vi my-server.example.com.cnf
    
    [ req ]
    ...
    x509_extensions = v3_ca # The extentions to add to the self signed cert
    ...
    

    v3_caセクションにsubjectAltNameを設定

    [ v3_ca ]
    ...
    subjectAltName=DNS.1:my-server.example.com
    ...
    

    subjectAltNameを複数設定することもできる。

    subjectAltName=DNS.1:my-server.example.com,DNS.2:my-server2.example.com
    

    詳しくは、`man 5 x509v3_config` を参照。

  3. 秘密鍵の作成
    $ openssl genrsa -out my-server.example.com.key 2048
    
  4. 証明書の作成(-configに作成した設定ファイルを指定する
    $ openssl req -new -x509 -days 36500 -sha256 -config my-server.example.com.cnf -key my-server.example.com.key -out my-server.example.com.crt