0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

自己署名証明書をdocker内で作ってみた

Posted at

Windows環境でdockerを使ってSSLの自己署名証明書(いわゆるオレオレ証明書)を作ってみる。

たまに作ると手順を忘れてるのでメモしておく。
opensslのバージョンが古かったりするとオプションパラメータが使えなかったりするので、docker内で作成すると楽である。

ブラウザで警告が表示されないようなサーバ証明書を作成するにはいくつか制約があるので注意。

  • サーバ証明書はバージョンV3かつサブジェクト代替名(SAN=Subject Alternative Name)が必要。
  • サーバ証明書の有効期限は最大398日間まで。
  • FireFoxはCAの自己署名証明書のみだと使用できない模様(色々と試してみたがダメだった)。このため、CA証明書とサーバ証明書をわけて作成する。

環境

  • Windows 10 Pro
  • docker (ver 20), docker-compose(ver 2.6)

手順

準備

まずはalpine linuxを起動。

docker run -it -p 443:443 -v c:\temp\cert:/var/nginx/cert alpine:3.17.2 sh

後でnginxで動作確認するため443ポートを開いておく。

証明書の保存先をボリュームで指定してローカルに保存する。(ここではc:\temp\certに保存される)
ボリュームの指定(-v)の左側(ローカルドライブ側)はWindowsだとフルパスが必要。

opensslをインストール

apk add openssl

ディレクトリを移動して、opensslの実行に必要なファイルを作成。

cd /var/nginx/cert

mkdir demoCA
echo "01" > demoCA/serial
echo "00" > demoCA/crlnumber
touch demoCA/index.txt

CA証明書作成

まずは自己署名でCAの証明書を作成する。

秘密鍵を作成。

CERT_CA_NAME=ca
openssl genrsa 2048 > $CERT_CA_NAME.key
オプション 説明
genrsa RSA秘密鍵を作成
2048 鍵の長さ(bit)。通常は2048

CSR(署名要求)を作成。

openssl req -new -subj "/C=JP/ST=Tokyo/O=$CERT_CA_NAME/CN=$CERT_CA_NAME" -key $CERT_CA_NAME.key -out $CERT_CA_NAME.csr
オプション 説明
req 署名要求を作成
-new 新規に作成
-subj xxx 所在地・組織名を指定
-key xxx 秘密鍵を指定
-out xxx 生成したCSRの出力先

CSRをもとに自己署名し証明書を作成。

openssl ca -selfsign -batch -days 3650 -extensions v3_ca -outdir . -keyfile $CERT_CA_NAME.key -in $CERT_CA_NAME.csr -out $CERT_CA_NAME.crt
オプション 説明
ca 署名を行う
-selfsign 自己署名を指定
-batch 確認のプロンプトを非表示
-days 3650 有効期限(日)
-extensions v3_ca CA用を指定
-outdir xxx 出力先。カレントディレクトリ(.)にしておく
-keyfile xxx CAの秘密鍵
-in xxx CSRファイル
-out xxx 作成した証明書ファイル

CAの証明書(ca.crt)と秘密鍵(ca.key)が作成されていれば成功である。

サーバ証明書作成

CA証明書を作成したので、これを使用してサーバ証明書に署名する。

CA証明書と同様に秘密鍵を作成。

CERT_NAME=cert
openssl genrsa 2048 > $CERT_NAME.key

SANを指定してCSRを作成。
SANはDNS:example.comのようにホスト名の先頭にDNS:をつけて指定する。
(複数指定する場合はDNS:a.example.com, DNS:b.example.comのようにカンマ区切りにする)

SUBJECT_ALT="subjectAltName = DNS:localhost"
openssl req -new -x509 -subj "/C=JP/ST=Tokyo/O=$CERT_CA_NAME/CN=$CERT_NAME" -extensions v3_req -addext "$SUBJECT_ALT" -key $CERT_NAME.key -out $CERT_NAME.csr
オプション 説明
req 署名要求を作成
-x509 x509形式で作成
-extensions v3_req サーバ用
-addext xxx 追加の設定を指定

注意点として、-x509を指定しないとSANが保存されなかった。
また、SANは通常のパラーメータでは指定できないので、-addextで設定ファイルの表記に従った形式で指定する必要がある。

CAの証明書と秘密鍵で署名して完了。

openssl x509 -text -days 365 -CA $CERT_CA_NAME.crt -CAkey $CERT_CA_NAME.key -in $CERT_NAME.csr -out $CERT_NAME.crt
オプション 説明
x509 x509形式で署名
-text 詳細を証明書に出力
-days 365 有効期限(日)。398日以内
-CA xxx CAの証明書を指定
-CAkey xxx CAの秘密鍵を指定
-in xxx CSRを指定
-out xxx 作成した証明書の出力先

以上でcert.key, cert.crtが作成できていれば成功である。

openssl caではバージョンV3にならなかったので、openssl x509で署名している。
CA証明書とサーバ証明書でコマンドが異なるのでややこしい。。。

証明書の内容は以下のコマンドで確認できる。

openssl x509 -noout -text -in $CERT_NAME.crt

/var/nginx/cert # openssl x509 -noout -text -in $CERT_NAME.crt
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            2a:4e:bc:f7:8f:76:ab:ae:68:93 ...
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = JP, ST = Tokyo, O = ca, CN = ca
        ...
        Subject: C = JP, ST = Tokyo, O = ca, CN = cert
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                ...
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Key Usage:
                Digital Signature, Non Repudiation, Key Encipherment
            X509v3 Subject Alternative Name:
                DNS:localhost
            X509v3 Subject Key Identifier:
                53:21:94:5A:0C:C4:12:BA:BE:38 ...
            X509v3 Authority Key Identifier:
                16:06:3C:F5:D6:8D:EF:B6:29:51 ...
        ...

サーバ証明書は以下の点を確認する。

  • Version: 3になっていること
  • X509v3 Basic ConstraintsがCA:FALSEになっていること
  • X509v3 Key UsageにDigital Signatureが設定されていること
  • X509v3 Subject Alternative NameにSANが指定されていること
  • X509v3 Subject Key IdentifierとX509v3 Authority Key Identifierが設定されていること。

確認

nginxを起動して証明書がブラウザで警告表示されないか確認する。

nginxを追加。

apk add nginx

nginxの設定ファイルを作成する。
SSL証明書を指定して443ポートで起動するように設定。
(証明書のパスやファイル名が異なる場合は正しいパスを指定する必要がある)

echo "
server {
    listen 443 ssl;

    ssl_certificate /var/nginx/cert/cert.crt;
    ssl_certificate_key /var/nginx/cert/cert.key;
}
" > /etc/nginx/http.d/default.conf

nginxを起動

nginx -g "daemon off;"

CAの証明書(ca.crt)をWindowsのエクスプローラー上で実行し証明書のインストールを行う。証明書ストアで参照から 『信頼されたルート証明機関』 を選択してインポートする。
image.png

FireFoxの場合は証明書ストアを独自に管理しているので、FireFoxの設定でインポートする。

https://localhost にアクセスして証明書のエラーが表示されなければ成功である。

CAの証明書は10年を指定してもエラーにはならなかったので、CA証明書の有効期限は長めにしておいて、サーバ証明書を毎年再発行して差し替える運用にするのがよいと思われる。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?