こんにちは! m.uriuです。
今回はOCIの証明書サービスついてのお話です。
OCIの証明書サービスでは、プライベート認証局(CA)とプライベート証明書を無料で作成できます。他にも、別の証明書サービスで発行した証明書のインポートも可能です。
またフレキシブル・ロード・バランサ(FLB)のHTTPSリスナーで証明書を使用する際、証明書サービスで管理している証明書から選択が可能です。
これを組み合わせると、認証局/証明書の発行からWEBページのHTTPS暗号化までを、無償でOCI環境で構築できます。
今回は、プライベート認証局/証明書発行からWEBページのHTTPS化までの手順と、
証明書サービスの機能などについてご紹介します。
目次
手順
今回は証明書サービスでプライベート認証局、プライベート証明書の作成~WEBサイトにHTTPSで接続、までの手順を紹介します。
以下の手順でリソース作成及び作業を実施します。
- IAMポリシー作成
- Vaultとキーを作成
- プライベート認証局作成
- プライベート証明書作成
- Webサーバ2台作成
- FLB作成
- ローカル端末の設定変更
- 接続
IAMポリシー作成
必要な権限を作成します。
まずは動的グループから作成します。IAMユーザだけでなく証明書サービス自体にも権限が必要になりますので、以下のルールを持つ動的グループを作成します。
以下のルールに一致
「resource.type ='certificateauthority‘」
次にIAMポリシーを作成します。
ポリシーは「証明書を作成するコンパートメント」に作成し、ポリシーステートメントには「証明書サービスにVaultとオブジェクト・ストレージへの操作権限を付与」するステートメントを記載します。
「Allow dynamic-group 【動的グループ名】 to use keys in compartment 【コンパートメント名】」
「Allow dynamic-group 【動的グループ名】 to manage objects in compartment 【コンパートメント名】 」
Vaultとキーを作成
認証局の発行に必要な、Vaultとマスター暗号化キーを作成します。
今回の検証の動作には関係ないので、高価なオプションの「仮想プライベート・ボールト」は外します。


続いて、マスター暗号化キーを作成します。
以下の項目を選択して作成します。
- 保護モード:HSM
- キーシェイプ、アルゴリズム:RDA/ECDSA(非対称キー)
※ECDSAは対応していないブラウザがあるため注意 - キーシェイプ、長さ:256ビット(任意)
※キーの長さは安全性と処理の時間でトレードオフなので、要件に合わせて設定


プライベート認証局作成
証明書サービスから認証局を作成します。
認証局タイプは、初めて作成する認証局なので「ルート認証局」に設定します。
名前や説明は任意ですが、テナンシ内で同じ名前は使えないことに注意してください。

サブジェクト情報では、証明書に記載される認証局の情報(名前や地域、組織名など)を入力します。
特別な要件が無ければ任意の値を入れます。
追加フィールドを開くと、国や地域、組織名などの追加情報を任意で入力できます。

権威の構成では、認証局の有効期限と暗号化に関する設定を選択します。
有効期限の開始日を空にすると、CA作成時の日時で自動的に設定されます。
ボールトやキーは、先ほど作成したものを選択し、署名アルゴリズムは任意のもので良いです。

ルールでは、このCAから作成する証明書の最大有効期間と下位CAの最大有効期間を設定します。
この後に作成する証明書でも有効期限を設定できるのですが、その際に設定できる日数はここで設定する「証明書の最大有効期間」から「-1日」までしか設定できません。
証明書の有効期限を長めに取ろうとしてうまく設定できない場合は、この値を見直してみると良いでしょう。
この値は作成後も変更できます。

失効構成では、失効した証明書の情報をバケットに保存する機能です。後からでも有効化はできますが、一度有効化すると無効化できないので注意しましょう。

最後にサマリーで設定内容を確認して作成を押し、作成完了です。


プライベート証明書作成
作成したプライベート認証局から、「証明書の発行」を選択してプライベート証明書を作成します。

基本情報を入力します。証明書タイプはOCI内部で管理するので、「内部CAによって発行済」を選択します。
名前と説明は任意の値を入力します。こちらもテナンシ内で同じ名前の証明書は作れないので注意しましょう。

認証局作成時と同様に証明書のサブジェクト情報を入力します。
共通名はCNに該当する値です。主にFQDNやドメイン名を入力します。今回は共通名と同じものを入力します。
サブジェクトの代替名は「DNS」か「IPアドレス」を選択でき、必要に応じて代替名を増やすこともできます。
追加フィールドを開くと、国や地域、組織名などの追加情報を任意で入力できます。

証明書構成では、証明書の用途や有効期限を設定できます。
証明書プロファイル・タイプは、[TLSサーバーまたはクライアント]、[TLSサーバー]、[TLSクライアント]、[TLSコード署名] から選択できます。
これから作る証明書はサーバ証明書、つまり[TLSサーバーまたはクライアント]または[TLSサーバー]が該当します。今回は広めに[TLSサーバーまたはクライアント]を選択しておきます。
有効期限の開始日は、空にすると証明書を作成した日時で有効期限開始日に設定されます。
有効期限の終了日ですが、デフォルトだと今の日数+90日で自動的に入力されています。証明書の有効期限は、CAで設定した証明書の日数「-1日」にしなければいけないので、認証局の設定をデフォルトの90日にしていた場合は、この画面で「-1日」に修正しましょう。

ルールでは、証明書の自動更新のルールを設定します。
「更新間隔(日数)」は、証明書新規作成または更新が行われてから次の更新が行われるまでの日数になります。
「拡張更新期間(日数)」は、新しいバージョンの証明書を予め用意する日数になります。更新間隔で設定した更新日になると、このあらかじめ用意したバージョンの証明書に更新されます。
自動更新のイメージ図も掲載しておきます。


最後にサマリーで設定内容を確認して証明書を作成します。


Webサーバ2台作成
以下のOCIチュートリアル「ロード・バランサでWebサーバーを負荷分散する」を参考に、サーバ名を表示するだけのWebサーバ2台を作成します。作成手順は割愛します。
OCIチュートリアル「ロード・バランサでWebサーバーを負荷分散する」

FLB作成
先ほどのチュートリアルを参考に、FLBを作成します。リスナーでトラフィックのタイプを「HTTPS」にし、SSL証明書で先ほど作成した証明書を選択します。

ローカル端末の設定変更
端末の設定変更を行います。この設定変更は、webサーバにアクセスする端末全てで必用になります。
まずhostsファイルの追記と証明書の追加を行います。
「<ロードバランサーのパブリックIPアドレス> <FQDN>」の行を追加します。

次に、ブラウザに証明書をインポートします。作成したプライベート認証局は、ブラウザの信頼された認証局に入っておらず、このままWebサーバにアクセスしようとすると警告が表示されるので、この手順が必要です。
インポートに必要な認証局の証明書のダウンロードは、認証局の詳細画面の左下のリソースメニューから「バージョン」を選択し、最新バージョンの右のトリコロンから「コンテンツの表示」を選択して表示してダウンロードできます。インポートには証明書PEMの方を使用します。

インポートする際は、拡張子が「.pem」だと取り込めないので、ダウンロード後は「.crt」に変換してからインポートしましょう。


接続
hostsファイルに追加したFQDNを使用してHTTPSでアクセスすると、警告は表示されず、Webページが表示されました。リロードでページの切り替えも成功しています。ブラウザからも証明書の情報が確認できます。
手順紹介は以上です。


補足
続いて、証明書サービスの検証で見つけた運用の肝や注意事項などを補足として4つほど紹介します。
補足1.証明書の更新
証明書サービスに登録した証明書は、自動または手動でコンソールから新しいバージョンに更新ができます。
自動更新は、証明書の詳細画面の左下のリソースから「ルール」を選択し、「更新ルールの編集」から、更新の頻度を設定できます。自動更新の仕組みについては、「2.4 プライベート証明書作成」をご覧ください。

手動更新は、証明書のバージョンのメニューから「証明書の更新」を選択し、有効期限の開始日と終了日を入力することで、新しいバージョンが作成されて更新が実行されます。
「保留中に設定」にチェックを入れると、「保留中」のバージョンが作成されます。このバージョンは右のトリコロンのメニューから「現行に設定」を選択するまでキープされ、「保留中」のまま保存されます。

補足2.FLBのリスナーに設定した証明書の更新について
「2.6 FLBの作成」でお見せしたように、FLBで使用する証明書はOCIの証明書サービスに登録した証明書を利用できます。
この証明書を自動または手動で更新を行った場合、リスナー側で証明書の再登録は不要となっています。
OCIの一部リソースは、定期的に証明書の最新バージョンを取得する仕組みがあるらしく、証明書サービスに登録した証明書が更新されると、その証明書に関連したリソース(FLB等)でも、手動で操作せずに更新された証明書が適用される仕組みがあるようです。
参考ブログはこちら
補足3.証明書の有効期限の監視について
証明書の管理をするうえで、証明書の有効期限が迫っていることを知らせる監視は欲しいものですが、
OCIのイベント・サービスや標準メトリックには、証明書の有効期限に関するイベントは実装されていません。
一応Cloud Guardには「Load balancer SSL certificate expiring soon」という、FLBに関連付けられた証明書の有効期限を検知する検出ルールはあるのですが、今回のように「OCIの証明書サービスで発行した証明書」がFLBに関連付けられていた場合、この検出ルールが機能しないようです。
外部の証明書サービスからインポートした証明書であればうまく機能するようです。
この問題についてのOCI側の公開情報はこちらから
まだ検証中ですが、カスタム・メトリックを使た監視方法があるそうなので、検証が成功すれば別の機会に紹介させていただきます。

補足4.OCIで作成した証明書の扱いについて
今回の「OCIの証明書サービスで証明書を発行し、WebページのSSL証明書として使用する」ことについて、OCIの仕様的に問題ないのかSRに問い合わせたところ、以下の回答をいただきました。
「Oracleはdigicert.comやgodaddy.comなどのような公開証明書認証局(Public CA)ではなく、インターネット全体からのHTTPSトラフィックに使用できるSSL証明書を生成することはできません。OCI証明書サービスを使用してCAおよび証明書を生成することは可能ですが、それを使用するには、FLBアドレスにアクセスするクライアントに対して、信頼された証明書として追加する必要があります」
また、「OCIの証明書と認証局は、あくまでも”プライベート証明書/認証局”」であることもSRに念押しされました。
検証でお見せしたように、今回の手順で作成した証明書は認証局をブラウザにインポートしないと「この接続は保護されていません~」といった警告が出てしまいます。仕様的にインターネット向けのWebサービスには使えないので、あくまでも社内環境などのローカルネットワーク向けの使用に留めるのが良いでしょう。
まとめ
OCIのサービスだけでプライベート認証局/証明書を作成する手順を紹介しました。
OCIの証明書サービスを利用することで、WebページのSSL証明書として利用可能な証明書を、認証局の作成から証明書の発行まで、無償で実施できます。
証明書サービスに登録した証明書は、有効期限の管理や更新の自動化だけでなく、LB等の他リソースで簡単に利用できるようになります。
AWSのように、有効期限の監視がOCIの標準機能で実施できないのが残念ですが、functionsとカスタム・メトリックを使ってどうにか実現できれば、今回の記事の続きとしてご紹介したいと思います。