スマートスタイル TECH BLOG

データベース&クラウド技術情報

OCIのFLBでクライアント証明書の情報をバックエンドサーバへ転送する

はじめに

OCIのFLB(フレキシブル・ロードバランサ)は、サーバ証明書に加えクライアント証明書にも対応しています。
リスナーの設定で証明書情報を設定した後、「ピア証明書の検証」を有効にし「深さの検証」を指定することで実現できます。

「ロード・バランサ管理対象証明書」の場合は、以下のようになります。

また、「証明書サービス管理対象証明書」で認証局を使用する場合は、以下のようになります。

ただ、これだけの設定では、クライアント証明書の情報はFLBで終端してしまい、バックエンドサーバには送られずに、アプリケーション側で証明書に含まれるサブジェクト情報等を参照したいケースでは問題が生じてしまいます。

(FLBでもTCPリスナーを使用した場合、またはNLB(ネットワーク・ロードバランサ)を使用する場合は、FLBに証明書情報を設定できず、バックエンドサーバで証明書や秘密鍵の情報を設定することになるので、このような懸念が生じませんが、複数のバックエンドサーバで証明書の情報を管理したり、WAFを使用できないといった制限を受けることとなってしまいます。)

このような問題の回避策として、FLBではクライアント証明書の情報をHTTPリクエストヘッダに追加して、バックエンドサーバへ送ることができるようになっています。

手順

HTTPリクエストヘッダにクライアント証明書の情報を追加する為には、ルール・セットを使用します。
具体的な手順は以下のリファレンスに記載があるので、ご確認下さい。

上記リファレンスでは、HTTPリクエストヘッダに追加する値として3通りの方法が選択できることが分かります。

ヘッダ値 説明
{oci_lb_client_cert} 証明書情報の先頭行を除く行頭にタブコードを付与した情報を転送します。
{oci_lb_client_cert_apache_compatible} 証明書情報の改行(\n)を削除した情報を転送します。
{oci_lb_client_cert_url_encoded} 証明書情報をURLエンコードした情報を転送します。

それぞれの設定値に従って、実際にどのようなヘッダが送信されているか確認してみます。

ヘッダ値:{oci_lb_client_cert}

まずは、ヘッダを「client_cert」として、 ヘッダ値に {oci_lb_client_cert} を設定したルール・セットを作成し、その後、リスナーに作成したルール・セットを適用します。

設定後、クライアント証明書をインポートしたブラウザからリクエストを送信し、バックエンドのサーバで tcpdump でリクエストをキャプチャしてみました。

タブコードが肝となる為、16進数も出力してますが、改行コード(0a)のあとに、水平タブコード(09)が付与されていることが分かります。
つまり、証明書の先頭行を除いては、全て行の先頭に水平タブコードが付与されています。

但し、Apache では、リクエストヘッダの1つが複数行に跨ってしまう為か、以下のようにブラウザへは「Bad Request」が返されました。

ヘッダ値:{oci_lb_client_cert_apache_compatible}

今度は、ヘッダ値を {oci_lb_client_cert_apache_compatible} に変更して確認してみます。

変更後に、ブラウザからリクエストを送信してバックエンドサーバでリクエストを確認してみます。

「client_cert」ヘッダには、クライアント証明書の改行(\n)が削除されたものが設定されていることが分かります。

ヘッダ値:{oci_lb_client_cert_url_encoded}

今度は、ヘッダ値を {oci_lb_client_cert_url_encoded} に変更して確認してみます。

変更後に、再度ブラウザからリクエストを送信してバックエンドサーバでリクエストを確認してみます。

証明書情報のURLエンコードした状態のものが設定されています。

まとめ

ルール・セットを使用してクライアント証明書情報をバックエンドのサーバに転送する方法について確認しました。

HTTPヘッダに追加する方法としては、今回ご紹介した3種類ありますが、{oci_lb_client_cert}{oci_lb_client_cert_apache_compatible} については、行の先頭にタブコードが付与されたり、改行コードが削除されたりしますので、アプリケーション側でパースできない場合もあるかと思います。
証明書情報をそのままにバックエンドサーバに転送したい場合は、 {oci_lb_client_cert_url_encoded} を設定して、アプリケーション側でURLデコードするとよいでしょう。

Return Top