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オフロード機能の活用を思いつくのではないでしょうか。
その場合に疑問に思うことがあります。
ロードバランサーは特定のWebサーバのアプリケーションに接続を固定するセッションアフィニティ機能の実現のためにL7レイヤーの情報(httpsヘッダやcookie等)を覗く必要があります。
ブラウザとWebサーバ間でデータが暗号化されてしまうと、ロードバランサーがL7レイヤーの情報を覗くことができず、セッションアフィニティが実現できないのではないでしょうか?
心配は無用です。
Azure Application GatewayのエンドツーエンドのSSL通信機能は、このような疑問にも応えてくれる仕組みを提供しております。
Azure Application Gatewayで一旦SSL通信を終了して暗号化されたデータを復号化し、L7レイヤーの情報を覗きます。それらの情報を元に振り分け先のWebサーバを決めて、Webサーバとの間で再びSSL通信を行うのです。
検証環境の構成と構築手順
検証環境の構成図です。
Application Gatewayには、復号化用の秘密鍵が含まれたPKCS#12形式の証明書と、暗号化用の公開鍵が含まれたPEM形式の証明書を登録する必要があります。
その他の細かい構築手順の説明は割愛します。マイクロソフトが公開している手順が参考になります。
現時点で公開されているのはPowerShellコマンドを使った構築手順です。Portal画面ではまだ細かい設定ができないようです。
Application Gatewayを構築する前に実施しておくべき作業を書いておきます。
- バックエンドのWebサーバにhttps接続環境作成
- Webサーバ用の秘密鍵とサーバ証明書作成
- Azure Application Gateway用の秘密鍵とサーバ証明書作成
今回はApacheを導入しました。
今回はApacheを使うので、pem形式で作成しました。
対応しているのは、pkcs#12(pfx)形式です。MSっぽいですね。
構築に関する補足事項を書いておきます。
- DNSサーバにロードバランサーのCNAMEを登録する必要がある。
- Azure Application Gatewayの作成コマンドの実行完了には時間がかかる。
Azure Application Gatewayのフロントエンド側のFQDNは自動的に作成され、IPアドレスも可変です。
検証環境での例
FQDN:94210a7c-e6c2-4557-aecf-3375dca57704.cloudapp.net
このFQDNは、ユーザに提供するURLとしては不適切なので、実運用を考慮すると、適切な名称を決めてDNSにCNAMEレコードを登録する必要があります。
今回の検証では、ユーザ向けのURLとして、
を使うことにしましたので、「94210a7c-e6c2-4557-aecf-3375dca57704.cloudapp.net」のCNAMEとして、「websvapgw.siostest02.com」をDNSに登録しました。
検証で実行した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
websv01側に配置したhtmlコンテンツが表示されましたので、websv01側に振られたことがわかります。
クライアント側のパケットキャプチャ
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
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を確認することができます。
これは、Application Gatewayが埋め込んだcookieで、ユーザー セッションと振り分け先サーバーを管理するためにクライアントに発行したものです。
この値が同じある限り、再度同じURLに接続しても同じWebサーバに接続することができます。
また、Webサーバ側のApacheのログに、x-forward-forの値を出力するように設定しました。
接続元クライアントのIPとポート「126.152.194.89:41998」がx-forward-forの値として設定されていることがわかります。
Application Gateway側でアクセスログを出力するように仕込むこともできます。
以下はアクセスログの抜粋です。
接続元クライアントのIPとポート「126.152.194.89:41998」を確認することができます。
以上