Azure / M365の更新をパワポにしてくれるアプリを使ってみた件(後編)

[前回](https://qiita.com/S-Sakurai/items/e5fcdce8b0dcb2fd7a77)まででプライベートでの接続でツールを実行することができるようになりました。
引き続き、セキュリティに気を付けながらパブリックで使えるようにしていきます。

なお前の記事で言及していなかったのですが、リソース名はMS-Learnのチュートリアルにある名前をそのまま使っている箇所が多いので適宜読み替えを行うなどしてもらえればと思います。

# 追加の環境構築①　Application Gateway
Application GatewayはL7のロードバランサですが、このツールは認証機能がないのでWAF(Web Applicaiton Firewall)を置くことで悪意ある第三者からのアクセスをそれとなく遮断するようにします。
WAFの機能だけであれば、Azure Front Doorで良かったのかも知れませんが、Application Gatewayで進めてしまいます。

1\. ポータルの検索ボックスに、「Application Gateway(s)」と入力します。検索結果から [Application Gateways] を選択します。
2\. [アプリケーション ゲートウェイの作成] の [基本] タブで、次の情報を入力または選択します。
|設定|値|
|:-|:-|
|**プロジェクトの詳細**||
|リソース グループ|rg-getAzureUpdate|
|**インスタンスの詳細**||
|ゲートウェイ名|myAppGateway|
|リージョン|Japan East|
|レベル|WAF V2|
|自動スケール|いいえ|
|インスタンス数|1|
|IP アドレスの種類|IPv4 のみ (既定値)|
|HTTP2|有効 (既定値)|
|WAF ポリシー|[新規作成] をクリックし、名前に「myFWPolicy」と入力。ボット保護の追加は「有効」を選択|
|**仮想ネットワークの構成**||
|仮想ネットワーク|vnet-1|
|サブネット|[サブネット構成の管理] をクリックし、[+サブネット]をクリック。[サブネットの追加] ウインドウで名前に「myAGSubnet」と入力。|

Application Gateway用のサブネットには、Application Gatewayのみを含めることができ、その他を配置することは許可されません。またアドレスのレンジはCIDR/24が推奨となっています。
プライベートサブネットも有効にしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330959/e373ce1f-5535-4a67-b802-715cebfb1728.png)

3\. サブネット追加後に、作成したサブネットを選択し、[次へ: フロントエンド>] をクリックします。
4\. [フロントエンド] タブで、次の情報を入力または選択します。

|設定|値|
|:-|:-|
|フロントエンド IP の種類|パブリック|
|パブリック IPv4 アドレス| [新規追加] をクリックし、名前に「myAGPublicIPAddress」と入力。|

5\. [次へ: バックエンド ＞] をクリックします。
6\. [バックエンド] タブで、[バックエンド プールの追加] をクリックします。
7\. [バックエンド プールの追加] ウィンドウで、次の情報を入力または選択します。

|設定|値|
|:-|:-|
|名前|myBackendPool|
|ターゲットを持たないバックエンド プールを追加します|いいえ|
|ターゲットの種類|仮想マシン|
|ターゲット|vm-1 (に付いているNIC)|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330959/ca4fd0dd-1de4-4e66-b44a-eeb19e926f79.png)

8\. [バックエンド プールの追加] ウィンドウで、 [追加] をクリックしてバックエンド プールの構成を保存し、 [バックエンド] タブに戻ります。
9\. [バックエンド] タブで、 [次へ:構成] をクリックします。
10\. [構成] タブで、ルーティング規則を使用して作成したフロントエンドとバックエンド プールを接続します。
11\. [ルーティング規則] 列で [ルーティング規則の追加] をクリックします。
12\. [ルーティング規則の追加] ウィンドウが開いたら、[ルール名] と [優先度] に次の値を入力します。

|設定|値|
|:-|:-|
|ルール名|myRoutingRule|
|優先度|100|

13\.  [ルーティング規則の追加] ウィンドウ内の [リスナー] タブで、次の情報を入力または選択します。

|設定|値|
|:-|:-|
|リスナー名|myListener|
|フロントエンド IP|パブリック IPv4|
|プロトコル|HTTP|
|ポート|80|
|リスナーの種類|Basic|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330959/179e236d-82ac-4efc-9222-00d4ef6c318c.png)

14\. [バックエンド ターゲット] タブで、 [バックエンド ターゲット] の [myBackendPool] を選択します。
15\. [バックエンド設定] で、[新規追加] をクリックして、次の情報を入力または選択します。

|設定|値|
|:-|:-|
|バックエンド設定名|myBackendSetting|
|バックエンド プロトコル|HTTP (既定値)|
|バックエンド ポート|8000|
|**追加設定**|(既定値どおり)|
|**ホスト名**|(既定値どおり)|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330959/9d4ccb47-3bc3-427b-bc1e-bd1739ebf1b8.png)

16\. [バックエンド設定の追加] ウィンドウで[追加] をクリックして [ルーティング規則の追加] ウィンドウに戻ります。[ルーティング規則の追加] ウィンドウで [追加] をクリックしてルーティング規則を保存し、 [構成] タブに戻ります。

17\. [次へ:タグ ＞]をクリックし、再度[次へ:確認と作成 ＞] をクリックします。

18\. [確認と作成] タブの設定を確認し、 [作成] をクリックして、Application Gatewayのデプロイ完了を待ちます。

# 追加の環境構築②　Application Gateway WAFポリシー
現在の状態は、パブリックとして用意したApplication Gatewayのフロントエンド IPに対して、Webブラウザでアクセスすると"誰でも"このツールにアクセスできてしまいます。
このため、WAFにカスタムルールを設定し接続元の制限をかけていきます。

1\. ポータルの検索ボックスに、「WAF」と入力します。検索結果から [Web Application Firewall ポリシー (WAF)] を選択します。
2\. Application Gateway作成時に作った[myFWPolicy] を選択します。
3\. 左メニューの [設定] 内の [カスタム ルール] を選択します。
4\. [カスタム ルール] ページで、[+ カスタム ルールの作成] をクリックします。
5\. [カスタム ルールの追加] ウインドウで、以下の情報を入力するか選択します。

|設定|値|
|:-|:-|
|カスタム ルール名|myrule1|
|ルールを有効にする|有効 (既定値)|
|ルールの種類|一致 (既定値)|
|優先度|100|
|**条件**||
|一致の種類|IP アドレス|
|演算|次の値を含まない|
|IP アドレスまたは範囲|接続を許可するIPアドレスまたはIPアドレス帯|
|結果|トラフィックを拒否する|

6\. [追加] をクリックして、[保存] をクリックします。
7\. 左メニューの[概要]をクリックして、[防止モードに切り替える] をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330959/a0021d51-005d-4ff5-9282-f79409bf955a.png)

この設定により、カスタムルールで設定した「接続を許可するIPアドレスまたはIPアドレス帯」以外からの通信を拒否する挙動になります。
実際に、接続が許可された送信元IPアドレスと許可していない送信元IPアドレスのクライアントから、アクセスを行ってそれぞれの挙動を確認します。
接続が許可されていない送信元IPアドレスからの接続は次のような画面が返却されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330959/1200611b-2565-44a2-af67-d9e729b2ce71.png)


# 追加の環境構築③　Network Security Group
ツールへのインバウンドは、Application GatewayからのルートとBastionからのルートのみですが、多重防御の意味でNSGを厳格に設定して不要なトラフィックを遮断します。

1\. ポータルの検索ボックスに、「NSG」と入力します。検索結果から [ネットワーク セキュリティ グループ] を選択します。
2\. 前回、仮想ネットワークを作成した際に作った[nsg-subnet-1]を選択します。
3\. 左メニューの [設定] にある [受信セキュリティ規則] をクリックします。
4\. [+追加] をクリックし、[受信セキュリティ規則の追加] ウインドウで、以下の情報を入力するか選択します。

Ⅰ. Application Gatewayからの接続を許可します。
|設定|値|
|:-|:-|
|ソース|IP Address|
|ソース IP アドレス/CIDR 範囲|10.0.2.0/24 (Application Gatewayのサブネット)|
|ソース ポート範囲|*|
|宛先|IP Address|
|宛先 IP アドレス/CIDR 範囲|10.0.0.4 (仮想マシンのプライベートIPアドレス)|
|サービス|Custom|
|宛先ポート範囲|8000|
|プロトコル|TCP|
|アクション|許可|
|優先度|100|
|名前|AllowCidrBlockCustom8000Inbound|
|説明||

Ⅱ.Bastionからの接続を許可します。
|設定|値|
|:-|:-|
|ソース|IP Address|
|ソース IP アドレス/CIDR 範囲|10.0.1.0/26 (Bastionのサブネット)|
|ソース ポート範囲|*|
|宛先|IP Address|
|宛先 IP アドレス/CIDR 範囲|10.0.0.4 (仮想マシンのプライベートIPアドレス)|
|サービス|SSH|
|宛先ポート範囲|22|
|プロトコル|TCP|
|アクション|許可|
|優先度|110|
|名前|AllowCidrBlockSSHInbound|
|説明||

Ⅲ.それ以外の通信をすべて拒否します。

|設定|値|
|:-|:-|
|ソース|Any|
|ソース ポート範囲|*|
|宛先|Any|
|サービス|Custom|
|宛先ポート範囲|*|
|プロトコル|Any|
|アクション|拒否|
|優先度|4096|
|名前|DenyAnyCustomAnyInbound|
|説明||

5\. それぞれ [保存] をクリックしNSGを更新します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330959/14f68ee5-ce73-4df2-91ba-9519767d251f.png)

その後、WebブラウザでのアクセスおよびBastionからの接続を行い、接続を許可されているもののみが接続でき、そうでないものは接続できないことを確認してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330959/9ba9f283-07fd-4a7c-888a-6af03cde77a1.png)


# 未使用時の停止と再開
Application Gatewayは、停止と起動が可能なネットワークリソースになっています。
このためツールの未使用時にApplication Gatewayを停止しておく場合は、次の操作で停止が可能です。
1\. 停止を行うApplication Gatewayを選択します。
2\. 左メニューの [オートメーション] にある [CLI / PS] をクリックします。
3\. [CLI] タブにある [az network application-gateway stop　アプリケーション ゲートウェイを停止します。] をクリックして展開します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330959/5c1ce1dd-514f-4c56-a09d-30a1009bddb0.png)
4\. [実行] ボタンをクリックします。
これによりCloud Shellが起動し、停止を行うazコマンドを代わりに実行してくれます。

```bash
Cloud Shell を要求しています。Succeeded. 
Connecting terminal...

Your Cloud Shell session will be ephemeral so no files or system changes will persist beyond your current session.
USER [ ~ ]$ az network application-gateway stop --resource-group rg-getAzureUpdate --name myAppGateway --subscription <サブスクリプションID>
USER [ ~ ]$ 
```
同様に、起動も[az network application-gateway start　アプリケーション ゲートウェイを開始します。]より可能です。(停止に比べて時間がかかります)

なおCloud Shellの初回実行時に次のような画面が表示されます。
今回のコマンドは[Bash]なのでそれを選択した次の画面で、Shellのファイル管理を行うストレージアカウントが確認されますが、必要に応じて選択をした後でコマンドが実行されます。(Bash/PowerShellの切り替えはあとで可能です)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330959/075a997d-3ef1-4f77-91be-c01179251ad1.png)

# おわりに
後半はツールというよりAzureリソースのみでパブリックで安全にツールを使える状態にするところを細かめの手順で説明させていただきました。キーコンテナで証明書を保持し、フロントエンドをSSLにするなどもう少し改善できる点はありますが、さらに今後の対応とさせていただきたいと思います。

ここまでお読みいただきありがとうございました。