- そもそもなぜ自己署名証明書なのか
- PKI基盤の選定
- XCA
- OpenXPKI
- 運用する上での規約
- OpenXPKI運用あれこれ
- ALB+Cognito+Google認証
- OpenXPKI内での認証
- デフォルトの証明書テンプレートがイケてない
- CRLの運用
- 最終形
- まとめ
- 参考サイト
チーフエンジニアの加辺(a.k.a. limitusus)です。
みなさん、自己署名証明書(いわゆるオレオレ証明書)使ってますか?
今回お客様から
クライアント証明書による認証機能を実現してほしい(自己署名証明書でOK)
という要望がありました。
そこで実際にどうやったら運用できるかを考え、実際に構築してみたのでご紹介します。
そもそもなぜ自己署名証明書なのか
無料でのTLS証明書発行サービスとしてはLet's Encrypt(ACME)やAWS Certificate Manager(DNS認証)が多く使われていますね。
これらの登場で2016年頃からサーバ証明書用途での利用はほぼ絶滅したのではないかと思います。
しかしながらやんごとなき事情でTLSクライアント証明書認証をすることになってしまった場合はどうか。
クライアント証明書を無料で発行してくれるサービスというのは今のところなさそう(?)です。
有料だと大手証明書販売業者が取り扱っていますが、10万円くらいはするようです。
一方でこのような需要は得てして社内サービス向けだったりして、そこに何万円もお金をかけるのも…という気持ちから自己署名証明書を発行したくなるケースというのがあるわけです。
自己署名証明書を発行するためには自己署名認証局を作成してやる必要があるわけですが、様々な場所で何度も述べられてきた通り、この認証局の管理というものが大変難易度の高いものとされています。
個人レベルなら運用なんてあまり考えなくてもよいわけですが、今回はきちんとしたPKI基盤の構築を行うことにしました。
PKI基盤の選定
技術基盤の選定はいつ行っても将来に何らかの負債を残すことになりがちです。今回もそれを覚悟で選定を行いました。
選定基準は以下のようにしていました。あとから覆されます。
- ルート証明書とは別に管理が行えること
- ルート証明書の鍵はオフライン管理したいため。
- Webベースのインターフェースが提供されていること
- 証明書の作成をCLIで行うこともできるのですが、運用の専門性が高まってしまいやすいため。
- クライアント証明書が発行できること
- 今回の要件で必要。
- AmazonLinux上で動作すること
- 現在主な基盤をAmazonLinux上に構築しており、環境をなるべく揃えるため。
このような基準で探していた結果、以下の運用に落ち着きました。
- 認証局そのものの管理はXCA (http://hohnstaedt.de/xca/)で行う
- 認証局からの証明書の発行業務はOpenXPKI (http://www.openxpki.org/) で行う
XCA
XCAはQtベースのアプリケーションです。
パスワードで暗号化された単一ファイルに管理対象の認証局のデータを全て入れておけます。
そのため取り回しもまあまあしやすいだろうということで使ってみることにしました。
導入当初はv1.4.1でしたが、これを書いている時点で2.1.0がリリースされています。
バックエンドがSQLベースになって大きく改善されているそうです。
これ単体でも末端の証明書の発行もできるのですが、今回XCAではCA証明書の管理までのみを行うようにしています。
OpenXPKI
OpenXPKIはプロジェクト10年目のPerl製OSS認証局管理ツールです。
こちらはXCAと異なりCA証明書を発行する機能はありません。
CAは別で管理していることを前提に、それをインポートして末端の証明書の発行業務を行うのに使います。
今のところ日本では導入サービスを行っている会社があるものの、情報は多くは出回っていないようです(そもそも自己署名認証局を運用する需要も多くないし…)。
OpenXPKIは先の選定基準を最後を除き全て満たしているのですが、導入時点の最新版v2.0(2018年5月リリース)でも公式にインストールがサポートされている環境がDebian JessieとUbuntu Trustyしかないという難点があります。
しかし他の製品でしっくりくるものを見付けられず
そのうち新しいUbuntuでも動かせるようになるだろうし、Trustyの運用くらいなら増えてもいいか
ということで採用することにしました。
運用する上での規約
安全なCA運用とするため、以下の規約を設けました。
- ルートCAをXCA上、自己署名で作成する
- サーバ証明書のCAとクライアント証明書のCAは分けてXCA上に作成し、ルートCAがこれに署名する
- サーバCAおよびクライアントCAそれぞれの証明書および秘密鍵をOpenXPKIにインポートして運用する
- ルートCAの秘密鍵はOpenXPKIにインポートしない(証明書はインポートする)
OpenXPKI運用あれこれ
ほとんど運用に関わる情報を紹介しているケースがないため、まだ手探り状態です。
その中で少しでも見出だした運用におけるポイントを紹介します。
ALB+Cognito+Google認証
OpenXPKIはEC2上に構築しましたが、誰でもアクセスできては困るのでALB + Cognito認証を用いて認証を行っています。
ここはもちろんAWS Certificate Manager発行のTLS証明書を使っています。
Cognito認証のGoogle認証を入れるとこのようなログイン画面になります
OpenXPKI内での認証
OpenXPKI自身の認証もあります。ここはユーザ名/パスワードによる認証としています。
X509証明書認証の設定もOpenXPKIの機能としては可能です。
しかしその場合はALBでの認証ができず、PKI基盤でのトラブル時に管理者すらアクセスできなくなってしまう危険もあるため分離することにしました。
デフォルトの証明書テンプレートがイケてない
OpenXPKIをインストールした直後のサーバ証明書テンプレートには「Default Profile style」と「Extended naming」があります。
前者はCN(Common Name)のうち後半部分が DC=Test Deployment,DC=OpenXPKI,DC=org
で固定されてしまっています。
では後者を使えばよいかというと、前者には入っているX509v3のSAN項目が入っておらず、こちらで発行するとGoogle Chromeでは証明書が適切に認識されません。
結果として、CNを自由に設定したサーバ証明書を作成するためには自身でテンプレートを作り込まなければなりません。
OpenXPKIではCSRを手元で作成してこれを読み込ませることもできますが事象は同様です。
どうCSRを作成しても最終的には証明書テンプレートに当て嵌まらない項目は無視されます。
CRLの運用
OpenXPKIでは管理しているCAのCRLをCLIで発行することができます。
証明書の失効に対応するため定期的に各CAのCRLを作成し、website hosting設定したS3にアップロードするようにしています。
# /tmp/ 以下にCRLが置かれる
1 1 * * * root openxpkicmd --realm ca-xxx crl_issuance
# 予めwebsite hostingを設定してあるS3 bucketにCRLをコピーしておく
31 1 * * * root AWS_DEFAULT_REGION=ap-northeast-1 aws s3 cp /tmp/xxx\ CA\ 1.pem s3://crl.example.com/12345abc.crl
証明書を利用しているサーバはこれを定期的に取得することで証明書の失効に対応できるようになっています。
最終形
最終的にはおおよそこのような構成となりました。
まとめ
自己署名証明書の基盤としてXCAとOpenXPKIを選定し、それなりに運用できる状態に持ってくることができました。
利用者の少ない分野でもあり製品がこなれていないため、現時点では利用者側で様々な運用知見を溜めていく必要があるフェーズといえると思います。
また、NetflixではLemurというアプリケーションを自社開発しているようです。こちらも気になっています。