必要なものは全てここにある
・・・だけだと終了してしまうので、もろもろ追記。
(まだ整理できてない箇所もあるので、違ってたら突っ込みお願いします)
そもそもクライアント認証って?
そもそもの発端は、「社内で使っていた管理画面を外部業者に委託したい」という所から。
社内限定であればIPベースのFW(AWSならセキュリティグループ)の設定で事足りてたのですが、いざ外部に公開となると、IP制限では対応しきれない...!
当然ベーシック認証も設定はしてあるものの、アタックされる可能性もなきにしもあらず。
そこで!ベーシック認証の代替手段として、「クライアント認証」の登場です。
仕組みはこういう(SSL:クライアント認証 )ページを見て頂いた方が早いのですが、平たく言うと 証明書を持った特定の端末(厳密にはブラウザ)からしかアクセスできない 認証方法となります。
証明書が漏れた場合はその証明書を失効させる事もできるため、セキュリティ的にはベーシック認証と比べかなり安心安全です。
用語の整理
まず最初の壁がここ。聞き慣れない(見慣れない)単語が多くて萎縮して発狂しないようにするために用語の整理。
用語 | 別の言い方 | 説明 | 内訳 |
---|---|---|---|
CA | Certificate Authority, 認証局 | 「この人ダイジョブ」ってサーバ証明書の信頼性の責任持つ人。証明書の保証人みたいな。保証人の保証人もいる(=中間CA) | - |
ルートCA | ルート認証局 | 保証人の保証人の...を辿っていった一番最後の人。他の保証人がいないので、証明書は オレオレ です。Verisign とか comodo とか Symantec とかがこれにあたる | - |
CSR | Certificate Signing Request | 認証局に「サインくれ」っていうために書く申請書みたいなもの。証明書を設置するサーバ側が発行する | 「サーバの公開鍵」+「組織名とか所在地とか」 |
CRT | CeRTification(の略。恐らく。), SSL証明書, サーバ証明書 | いわゆるサーバ証明書(後で補足予定) | (「CSR」+「CAのサイン」)→CA秘密鍵で暗号化 |
クライアント認証のためにやること
最初の link の概略になりますが。処理の流れは以下↓
- openssl をインストールする
- 認証局(=プライベートCA)を自前で作る
- サーバ証明書を作成する。そして自分で作ったCAでサインする。
- クライアント証明書を作成する。そして自分で作ったCAでサインする。
- クライアントに証明書を渡して、ブラウザにインストールする。
- nginx の設定をする
諸注意
4. クライアントに証明書をインストールする
PKCS#12
ファイルの作成
PKCS#12
ファイルは、クライアントに配布するためのパッケージファイルです。
中身は以下の3点が入っており拡張子は .p12
となります。
※上記のリンクは拡張子が .pfx
となってますが、同じものっぽい?
- クライアント証明書
- クライアント秘密鍵
- 認証局証明書
上記のリンクの方法(4-4)だとプライベートCAの証明書が入っていないので、3点含めて pkcs#12
に変換します。
newcert.pem
, newreq.pem
がカレントディレクトリにある状態で、次のコマンドを実行します。
# /usr/lib/ssl/misc/CA.sh -pkcs12
Enter Export Password: PKCS#12 保護用パスワードを入力(何でも可能)
Verifying - Enter Export Password:
CA.sh
は内部的には openssl
を実行しているので、もし↑の CA.sh
でエラーが出た時は愚直に openssl
コマンド叩くしかないです。
# openssl pkcs12 -nokeys -in newcert.pem -inkey newreq.pem -certfile /path/to/cacert.pem -out newcert.p12 -export -name "My Certificate"
クライアント側のインストール
上記で作成した PKCS#12
ファイルを、何かしらの方法でクライアント認証をしたい端末に送ります。
後は最初のリンクの「(おまけ)プライベート認証局を登録(インポート)する」の項目とほぼ一緒です。
読み込むファイルを指定した時にパスワードを聞かれるので、先ほど PKCS#12
ファイルを作成した時に使ったパスワードを入力してください。
プライベートCAを読み込んだあと、以下のチェックボックスを忘れずに有効にしてください。
対応クライアントを増やすには
4, 5 をやればよいはず。
5. nginx 側の設定
server {
listen 443 ssl; # ssl on; ではなく、listen に書くのが推奨
server_name foo.example.com;
# server certificate
ssl_certificate /etc/ssl/CA/certs/foo.example.com.crt; # サーバのSSL証明書。3.で作ったもの
# server private key
ssl_certificate_key /etc/ssl/CA/private/foo.example.com.key; # サーバの秘密鍵。3.で作ったもの
ssl_verify_client on; # クライアント認証しまっせ
# ssl_verify_depth 2; # 中間CA を使う場合のみ
# CA certificate
ssl_client_certificate /etc/ssl/CA/capem.pem; # プライベートCAの証明書。2.で作ったもの
location ~ /foo {
# as you like
}
}
設定後、nginx の再起動を忘れずに。
参考
http://www.ssl-concier.com/news/topics/164
http://d.hatena.ne.jp/install-memo/20110906/1315291837
http://server-setting.info/centos/private-ca-cert.html
http://vimtaku.github.io/blog/2014/03/16/apache-nginx-client-certificate/
http://www.nslabs.jp/pki-client-certification-with-nginx.rhtml
http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_client_certificate