https(Let's Encrypt) + クライアント証明書でアクセス制限するメモ
背景
- https なサービスを限られたユーザーにだけセキュアに提供したい
- https なサービス/webサイトのテストや, ファイル配布(e.g. simple directory or webdav)など.
- パスワード制限とか FIDO, WebAuthn はめんどい
- 自前(社内)だけなら Tailscale などで VPN というてもあるけど, PC で別の VPN サービス使っていたりで共存させるのが難しいときとか.
ローカル開発環境の https 化 https://blog.jxck.io/entries/2020-06-29/https-for-localhost.html で 127.0.01 で https 張るのもある. その次のステップとして本番サーバーにデプロイして, テストしたいときなど.
サーバー証明書は Let's Encrypt で, クライアントはオレオレでクライアント証明書を発行して対応します!
情報
Let’s Encryptと自己認証局でクライアント証明書接続
ありがとうございます.
サーバ証明書, https 化
Let's encrypt の設定などはいろいろインターネットにありますのでそれを参照ください.
ちなみに筆者は LightSail(bitnami) で nginx で, certbot で Let's Encrypt 設定しようとしてハマりました.
Lightsail で nginx + Let's Encrypt 設定のメモ
クライアント証明書
Ubuntu + OpenSSL で処理するものとします.
EasyRSA を使う手もありますが, OpenSSL コマンド直でやります.
執筆の 2023 年時点では, つよつよな暗号 ed25519 を使いたくなりますが,
少なくともブラウザへの証明書取り込みではまだ対応していなさそうっぽのようなので,
RSA 4096 にします(CA の鍵作成では ed25519 使ってもよいでしょう).
クライアント証明書を使うのが ~2025 年であれば, 2048 でもよいカモです.
また, 少なくとも 1024 は使わないようにしましょう.
手順
ありがとうございます.
CA 秘密鍵を生成します.
$ openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:4096 -out ca.key
パスワードを設定したい場合は -des3
や -aes-128-cbc
を指定しましょう.
自己署名証明書
$ openssl req -x509 -key ca.key -days 365 -out ca.crt
ここから, 各クライアント(ユーザー)ごとに作ります.
まずクライアントの秘密鍵
$ openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:4096 -out client.key
こちらも必要に応じて -des3
or -aes-128-cbc
でパスワード設定.
CSR
$ openssl req -new -key client.key -out client.csr
オレオレ CA で署名
$ openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 270 -out client.crt
証明書のシリアル番号を管理する ca.srl
が無い場合(最初にクライアント証明書を作るときなど)は, -CAcreateserial
で自動生成か, シリアル番号直指定します.
そうしないと
ca.srl: No such file or directory
というエラーがでます.
PKCS#12
形式のファイルの作成
ブラウザや OS の証明書ストアで読み込めるように, pkcs#12 形式にします.
$ openssl pkcs12 -export -in client.crt -inkey client.key -out client.p12
あとはこれをユーザーになにかしらセキュアな方法で渡し, ユーザー側に取り込んでもらう.
メールベースで渡す場合は, PGP(Kleopatra GUI)でやりとりするのがよいでしょう.
nginx での設定
あたり参考ください.
TODO
- Revoke の対応(クライアント証明書が誤って流出や別のユーザーに渡ったときに, 失効させたいとき)
Discussion