App Service ドメインで購入したドメインを更新する


App Service ドメインで購入したドメインの期限が迫ってきて、donotreply@secureserver.net のアドレスから、こんなメールが届きました。

内容的には確かに自分が買ったドメインではあるものの、メールの送信元が Azure でも Microsoft でもないし、迷惑メールに仕分けされてたんで一瞬怪しいなぁと思ってググったら、自分のブログが出てきました(

よく考えたら App Service ドメインって裏は GoDaddy 系 (?) で、管理画面は secureserver.net でしたね。一件落着。

Azure ポータルで App Service ドメインの設定を再確認しましたが、自動更新を有効にしてたので特に何もせずにスルーしても平気そうでした。

せっかくなので [ドメインの更新] から手動で更新して、スクショだけ取っておきましたとさ。

おしまい。


Azure Portal や Office 365 への通信は、ExpressRoute のみでは完結しません


[サマリー]

  • ExpressRoute の Microsoft Peering を構成すれば、Azure や Office 365 (要個別承認) の Public IP に対して閉域網で通信できます。
  • ただし、Azure Portal や Office 365 宛の通信は ExpressRoute のみでは完結せず、一部は Internet 宛の通信が必要です。
  • Proxy や Azure Firewall 等で URL フィルターはできますが、ACL や NSG のように IP でフィルターすることはできません。

[詳細]

Azure Portal や Office 365 にアクセスをする際に F12 や Fiddler トレースをとれば明らかなように、単一のページを表示するだけでも裏では多量の通信先へアクセスが行われています。Azure Portal は様々な REST API を叩いて各種リソースの情報を呼び出して表示をしていますが、どのブレード (ページ) を開くかによって REST API も様々ですし、アイコン等は Azure 外の CDN 上でホストされていることもあり、通信先は ExpressRoute でアクセスできる Public IP だけではありません。

このため、完全閉域で Internet に一切アクセスできない環境からは、Azure Portal 等へアクセスをすることはできません。

なお、Proxy や Azure Firewall 等で URL フィルターをしている場合には、以下のブログやドキュメントに記載の URL を許可してあげることで概ね解決できるかと思います。(IP は変動する可能性もあり非公開のため、ACL や NSG で IP フィルターにて制御することはできません。)

※「概ね」と書いているのは、Azure Portal は毎日のように実装が変わるものであり、新機能が追加された際に通信先が追加される可能性も十分考えられるからです。

また、Office 365 については、以下のドキュメントやリンク先の RSS / JSON / PAC ファイルに、ER の疎通可否 (ER 列の「はい / いいえ」)、URL / IP / Port などが詳しくまとまっています。上記 Azure の場合と同様に、ワイルドカード指定で IP 未記載のものもありますので、ACL や NSG で IP フィルターを行うことはできないものと認識しましょう。

IP も FQDN も変動するおそれがありますし、ぶっちゃけ管理工数がバカにならないので、法規制があるような場合を除いては Internet 宛の通信を制限しない方が良いと思います。


Azure VM に Public IP を紐づけられないように制限したい


セキュリティやコンプライアンス上の理由で、Azure VM には直接 Public IP を紐づけられないように制限したいといったシナリオがあるかと思います。そういう場合には Azure Policy を利用することで制限することが可能ですのでご紹介しておきます。

まず、Azure Portal で [ポリシー] の [定義] を開くと、既に用意されている組み込みのポリシーが表示されます。あいにく、組み込みポリシーには Public IP を禁止するようなものがありませんので、 [+ ポリシー定義] から新規ポリシーを作成します。

ポリシー定義の画面では、ポリシー定義の場所 (サブスクリプションなど) を選択して任意の名前を付け、ポリシー ルールの箇所に具体的なポリシーの設定内容を定義します。今回は VM (厳密には NIC) に Public IP を付けることを禁止したいので、リソース タイプが networkInterfaces で、かつ NIC の ipconfigurations に publicIpAddress が設定されていない事を強制するため、以下のようなポリシーを定義します。

ポリシー定義の例

{
  “mode”: “All”,
  “policyRule”: {
    “if”: {
      “allOf”: [
        {
          “field”: “type”,
          “equals”: “Microsoft.Network/networkInterfaces”
        },
        {
          “not”: {
            “field”: “Microsoft.Network/networkInterfaces/ipconfigurations[*].publicIpAddress.id”,
            “exists”: “false”
          }
        }
      ]
    },
    “then”: {
      “effect”: “deny”
    }
  },
  “parameters”: {}
}

ポリシーが作成できたら、[割り当て] からポリシーを適用したいサブスクリプションやリソース グループを選択して割り当てます。

以下のようなメッセージが表示され、初回のスキャンが完了するまでに 30 分ほど時間がかかります。気長に待ちましょう。

初回の評価が終わると、既存のリソースでポリシーに準拠していないリソースがリストアップされます。

また、ポリシーの適用後に NIC に Public IP を紐づけて保存しようとすると、以下のようにエラーになるので、意図した通りに制限できたことが分かります。

JSON でポリシー定義を良い感じ書けば自由に制御できるので、Azure リソースのスキーマを理解したうえで使いこなしましょう。ちなみに、Azure Policy のプロパティに指定できるエイリアスは、Azure PowerShell で調べることが可能なので、この辺を使いこなすと楽だと思います。

https://docs.microsoft.com/ja-jp/azure/governance/policy/tutorials/create-custom-policy-definition#find-the-property-alias


Azure Load Balancer を Basic から Standard に変更する方法


Azure のロードバランサーは Basic / Standard の External (ALB) / Internal (ILB) と 4 パターンありますが、以下のドキュメントにもある通り、SKU を変更することはできません。

SKU 間での移行

SKU は変更不可です。

 重要
このドキュメント全体を確認して、SKU ごとの違いを理解し、シナリオを慎重に検証してください。 シナリオに合わせて追加の変更が必要になる場合があります。

したがって、Basic から Standard に変更する場合は、一度 Basic SKU の LB を削除し、新規で Standard の LB を作る必要があります。

SKU ごとの機能差

ザックリまとめると、SKU ごとの機能差は以下の通りです。

SKU 移行時の注意点

1. LB と Public IP の SKU は統一する必要があります。

つまり、VM に Basic SKU の Public IP を紐づけている状況で、Standard SKU の LB に所属させることはできません。Public IP も Standard SKU のものを新規作成して付け替える必要があります。

2. 可用性セット内の全てのリソースで SKU を統一する必要があります。

可用性セットは、同一の役割のサーバーをグルーピングし、同一の物理サーバー上に配置させないことで、可用性を担保するための仕組みです。言い換えれば、可用性セット内の 1 台の VM は Basic の LB に、もう 1 台の VM は Standard の LB に紐づくといったことはできないため、可用性セット内の全ての VM を同一 SKU の LB 配下に入れる必要があります。

3. VM が Public IP を持たず、Standard ILB にのみ紐づく場合は Internet アクセスができません。

VM に ILB しか紐づいておらず、Public IP もない場合、Internet アクセスができなくなります。Standard ILB は SNAT の機能を有していないため、VM に直接 Public IP を紐づけるか、ILB とは別に ALB (外部 LB) を紐づける必要があります。

あとから構成変更しようとすると割と手間がかかるので、構築時にきちんと設計しましょう。


Application Gateway のテンプレートに SSL オフロード用の証明書を埋め込む方法


Application Gateway の ARM テンプレートに SSL 証明書 (PFX) とパスワードを設定する際の方法をメモしておきます。

まあ、GitHub の以下にサンプルがあるので、それを真似するだけなんですが。

azure-quickstart-templates/101-application-gateway-public-ip-ssl-offload/azuredeploy.json

該当箇所は、125 – 133 行目の以下の箇所。

    "sslCertificates": [
      {
        "name": "appGatewaySslCert",
        "properties": {
          "data": "[parameters('certData')]",
          "password": "[parameters('certPassword')]"
        }
      }
    ],

data と password のパラメーターに証明書のデータ (PFX を Base-64 エンコードしたもの) と、パスワードを指定すれば OK です。

上記の例では、[parameters()] で事前に定義した変数を参照する形になっています。 該当箇所は 50 – 61 行目のあたり。

"certData": {
  "type": "string",
  "metadata": {
    "description": "Base-64 encoded form of the .pfx file"
  }
},
"certPassword": {
  "type": "securestring",
  "metadata": {
    "description": "Password for .pfx certificate"
  }
},

PFX ファイルを Base-64 でエンコードするには、Windows PowerShell で以下の様な感じでやりましょう。

$CertPath = "<PFX ファイルのフルパス>"
[System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes($CertPath)) | Out-File "<Base64 エンコードしたテキストの出力先フルパス>"

ARM テンプレートの使い方は、この辺のリンクをどうぞ。


Azure VM の SNAT の話


Azure VM は NAT Gateway のようなリソースがなくても勝手に SNAT して Internet 接続ができるようになっています。
ただ、勝手にいい感じにやってくれる親切設計な反面、仕組みを理解せずに使ってる人が多すぎるので、整理しておこうかなと。

SNAT に使用される Public IP

一応ドキュメントに記載はあるんですが、わかりづらいのでシンプルにまとめると以下のような感じになります。

  • VM に Public IP がある場合: VM (NIC) に紐づいた Public IP で SNAT
  • VM に Public IP がなく、外部 LB に紐づいている場合: LB の Public IP で SNAT
  • VM に Public IP も外部 LB にも紐づいていない場合: 当該リージョンの任意の Public IP で SNAT

したがって、送信元 IP を固定したい (対向側の Firewall 等で IP 指定で許可設定をしたい) 場合には、前者 2 点のいずれかになります。

SNAT Port の割り当て

VM が Public IP を持たないシナリオの場合、個々の VM に割り当てられる SNAT Port の数に注意が必要です。

  • VM に Public IP がある場合: 64k Port
  • VM に Public IP がなく、外部 LB に紐づいている場合: 最大で 1024 Port
  • VM にも外部 LB にも紐づいていない場合: 1024 Port

1 つの Public IP では TCP / UDP それぞれ 64k Port しか使えませんので、外部 LB の Public IP を使用する (複数の VM で Public IP を共有する) 場合 は、1 台あたりに割り当てられる Port が 1024 までに限られる点に気を付けましょう。(なお、LB 配下の VM が 1 台だけであっても、1024 Port しか使えません)
なお、LB のバックエンド プールが 50 台を超える場合には、割り当て Port がさらに少なくなります。(参考)

SNAT Port を使い果たした場合

LB の SNAT Port が使い果たした場合、当然ですが SNAT できないため Public IP 宛の通信ができなくなります。
Azure VM から Public IP あてに多数のセッションを張る場合や、Docker などのコンテナを利用するような場合は、1024 Port を早々に食いつぶす可能性もあるので、きちんと見積もりや設計を行いましょう。(Azure 基盤側としては、VM 上で何台コンテナが起動しているかは把握できないので、同一 VM 上で稼働するすべてのコンテナで 1024 Port を共有することになります。)

ちなみに、負荷テストや再現試験などで SNAT Port を意図的に枯渇させたい場合、Linux で hping3 を使うのがお手軽です。
例えば、以下のような形で実行することで、SYN パケットを100 マイクロ秒ごとに任意の Public IP (xx.xx.xx.xx) の 65000 番の Port に対して、ひたすら投げつけることができます。(一歩間違うと SYN Flood 攻撃になるので、やり方と通信先は慎重に検討しましょう。)

apt install hping3 -y
hping3 -S -i u100 -p 65000 <xx.xx.xx.xx>

外部 LB 配下の VM (すなわち 1024 Port しか使えない環境) で上記を実行すると、1 秒ほどで大量の応答が返ったのち、突然出力が止まるかと思います。Ctrl + C で hping3 を終了すると、以下のように 1024 packets までは応答が得られたものの、あとはパケロスしていたことが確認できます。

len=46 ip=xx.xx.xx.xx ttl=57 DF id=0 sport=65000 flags=SA seq=1011 win=29200 rtt=30.4 ms
len=44 ip=xx.xx.xx.xx ttl=64 DF id=0 sport=65000 flags=SA seq=1016 win=29200 rtt=29.8 ms
len=44 ip=xx.xx.xx.xx ttl=64 DF id=0 sport=65000 flags=SA seq=1007 win=29200 rtt=31.0 ms
len=44 ip=xx.xx.xx.xx ttl=64 DF id=0 sport=65000 flags=SA seq=1013 win=29200 rtt=30.3 ms
len=44 ip=xx.xx.xx.xx ttl=64 DF id=0 sport=65000 flags=SA seq=1012 win=29200 rtt=30.6 ms
len=44 ip=xx.xx.xx.xx ttl=64 DF id=0 sport=65000 flags=SA seq=1006 win=29200 rtt=31.4 ms
len=44 ip=xx.xx.xx.xx ttl=64 DF id=0 sport=65000 flags=SA seq=1009 win=29200 rtt=31.1 ms
len=44 ip=xx.xx.xx.xx ttl=64 DF id=0 sport=65000 flags=SA seq=1008 win=29200 rtt=31.2 ms
len=44 ip=xx.xx.xx.xx ttl=64 DF id=0 sport=65000 flags=SA seq=1014 win=29200 rtt=30.4 ms
len=44 ip=xx.xx.xx.xx ttl=64 DF id=0 sport=65000 flags=SA seq=1021 win=29200 rtt=29.5 ms
len=44 ip=xx.xx.xx.xx ttl=64 DF id=0 sport=65000 flags=SA seq=1019 win=29200 rtt=29.9 ms
len=44 ip=xx.xx.xx.xx ttl=64 DF id=0 sport=65000 flags=SA seq=1022 win=29200 rtt=29.5 ms
len=44 ip=xx.xx.xx.xx ttl=64 DF id=0 sport=65000 flags=SA seq=1018 win=29200 rtt=30.1 ms
len=44 ip=xx.xx.xx.xx ttl=64 DF id=0 sport=65000 flags=SA seq=1017 win=29200 rtt=30.2 ms
len=44 ip=xx.xx.xx.xx ttl=64 DF id=0 sport=65000 flags=SA seq=1020 win=29200 rtt=29.9 ms
len=44 ip=xx.xx.xx.xx ttl=64 DF id=0 sport=65000 flags=SA seq=1023 win=29200 rtt=29.4 ms
^C
--- xx.xx.xx.xx hping statistic ---
21434 packets transmitted, 1024 packets received, 96% packet loss
round-trip min/avg/max = 3.5/9.2/32.9 ms

なお、SNAT で使用した Port はセッションが閉じられたり (FIN/ACK)、強制的に切断されたり (RST)、アイドル タイムアウトに達した場合 (既定で 4 分) に開放されます。

また、外部 LB が Standard SKU の場合に限り、使用済みの SNAT Port をメトリックの機能で確認することが可能です。
先の例のように Ctrl + C で止めずに、長時間 1024 Port を消費させたままの状態にすると、以下のような感じになります。

Basic SKU の外部 LB を使っている場合は、上記のようなメトリックは利用できませんが、たしか診断ログの機能でアラート イベント ログに “Ports exhausted” と記録されたかと思います。 (参考)

SNAT Port の割り当てを増やしたい場合

VM (NIC の ipconfig) あたり 1024 Port では足りないという場合、対処策は以下のいずれかになります。

  • VM に Public IP を直接紐づける
  • Standard SKU の外部 LB で allocatedOutboundPorts を設定して、SNAT Port の割り当てを変更する

後者の allocatedOutboundPorts は Basic SKU では使えず、Standard SKU でのみ提供される機能ですが、1 VM あたりに割り当てる SNAT Port を 10000 Port などと明示的に設定することが可能です。(もちろん、1 台当たりの Port × LB 配下の VM 台数が 64k に収まるように設計する必要があります。)

現状 Portal からは設定ができないため、Azure PowerShell や CLI、REST、JSON テンプレートなどで設定する必要があります。(参考)

# 既存の LB の設定を取得
$LB = Get-AzLoadBalancer -ResourceGroupName SNAT-Test -Name SNAT-Test-StandardLB

# OutboundRule で AllocatedOutboundPort 等のパラメーターを設定
Add-AzLoadBalancerOutboundRuleConfig -LoadBalancer $LB -Name OutboundRule -AllocatedOutboundPort 10000 -Protocol All -EnableTcpReset -IdleTimeoutInMinutes 4 -FrontendIpConfiguration $LB.FrontendIpConfigurations -BackendAddressPool $LB.BackendAddressPools[0]

# LoadBalancingRule による SNAT を無効化 (これを忘れるとエラーになるので注意)
$LB.LoadBalancingRules[0].DisableOutboundSNAT = $true

# 設定を保存
Set-AzLoadBalancer -LoadBalancer $LB

以上、Azure での SNAT でハマりやすいポイントと対処策についてでした。