はじめに
2021/10月末に Oracle Cloud Infrastructure (OCI) に 新しく 証明書サービス (Certificates Service) がリリースされました。無償 で利用が可能なサービスで、主に、下記のようなことが実現可能です。
- プライベート認証局(CA) の作成・管理
- プライベート証明書の発行・管理
- 3rd Patry 証明書のインポート
- 証明書を必要とするOCIリソース (LB等) とのシームレスな連携
本記事では、証明書サービスを利用して発行したプライベート証明書を、OCI のロードバランサ・サービスに連携させ、 Webサイトを HTTPS に対応させるまでの流れ について説明していきます。
目次
・システムの全体像
・前提条件
・STEP0:動的グループの設定
・STEP1:Vault の作成
・STEP2:プライベート認証局の作成
・STEP3:プライベート証明書の作成
・STEP4:ロードバランサーの設定
・STEP5:端末の設定
・STEP6:動作確認
システムの全体像
本記事で作成する環境の構成は、下記の通りです。
全て無償枠があるサービスなので、その範囲内で構築すれば、完全無償で実現することが出来ます。
前提条件
本記事では 下記を 前提条件 としています。
- OCI チュートリアル - 「ロードバランサーでWebサーバーを負荷分散する」 を参考に、 仮想クラウドネットワーク、ロードバランサー、仮想マシンなどのインスタンスが作成済み であること。
-
管理者権限を持つユーザー であること。
※権限を絞りたい場合は 下記ドキュメントをご参照ください。(動的グループの設定については本記事でも説明します)
参考:認証局の管理に必要なIAMポリシー / 証明書の管理に必要なIAMポリシー
STEP0:動的グループの設定
証明書サービスの利用に当たっては、操作を行う「ユーザー」が 適切な権限 を持っているだけでは足りません。
「証明書サービス」自体 が 「Vault」「オブジェクト・ストレージ」を利用するため に、 動的グループの設定 および 権限付与 が必要になります。
※ 正確には、オブジェクト・ストレージへの権限付与が必要なシーンは、認証局の作成時に「CRL 失効リストの配布ポイントを設定する場合のみ」ですが、ここでは両方に対する権限付与の方法を紹介しています。
1. 動的グループの設定
動的グループの作成 は、OCI コンソール・メニュー「三」から、アイデンティティとセキュリティ
- 動的グループ
で アクセスできます。設定内容は以下の通りです。
- 名前 :任意 (例:CertificateAuthority-DG など)
- 説明 :任意
- 下で定義したいずれかのルールに一致 or 下で定義したすべてのルールに一致 :どちらでも可 (今回は 一致ルールが 1つなので どちらを選択しても同じ)
-
一致ルール :
resource.type ='certificateauthority'
上記設定により、すべての認証局を、この動的グループのメンバとして 指定したことになります。対象を絞り込みたい場合は、一致ルールで コンパートメント の OCID を指定することも可能です。
2. ポリシーの作成
作成した 動的グループ に権限を付与する「ポリシー」を作成します。ポリシー は、OCI コンソール・メニュー「三」から、アイデンティティとセキュリティ
- ポリシー
で アクセスできます。設定内容は以下の通りです。
- 名前 :任意 (例:CertificateAuthority-Policy など)
- 説明 :任意
- コンパートメント :任意のコンパートメントを選択
- ポリシー・ビルダー :「手動エディタの表示」を有効化し、下記テキストを設定
Allow dynamic-group 動的グループ名 to use keys in compartment コンパートメント名
Allow dynamic-group 動的グループ名 to manage objects in compartment コンパートメント名
上記設定により、「 (認証局をメンバとして含む) 動的グループ」に対して、「特定コンパートメント」レベルで「オブジェクト・ストレージ」と「Vault 内の 鍵」に対する 操作権限 を付与したことになります。
これらの権限設定を忘れた場合、認証局の作成で 以下のようなエラーが発生します。
Vault への権限不足:
Authorization failed or requested resource not found: Key Id <OCID>
オブジェクト・ストレージへの権限不足:
Validation of the certificate revocation list (CRL) bucket failed.
STEP1:Vault の作成
次に、認証局で利用するための「キー」と その格納庫である「Vault」を作成していきます。オンプレミス で プライベート認証局を立てる場合、鍵の安全な管理が難しかったりすると思いますが、クラウド・サービスを活用すると運用が楽なのは 良い点ですね。
1. Vault の作成
Vault は OCI コンソール・メニュー「三」から、アイデンティティとセキュリティ
- ボールト
で アクセスできます。設定内容は以下の通りです。
- コンパートメントに作成 :任意のコンパートメントを選択
- 名前 :任意
- 仮想プライベート・ボールトにする : チェック無
「チェック有」にした場合、「仮想プライベート・ボールト」は、1時間あたり「¥446.88」のサービスのため、 課金が発生 します。後から変更することも出来ません。
また、ボールト・サービスは作成後、すぐに削除することが出来ず、最短でも 7日後の削除指定のみ可能 なため、誤って作成すると 最低でも「約¥75,264」の課金が発生 するので、十分に注意して実施してください (参考:OCI ドキュメント - To delete a vault)
今回は検証用途で、課金をなるべく発生させたくないので「チェック無」にしていますが、セキュリティ要件などで「より強力な鍵管理」が必要な場合には検討すると良いかと思います。
2. キーの作成
続いて、「キー」を作成していきます。
ボールトの詳細画面左下の リソース
メニューから マスター暗号化キー
を選択し、青色のボタンから「キーの作成」が出来ます。下記を参考に、キーを作成します。
- コンパートメントに作成 :任意のコンパートメントを選択
- 保護モード :[HSM] を選択
- 名前 :任意
- キーのシェイプ: アルゴリズム :[RSA] を選択
- キーのシェイプ: 長さ :[2048 ビット] を選択
- 外部キーのインポート :チェック無
保護モード [ソフトウェア] は証明書サービスでサポートされないため、[HSM] を選択します。ここで作成する HSMキーも有償サービスですが、 20個 までは 無償 となっています。
キーシェイプ については、証明書サービスで サポートされるシェイプ が「2048ビットまたは4096ビットの RSAキー」「P-384曲線を使った ECDSAキー 」のいずれかとなっているので、その中から選択します。(今回は [RSA] の [2048 ビット])
どのアルゴリズムにするかは、ご利用目的・要件に応じて選んでください。
ECDSA は RSA よりも短い鍵の長さで同レベルの安全性を確保できるとされていますが、 古いブラウザなどではサポートされない可能性 があります。
とはいえ、最近では 対応している OS や ブラウザ も多いようなので、どちらでも良いと思いますが、今回は RSA を選択しています。
STEP2:プライベート認証局の作成
次に、プライベート認証局を作成していきます。認証局は OCI コンソール・メニュー「三」から、アイデンティティとセキュリティ
- 認証局
で アクセスできます。設定項目が多いので、順に見て行きます。
※ 認証局も 作成後すぐに削除はできず、最短で 7日後から削除指定が可能 です。誤って作成した場合も、しばらく残すことになるので、注意して作成してください。
■ 基本情報
■ サブジェクト情報
- 共通名 :任意の値を設定 (=CN/CommonName に該当する項目です。証明書の発行者を意味し、証明書の Issuer などに表示されます。)
-
追加フィールド の項目は、認証局を作る上では 必須項目ではありません。用途 (証明したい内容) に応じて設定します。
単に ドメインの証明 (DV) がしたい場合には 共通名だけを、組織の実在証明 (OV) をしたい場合には、以下の項目なども設定する、といった感じです。- 国(=C) :日本
- 州/省(=S) :Tokyo
- 組織(=O):skogkatter
- 編成単位(=OU):security
■ 権威の構成
- 有効期間の開始日 :デフォルトのまま (即時有効になる)
-
有効期間の終了日 :デフォルトのまま (10年後のUTC0:00時)
有効期間の開始日+1日~2037年12月31日の範囲で指定可能。 - <コンパートメント名> のボールト :STEP1で作成したものを選択
- <コンパートメント名> のキー :STEP1で作成したものを選択
- 署名アルゴリズム :[SHA256_WITH_RSA] を選択
署名アルゴリズムは、ボールトのキーシェイプによって選択肢が変わります。キーシェイプを RSA にしていた場合、[SHA256_WITH_RSA]、[SHA384_WITH_RSA]、[SHA512_WITH_RSA] から、ECDSA にしていた場合、[SHA256_WITH_ECDSA]、[SHA384_WITH_ECDSA]、[SHA512_WITH_ECDSA] から選択します。
SHAxxx の「xxx」は 生成されるハッシュ値の 桁数 を意味しており、 長いものは それだけ安全性が高い と言えますが、一方で 計算に時間を要したり、実装のし易さに影響 します。ご利用想定の環境や、性能・セキュリティ要件に合わせて選択してください。
今回は、いくつかの実在する証明書を確認した限り、「SHA256RSA」が多そうだったので、それに合わせて [SHA256_WITH_RSA] を選択しています。
■ ルール
- 証明書の最大有効期間(日数) :デフォルトのまま (90日後)
- 下位CAの最大有効期間(日数) :デフォルトのまま (3650日後)
証明書の最大有効期間は ドキュメント上で「90日以内にすることを強くお勧めします」と触れられています。一般的にも 証明書は 90日で作成されているものが多いと思うので、それに従って作成しています。
■ 失効構成
- 失効のスキップ :チェック有
今回は「検証目的」ということもあり、CRL(証明書失効リスト) の 配布ポイント (CRL Distribution Point) は設けません。
配布ポイントを設ける場合には、認証局を作成する前に、 他で利用されていない、その認証局専用の オブジェクト・ストレージ の作成 が必要です。
既に利用済みのオブジェクト・ストレージを指定した場合、「There is a conflict with the entity with OCID <OCID>」というエラーが発生します。
また、設定する場合、「オブジェクト名形式」では、オブジェクト名に中括弧を含めて、サービスが発行元のCAバージョン番号を挿入できる場所を示すことができます。例えば、「ocica-{}.crl」などです。これにより、新しいCAバージョンを作成するたびに既存のCRLが上書きされるのを防ぐことができます。
■ サマリー
最終確認をして、問題なければ、「認証局の作成」を行います。
以上で、「認証局」の作成は完了です。
尚、本記事の構成では、中間認証局 は作らず、ルート認証局 のみを作成しています。理由としては「検証目的」で「小規模な構成」だからです。
本番用途では、セキュリティ要件や、 ルート証明書の秘密鍵が万が一漏えいした場合の影響を軽減する ため、必要に応じて 下位 (中間) 認証局を設けることも検討してください。
STEP3:プライベート証明書の作成
次は、プライベート証明書を作成していきます。証明書は OCI コンソール・メニュー「三」から、アイデンティティとセキュリティ
- 証明書
で アクセスできます。または、STEP2で作成した認証局の詳細画面から直接、作成画面に移ることも可能です。
証明書についても、作成後すぐに削除はできず、最短で 翌日から削除指定が可能 です。誤って作成した場合も、すぐには消せないので、注意して作成してください。
こちらも設定項目が多いので、順に見て行きます。
■ 基本情報
- コンパートメント :任意のコンパートメントを選択
- 証明書タイプ :[内部CAによって発行済み] を選択
- 名前 :任意の値を設定
- 説明 :任意の値を設定
[内部CAによって発行済み] は、秘密鍵 および CSR を 証明書サービス内部 で作成し、証明書を発行する場合に選択する項目です。
自分自身で(サーバーなどで) 秘密鍵を生成し、CSR を作成した上で、証明書を発行したい場合は、[内部CAによって発行され、外部で管理] を選択します。
また、 [インポート済] のタイプでは、3rd Party の 証明書を、証明書サービスに登録することが可能です。いずれも項目名がしぬほど分かりにくい…。
■ サブジェクト情報
- 共通名 :任意の値を設定 (=CN/CommonName に該当する項目です。証明対象の名称を意味します。主に FQDN や ドメイン名を付けると思います。)
-
サブジェクトの代替名 :(SANs に該当する項目です) リストボックスから [DNS名] を選択し、テキストボックスに 任意の FQDN または ドメイン名 を指定します。
※ ここで指定した値を使って、後ほどロードバランサーにアクセスします。 -
追加フィールド の項目は、認証局を作る上では 必須項目ではありません。こちらも 用途 (証明したい内容) に応じて設定します。
単に ドメインの証明 (DV) がしたい場合には 共通名だけを、組織の実在証明 (OV) をしたい場合には、以下の項目なども設定する、といった感じです。- 国(=C) :日本
- 州/省(=S) :Tokyo
- 組織(=O):skogkatter
- 編成単位(=OU):security
サブジェクトの代替名では、[IPアドレス] を指定することも可能です。また、「+別のサブジェクト代替名」ボタンから、項目を追加し、複数の代替名を指定することも可能です。
■ 証明書構成
- 証明書プロファイル・タイプ :[TLSサーバーまたはクライアント] を選択
- <コンパートメント名>の発行元認証局 :STEP2で作成したものを選択
- 有効期間の開始日 :デフォルトのまま (即時有効になる)
-
有効期間の終了日 :デフォルトの日付 「- 1日」 を指定
有効期間の開始日+1日~2037年12月31日 または 証明書発行元の認証局で指定した証明書の最大有効期間未満 いずれか短い方 の範囲で指定可能。
デフォルトは 90日後が指定されているが、その値では 未満 にならない為、「-1」を設定。 - キー・アルゴリズム :[RSA2048] を選択
証明書プロファイル・タイプは、[TLSサーバーまたはクライアント]、[TLSサーバー]、[TLSクライアント]、[TLSコード署名] から選択できます。今回は サーバー証明書として利用する予定で、[TLSサーバーまたはクライアント] を選択しています。用途に合わせて選択してください。
また、キー・アルゴリズムは [RSA2048]、[RSA4096]、[ECDSA_P256]、[ECDSA_P384] のいずれかより選べます。今回の例では、ポピュラーな [RSA2048] を選択しています。
■ ルール
- 更新間隔(日数) :デフォルトのまま (89日後)
- 拡張更新期間(日数) :デフォルトのまま (30日後)
認証局の作成時に指定した「証明書の最大有効期間」、証明書構成で指定した「有効期間の終了日」、および、本項目での設定値が 噛み合わない場合、「The validity period 7793377294 exceeds the maximum validity period allowed 7776000000.」というエラーが出ます。エラーが発生した場合には、それらの日数 を見直しましょう。
■ サマリー
最終確認をして、問題なければ、「証明書の作成」を行います。
以上で、「証明書」の作成は完了です。
STEP4:ロードバランサーの設定
終盤に近付いてきました。続いては、ロードバランサーに新たなリスナーを追加していきます。既にロードバランサーがある前提で進めるので、無い場合は 前提条件で記載した チュートリアル を参考に、作成しておいてください。
ロードバランサーは OCI コンソール・メニュー「三」から、ネットワーキング
- ロード・バランサ
で アクセスできます。
1. リスナーの作成
作成済みのロードバランサの詳細画面を開き、左下の リソース
メニューから リスナー
を選択し、「リスナーの作成」をしていきます。設定内容は以下の通りです。
- 名前 :任意の値を設定
- プロトコル :[HTTPS] を選択
- ポート :デフォルトのまま (HTTPSの場合自動的に443が設定)
- SSLの使用 :デフォルトのまま (HTTPSの場合自動的に有効化)
- 証明書リソース :[証明書サービス管理対象証明書] を選択
- <コンパートメント名> の証明書 :STEP3で作成したものを選択
- CA証明書ソースの指定 :チェック無
-
バックエンド・セット :既存のバックエンド・セットを選択
※ 前提条件にあるチュートリアルで作成したバックエンド・セットを利用します -
アイドル・タイムアウト(秒) :デフォルトのまま
※ 何も指定しない場合、TCPリスナーでは300秒、HTTPリスナーでは60秒になります - ルーティング・ポリシー :選択なし
今回、ロードバランサーとバックエンドのWebサーバー間は、HTTP通信としています。(ロードバランサで TLS/SSL 終端 する) そのため、「CA証明書ソースの指定」では「チェック無」にしています。
もちろん バックエンドまで HTTPS 通信させることも可能 です。その場合はチェックを有効化し、作成したプライベート認証局を指定してください。バックエンドまで HTTPS 通信させるかどうかは、性能やセキュリティ要件などに合わせて設定してください。
以上で、「リスナーの作成」は完了です。
2. セキュリティ・リストの設定
続いて、インターネット から OCI上の ロードバランサー に 443ポートでアクセスできるようにするため、セキュリティ・リストの設定をします。
まず、OCI コンソール・メニュー「三」から、ネットワーキング
- 仮想クラウド・ネットワーク
- ロードバランサーを配置している VCN
を選択 - 左下 リソース
メニュー - セキュリティ・リスト
を選択 - ロードバランサー用のサブネットに設定している セキュリティ・リスト
を選択 します。
「イングレス・ルールの追加」で、以下の内容を設定してください。
- *ステートレス :チェック無
- ソース・タイプ :[CIDR] を選択
- ソースCIDR :[0.0.0.0/0] を設定
- IPプロトコル :[TCP] を選択
- ソース・ポート範囲 :デフォルトのまま
- 宛先ポート範囲 :[443] を設定
- 説明 :任意
以上で、「セキュリティ・リストの設定」は完了です。
STEP5:端末の設定
OCI 上での設定は STEP4 までで ほぼ完了しています。
STEP5では、自端末から FQDN でロードバランサーにアクセスするための「hostsファイルの設定」、また、ブラウザ上で警告が表示されないように、ブラウザに信頼されたルート証明機関として、ルート認証局の証明書を「インポート」していきます。
1. hostsファイルの設定
Windows を前提とした手順を説明します。
Windows では hostsファイルは「 C:\Windows\System32\drivers\etc
」配下に存在します。ファイルエクスプローラ から、上記フォルダを開きます。
※作業の前に、誤って設定した場合に もとに戻せるように、hostsファイル の バックアップを取っておくことをお勧めします。
次に、管理者権限で開いたテキストエディタ上で、hostsファイルを開いてください。(管理者権限で開いていないと、編集・保存ができません)
ファイルの最下行に以下を追加します。
<ロードバランサーのパブリックIPアドレス> <FQDN>
例えば、「 1xx.2xx.1xx.1xx www.sslskogkatter.com
」などです。
編集完了後、保存して完了です。
本来は プライベートDNS などと組み合わせて利用していくのが良いと思いますが、個人の検証なので DNS は立てずに、hostsファイルの編集をしています。
2. 証明書のインポート
続いて、ブラウザの 信頼されたルート証明機関 として、ルート認証局の証明書を「インポート」していきます。
■ 証明書のダウンロード
ルート認証局の証明書を取得するために、STEP2で作成した プライベート認証局の詳細画面を開き、左下の リソース
メニューから バージョン
を選択し、最新のバージョンの トリコロン をクリックします。「コンテンツの表示」から ルート認証局の証明書をダウンロードできます。今回は、「証明書PEM」の方をダウンロードしています。
■ 証明書の変換
ダウンロードした時点では 証明書は「*.pem」になっており、Chrome に そのままインポートができなさそうだったので、手元の端末で「*.crt」に変換しています。
openssl x509 -outform der -in certificate.pem -out certificate.crt
■ 証明書のインポート
続いて、ブラウザ (今回は Chrome) に証明書をインポートします。ブラウザの Settings
- Security and Privacy
- Security
- Manage certificates
で、「信頼されたルート証明機関」タブを選択します。あとは、ウィザードに従ってインポートしてください。
以上で、「証明書のインポート」は完了です。
このインポート作業は ルート認証局の証明書バージョンが更新されるたびに必要 になります。(今回ですと 10年に1度くらい)
「インポートなんてしなくて良いのではないか」と思われるかもしれませんが、確かに、検証用途では割愛しても良いかもしれません。ただ、実運用を考えた際には、例え 社内の限られたメンバーだけがアクセスする場合であっても、 必ず行うことを推奨 します。
これを怠り、一度 警告画面の表示に慣れてしまうと、実際に危険なサイトにアクセスしてしまった時も「いつものか」と危機感が薄れてしまい、セキュリティ事故につながる可能性があるからです。
STEP6:動作確認
Chromeを起動し、「https://<hostsファイルで設定したドメイン名>」でアクセスしてみます。
上記のように「鍵マーク」がキチンと表示されていれば成功です。
何かしらのエラーや警告画面が ブラウザに表示された場合は、 エラーコードを元に、原因を探ってみてください 。
例えば、
SSL_ERROR_BAD_CERT_DOMAIN
が出た場合、接続時のサイトの FQDN と 証明書のコモンネーム (またはSANs) が一致していない可能性があります。証明書の作成時に指定した「共通名」を確認し、hosts に反映し直しましょう。
ERR_SSL_VERSION_OR_CIPHER_MISMATCH
が出た場合、暗号化方式が古い、または、ブラウザが対応していないことが 一つの可能性として挙げられます。暗号アルゴリズムを見直してみましょう。
おわりに
いかがでしたでしょうか。
無償枠内に収めるように構築すれば、完全無償で HTTPS通信可能な Web環境 + 負荷分散付き が 構築できてしまうのは スゴイですね。
今回、調べながら書いていったので、もし自分の理解が誤っているところなどが ありましたら、ぜひコメント頂けると助かります!