2019年12月28日土曜日

nginx でクライアント証明書認証してみる (キーチェーンアクセス編)

概要

クライアント証明書認証は https のサイトにアクセスするのに指定の証明書がないとアクセスできない認証です
IP だけではアクセス制御できない場合に使えます
今回は証明書の発行をキーチェーンアクセスで行い、そこで発行した証明書を使って nginx でクライアント証明書認証を試してみました

環境

  • macOS 10.15.2
  • nginx 1.15.2

認証局の作成

まずはキーチェーンアクセスを使って認証局を作成します
証明書は認証局がないと発行できません

ユーザ証明書を「SSL クライアント」にします
名前は好きな名前にしましょう

以下のように認証局が作成できれば OK です

キーチェーンアクセスの一覧にも認証局が存在することを確認します

クライアント証明書の発行

次に作成した認証局からクライアント証明書を書き出します

作成した認証局を右クリックし書き出しを選択します

鍵は p12 形式で書き出します

鍵にはパスワードを設定することもできます
今回はテストなのでパスワードなしにします

鍵が書き出せたら同様に認証局を右クリックして書き出しを選択します
そして .cer 形式で証明書を書き出します

証明書と鍵の変換

nginx で使うためには証明書と鍵ファイルをそれぞれ「.crt」「.key 」形式に変換する必要があります

  • openssl x509 -in ca.cer -inform DER -out ca.crt -outform PEM
  • openssl pkcs12 -in ca.p12 -nocerts -nodes -out ca.key

鍵を変換する際にパスワードを求められますが今回は設定していないので空で OK です

nginx の設定

あとは作成したクライアント証明書を nginx に設定して起動します
クライアント証明書認証は https でなければ動作しないのでサーバ証明書を適当に用意します
また以下の設定は最低限の設定のみになっています

  • cd /usr/local/etc/nginx/
  • vim nginx.conf
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       443 ssl;
        server_name  localhost;

        ssl_certificate      /etc/letsencrypt/live/hoge.fuga.com/fullchain.pem;
        ssl_certificate_key  /etc/letsencrypt/live/hoge.fuga.com/privkey.pem;
        ssl_verify_client on;
        ssl_client_certificate /path/to/ca.crt;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
            root   html;
            index  index.html index.htm;
        }
    }

    include servers/*;
}

ssl_verify_client on;ssl_client_certificate /path/to/ca.crt; がクライアント証明書認証を有効にしている部分です
それ以外のディレクティブは SSL に関する設定になります

/path/to/ca.crt は先程変換した証明書のパスをフルパスで指定しましょう
鍵は nginx には指定せずクライアントがアクセスする際に指定します

動作確認

nginx を再起動しましょう

  • sudo nginx -s stop
  • sudo nginx

まずは curl を使って確認してみます
クライアント証明書を指定するオプションは --cert でクライアント証明書の鍵を指定するオプションは --key になります

  • curl -k --cert ./ca.crt --key ./ca.key https://localhost

これでアクセスできると思います
もしクライアント証明書と鍵が指定されていない場合は nginx が「400 No required SSL certificate was sent」というエラーを返します
またクライアント証明書と鍵の指定が誤っている場合は「400 The SSL certificate error」が返ります

こんな感じでクライアント証明書と鍵の指定が合っていないと正常にアクセスできないのでこの仕組を使ってアクセス制御を実現できるます

ちなみに Chrome などのブラウザでアクセスしたい場合はキーチェーンアクセスなどの証明書を管理するアプリに鍵をインポートしましょう
基本は p12 ファイルをそのまま配布してダブルクリックなどすれば各 OS に付属の証明書管理アプリが立ち上がってインポートできると思います

今回は curl とブラウザのクライアント証明書を使ったアクセス方法を紹介しましたがクライアントのソフトウェアによって証明書の設定は様々なのでそれぞれに合った設定をしてください

最後に

nginx でクライアント証明書認証を試してみました
クライアント証明書の発行は MacOS 付属のキーチェーンアクセスで行いました
キーチェーンアクセスに慣れている人はこの方法でも良いと思います
クライアント証明書の管理も簡単になります

openssl コマンドを使ってすべての作業をクライアント証明書の発行を行うことも可能です
openssl の手順はネットを検索すればいろいろ出てくると思います

また混乱しそうなので説明しておくとサーバ証明書とクライアント証明書は全くの別物です
同じ認証局から発行されている必要もないのでご注意ください

0 件のコメント:

コメントを投稿