🔑

https(Let's Encrypt) + クライアント証明書でアクセス制限するメモ

2023/05/24に公開

背景

  • 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://www.konekuri.com/87/

ありがとうございます.

サーバ証明書, https 化

Let's encrypt の設定などはいろいろインターネットにありますのでそれを参照ください.

ちなみに筆者は LightSail(bitnami) で nginx で, certbot で Let's Encrypt 設定しようとしてハマりました.

Lightsail で nginx + Let's Encrypt 設定のメモ
https://qiita.com/syoyo/items/f951bd6be851773a98ca

クライアント証明書

Ubuntu + OpenSSL で処理するものとします.

EasyRSA を使う手もありますが, OpenSSL コマンド直でやります.

執筆の 2023 年時点では, つよつよな暗号 ed25519 を使いたくなりますが,

https://vpslife.server-memo.net/create_client_cert/

少なくともブラウザへの証明書取り込みではまだ対応していなさそうっぽのようなので,
RSA 4096 にします(CA の鍵作成では ed25519 使ってもよいでしょう).
クライアント証明書を使うのが ~2025 年であれば, 2048 でもよいカモです.
また, 少なくとも 1024 は使わないようにしましょう.

https://www.tohoho-web.com/ex/openssl.html

手順

https://rin-ka.net/nginx-client-certificates/

https://zenn.dev/ztrehagem/scraps/01d6aebd9fc352

https://qiita.com/tarosaiba/items/9fa3320b633e0f5e87b5

ありがとうございます.

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 で自動生成か, シリアル番号直指定します.

http://certificate.fyicenter.com/1972_OpenSSL_x509-req_-Error_my_ca.srl%3A_No_error_.html

そうしないと

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)でやりとりするのがよいでしょう.

https://qiita.com/karkwind/items/9cb2907060f210fc940a

nginx での設定

https://qiita.com/tarosaiba/items/9fa3320b633e0f5e87b5

あたり参考ください.

TODO

  • Revoke の対応(クライアント証明書が誤って流出や別のユーザーに渡ったときに, 失効させたいとき)

Discussion