opensslを使用してChromeで使える自己署名証明書(オレオレ証明書)を作成する方法を解説します。
また、簡単に生成できるツールも用意しました。よければご活用下さい(dockerが必要です)
発端
ローカル環境でhttpsを実現するために、オレオレ(自己署名)SSL証明書を作成したのですがchromeではNET::ERR_CERT_COMMON_NAME_INVALID
となってしまいました。
原因は、Chromeの仕様変更により、ドメイン名のチェックをCommon Name(通称CN)ではなくSubject Alternative Names(通称SAN)を参考にする様になったためだそうです。
ここではSubject Alternative Namesを含んだ自己署名サーバ証明書の作り方を解説します。
(追記) 自己署名証明書を作成するツールを作りました。
self-sign-cert
dockerがインストールされている必要がありますが、1コマンドで自己署名証明書が作成できます。
詳しい使い方は該当リポジトリのReadmeを参照してください。
手順
SANを含んだサーバ証明書を生成する
適当なディレクトリに移動する
mkdir /work
cd /work
SANの設定が書かれたテキストファイルを用意します。
ドメイン名とIPアドレスは自身の環境に合わせて変更してください。
ファイル名は何でもよいですが、ここではsubjectnames.txt
としました。
subjectAltName = DNS:your-domain.com, IP:127.0.0.1
秘密鍵(server.key)、署名要求(server.csr)、サーバ証明書(server.crt)を生成します。
サーバ証明書を作成する際に-extfile
オプションでSANを埋め込むのがキモです。
# 秘密鍵(server.key)を生成する
openssl genrsa 2048 > server.key
# 秘密鍵から署名要求(server.csr)を生成する
# your-domain.comは自身の環境に合わせて変更してください。
openssl req -new -key server.key -subj "/C=JP/ST=Some-State/O=Some-Org/CN=your-domain.com" > server.csr
# 署名要求を秘密鍵で署名してサーバ証明書を作成する
openssl x509 -days 3650 -req -extfile subjectnames.txt -signkey server.key < server.csr > server.crt
生成したサーバ証明書の内容を確認する
openssl x509 -in server.crt -text -noout
以下の様にCommon NameとSubject Alternative Namesが出力されていればOK
Nginxの設定
NginxでSSLを使うための設定を追加します。
ここでは/etc/nginx/conf.d/default.conf
を修正しています。
server {
listen 80;
listen 443 ssl;
ssl_certificate /work/server.crt; # サーバ証明書のパスを指定
ssl_certificate_key /work/server.key; # 秘密鍵のパスを指定
server_name your-domain.com; # CN, SANと合わせる
...
nginxの設定のテスト&再読み込み
※環境によりコマンドが異なる場合があります。
nginx -t
nginx reload
Chromeに信頼できるサーバ証明書として登録する
サーバ証明書(server.crt)をChromeに登録します。
手順は以下のページを参考にしてください。
Google Chromeへ証明書ファイルをインポートするには | サポート・お申し込みガイド | GMOグローバルサイン【公式】
動作確認
chromeからhttps://your-domain.com
にアクセスしてNET::ERR_CERT_COMMON_NAME_INVALIDが発生しなければOKです。
あとがき
自己署名証明書を作るのにわりと手間取りまして、よくよく考えるとopenssl全然分からんし署名要求って何?サーバ証明書って結局なんなの??登場人物多すぎ!!(泣)というレベルで全然わかってませんでした。
そんな訳で、整理も兼ねて図を書きましたところ、それなりに分かりやすい図が出来た(気がする)のでシェアさせてください。
これを見れば「自己署名証明書の作成って結局何やってんの?」というのが分かる様になってopensslの一連のコマンドが何をやっているのかもイメージできる様になるはずです。
では早速ですが、まず、一般的な「認証局に署名して貰ってサーバ証明書を作成する」ケースです。
①自身のサーバ上で秘密鍵を生成する
②自身のサーバ上で秘密鍵から署名要求を生成する
③署名要求を認証局に渡して署名してもらう。これがサーバ証明書となる。
④クライアントにはあらかじめ認証局のサーバ証明書を「信頼できる証明書」として登録しておく。
続いて、今回の「自己署名でサーバ証明書を作成」するケースです。
①、②は同じです。
こちらのケースでは自己署名なので認証局は登場しません。
ではどうするかというと③で自身の秘密鍵を使って署名します。
そうして出来たサーバ証明書を「信頼するサーバ証明書」としてクライアントに登録します。
今回使用したopensslコマンドとの対応ですが
openssl genrsa
が秘密鍵を生成するコマンドで図中①に対応
openssl req
が秘密鍵から署名要求を生成するコマンドで図中②に対応
openssl x509
が署名要求を署名してサーバ証明書を作成するコマンドで図中③に対応
となっております。
以上、
どうでしょうか、なんとなくサーバ証明書を生成する一連の流れがイメージできたでしょうか?
理解の一助となっていれば幸いです。