参考にしたサイト
クライアント証明書を要求するサイトの構築(Apache+OpenSSL)その2 - Qiita [キータ]書きました。
ランダムパスワード生成方法
- 多くのパスワードを作る必要があるので
pwgen
使うと便利。
サーバ証明書の作成
1. 独自認証局の秘密鍵、ルート証明書(CA)の作成
- C: 国名 (JP)
- ST: 都道府県 (Tokyo)
- O: 会社名 (My Company Ltd)
- OU: 部署名 (sales)
- CN:サーバーのドメイン名 (
mycompany.co.jp:8000
等。証明書の表示名に使われます。)
cd /opt/
mkdir -p demoCA/{private,newcerts}
cd demoCA
echo 01 > serial
openssl req \
-x509 \
-days 3650 \
-newkey rsa:2048 \
-keyout private/cakey.pem \
-out cacert.pem \
-subj "/C=JP/ST=Tokyo/O=localhost/OU=test/CN=$(hostname)"
# cakey.pem のパスワードを入力
file | 備考 |
---|---|
private/cakey.pem | 秘密鍵 |
cacert.pem | 認証局(CA)証明書 |
2. 秘密鍵とサーバ署名要求(CSR)の作成
サーバ証明書
cd /opt/demoCA/
openssl req \
-newkey rsa:2048 \
-keyout newkey.pem \
-out newreq.pem \
-subj "/C=JP/ST=Tokyo/O=localhost/OU=test/CN=$(hostname)"
# newkey.pem のパスワードを入力
file | 備考 |
---|---|
newkey.pem | ホストキー(パスワードあり) |
newreq.pem | ホスト証明書 |
3.パスワードなしのホストキー作成
apacheに組みこむ用。
/opt/demoCA/
openssl rsa -in newkey.pem -out nokey.pem
# newkey.pem のパスワードを入力
4. CSRへの署名
/opt/demoCA/
touch index.txt
cd /opt
openssl ca \
-in demoCA/newreq.pem \
-days 3650 \
-out demoCA/cert.pem \
-notext
# /opt/demoCA/private/cakey.pem のパスワードを入力
5. openssl.cnfを編集
cd /opt/demoCA
cp -a /etc/ssl/openssl.cnf .
openssl.cnfを書き換える
openssl.cnf.patch
/opt/demoCA/openssl.cnf--- /etc/ssl/openssl.cnf 2017-05-19 17:31:50.000000000 +0900
+++ openssl.cnf 2018-10-16 09:16:10.628048155 +0900
@@ -39,7 +39,7 @@
####################################################################
[ CA_default ]
-dir = ./demoCA # Where everything is kept
+dir = /opt/demoCA # Where everything is kept
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.
@@ -70,9 +70,9 @@
# 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
@@ -85,8 +85,8 @@
countryName = match
stateOrProvinceName = match
organizationName = match
-organizationalUnitName = optional
-commonName = supplied
+organizationalUnitName = supplied
+commonName = optional
emailAddress = optional
# For the 'anything' policy
@@ -97,8 +97,8 @@
stateOrProvinceName = optional
localityName = optional
organizationName = optional
-organizationalUnitName = optional
-commonName = supplied
+organizationalUnitName = supplied
+commonName = optional
emailAddress = optional
####################################################################
@@ -126,23 +126,23 @@
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
-countryName_default = AU
+countryName_default = JP
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
-stateOrProvinceName_default = Some-State
+stateOrProvinceName_default = Tokyo
localityName = Locality Name (eg, city)
0.organizationName = Organization Name (eg, company)
-0.organizationName_default = Internet Widgits Pty Ltd
+0.organizationName_default = localhost
# we can do this but it is not needed normally :-)
#1.organizationName = Second Organization Name (eg, company)
#1.organizationName_default = World Wide Web Pty Ltd
-organizationalUnitName = Organizational Unit Name (eg, section)
+organizationalUnitName = Organizational Unit Name (eg, username)
#organizationalUnitName_default =
commonName = Common Name (e.g. server FQDN or YOUR name)
6. 証明書失効リスト用
echo "00" > crlnumber
クライアント用証明書の作成
p12キーの生成
各クライアントに配布する用にp12キーを生成。
クライアント名.p12 のパスワードも伝える必要がありますので、クライアント名.p12.txtにパスワードを書いときます。
このp12キーはクライアントの端末にインストールすることになります。
/opt/demoCA/create_cert.sh
#!/bin/sh
set -eux
CLNT=$1
CA_ROOT=/opt/demoCA
REPOS=${CA_ROOT}/repository
mkdir -p $REPOS/${CLNT}
# key : 秘密鍵生成
openssl genrsa -rand /var/log/messages -out ${REPOS}/${CLNT}/${CLNT}-client.key -des3 2048
# key -> csr : 署名要求
openssl req -new -key ${REPOS}/${CLNT}/${CLNT}-client.key -out ${REPOS}/${CLNT}/${CLNT}-client.csr -config openssl.cnf
# csr -> pem : 署名(Base64形式)
openssl ca -config openssl.cnf -keyfile ${CA_ROOT}/private/cakey.pem -cert ${CA_ROOT}/cacert.pem -in ${REPOS}/${CLNT}/${CLNT}-client.csr -out ${REPOS}/${CLNT}/${CLNT}-client.pem
# pem -> crt : 証明書
openssl x509 -in ${REPOS}/${CLNT}/${CLNT}-client.pem -out ${REPOS}/${CLNT}/${CLNT}-client.crt
# crl (失効リスト更新)
openssl ca -config openssl.cnf -gencrl -out ${CA_ROOT}/ca.crl -keyfile ${CA_ROOT}/private/cakey.pem -cert ${CA_ROOT}/cacert.pem -verbose -crldays 3650
# p12 (webブラウザ用。秘密鍵と公開鍵(証明書)を PKCS #12ファイルにまとめる)
openssl pkcs12 -export -in ${REPOS}/${CLNT}/${CLNT}-client.crt -inkey ${REPOS}/${CLNT}/${CLNT}-client.key -out ${REPOS}/${CLNT}/${CLNT}-client.p12 -certfile ${CA_ROOT}/cacert.pem -name 'demoCA Client Cert' -caname 'demoCA'
#p12.txt (p12のパスワードをtxtに保存)
echo -n "enter ${CLNT}.p12 pass : "
read P12PASS
echo ${P12PASS} > ${REPOS}/${CLNT}/${CLNT}-client.p12.txt
途中パスワード入力を間違えると手動でのリカバリーが大変なのでバージョン管理で戻せるようにする。
chmod +x create_cert.sh
git init
git add -A && git commit -m "init"
使い方
./create_cert.sh kitamura
# repository/ユーザ名/ユーザ名.key のパスワード
# repository/ユーザ名/ユーザ名.p12 のパスワード
# private/cakey.pemのパスワード
git add -A && git commit -m "add: クライアント名"
Apacheの設定
sudo sh -c "echo ServerName $HOSTNAME" >> /etc/apache2/httpd.conf
/etc/apache2/sites-available/default-ssl.conf
SSLCertificateFile /opt/demoCA/cert.pem
SSLCertificateKeyFile /opt/demoCA/nokey.pem
SSLCACertificateFile /opt/demoCA/cacert.pem
<Location /owncloud/>
SSLVerifyClient require
</Location>
a2enmod ssl
a2ensite default-ssl
sudo apachectl configtest
sudo /etc/init.d/apache2 restart
(memo) pemファイルの変換
openssl pkcs12 -export -in [input_file] -out [output_file]
openssl x509 -in [input_file] -inform PEM -text -noout