Azure Firewall による Web Proxy

Azure Firewall の Proxy の機能がパブリックプレビューで利用できるようになっています。これは Squid のようなフォワードプロキシの機能を提供するもので、UDR によるルーティングの構成なしで Azure Firewall 経由の通信を実現できるようになります。実際に動作を確認し、留意点等をまとめましたので、ご利用の際はご一読いただければ幸いです。

https://learn.microsoft.com/ja-jp/azure/firewall/explicit-proxy

## 利用シナリオ
- UDR を設定せずに Azure Firewall 経由の通信を実現したい。UDR の場合、サブネット単位での設定となるが、プロキシの場合はクライアント単位での制御が可能。
- Private Link を使わずにオンプレから ER/VPN 経由で Azure PaaS に接続したい (Web トラフィックのみ)

## 構成図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/2bf98085-976e-ac79-fc9d-828185370a1f.png)

## 前提
- 構成図内の各リソースを作成済みであること。
- Azure Firewall Policy を利用していること。
- Azure Firewall と Firewall Policy は Standard または Premium SKU で作成済みであること。[IDPS 等検証のため Primum で実施] ※ Basic SKU での利用はサポートされていません。

## Proxy 設定の追加 (Firewall Policy)

Azure Policy の画面にて明示的なプロキシを有効にします。HTTP, HTTPS のポートは同じポートがつかえないため、別々のポート番号を指定する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/eb3e63f9-2c04-ebc2-6596-9ffd5f1e6e66.png)

## Proxy 設定の追加 (クライアント)
クライアントの Windows Server で [コントロールパネル] -> [インターネットオプション] -> [接続] -> [LAN の設定] -> [LAN にプロキシサーバーを使用する] - [詳細設定] の画面にて Azure Firewall の Private IP アドレスと HTTP,HTTPS ポートを設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/9f3125d9-e0fe-e049-aa65-28d771cd9840.png)

## 動作確認

### アプリケーションルールの動作確認 (FQDN)

アプリケーションルールに FQDN を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/2a6bd68f-e0d0-0b52-de94-5bdfbdb3b8ea.png)

ブラウザで Web サイトにアクセスしてみます。
HTTP, HTTPS の両方のアクセスが Azure Firewall のプロキシ経由となっていることを確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/8ff04aa0-4f9e-0e57-5618-66fcec059874.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/691cddce-bdac-1146-1415-2390d8b9dca2.png)

### アプリケーションルールの動作確認 (URL)

アプリケーションルールで特定の URL のみを許可します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/0d67760d-2f9f-c69a-3018-db6e79be7b8a.png)

該当する URL は許可されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/a8360487-c593-51d9-d56a-7802dc6f20b8.png)

該当しない URL は拒否されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/dd50e0a1-9c82-57ab-a04a-2d41d6b18930.png)


### アプリケーションルールの動作確認 (Category)

**Web カテゴリ**にて**スポーツ**を許可します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/c9f88f15-92cd-a058-b337-57e55b73ea1f.png)

スポーツと判定されるサイトにアクセスします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/7f50bde8-44a5-44d4-a08c-72d914b1112d.png)

Proxy 経由でアクセスできました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/335d667b-f4a8-9de2-736e-be3da5d6bb5b.png)

### アプリケーションルールの動作確認 (FQDN Tag)

Teams へのアクセスで必要となりそうな、Office365 Skype と Common の FQDN Tag を許可します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/d2f14681-175e-882a-3a97-e8b1e6fd9c92.png)

Web ブラウザで Proxy 経由で Teams にアクセスできました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/dda7a196-1800-0725-a030-8cd2183a400f.png)

FQDN tag のテスト目的で行いましたが、Proxy 経由での Teams 利用は**推奨されていません**のでご留意ください。

https://learn.microsoft.com/ja-jp/microsoftteams/proxy-servers-for-skype-for-business-online#not-using-a-proxy-server-is-recommended

### アプリケーションルールの動作確認 (IDPS)

TLS 検査有効化 (証明書の自動生成を利用) し、IDPS も拒否モードに変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/082123ff-b449-e24c-360d-d2651ea729b3.png)

アプリケーションルールで TLS 検査を有効化します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/b59e6056-bb24-8e79-7539-8654cbe4bc36.png)

ModHeader というブラウザの拡張機能を使って、User-Agent を "HaxerMen" に上書きします。公開情報にあるとおり、この User-Agent は拒否されるはずです。
https://learn.microsoft.com/ja-jp/azure/firewall/premium-deploy#to-test-idps-for-http-traffic

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/9b902646-f87a-9562-6e23-ad3642c2a8ce.png)

動作確認してみると想定通り、拒否されてタイムアウトとなりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/73d56537-57dc-d3ee-7e1d-798d8560aa19.png)

### ネットワークルールの動作確認
ネットワークルールでの制御ができるかを確認するため、以下の様なすべての TCP の通信を許可するルールのみを Firewall Policy に作成してみました。アプリケーションルールは削除してあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/c685d6fe-05f9-6022-801f-508442675ebf.png)

ネットワークルールでは動作せず、以下の様に Web ページに到達できませんでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/b7518bf7-2d35-e63f-8d41-ddb58c5a3d6a.png)

パケットを見てみると、TCP の通信として Azure Firewall と TCP 3way handshake は成功してますが、その後、Azure Firewall にてリクエストが拒否されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/28d0c8ff-26d1-14b2-66ec-746c51d9362d.png)

## PAC ファイルの動作確認

以下のように URL が http なら 8080, https なら 8443 というシンプルな PAC ファイル (testproxy.pac) を作成します。
```c
function FindProxyForURL(url) {
    if (shExpMatch(url, "http://*")) {
        return "PROXY 10.10.0.4:8080";
    }
    else if (shExpMatch(url, "https://*")) {
        return "PROXY 10.10.0.4:8443";
    }
    return "DIRECT";
}
```

PAC ファイルの書き方はこちらが参考になりました。

https://jpdsi.github.io/blog/internet-explorer-microsoft-edge/pac/

https://learn.microsoft.com/ja-jp/internet-explorer/ie11-ieak/proxy-auto-config-examples

PAC ファイルを BLOB ストレージにアップロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/b3373a04-8685-eb9a-837f-c641e0094b7b.png)

:::note warn
Azure Storage のファイアーウォール設定についてですが、**すべてのネットワークから有効** にする必要があるようです。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/ba7f4160-46c3-4362-8b9e-82119262fb4d.png)

Firewall Policy にて **プロキシの自動構成**を有効化し、PAC ファイルの SAS キーを指定し、ポート番号を指定して、適用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/fb6153dd-f29a-3a81-d9e2-eeb6accfd459.png)

クライアントの Proxy 設定画面にて **自動構成スクリプトを使用する** に **http://AzureFirewallのプライベートIP:PACファイルポート/[PACファイル名]** を指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/fb1a3083-9ba9-6543-f4eb-ed67a9aa22b7.png)

ブラウザでアクセスすると Azure Firewall のプロキシ経由で Web サイトにアクセスできました。(FQDN はアプリケーションルールで許可済み)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/fe5c25bc-f53c-6493-7015-a2b73b8572fd.png)


## 診断ログ
診断ログ [AzureDiagnostics] を有効化し、AzureDiagnostics テーブルを確認してみます。

Category : AZFWApplicationRule のログに IsExplicitProxyRequest_b という列で Proxy 利用の有無がわかるようになっているようです。現状、IsTlsInspected_b が true だと Proxy を使ってても false と記録されてしまうようです。今後の改善に期待したいと思います。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/b7e95906-53f1-3558-65f1-41a9fb7f95b5.png)

## X-Forwarded-For について

以下の様に接続先の Web サイトにてリクエストのの HTTP ヘッダーの情報を確認してみましたが、Azure Firewall にてクライアントの IP アドレス [192.168.0.4] が X-Forwarded-For として付与されておりました。
```r
        GET / HTTP/1.1
        X-FORWARDED-PROTO: http
        X-FORWARDED-PORT: 80
        X-Forwarded-For: 192.168.0.4, 20.27.45.116:1024
        X-Original-URL: /
        Connection: keep-alive
```
```r
        GET / HTTP/1.1
        X-FORWARDED-PROTO: https
        X-FORWARDED-PORT: 443
        X-Forwarded-For: 192.168.0.4, 20.27.45.116:1024
        X-Original-URL: /
        Connection: keep-alive
```

## 留意点

### NSG
Proxy の動作として Azure Firewall のプライベート IP との通信のみで外部サイトに接続可能となりますので、意図的に NSG にて Internet へのアウトバウンドを拒否しているような環境でも、Azure Firewall の Private IP が許可されていれば、Internet 上の Web サイトへ接続できてしまう可能性があります。(接続できるかどうかは Azure Firewall のルール次第となります)

以下の様に NSG のアウトバウンド規則で Azure Firewall の Private IP のみを許可している構成においても、外部の Web サイトにアクセス可能であることを確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/a9c7139f-2ecb-9524-b4f2-1f01f069d3d9.png)

### ストレージアカウントのファイアーウォールの設定について

**すべてのネットワークから有効** 以外の設定として東アジアにストレージアカウントをおいて Azure Firewall のパブリック IP を許可を試してみましたが、Firewall Policy の設定は以下の様なエラーとなりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2266293/b17dc81e-1a9a-2fa3-3e1e-04dd483e6549.png)

一度、ファイアーウォールの設定を **すべてのネットワークから有効** に変更し、Firewall Policy の Proxy の設定が完了した後に、再度、他のファイアーウォール設定 (選択した仮想ネットワークと IP アドレスから有効/無効) にした場合もアプリケーションルール等の更新で同様のエラーが発生しましたので、恒久的にストレージアカウントのファイアーウォールはすべて公開する必要があるようです。