nginx
Ubuntu

nginx で クライアント認証したい!- ベーシック認証の置き換え

More than 1 year has passed since last update.

必要なものは全てここにある

http://server-setting.info/centos/private-ca-cert.html

・・・だけだと終了してしまうので、もろもろ追記。
(まだ整理できてない箇所もあるので、違ってたら突っ込みお願いします)

そもそもクライアント認証って?

そもそもの発端は、「社内で使っていた管理画面を外部業者に委託したい」という所から。
社内限定であればIPベースのFW(AWSならセキュリティグループ)の設定で事足りてたのですが、いざ外部に公開となると、IP制限では対応しきれない...!

当然ベーシック認証も設定はしてあるものの、アタックされる可能性もなきにしもあらず。

そこで!ベーシック認証の代替手段として、「クライアント認証」の登場です。

仕組みはこういう(SSL:クライアント認証 )ページを見て頂いた方が早いのですが、平たく言うと 証明書を持った特定の端末(厳密にはブラウザ)からしかアクセスできない 認証方法となります。

証明書が漏れた場合はその証明書を失効させる事もできるため、セキュリティ的にはベーシック認証と比べかなり安心安全です。

用語の整理

まず最初の壁がここ。聞き慣れない(見慣れない)単語が多くて萎縮して発狂しないようにするために用語の整理。

用語 別の言い方 説明 内訳
CA Certificate Authority, 認証局 「この人ダイジョブ」ってサーバ証明書の信頼性の責任持つ人。証明書の保証人みたいな。保証人の保証人もいる(=中間CA) -
ルートCA ルート認証局 保証人の保証人の...を辿っていった一番最後の人。他の保証人がいないので、証明書は オレオレ です。Verisign とか comodo とか Symantec とかがこれにあたる -
CSR Certificate Signing Request 認証局に「サインくれ」っていうために書く申請書みたいなもの。証明書を設置するサーバ側が発行する 「サーバの公開鍵」+「組織名とか所在地とか」
CRT CeRTification(の略。恐らく。), SSL証明書, サーバ証明書 いわゆるサーバ証明書(後で補足予定) (「CSR」+「CAのサイン」)→CA秘密鍵で暗号化

クライアント認証のためにやること

最初の link の概略になりますが。処理の流れは以下↓

  1. openssl をインストールする
  2. 認証局(=プライベートCA)を自前で作る
  3. サーバ証明書を作成する。そして自分で作ったCAでサインする。
  4. クライアント証明書を作成する。そして自分で作ったCAでサインする。
  5. クライアントに証明書を渡して、ブラウザにインストールする。
  6. 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を読み込んだあと、以下のチェックボックスを忘れずに有効にしてください。
スクリーンショット 2015-12-29 20.08.13.png

対応クライアントを増やすには

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