はじめに
タイトル通りですが、Azure Application Gateway(以下AppGW)の構成要素がわかりづらかったり、
Azure API Management(以下APIM)の独特な動きでハマって時間がかかったので、
備忘を兼ねてbraindump。
実現したいこと
AppGWの機能・構成要素のざっくり説明
Application Gateway はレイヤー 7 のロード バランサー
SSL ターミネーション、Cookie ベースのセッション アフィニティ、ラウンド ロビンによるトラフィックの負荷分散、WEBアプリケーションファイアーウォールなどの機能がある
サイズはSmall、Medium、Largeの3タイプ、SLAはMedium/Largeかつ2インスタンス以上が対象なので、見積もりとかで注意
サブネット
AppGWはサブネットを占有する
AppGWにプライベートIPを割り当てる場合、/29 以上、割り当てない場合、/28 以上のサイズが必要
フロントエンドIP(FrontendIPConfiguration)
入口となるプライベートIPまたは、PublicIPリソース(xxxx.region.cloudapp.azure.com)を割り当てる
**現時点では**1AppGWあたり一つのPublicIPの制限がある
PublicIPは動的のみの為、基本的にはDNSはCNAMEレコードで設定することとなる
(Application Gateway を停止/起動すると、VIPが変更される)
フロントエンドポート(FrontendPort)
入口のPublicポート
任意指定可能(ふつうは80,443だと思われる)
リスナー(HttpListener)
フロント側の設定をまとめる要素
フロントエンドIP、フロントエンドポート、プロトコル、SSL証明書を紐づける
マルチサイト(マルチドメイン)構成の場合、ホスト名を指定する
プロトコルがHTTPSなら、秘密鍵証明書(PFX)を指定する
ホスト名指定=マルチサイト(とPortal上は呼ばれる)(マルチドメイン構成)
バックエンドプール(BackendAddressPool)
複数作成可能
NIC、仮想マシン スケール セット、パブリック IP、内部 IP、完全修飾ドメイン名 (FQDN)、Azure Web Apps が設定できる
Azureの外部に出る場合、アウトバウンドIPはAppGWに割り当てたパブリックIPとなる
HTTP設定(BackendHttpSetting)
バックエンドへアクセスする際のHTTP設定(日本語の名前、もう1単語欲しいよね わかりづらい)
以下の項目を設定する
- プロトコル(HTTPorHTTPS)
- HTTPSなら、バックエンドの証明書公開鍵(CER)を指定する(再暗号化)
- ポート
- Cookieベースアフィニティ
- Cookie ベースのセッション アフィニティ
- バックエンドが単一IPならば無意味(おそらく)
- 接続のドレイン
- 正常性プローブによって、バックエンドノードが切り離される際、接続が終わるまで維持する(新規コネクションは張らない)
- バックエンドパスのオーバーライド
- Rewriteではない(パスの上書きロジック、変な挙動する(気がする))
- カスタムプローブの使用
- 正常性プローブのカスタム設定を選択
- ホスト名
- バックエンドプールへリクエスト転送時、ホストヘッダの変更を行う
- PowerShell/ARMでの設定は可能。
- ポータルで設定不可、閲覧不可
- PickHostNameFromBackendAddressオプションがあり、バックエンドプールが(複数の?)ホスト名の場合、その値を使用することが可能
ルール(RequestRoutingRules)
BASICとパスベースの2種類ある
リスナー、バックエンドプール、HTTP設定を紐づける
BASICは単一のバックエンド/HTTP設定を紐づける
パスベースはパス毎にバックエンド/HTTP設定を紐づける
正常性プローブ(Probe)
バックエンドの正常性を確認するプローブのうち、既定以外の正常性プローブを設定したい場合に作成する
ホスト名、プロトコル、パス、チェック間隔、タイムアウト等を設定する
PickHostNameFromBackendHttpSettingsオプションがあり、HTTP設定のホスト名を引き継ぐことも可能
WAF
Web アプリケーション ファイアウォール
AppGWのサイズ( Small、Medium、Large)のうちMedium、Largeのみ使用可能。
BASIC(WAFなし)と比べるとおおよそ倍の価格となる
OWASP コア ルール セット 3.0 または 2.2.9の規則に対応
検出モード/防止モードがある
APIMの構成要素のざっくり説明
価格レベル
DEVELOPER/BASIC/STANDARD/PREMIUMの4つ
特筆すべきは、仮想ネットワークサポートはDEVELOPER/PREMIUMのみである点
今回は、PortalにもWAFを適用したいので、VNET参加は必須となる
(Proxyのみであれば、ポリシーで制御可能(なはず))
VNET
外部/内部の2つのモード
外部=PublicIPあり+VNETエンドポイント
内部=VNETのみ(既定のドメインは、パブリック DNS サーバーには登録されない)
既定のホスト名
- 管理:xxx.management.azure-api.net
- ポータル:xxx.portal.azure-api.net
- プロキシ:xxx.azure-api.net
- SCM:xxx.scm.azure-api.net
できあがった構成の詳細
構成図
フロントエンドIP
パブリックIPリソースを指定する
DNSのCNAMEレコードで、ドメインが解決できるようにする
- portal.example.com->example.japaneast.cloudapp.azure.com
- api.example.com->example.japaneast.cloudapp.azure.com
フロントエンドポート
HTTPリダイレクトの構成は不要の為、443のみ作成
HTTPリスナー①
項目 | 値 |
---|---|
FrontendIPConfiguration | フロントエンドIP |
FrontendPort | フロントエンドポート(443) |
Protocol | HTTPS |
SSLSertificate | portal.example.com(pfx) |
HostName | portal.example.com |
RequireServerNameIndication | true |
HTTPリスナー②
項目 | 値 |
---|---|
FrontendIPConfiguration | フロントエンドIP |
FrontendPort | フロントエンドポート(443) |
Protocol | HTTPS |
SSLSertificate | api.example.com(pfx) |
HostName | api.example.com |
RequireServerNameIndication | true |
バックエンドプール
APIMのプライベートIPアドレス
(10.0.1.0/24にAPIMデプロイすると10.0.1.5になる(1-3は予約されるので、常に2個目?ヨクワカラン))
(apim.staticIPs[0]でもとれるので、依存関係アリのARMTemplateにしても良いかも)
バックエンドHTTP設定①
項目 | 値 |
---|---|
Port | 443 |
Protocol | Https |
CookieBasedAffinity | Disabled |
HostName | portal.example.com |
PickHostNameFromBackendAddress | false |
RequestTimeout | 180 |
Probe | APIM正常性プローブ |
AuthenticationCertificate | portal.example.com(cer) api.example.com(cer) |
バックエンドHTTP設定②
項目 | 値 |
---|---|
Port | 443 |
Protocol | Https |
CookieBasedAffinity | Disabled |
HostName | api.example.com |
PickHostNameFromBackendAddress | false |
RequestTimeout | 180 |
Probe | APIM正常性プローブ |
AuthenticationCertificate | api.example.com(cer) |
APIM正常性プローブ
項目 | 値 |
---|---|
Protocol | Https |
Host | api.example.com |
Path | /status-0123456789abcdef |
Interval | 30 |
Timeout | 120 |
UnhealthyThreshold | 8 |
PickHostNameFromBackendHttpSettings | false |
MinServers | 0 |
Match-body | (empty) |
Match-statusCodes | 200-399 |
リクエストルーティングルール①
項目 | 値 |
---|---|
RuleType | Basic |
HttpListener | HTTPリスナー① |
BackendAddressPool | APIMバックエンドプール |
BackendHttpSettings | バックエンドHTTP設定① |
リクエストルーティングルール②
項目 | 値 |
---|---|
RuleType | Basic |
HttpListener | HTTPリスナー② |
BackendAddressPool | APIMバックエンドプール |
BackendHttpSettings | バックエンドHTTP設定② |
ハマったポイント
-
APIMは適切なホストヘッダー(SNI)を持つ要求だけに応答する点
- バックエンドHTTP設定
- 今回のようにバックエンドアドレスプールがIPの場合、ホスト名を指定する必要がある
- (ホスト名はPortalで設定/閲覧 出来ない)
- 正常性プローブ
- →既定の正常性プローブはhttp(s)://backendip/にアクセスする(ホスト名を指定しない)ので、使用不可
- (+proxyは/で200を返さない)
- バックエンドHTTP設定
-
APIMは/status-0123456789abcdefというプローブ用のURLを提供している点 ※2
- ドキュメントが見つからない。言及しているのはリリースノートとDocs内のVNETAPIM-AppGWの記事くらい
- Portalのホスト名を指定したカスタム正常性プローブ(/status-0123456789abcdef)は動作しなかった。
- →Portal側のカスタム正常性プローブもHostをProxy側に向ける
-
正常性プローブは接続先をHTTP設定のAuthenticationCertificateを使用して認証する点
- Portal側のHTTP設定①にもProxyの証明書の指定が必要となる ※1
出来上がったARMTemplate
$HostName = "portal.example.com"
Get-PfxCertificate -FilePath ($HostName+".pfx") | Export-Certificate -FilePath ($HostName+".cer") -Type CERT
$PfxBytes = Get-Content ($HostName+".pfx") -Encoding Byte
[System.Convert]::ToBase64String($pfxBytes) | Out-File ($HostName+".pfx_base64.txt")
$CerBytes = Get-Content ($HostName+".cer") -Encoding Byte
[System.Convert]::ToBase64String($CerBytes) | Out-File ($HostName+".cer_base64.txt")
おわりに
trial and errorで試そうにも、AppGW/APIMの構成変更に時間がかかりすぎて全然進まなかった
もっと構成変更素早くしてほしい
時間かかるだけじゃなく、途中でリソースが死んでサポートに連絡したり
MSDNの無料枠使い切りそうになったり
ドキュメント類もなんか足りない
シナリオに対する手順ベースに記述されてばかりで、各構成要素の意味を解説する記事があまりない
pickHostNameFromBackendHttpSettingsとかPickHostNameFromBackendHttpSettingsとか
パスベースルーティングのパス書き換えの仕様も謎
あと、既定の正常性プローブのアクセス先ホスト名が127.0.0.1ってほんと意味わからんかった
あと、AppGWははやくRewriteサポートすべき
WAFも嬉しいが、真に必要なのはマネージドなリバプロだったりする
AppGWはARR使ってる?のになんで対応が遅いのか(↓2016/2に開かれてる)
Support URL rewriting with Application Gateway – Customer Feedback for Microsoft Azure
参考文献
公式ドキュメント
APIM
-
内部 VNET 内の API Management と Application Gateway の統合 (英語版はこちら)
- →Proxyのみで、Portalを公開する方法までは示されていない。
- SNI ヘッダーを使用せずに呼び出すクライアント
AppGW
- Application Gateway での無効なゲートウェイによるエラーのトラブルシューティング
- Application Gateway によるマルチテナント バックエンドのサポート
- Application Gateway による正常性監視の概要