Azure Application GatewayのエンドツーエンドのSSL通信を検証してみた

◆ Live配信スケジュール ◆
サイオステクノロジーでは、Microsoft MVPの武井による「わかりみの深いシリーズ」など、定期的なLive配信を行っています。
⇒ 詳細スケジュールはこちらから
⇒ 見逃してしまった方はYoutubeチャンネルをご覧ください
【4/18開催】VSCode Dev Containersで楽々開発環境構築祭り〜Python/Reactなどなど〜
Visual Studio Codeの拡張機能であるDev Containersを使ってReactとかPythonとかSpring Bootとかの開発環境をラクチンで構築する方法を紹介するイベントです。
https://tech-lab.connpass.com/event/311864/

Azureのロードバランサー

こんにちは。技術部の髙岡です。
ロードバランサーには一般的にL4レベルとL7レベルの2種類がありますが、Azureでは各々に対応するロードバランサーを提供しています。

L4ロードバランサー
Azure Load Balancer
L7ロードバランサー
Azure Application Gateway

今回はAzure Application GatewayでSSLオフロードでなく、エンドツーエンドのSSL通信を行う環境を作成しました。
尚、Azure Application Gatewayを導入してみての感想は、別のブログでも触れておりますので、そちらも読んでみてください。
Azure Application Gatewayの構築方法と利用してみての感想

Azure Application Gatewayが解決する課題

ロードバランサーでのSSL通信といえば、WebサーバのSSL暗号化・復号化の負荷を下げるためのSSLオフロード機能の活用を思いつくのではないでしょうか。
image7
その場合に疑問に思うことがあります。
ロードバランサーは特定のWebサーバのアプリケーションに接続を固定するセッションアフィニティ機能の実現のためにL7レイヤーの情報(httpsヘッダやcookie等)を覗く必要があります。

ブラウザとWebサーバ間でデータが暗号化されてしまうと、ロードバランサーがL7レイヤーの情報を覗くことができず、セッションアフィニティが実現できないのではないでしょうか?
image3

心配は無用です。
Azure Application GatewayのエンドツーエンドのSSL通信機能は、このような疑問にも応えてくれる仕組みを提供しております。
image5
Azure Application Gatewayで一旦SSL通信を終了して暗号化されたデータを復号化し、L7レイヤーの情報を覗きます。それらの情報を元に振り分け先のWebサーバを決めて、Webサーバとの間で再びSSL通信を行うのです。

検証環境の構成と構築手順

検証環境の構成図です。
image4
Application Gatewayには、復号化用の秘密鍵が含まれたPKCS#12形式の証明書と、暗号化用の公開鍵が含まれたPEM形式の証明書を登録する必要があります。
その他の細かい構築手順の説明は割愛します。マイクロソフトが公開している手順が参考になります。

現時点で公開されているのはPowerShellコマンドを使った構築手順です。Portal画面ではまだ細かい設定ができないようです。

Application Gatewayを構築する前に実施しておくべき作業を書いておきます。

  • バックエンドのWebサーバにhttps接続環境作成
  • 今回はApacheを導入しました。

  • Webサーバ用の秘密鍵とサーバ証明書作成
  • 今回はApacheを使うので、pem形式で作成しました。

  • Azure Application Gateway用の秘密鍵とサーバ証明書作成
  • 対応しているのは、pkcs#12(pfx)形式です。MSっぽいですね。

構築に関する補足事項を書いておきます。

  • DNSサーバにロードバランサーのCNAMEを登録する必要がある。
  • Azure Application Gatewayのフロントエンド側のFQDNは自動的に作成され、IPアドレスも可変です。
    検証環境での例

    IPアドレス:40.74.84.255
    FQDN:94210a7c-e6c2-4557-aecf-3375dca57704.cloudapp.net

    このFQDNは、ユーザに提供するURLとしては不適切なので、実運用を考慮すると、適切な名称を決めてDNSにCNAMEレコードを登録する必要があります。
    今回の検証では、ユーザ向けのURLとして、

    https://websvapgw.siostest02.com/index.html

    を使うことにしましたので、「94210a7c-e6c2-4557-aecf-3375dca57704.cloudapp.net」のCNAMEとして、「websvapgw.siostest02.com」をDNSに登録しました。

  • Azure Application Gatewayの作成コマンドの実行完了には時間がかかる。
  • 検証で実行したAzure Application Gatewayの作成コマンドです。

    $appgw = New-AzureRmApplicationGateway -Name appgateway -SSLCertificates $cert -ResourceGroupName ‘test-rg’ -Location "Japan west" -BackendAddressPools $pool -BackendHttpSettingsCollection $poolSetting -FrontendIpConfigurations $fipconfig -GatewayIpConfigurations $gipconfig -FrontendPorts $fp -HttpListeners $listener -RequestRoutingRules $rule -Sku $sku -SSLPolicy $SSLPolicy -AuthenticationCertificates $authcert -Verbos

    今回の検証では、コマンド実行が完了するまで20分位かかりました。

ロードバランサーの本質的な機能の確認

ロードバランサーの本質的な機能であるNATと、セッションアフィニティ機能がAzure Application Gatewayで実現できているのかを、パケットキャプチャとログを見て確認してみました。

NATの確認
このようなフローでパケットが流れていくと想定しています。
パケット
クライアントとWebサーバ側でパケットキャプチャを取得してNATされているかを確認します。

クライアントからcurlコマンド実行
# curl --verbose https://websvapgw.siostest02.com/index.html --cacert ./websvapgw.crt
image6
websv01側に配置したhtmlコンテンツが表示されましたので、websv01側に振られたことがわかります。

クライアント側のパケットキャプチャ
image1
Sourceが「192.168.10.132:40939(クライアント)」Destinationが「40.74.84.255:443(Application Gatewayのフロントエンド側)」でパケットを送信し、戻りは逆であることがわかります。

websv01側のパケットキャプチャ
# tcpdump -nn port not 22 and not udp and port 443 and host not 104.215.32.46
image9
Sourceが「10.1.3.4:56526」Destinationが「10.1.3.36:443(websv01)」でパケットを送信し、戻りは逆であることがわかります。

ここで、いきなり「10.1.3.4」というIPが出てきましたが、上記の検証環境の構成図で「バックエンド側LBのIP」と記載したIPのことです。
ゲートウェイサブネットのIPレンジとして設定した「10.1.3.0/27」の範囲から、自動的に割り振られるのがApplication Gatewayの仕様のようです。

セッションアフィニティの確認
次に、cookieベースのセッションアフィニティ実現のために設定されているcookieを確認してみました。

先に実行したcurlコマンドの結果から、httpsヘッダのcookieを確認することができます。
image10
これは、Application Gatewayが埋め込んだcookieで、ユーザー セッションと振り分け先サーバーを管理するためにクライアントに発行したものです。
この値が同じある限り、再度同じURLに接続しても同じWebサーバに接続することができます。

また、Webサーバ側のApacheのログに、x-forward-forの値を出力するように設定しました。
image2
接続元クライアントのIPとポート「126.152.194.89:41998」がx-forward-forの値として設定されていることがわかります。

Application Gateway側でアクセスログを出力するように仕込むこともできます。
以下はアクセスログの抜粋です。
image8
接続元クライアントのIPとポート「126.152.194.89:41998」を確認することができます。

以上

アバター画像
About 髙岡 貴史 21 Articles
登山家兼投資家兼インフラ寄りのエンジニア。最近はDatastaxを中心としたデータ処理基盤に関心あり。
ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。


ご覧いただきありがとうございます。
ブログの最新情報はSNSでも発信しております。
ぜひTwitterのフォロー&Facebookページにいいねをお願い致します!



>> 雑誌等の執筆依頼を受付しております。
   ご希望の方はお気軽にお問い合わせください!

Be the first to comment

Leave a Reply

Your email address will not be published.


*


質問はこちら 閉じる