※最低限、CNやsubjectAltNameは要件に応じて書き換えてください
CA用の鍵と証明書の作成
openssl req \
-newkey rsa:2048 -nodes -subj "/C=JP/ST=Tokyo/L=Chiyoda-ku/O=ACME, Inc./CN=rootca" \
-keyout ca.key | \
openssl x509 -req -signkey ca.key \
-days 10000 -extensions myreqexts -extfile <(printf "[myreqexts]\nkeyUsage=cRLSign,digitalSignature,keyCertSign
basicConstraints=CA:TRUE") \
-out ca.crt
# 確認
openssl x509 -in ca.crt -text -noout
サーバ認証用の鍵と証明書の作成
openssl req \
-newkey rsa:2048 -nodes -subj "/C=JP/ST=Tokyo/L=Chiyoda-ku/O=ACME, Inc./CN=servername" \
-keyout server.key | \
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial \
-days 10000 -extensions myreqexts -extfile <(printf "[myreqexts]
subjectAltName=DNS:servername,DNS:www.example.com
keyUsage=digitalSignature,keyEncipherment
extendedKeyUsage=serverAuth") \
-out server.crt
# 確認
openssl x509 -in server.crt -text -noout
クライアント認証用の鍵と証明書の作成
openssl req \
-newkey rsa:2048 -nodes -subj "/C=JP/ST=Tokyo/L=Chiyoda-ku/O=ACME, Inc./CN=clientname" \
-keyout client.key | \
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial \
-days 10000 -extensions myreqexts -extfile <(printf "[myreqexts]
subjectAltName=DNS:servername,DNS:www.example.com
keyUsage=digitalSignature,keyEncipherment
extendedKeyUsage=clientAuth") \
-out client.crt
# 確認
openssl x509 -in client.crt -text -noout
Kubernetesクライアント証明書認証用の証明書作成
# Also see https://kubernetes.io/docs/reference/access-authn-authz/authentication/#x509-client-certs
openssl req \
-newkey rsa:2048 -nodes -subj "/CN=user/O=group1/O=group2" \
-keyout user.key | \
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial \
-days 10000 \
-out user.crt
# 確認
openssl x509 -in user.crt -text -noout
あとがき
たまにopensslでオレオレCAや自己署名証明書をつくる機会があるのですが、そのたびに忘れてググっているので改めて調べてみました。
よく見かける方法だと、CAは以下のような2ステップが必要になります。
- 鍵作成
- 証明書作成
サーバ証明書は以下のような3ステップが必要になります
- 鍵作成
- CSR作成
- 証明書作成
CAについては、鍵と証明書をまとめて発行するために以下のようなコマンドが紹介されている場合もありますが、これだと openssl バージョンによってはextensionsが証明書に設定されない場合があるようです。
よくみかけるCAの作り方(extensionsが設定されない)
openssl req -x509 -new \
-nodes -newkey rsa:2048 -subj "/CN=rootca" -days 10000 \
-config <(printf "
[req]
distinguished_name=distinguished_name
req_extensions=req_extensions
[distinguished_name]
C = US
ST = VA
L = SomeCity
O = MyCompany
OU = MyDivision
CN = www.company.com
[req_extensions]
keyUsage = cRLSign, digitalSignature, keyCertSign
extendedKeyUsage = serverAuth
basicConstraints = CA:TRUE
") \
-keyout ca.key -out ca.crt
# 確認
openssl x509 -in ca.crt -ext keyUsage -text -noout
#=> "No extensions in certificate" エラー
また、サーバ証明書用だと以下のようなkey作成を-newkeyで省略した2ステップ版もよくみますね
2ステップでサーバ証明書の作成
# サーバ用のCSRの作成
openssl req \
-newkey rsa:2048 -nodes -keyout server.key -subj "/CN=servername" -days 10000 -reqexts myreqexts -config <(cat /etc/ssl/openssl.cnf <(printf "\n[myreqexts]\nsubjectAltName=DNS:servername,DNS:www.example.com")) \
-out server.csr
#サーバ証明書の作成
openssl x509 \
-req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 10000 -extensions myreqexts -extfile <(printf "[myreqexts]\nsubjectAltName=DNS:servername,DNS:www.example.com") \
-out server.crt
こちらはCAを作る場合と比べてなにか問題があるというわけではないと思いますが、今回紹介した openssl req
と openssl x509
を組み合わせたワンラインナーだと、証明書の用途によらず同じような方法で済むため、わかりやすいのではないかと思います。