カテゴリー
コンピューター

Google Chrome に怒られない開発用途限定の自己署名なSSLサーバ証明書をコマンド一発で作る方法

コマンド

# サーバ証明書 (および秘密鍵) の作成
openssl req -x509 -newkey rsa:2048 -nodes -days 3650 \
-keyout private_key.pem \
-out certificate.pem \
-config - <<EOF
[req]
distinguished_name = req_distinguished_name
x509_extensions = usr_cert
prompt = no

[req_distinguished_name]
C = JP
O = oki2a24.com
OU = MyDivision
CN = localhost

[usr_cert]
basicConstraints = critical, CA:FALSE
subjectAltName = DNS:localhost
EOF

# サーバ証明書の確認
openssl x509 -text -noout -in certificate.pem

使用したバージョン

root@495db3743f1d:/var/www/html# openssl version
OpenSSL 1.1.1n  15 Mar 2022
root@495db3743f1d:/var/www/html# 

まとめ・ポイント

  • コマンドについて
    • private_key.pem: 秘密鍵
    • certificate.pem: サーバ証明書
    • ヒアドキュメント部分は別ファイルにしても良い。
  • サーバ証明書を Chrome から登録するには、 chrome://settings/security のページの "証明書の管理 HTTPS / SSL の証明書と設定を管理します" のリンクから登録する。 Mac なので、キーチェーンアクセスが立ち上がり、そこで登録した。
  • ブラウザで確認するとき、作成したサーバ証明書であるかどうかを判断するために有効期限に注目していた。おかしいと感じた場合は、 Chrome を再起動したり、それでもダメな場合は Mac を再起動して作成したサーバ証明書が使われるようにした。

実践。実際のサーバ証明書作成の様子

root@495db3743f1d:/var/www/html/docker/php/ssl# openssl req -x509 -newkey rsa:2048 -nodes -days 3650 \
-keyout private_key.pem \
-out certificate.pem \
-config - <<EOF
[req]
distinguished_name = req_distinguished_name
x509_extensions = usr_cert
prompt = no

[req_distinguished_name]
C = JP
O = oki2a24.com
OU = MyDivision
CN = localhost

[usr_cert]
basicConstraints = critical, CA:FALSE
subjectAltName = DNS:localhost
EOF
Generating a RSA private key
......................................................................................................+++++
..............................+++++
writing new private key to 'private_key.pem'
-----
root@495db3743f1d:/var/www/html/docker/php/ssl# 
root@495db3743f1d:/var/www/html/docker/php/ssl# 
root@495db3743f1d:/var/www/html/docker/php/ssl# 
root@495db3743f1d:/var/www/html/docker/php/ssl# openssl x509 -text -noout -in certificate.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            20:3b:0f:56:c5:35:da:e0:d7:53:eb:a9:34:47:1f:d9:c6:3b:df:e1
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = JP, O = oki2a24.com, OU = MyDivision, CN = localhost
        Validity
            Not Before: Aug 12 07:30:05 2022 GMT
            Not After : Aug  9 07:30:05 2032 GMT
        Subject: C = JP, O = oki2a24.com, OU = MyDivision, CN = localhost
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:c3:10:fa:a7:23:b7:b2:d7:78:a2:4d:06:a1:14:
                    78:1d:2a:db:f8:88:a1:10:1c:1f:28:97:d8:58:22:
                    00:f8:b3:b3:52:aa:b0:8e:01:89:b4:33:64:3c:9b:
                    9a:d2:3f:1f:a4:7d:96:8e:ea:e6:2b:ee:ac:95:37:
                    0f:2d:cf:f4:a3:9d:03:85:a0:f8:04:8a:80:0d:06:
                    01:90:2b:0f:2a:49:46:aa:1d:c8:3e:58:d0:6c:23:
                    73:11:d5:b5:e5:ed:ba:dc:d3:aa:72:ad:87:e8:03:
                    bf:1d:43:04:1f:58:34:d8:ec:f2:38:fe:f1:37:9c:
                    77:8b:af:ef:69:f4:f3:04:aa:da:68:31:50:42:2b:
                    e8:b2:84:ad:47:35:9e:70:79:e0:d2:b8:55:97:08:
                    bd:15:04:17:b9:6e:69:05:2a:bd:f8:d6:9b:63:ec:
                    95:02:e1:85:22:f9:cc:19:b4:15:b9:f5:00:f0:2d:
                    8a:47:bb:77:bd:86:6d:df:72:e3:f8:da:8d:37:ea:
                    0e:6b:7a:30:77:e2:df:24:a1:c1:34:e2:bc:0f:0e:
                    c5:c6:8a:26:4d:ee:05:aa:28:ed:93:c8:39:02:8e:
                    11:d2:f7:fe:83:53:2d:60:a5:ca:12:1f:e3:a9:0f:
                    40:42:9c:50:78:ff:e7:db:f8:88:13:5c:89:6f:db:
                    9e:99
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Alternative Name: 
                DNS:localhost
    Signature Algorithm: sha256WithRSAEncryption
         1f:24:ea:57:38:d7:2e:96:df:19:ae:32:b3:25:66:62:87:9a:
         f8:20:c3:ae:31:0e:ff:95:c0:26:21:50:22:81:58:d5:15:5b:
         aa:74:32:17:b1:d0:18:e7:1b:97:25:be:fa:61:74:1f:d5:eb:
         61:81:9b:f3:fe:51:d9:c4:f8:67:71:a2:9c:e3:d4:be:1f:f6:
         6a:8a:1c:54:12:96:26:d0:59:fe:7a:85:0a:3a:bb:a7:a9:88:
         d7:82:47:f5:c2:39:a0:cd:a4:08:4a:f6:10:ad:8d:06:f0:de:
         67:6c:f1:81:11:c9:0c:8a:0e:76:77:23:24:6c:e2:0b:cd:b0:
         33:4e:c2:4b:ec:8e:51:a0:bc:a6:94:96:25:68:e1:e3:ac:dc:
         20:c4:3f:92:6f:4a:0f:b1:03:e2:08:15:0b:78:2f:8c:7b:a4:
         05:88:3f:5d:bf:24:18:0d:7d:52:25:d8:b2:f1:27:16:8c:d0:
         26:61:92:c5:b4:67:e8:50:5f:0b:f2:aa:02:86:27:5e:2d:5a:
         71:c0:e4:28:b1:f6:2a:8c:ac:45:05:57:47:23:63:f6:20:8e:
         85:4c:28:68:c1:c2:b5:8d:a9:ea:4b:b9:ee:0c:26:0d:9b:88:
         10:8f:ab:e9:6e:d6:2a:ca:92:94:93:0e:ea:ae:bb:20:75:d3:
         43:01:16:2b
root@495db3743f1d:/var/www/html/docker/php/ssl# 

実践。サーバ証明書 Mac キーチェーンアクセスに登録した絵

実践。 Chrome でサーバ証明書を確認した絵

おわりに

以前自己署名のサーバ証明書を作って活用していたことがあったのですが、作り方をすっかり忘れてしまいました。あーでもないこーでもないと数日試行錯誤して、ようやく納得いく作り方が完成しましたので、メモいたしました。

その際、次のキーワードなどで調べました。

  • NET::ERR_CERT_INVALID openssl localhost
  • openssl san localhost
  • docker php-apache ssl
  • chrome 自己証明書 localhost
  • ERR_SSL_KEY_USAGE_INCOMPATIBLE
  • openssl-req man
  • openssl req 自己署名
  • openssl req ワンライナー
  • chromeに怒られない openssl

また、最終的に次のページの方法をベースといたしました。ありがとうございました。

なお、納得いく、とは申しましても、 openssl の仕組みや背景をすっかり理解して使っている訳ではないので、何か漏れはあるかもしれませんが、それでも一応当初の目的は達成できた、という状況であることをお断りします。

また、タイトルにもありますが、今回作成したサーバ証明書はあくまでも開発用途であり、一般に公開するようなサーバで使用することは想定しておりませんことも併せてお断りします。

なんにせよ、これで開発でも https で行えるようになりました。

使い方としては、 Docker のビルド時にイメージに入れるのではなく、 Docker コンテナ起動時にボリューム共有でサーバ証明書と秘密鍵を渡すようにしています。こうすることで、環境が変わったときにふさわしいサーバ証明書と秘密鍵にすぐに切り替えられることを狙っています。

以上です。

コメントを残す