LoginSignup
91
94

More than 5 years have passed since last update.

究極のノマドを追求したらカギっ子管理者になってたオレオレ証明書の巻!!

Last updated at Posted at 2014-05-14

課題

管理画面などはセキュリティ上の理由からBasic認証にしてみたり、IPで制限かけたりMacアドレスで制限かけたりすることが多い。ただ、この方法だけ見てみると、どっちもイマイチでBasic認証だと弱いしIP制限やMacアドレスだと休日何かあった時に毎回会社に来るとか...。休日の時に見なければならないということはおおよそ緊急なので、移動してる間に問題が拡大している可能性もある。

なんかイイ方法ないの?

鍵を持つ。

サーバ側では、鍵を持っている人しかアクセスさせないようにすれば場所に縛られることなくセキュアにアクセス出来る。コレを実現するのにクライアント証明書の設定をする。

self_certs.png

0.まずはopensslのバージョンを確認する

Openssl公式サイトで確認してopenssl 1.0.1g以上にすること

1.設定ファイルの編集してみる

鍵長等はコチラを参考にさせてもらい設定の方針を決めてみる

  • 頻繁に更新が必要なのも大変なので有効期限を10年にする (default_days)
  • ハッシュ方法は限られた数を想定しているため固めにsha512にしてみる (default_md)
  • 鍵長を2048bitsにする (default_bits)
  • ルートCA用の設定は[ v3_ca ]で変更
  • クライアント認証の設定は行末に[ clientAuth ]を追加
  • サーバ認証用の設定は行末に[ serverAuth ]を追加
cmd
cp -p /etc/pki/tls/{openssl.cnf,openssl.cnf.`date +"%Y%m%d"`}
vi /etc/pki/tls/openssl.cnf
openssl.cnf
diff -u openssl.cnf.20140510 openssl.cnf
--- openssl.cnf.20140510    2014-04-07 20:26:41.000000000 +0900
+++ openssl.cnf 2014-05-10 05:50:21.198111607 +0900
@@ -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 = sha512            # use public key sha256
 preserve   = no            # keep passed DN ordering

 # A few difference way of specifying how similar the request should look
@@ -104,7 +104,7 @@
 ####################################################################
 [ req ]
 default_bits       = 2048
-default_md     = sha1
+default_md     = sha512
 default_keyfile    = privkey.pem
 distinguished_name = req_distinguished_name
 attributes     = req_attributes
@@ -237,14 +237,14 @@

 # This is what PKIX recommends but some broken software chokes on critical
 # extensions.
-#basicConstraints = critical,CA:true
+basicConstraints = critical,CA:true
 # So we do this instead.
-basicConstraints = CA:true
+#basicConstraints = CA:true

 # Key usage: this is typical for a CA certificate. However since it will
 # prevent it being used as an test self-signed certificate it is best
 # left out by default.
-# keyUsage = cRLSign, keyCertSign
+keyUsage = cRLSign, keyCertSign, digitalSignature, keyAgreement, keyCertSign, keyEncipherment

 # Some might want this also
 # nsCertType = sslCA, emailCA
@@ -260,6 +260,8 @@
 # You can even override a supported extension:
 # basicConstraints= critical, DER:30:03:01:01:FF

+extendedKeyUsage = serverAuth, clientAuth
+
 [ crl_ext ]

 # CRL extensions.
@@ -350,3 +352,17 @@
                # (optional, default: no)
 ess_cert_id_chain  = no    # Must the ESS cert id chain be included?
                # (optional, default: no)
+
+[ clientAuth ]
+extendedKeyUsage = clientAuth
+basicConstraints=CA:FALSE
+keyUsage = digitalSignature, keyEncipherment
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
+[ serverAuth ]
+extendedKeyUsage = serverAuth , clientAuth
+basicConstraints=CA:FALSE
+keyUsage = digitalSignature, keyEncipherment
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer

鍵の用途(keyUsage)部分に指定できるパラメータ。更に詳しい情報はコチラ

parameter usage
digitalSignature デジタル署名
nonRepudiation 否認防止
keyEncipherment 鍵配布
dataEncipherment データ暗号化
keyAgreement 鍵の検証
keyCertSign 鍵署名
cRLSign 証明書失効リスト(CRL)の検証
encipherOnly 暗号化のみ
decipherOnly 復号化のみ

2.自己ルートCAの開設してみる

生成されるもの ファイル 備考
CA公開鍵 /etc/pki/CA/cacert.pem
CA秘密鍵 /etc/pki/CA/private/cakey.pem 非公開ファイル、厳重に管理すること
/etc/pki/tls/misc/CA
$ sudo /etc/pki/tls/misc/CA -newca

CA certificate filename (or enter to create)
'[enterを押す]'
Making CA certificate ...
Generating a 2048 bit RSA private key
.............................................................................+++
.........................+++
writing new private key to `/etc/pki/CA/private/./cakey.pem`
Enter PEM pass phrase: '[passwordを入れる]'
Verifying - Enter PEM pass phrase: '[再度passwordを入れる]'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:JP '[国名を2文字で記入]'
State or Province Name (full name) []:Tokyo '[都道府県を記入]'
Locality Name (eg, city) [Default City]:Shibuya-ku '[市区町村を記入]'
Organization Name (eg, company) [Default Company Ltd]:hoge Corp '[会社名などを記入]'
Organizational Unit Name (eg, section) []:hoge '[部署名などを入れる]'
Common Name (eg, your name or your server`s hostname) []:hoge.jp '[ドメインを記入]'
Email Address []:  '[(任意)入れなくてもよい]'

Please enter the following `extra` attributes
to be sent with your certificate request
A challenge password []: '[(任意)入れなくてもよい]'
An optional company name []: '[(任意)入れなくてもよい]'
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for /etc/pki/CA/private/./cakey.pem: '[上記で記入したpasswordを再度入力]'
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 13847243035304331584 (0xc02b4a2cbdd10940)
        Validity
            Not Before: May  9 21:07:11 2014 GMT
            Not After : May  8 21:07:11 2017 GMT
        Subject:
            countryName               = JP
            stateOrProvinceName       = Tokyo
            organizationName          = hoge Corp
            organizationalUnitName    = hoge
            commonName                = hoge.jp
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                2F:A4:34:1B:CE:B5:58:54:E3:14:C7:B3:B2:BE:CB:04:A7:80:0D:BA
            X509v3 Authority Key Identifier:
                keyid:2F:A4:34:1B:CE:B5:58:54:E3:14:C7:B3:B2:BE:CB:04:A7:80:0D:BA

            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Key Usage:
                Digital Signature, Key Encipherment, Key Agreement, Certificate Sign, CRL Sign
            X509v3 Extended Key Usage:
                TLS Web Server Authentication, TLS Web Client Authentication
Certificate is to be certified until May  8 21:07:11 2017 GMT (1095 days)

Write out database with 1 new entries
Data Base Updated

大事なファイルなのでパーミッションを換えておく

chmod 400 /etc/pki/CA/private/cakey.pem

困ったときは

topic command
ルートCAを作り直したいとき rm -rf /etc/pki/CA/*
公開鍵の内容を確認したいとき openssl x509 -noout -in [公開鍵] -text
秘密鍵の内容を確認したいとき openssl rsa -noout -in [秘密鍵] -text

3.サーバ証明書をツクル

nginxがインストールされている事を前提として、SSL証明書を更新する事を想定してyyyymmddをつけたディレクトリを作成

3-1.サーバ秘密鍵とCSRの作成して署名をする

生成されるもの ファイル 備考
サーバ秘密鍵 hoge.key 非公開ファイル、厳重に管理すること
証明書署名要求(CSR) hoge.csr
サーバ証明書 hoge.crt

3-2.サーバ秘密鍵とCSRを作成する

create_csr
mkdir /etc/nginx/ssl_`date +"%Y%m%d"` && cd !$
openssl req -new -nodes -newkey rsa:2048 -sha256 -keyout hoge.key -out hoge.csr

3-3.[任意]サーバ秘密鍵のパスワードを解除

no_key
cd /etc/nginx/ssl_`data +"%Y%m%d"`
openssl rsa -in hoge.key -out hoge_no.key

3-4.自己ルートCAでCSRへの署名

sign
openssl ca -out /etc/nginx/ssl_`date +"%Y%m%d"`/hoge.crt -infiles /etc/nginx/ssl_`date +"%Y%m%d"`/hoge.csr

[tips]署名がうまくいかない時

Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for /etc/pki/CA/private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
..(snip)..
Certificate is to be certified until May  8 10:58:48 2024 GMT (3650 days)
Sign the certificate? [y/n]:y
failed to update database
TXT_DB error number 2
revoke
ll /etc/pki/CA/newcerts/
  -rw-r--r-- 1 root root 4625  5月 10 06:07 2014 C02B4A2CBDD10940.pem
openssl ca -revoke /etc/pki/CA/newcerts/C02B4A2CBDD10940.pem

4.nginxでクライアント証明書のチェックをするようにしてみる

prepare
cp -p /etc/nginx/conf.d/{default.conf,default.conf.`date +"%Y%m%d"`}
vi /etc/nginx/conf.d/default.conf
主要パラメータ 内容 備考
ssl_verify_client クライアント認証の検証有無を設定
ssl_verify_depth サーバがクライアントの身元を確認するために
証明書のチェーンを何階層までたどるかを設定
ssl_ciphers こちらで確認して下さい
nginx_config_sample
server {
    listen 443;
    server_name hoge.jp;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    ssl on;
    ssl_certificate /etc/nginx/ssl_20140511/hoge.crt;
    ssl_certificate_key /etc/nginx/ssl_20140511/hoge_no.key;
    ssl_client_certificate /etc/pki/CA/cacert.pem;
    ssl_session_timeout 5m;

    ssl_verify_client on;
    ssl_verify_depth 3;

    ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE+RSAGCM:ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!aNULL!eNull:!EXPORT:!DES:!3DES:!MD5:!DSS;
    ssl_prefer_server_ciphers on;
}
service nginx configtest
service nginx restart

5.クライアント証明書もツクル

基本的にはサーバ証明書と同様に作成

5-1.クライアント秘密鍵とCSRの作成して署名をする

生成されるもの ファイル 備考
クライアント秘密鍵 client_hoge.key 非公開ファイル、厳重に管理すること
証明書署名要求(CSR) client_hoge.csr
クライアント証明書 clinet_hoge.crt
create_csr
cd /tmp
openssl req -new -nodes -newkey rsa:2048 -sha256 -keyout client_hoge.key -out client_hoge.csr
sign
openssl ca -out /tmp/client_hoge.crt -infiles /tmp/client_hoge.csr

5-2.pkcs12形式にまとめる

クライアント証明書を配布出来るようにpkcs12形式でファイルを作成

生成されるもの ファイル 備考
pkcs12ファイル client_hoge.p12 特定の人に配布するためのファイル

秘密鍵とクライアント証明書をpkcs12形式でまとめます。

pkcs12
openssl pkcs12 -export -in client_hoge.crt -inkey client_hoge.key -certfile /etc/pki/CA/cacert.pem -out client_hoge.p12

6.ようやくブラウザからアクセス!

クライアント証明書が無い場合

証明書がないためBad Requestで画面が表示できない。

400_The_SSL_certificate_error.png

クライアント証明書を入れてみる[Macの場合]

先ほど作成したpkcs12形式のファイルをダブルクリック

client_cert.png

キーチェーンに追加

add_certs.png

リストに追加されるがルート証明書が✕になっているの何とかする

before_check.png

自分自身を信じてみる

身元が判明しているのでルート証明書をSSLだけ信頼してみる

root_certs.png

リストを確認すると青い+になった

after_check.png

ブラウザで確認してみる。

ssl_certificate_ok.png

[tips]確認している時にハマったこと

  • ブラウザにキャッシュされてしまうためかいつまでもクライアント証明書が有効にならない
 設定がほんとに間違えている可能性もあるが、まずはシークレットモードでも試してみる

[tips]他にも色々使える

  • スマホにもクライアント証明書を使用できる
  • Mailサーバ証明書 (SMTPS, IMAPS, POP3S)
  • バージョン管理 (git, Mercurial, etc..)
  • DB接続 (mysql, etc..)

まとめ

やってみると、最低限おんなじようなことを3回くらいやらなければならないので面倒に見えるが慣れれば10分位でできるので是非お試しあれ!ただ、所詮オレオレ証明書なのでBasic認証なども組み合わせてセキュリティには十分注意してください!

91
94
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
91
94