nginx で StartSSL のクライアント証明書を使ったクライアント認証をやる

[`evernote` not found]
Bookmark this on Hatena Bookmark
Share on Facebook
LINEで送る

--- 追記 ここから ---

注意

startsslの証明書が主なブラウザから弾かれるようになりました.
詳しくは,この辺とか→StartSSL の証明書が使い物にならなくなっていた件 | ぴんくいろにっき

個人的には,移行をおすすめします.
私は,2017年4月から別の認証局へ移行しております.

--- 追記 ここまで ---

毎回,認証が表示されるのが面倒臭いので,クライアント認証を導入する.

環境

nginxのバージョンを上げるか,opensslのバージョンを上げるかしないとエラーを吐くので,nginxを1.9.12以降に上げるか(#901 (Changes in openssl master wrt SSL_shutdown()) – nginx),opensslを1.1.0以降に上げる(SSL error NginX 1.9.10

本記事では,試験鯖でnginx公式リポジトリ(Debian 8 (Jessie) - Web サーバ Nginx 構築(Nginx 公式リポジトリ使用)! - mk-mode BLOG)を使用して入れた1.10.2-1と,
jessie-backportsを使用して入れた1.0.2k-1により動作確認することとする.

ちなみに,この鯖はそれらとは環境がまた違います.

nginxのアップデート

ownCloudを入れていてnginxを使っている時にnginx-commonを消すとapache2が入ってしまい,/etc/systemd/system/nginx.service/dev/nullを指すようになってしまったので,/lib/systemd/systemにnginx.serviceを書いて(NGINX systemd service file | NGINX),おまじないを唱える.

sudo systemctl unmask nginx.service

そうすると,systemdで制御できるようになるようなので,service nginx startとかが効く.
nginx.serviceに書いてあるバイナリーのバージョンを確認して,問題なければnginxの設定に入る.

nginxの設定

startsslのログインにクライアント証明書を使ったクライアント認証が必要(最近はメールアドレスへのワンタイムパスがサポートされたけど,昔は証明書を失くしたら二度とログインできなかった)なので,当然インストール済だとして,その証明書を使うことにする.
証明書のsubjectは以下とする.

/description=For login authentication only/CN=mail@address.com/emailAddress=mail@address.com

subjectを確認する方法は

openssl pkcs12 -nokeys -info -in CERTIFICATIONFILE.pfx

とかやる.pkcs12の部分は証明書の形式に応じて変更する.

あとはnginxのserverあたりに設定を書く.
基本的な設定は,この辺を流用すると楽チン.Generate Mozilla Security Recommended Web Server Configuration Files

server {
    listen 443 http2;
    server_name YOURDOMAIN;

    ssl on;
    ssl_verify_client on; # クライアント認証を有効化
    ssl_verify_depth 2;   # 認証局を辿る数

    # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
    ssl_certificate /path/to/crt/of/your/server.crt;
    ssl_certificate_key /path/to/key/of/your/server.key;
    ssl_client_certificate /path/to/crt/of/your/CA.crt;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;


    # modern configuration. tweak to your needs.
    ssl_protocols TLSv1.2;
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
    ssl_prefer_server_ciphers on;

    # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
    add_header Strict-Transport-Security max-age=15768000;

    # OCSP Stapling ---
    # fetch OCSP records from URL in ssl_certificate and cache them
    ssl_stapling on;
    ssl_stapling_verify on;

    # Add headers to serve security related headers
    # Before enabling Strict-Transport-Security headers please read into this topic first.
    #add_header Strict-Transport-Security "max-age=15552000; includeSubDomains";
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Robots-Tag none;
    add_header X-Download-Options noopen;
    add_header X-Permitted-Cross-Domain-Policies none;

    # Path to the root of your installation
    root /path/to/your/document/root;
    index index.php index.htm;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    if ($ssl_client_s_dn !~ "/CN=mail@address.com/emailAddress=mail@address.com")
    {
           return 401;
    }

    # あとは普通の設定と同様
}

ね,簡単でしょ?

One Reply to “nginx で StartSSL のクライアント証明書を使ったクライアント認証をやる”

Comments are closed.