opensslのreq
はCSRを作るコマンドですが、-newkey
をつけると秘密鍵の生成、-x509
をつけるとCSRを作った後にそれで署名した証明書を作ってくれるので、コマンド1発で作れます
また、-config
で作成時のオプションなどをファイルで管理できます。以下の例はファイル名に-
を指定することで標準入力から読ませていますが、ファイルにしてファイルパスを指定することもできます。Subject Alternative Name(SAN)に対応する場合はファイルで。一応、SANにはWildcardもzone apexなドメインも指定できます。
-days 3650
は署名する際に設定される期間です。自己署名なので適当に長くしてください。
configの読み方/書き方は次のドキュメントが役に立つと思います。
- https://www.openssl.org/docs/man1.0.2/man1/openssl-req.html
- https://www.openssl.org/docs/man1.0.2/man5/x509v3_config.html
以下はSANで2つのドメインに対応したSSL通信用の証明書を作成する例です
# req_distinguished_nameやalt_namesは適宜書き換える
openssl req -x509 -days 3650 -nodes -newkey rsa:4096 -keyout /etc/nginx/server.key -out /etc/nginx/server.crt -config - << __EOF__
[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
C = JP
ST = Tokyo
L = Chuo-ku
O = MyCompany
OU = MyDivision
CN = mydomain.example
[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = mydomain.example
DNS.2 = sub.mydomain.example
__EOF__
# 証明書の内容を確認
openssl x509 -in /etc/nginx/server.crt -noout -text
以上。
(おまけ)Nginxコンテナ内でSSL証明書を作成して利用する
DockerのNginxイメージは起動時に「/docker-entrypoint.d/」の配下にあるスクリプトをenvsubstで変数の置き換えをして配置し、それを実行してからnginxを起動するということを行ってくれます。
これを利用して、Nginxコンテナが起動したときに自己署名証明書を作るようにします。
docker-compose の例です。appというアプリケーションの前にnginxを置きたいと考えます。
version: '3.8'
services:
nginx:
image: nginx:1.18-alpine
volumes:
- ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf
- ./docker/nginx/docker-entrypoint.d/50-self-signed-certificate.sh:/docker-entrypoint.d/50-self-signed-certificate.sh
ports:
- "443:443"
- "80:80"
environment:
- NGINX_HOST=mydomain.example
links:
- app:app
app:
# 省略
#!/bin/sh
set -ue
# nginx:1.18-alpine なので apk add で openssl コマンドをインストールする
apk add openssl
# req_distinguished_nameやalt_namesは適宜書き換える
openssl req -x509 -days 3650 -nodes -newkey rsa:4096 -keyout /etc/nginx/server.key -out /etc/nginx/server.crt -config - << __EOF__
[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
C = JP
ST = Tokyo
L = Chuo-ku
O = MyCompany
OU = MyDivision
CN = ${NGINX_HOST}
[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = ${NGINX_HOST}
DNS.2 = sub.${NGINX_HOST}
__EOF__
openssl x509 -in /etc/nginx/server.crt -noout -text
これでコンテナ内に/etc/nginx/server.crt
と/etc/nginx/server.key
が出来上がるので、/etc/nginx/nginx.conf
はそのファイルパスを使ってSSLの設定すればよいという感じになります。
自己署名証明書をインストールしたい場合、証明書を取り出す必要があるので次のようにして取り出します。
docker exec "(NginxのCONTAINER_ID)" cat /etc/nginx/server.crt
当然ですがこのままではNginxを起動するたびに新しい自己署名証明書が作られます。それが不便に感じる場合は以下のいずれかでしょう。(このおまけが台無しですが)
- 最初からADDしてCOPYしてRUNして含めたイメージを作る
- ホスト側で作っておいてADDで含めたイメージを作る
- runするときにVolumeでファイルをマウントする
自己署名証明書なので安全ではないのですが、httpsの動作の検証でサクッとほしくなる時があるのでとりあえず作るならこういう手もありますよということで。