LoginSignup
12
10

More than 5 years have passed since last update.

Application Gateway (WAF) でAzure API ManagementのProxyとPortalを保護する

Last updated at Posted at 2018-07-28

はじめに

タイトル通りですが、Azure Application Gateway(以下AppGW)の構成要素がわかりづらかったり、
Azure API Management(以下APIM)の独特な動きでハマって時間がかかったので、
備忘を兼ねてbraindump。

実現したいこと

  • APIMで、APIエンドポイント(以下Proxy)、開発者ポータル(以下Portal)を公開する
  • Proxy,Portalの両公開エンドポイントにはAppGWでWAFを適用する
  • イメージ image.png

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

できあがった構成の詳細

構成図

image.png

フロントエンド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設定②

ハマったポイント

  1. APIMは適切なホストヘッダー(SNI)を持つ要求だけに応答する
    • バックエンドHTTP設定
      • 今回のようにバックエンドアドレスプールがIPの場合、ホスト名を指定する必要がある
      • (ホスト名はPortalで設定/閲覧 出来ない)
    • 正常性プローブ
      • →既定の正常性プローブはhttp(s)://backendip/にアクセスする(ホスト名を指定しない)ので、使用不可
      • (+proxyは/で200を返さない)
  2. APIMは/status-0123456789abcdefというプローブ用のURLを提供している点 ※2
    • ドキュメントが見つからない。言及しているのはリリースノートDocs内のVNETAPIM-AppGWの記事くらい
    • Portalのホスト名を指定したカスタム正常性プローブ(/status-0123456789abcdef)は動作しなかった。
    • →Portal側のカスタム正常性プローブもHostをProxy側に向ける
  3. 正常性プローブは接続先をHTTP設定のAuthenticationCertificateを使用して認証する
    • Portal側のHTTP設定①にもProxyの証明書の指定が必要となる ※1

出来上がったARMTemplate

template
parameter

PFXファイルからPFXとCERのBASE64エンコード.ps1
$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

AppGW

その他

12
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
10