オライリーのReal World Http 第2のハンズオンを進めていて、opensslコマンドで自己(オレオレ)証明書を作ってSSL化するところで躓いた。
https://www.oreilly.co.jp/books/9784873119038/
記事の目的、用途
備忘録。同じく証明書の知識が浅いまま、同テキストに立ち向かう人のヒントになれば。
問題
サーバー側の証明書を作成するにあたって(テキストではserver.crt)、ドメイン名を設定する必要がある。
ドメイン名の設定方法は従来CommonNameで設定していたが、RFC2818により非推奨となった。
テキスト中で使用しているgolangのライブラリでもこれに対応しており下記のエラーが出る
x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0
ネットを調べているとブラウザChromeやwebサーバーのNginxでもCommonNameでドメイン名を設定した証明書は同様のエラーを出すらしい
[参考]
GoogleChromeの場合
Nginxの場合→golangのライブラリと同じエラーメッセージ
解決策
もともとマルチドメイン証明書の設定のために用いていたSAN(Subject Alternative Name)を使用する。
openssl x509で証明書を作るときに-extfileで指定する設定ファイルにSANの項目を追加する。
テキスト中のコマンド例
openssl x509 -req -days 365 -in server.csr -sha256 -out server.crt -CA ca.crt CAkey ca,key -CAcreateserial -extfile /etc/ssl/openssl.cnf -extensions Server
設定ファイルに追加する項目
subjectAltName = DNS:ドメイン名1, DNS:ドメイン名2
テキストの場合、localhostの証明書を作るので下記のようになる
subjectAltName = DNS:localhost
テキストの場合、-extensionsで設定を切り替えるため、ServerやCAなどの項目ごとに設定を分けて書いている。
今回は、サーバー証明書のドメイン名をSAN指定すれば良いので、Serverの設定値に追加する。
[Server]
basicConstraints=CA:FALSE
keyUsage=digitalSignature,dataEncipherment
extendedKeyUsage=serverAuth
subjectAltName = DNS:localhost
追記
client側で証明書要求(.csr)を作成するときに、CommonNameに何らかの値を入力していると、httpsリクエスト時にエラー。何も入力しないこと。
x509: certificate signed by unknown authority (possibly because of "x509: invalid signature: parent certificate cannot sign this kind of certificate" while trying to verify candidate authority certificate "hogehoge")