はじめに
chrome58 から、SSL証明書の CN (Common Name) から SAN (509v3 extensions: X509v3 Subject Alternative Name) を評価するようになったため、従来のオレオレ証明書の作り方が通用しなくなった。
openssl 1.1.1以上であれば、-addext
オプションでSANをコマンドラインで指定できるようになったらしいので、なるべく現環境に影響を及ぼさず簡単にオレオレ証明書を作成できないか検証してみた。
前提条件
- openssl 1.1.1 以上(-addextオプションを使う)
- ubuntu 18.04.2 (筆者の環境)
openssl 1.1.1 をビルドする
ubuntu 18.04では、openssl 1.1.0g で-addext
オプションが使えないので、致し方なくビルドする。
なぜかRUNPATHの指定がないので、ライブラリパスの問題を回避するために(面倒だから)、-static
を指定する。
$ wget https://www.openssl.org/source/openssl-1.1.1b.tar.gz
$ tar zxvf openssl-1.1.1b.tar.gz
$ cd ./openssl-1.1.1b/
$ ./config --prefix=/opt/openssl-1.1.1b -static
$ make
$ make test
$ sudo make install
CA環境をつくる
適当なところにディレクトリを作成し、CA.pl
とopenssl.cnf
をコピーする。
$ mkdir rootca
$ cd rootca
$ cp -rp /opt/openssl-1.1.1b/ssl/misc/CA.pl .
$ cp -rp /opt/openssl-1.1.1b/ssl/openssl.cnf .
CA.pl
を書き換える。
--- /opt/openssl-1.1.1b/ssl/misc/CA.pl 2019-03-23 04:47:58.527507782 +0900
+++ CA.pl 2019-03-23 07:50:32.303802280 +0900
@@ -15,6 +15,9 @@
use strict;
use warnings;
+$ENV{'OPENSSL'} = "/opt/openssl-1.1.1b/bin/openssl";
+$ENV{"OPENSSL_CONFIG"} = "-config ./openssl.cnf";
+
my $openssl = "openssl";
if(defined $ENV{'OPENSSL'}) {
$openssl = $ENV{'OPENSSL'};
@@ -25,8 +28,8 @@ if(defined $ENV{'OPENSSL'}) {
my $verbose = 1;
my $OPENSSL_CONFIG = $ENV{"OPENSSL_CONFIG"} || "";
-my $DAYS = "-days 365";
-my $CADAYS = "-days 1095"; # 3 years
+my $DAYS = "-days 3650";
+my $CADAYS = "-days 3650"; # 3 years
my $REQ = "$openssl req $OPENSSL_CONFIG";
my $CA = "$openssl ca $OPENSSL_CONFIG";
my $VERIFY = "$openssl verify";
openssl.cnf
を書き換える。
-
copy_extensions
は、CA署名時にSANを渡すために必要。(必須) -
unique_subject
は、revokeしなくても同じ証明書が何度も発行できるようにするためのもの。
あとはお好みで。
--- /opt/openssl-1.1.1b/ssl/openssl.cnf 2019-03-23 04:47:58.551507775 +0900
+++ openssl.cnf 2019-03-23 07:50:20.979734732 +0900
@@ -46,7 +46,7 @@ dir = ./demoCA # Where everything is k
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
-#unique_subject = no # Set to 'no' to allow creation of
+unique_subject = no # Set to 'no' to allow creation of
# several certs with same subject.
new_certs_dir = $dir/newcerts # default place for new certs.
@@ -65,16 +65,16 @@ name_opt = ca_default # Subject Name o
cert_opt = ca_default # Certificate field options
# Extension copying option: use with caution.
-# copy_extensions = copy
+copy_extensions = copy
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crlnumber must also be commented out to leave a V1 CRL.
# crl_extensions = crl_ext
-default_days = 365 # how long to certify for
+default_days = 3650 # how long to certify for
default_crl_days= 30 # how long before next CRL
-default_md = default # use public key default MD
+default_md = sha256 # use public key default MD
preserve = no # keep passed DN ordering
# A few difference way of specifying how similar the request should look
@@ -105,7 +105,7 @@ emailAddress = optional
####################################################################
[ req ]
-default_bits = 2048
+default_bits = 4096
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
CA証明書を作る
パスフレーズをなくすために-extra-req "-nodes"
を追加。
$ ./CA.pl -newca -extra-req "-nodes"
サーバ証明書のCSRを作る
パスフレーズをなくすため、-newreq
ではなく-newreq-nodes
で作成する。
SANを-addext
の後に記載していく。
DNS:
で続く箇所は、DNSホスト名が指定でき、サブドメインに当たる部分を*
で置き換えることができる。
IP:
で続く箇所は、IPアドレスを個別に指定できる。残念ながらネットワークアドレスは指定できないようだ。
$ ./CA.pl -newreq-nodes -extra-req "-addext 'subjectAltName = DNS:sample.com,DNS:*.sample.com,IP:192.168.1.1'"
サーバ証明書を署名する
通常の手順と変わらないが、証明書にSANがふくまていることが確認できる。
$ ./CA.pl -sign
====
/opt/openssl-1.1.1b/bin/openssl ca -config ./openssl.cnf -policy policy_anything -out newcert.pem -infiles newreq.pem
Using configuration from ./openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number:
...(snap)...
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
...(snap)...
X509v3 Subject Alternative Name:
DNS:sample.com, DNS:*.sample.com, IP Address:192.168.1.1
Certificate is to be certified until Mar 19 23:10:18 2029 GMT (3650 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
==> 0
====
Signed certificate is in newcert.pem
各ファイル
ファイル名 | 用途 |
---|---|
./demoCA/cacert.pem |
CA証明書 |
./demoCA/private/cakey.pem |
CA証明書の秘密鍵 |
newcert.pem |
サーバ証明書 |
newkey.pem |
サーバ証明書の秘密鍵 |
その他便利なコマンド
生成したサーバ証明書を使ってブラウザで動作確認する。
以下は、https://<CA作成したサーバ>:8443/
で確認することができる。
$ openssl s_server -accept 8443 -cert newcert.pem -key newkey.pem -WWW
生成したサーバ証明書をPKCS#12形式に変換する。
$ openssl pkcs12 -export -in newcert.pem -inkey newkey.pem -out server.p12
よきオレオレライフを。