昨年11月にAmazon Web Service(AWS)のApplication Load Balancer(ALB)で相互TLSがサポートされました。これにより、ALBでのクライアント証明書認証が可能となりました。
そこで今回、弊社のクライアント証明書サービス「マネージドPKI Lite by GMO」で発行しましたテスト用のクライアント証明書を用いて検証しましたので、そのクライアント証明書認証の設定方法とその設定後の結果を紹介します。
初めに
事前準備として、EC2仮想インスタンス2台(Ubuntu + Apache)と、ALBでロードバランシングをおこなう構成を作成しておきます。
非常に簡単ですが、今回は以下の構成になります。
この時点では、クライアントPCとALBはhttpで通信を行っている状態とします。
ALBの相互TLS化
それでは、ALBの相互TLS化と、クライアント証明書の情報をバックエンドのWebサーバにわたすよう設定をしていきます。
まずはALBでhttpsをリッスンするようにしていきます。
①AWS管理コンソールで対象のロードバランサーを選択肢、リスナーの追加をおこないます。
②デフォルトSSL/TLSサーバ証明書の設定で、サーバ証明書の設定をしていきます。
※サーバ証明書は、当社のサイト から45日間有効なテスト用のパブリック証明書が取得できます。
「証明書をインポート」を選択し、秘密鍵ファイルや証明書ファイルをテキストエディタで開き、その内容をコピーし、貼り付けます。
今回、証明書チェーンには、設定するテスト用サーバ証明書の中間証明書をダウンロードして同様にテキストエディタで開き、その内容をコピーし貼り付けていますが、ここは省略することも可能です。
※クライアントがブラウザではない場合などに問題が発生する可能性もあるので、設定しておくことを推奨します。
③ この状態で保存するとHTTPS:443リスナーが有効となってALBがhttps対応となります。
以下の図ではHTTP:80リスナーのデフォルトアクションをhttpsへのリダイレクトに変更しています。
クライアント証明書認証の有効化
次に、mTLS(クライアント証明書認証)を有効にします。今回は、当社のテストシステムで発行したクライアント証明書を使用します。
① まずはトラストストアを作成します。CAチェーン(ルート証明書・中間証明書)や、失効リスト(CRL)はS3に保存しておく必要があります。
CAチェーンには、今回はこちらにある2つの証明書をテキストエディタで開き、それぞれのテキストを結合したものをS3バケットに保存します。
-----BEGIN CERTIFICATE-----
MIIFODCCBCCgAwIBAgIQeEqpED+lwQQhLxtUbFMdAjANBgkqhkiG9w0BAQsFADBU
(中間CA証明書データ、以下略)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDkDCCAnigAwIBAgILBAAAAAABIVhTCKMwDQYJKoZIhvcNAQELBQAwVDEgMB4G
(ルート証明書データ、以下略)
-----END CERTIFICATE-----
失効リスト(CRL)は以下からダウンロード可能です。http://crl.staging.globalsign.com/gsgccr3personalsign2ca2020.crl
※今回は、中間CA証明書の失効確認は行わない設定とします。
② ダウンロードしたファイルはDER(バイナリ)形式でありそのままではAWSでは利用できないので、PEM(テキスト)形式に変換します。
以下はOpenSSLを使った場合のコマンド例です。
openssl crl -in root-r3.crl -inform der -out root-r3.pem -outform pem
③PEM形式にしたCRLファイルをS3バケットに保存しておきます。
※CRLは定期的に更新されるので、定期的にダウンロードしPEM形式に変換のうえS3バケットにコピーし、トラストストアに追加(古いものを削除)といったスクリプト等による運用が想定されます。
④ 次に、EC2コンソールの左側メニューよりトラストストアを選択肢、トラストストアの作成をクリックします。
認証局バンドルにはS3にアップロードしたCAチェーンのファイルを設定し、証明書失効リストにはCRLファイルを指定してトラストストアを作成しておきます。
⑤ ロードバランサーのHTTPS:443リスナーの設定をmTLS対応に変更します。
相互認証(mTLS)にチェックをして、「トラストストアで検証」を選択し、トラストストアには上記で作成したトラストストアを指定するという流れです。
なお「パススルー」を選択するとALBでクライアント証明書の検証はされず、証明書データがHTTPヘッダーで送られてくるのでWebアプリケーションで何らかの認証・認可処理をおこなう形になるようです。
また、「パススルー」「トラストストアで検証」のいずれを選択してもALBはTLS接続時に信頼チェーンを送ってこないので、クライアントが持っているクライアント認証用の証明書が全て選択肢としてブラウザに表示されます。
これで準備は終了です。
アクセス結果
「トラストストアで検証」を選んだ場合は、クライアント証明書情報がhttpリクエストヘッダーに追加されてバックエンドのWebサーバに送られるので、このヘッダーを確認するためのコードを2台のWebサーバにコピーします。
今回はChatGPTにて作成したコードをそのまま利用します。
コードの設定後、アクセスすると証明書が求められます。
これにより、ALBが付加するhttpヘッダーにより証明書情報がWebサーバに伝搬されていることがわかります。
1号機へのアクセス
2号機へのアクセス
「マネージドPKI Lite byGMO」(パブリックCAによるクライアント証明書発行サービス)の場合は、X-Amzn-Mtls-Clientcert-Subjectヘッダーなどをみて、サブジェクトOやOUが専用ベースDNで指定したものと一致するか、バックエンドアプリで判定する必要があります。
(グローバルサインでは、プライベートCAによるクライアント証明書発行サービスも行っており、その場合はこの判定は必須ではありません。)
失効した証明書や、信頼していないCAが発行した証明書でアクセスした場合は接続失敗し、接続ログを出力している場合はタイムスタンプやアクセス元IPアドレス、当該証明書のサブジェクトなどとともにエラー理由が書かれます。
- 失効済み証明書の場合:ClientCertCrlHit
- 信頼されていないCAから発行された証明書の場合:ClientCertUntrusted
※接続ログの詳細についてはAWSのサイトに説明があります。
まとめ
AWS ALBでのTLSクライアント認証(mTLS)の設定方法とその検証結果をご紹介しました。
本記事の設定も含めて、クライアント証明書のテストをご希望のお客様は、お問い合わせフォームより「テスト用クライアント証明書の利用希望」と「証明書の利用用途や検証理由」などの旨と合わせて、お気軽にご連絡ください。