Azure上のVMのDefault Gatewayをオンプレミスに向けてみる(強制トンネリング、Forced Tunneling)

こんにちわ。
世間はIgniteで盛り上がっていますが、まだ内容を確認できていないので平常運転でいきます。
Qiita内で「強制トンネリング」と検索してもヒットしなかったので書いてみます。

#Azure上のVMのDefault Gatewayをオンプレミスに向けたい場合
Azure上のVMのDefault Gatewayをオンプレミスに向ける、これを日本語では<font color="red">強制トンネリング</font>、英語では<font color="red">Forced Tunneling</font>と言います。
本記事では以降用語を<font color="red">強制トンネリング</font>で統一します。
設定方法や概念は公式ドキュメントだと[ここ](https://docs.microsoft.com/ja-jp/azure/vpn-gateway/vpn-gateway-forced-tunneling-rm)に記載があります。
過去にも何度かお客様環境に実装したことのある構成ですので、今回弊社環境でデモ環境を作ってみます。

#強制トンネリングはどういう環境になるのか？
強制トンネリングとはAzure上のネットワーク構成、特にDefault Gatewayに関するルーティング構成です。
強制トンネリングでない通常の構成では、<font color="red">Azure上のVMはAzureから直接インターネットに接続しています。</font>
先ほどの公式ドキュメントにも構成図があるのですが、本記事でも簡単に作成してみました。

##通常構成
まずは比較の為強制トンネリングでない、通常の構成を記載します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/ca9c02d3-66d0-de24-61ca-82561eae28e1.png)

はい。
<font color="red">「Azure上のVMはAzureからインターネットに直接接続しています。」</font>
という言葉を構成図にするとこうなります。
この構成を本記事では便宜上「通常構成」と呼びます。

##強制トンネリング構成
それでは本題の強制トンネリングの構成です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/0a3db439-aaa7-2241-f912-444e0acccc74.png)
はい。
このようにAzure上のVMからのインターネット通信が一度オンプレミスのルーターに転送され、オンプレミスのルーターからインターネット接続する経路になります。
本記事の[強制トンネリングはどういう環境になるのか？](https://qiita.com/drafts/c6da30484e3dda87e7b1/edit#%E5%BC%B7%E5%88%B6%E3%83%88%E3%83%B3%E3%83%8D%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%AF%E3%81%A9%E3%81%86%E3%81%84%E3%81%86%E7%92%B0%E5%A2%83%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%AE%E3%81%8B)で述べた「Default Gatewayに関するルーティング構成」ということになります。

#強制トンネリングのメリットとデメリット
まずはメリットから
##強制トンネリングのメリット
・Azure上のVMもオンプレミスのマシンも、共通のルーター、Firewall、UTMからインターネット接続を行うため、ポリシーの一元管理が容易にできる。
これは小規模だとあまり感じないかもしれませんが、大規模になると結構響いてきます。
例えば10拠点あるネットワーク環境を想定し、それぞれの拠点からインターネット接続を行っている場合を考えてみてください。
同じネットワークポリシー、例えばQiitaには接続してもいいがFacebookは接続NG、のような接続先を絞るネットワークポリシーが存在する場合、10拠点バラバラでインターネット接続を行っていれば、ネットワークポリシー変更時に10台のネットワーク機器で同じ設定を行わなければなりません。(最近一元管理のサービスも出てきていますので一概には言えませんが・・・)
これが1拠点のネットワーク機器から集約してインターネット接続を行っている環境であれば、1台のネットワーク機器の設定変更で済みます。
<font color="red">設定変更漏れの危険性が低くなる</font>というメリットが考えられます。
この10拠点のうち、1拠点がAzureであると考えればメリットを感じてもらえると思います。

##強制トンネリングのデメリット
・Azure上のVMがインターネット接続を行う度にダウンロード課金がかかる。
これは結構致命的です。
Azure上にServerマシンしかない場合はWindows Updateやapt-update、apt-upgrade(yumも含む)のみの通信となりますので、かかる課金はある程度絞れると思いますが、それでも課金はかかります。
Windows Serverの場合はAzure上にWSUSを、Linuxの場合はローカルリポジトリを構築すればよりUpdateによる課金は絞れると思います。
しかしAzure上にAVDを構築する場合はダウンロード課金がえらいことになってしまいます。
・Azure上のVMがインターネット接続を行う度に、VPN接続帯域が圧迫される。
これもダウンロード課金と同じ原理で、VPN接続部分に負荷がかかるからです。
Azure上のVMにファイルサーバーがある場合、オンプレミスからVPN接続を介したAzureへの「上り」の通信と、Azure上のVMからインターネット接続を行う際の「下り」の通信がVPN接続部分に同時に発生します。
通信が輻輳しますね。

#強制トンネリングを選択するか否か
メリットとデメリットを比べてみるとデメリットの方が大きく見えるのですが、<font color="red">Azure上のVMがServerマシンしかなく、推奨されませんがAzure上のUpdateを停止した状態</font>であればデメリットはなく、メリットの方が大きくなります。
ですので強制トンネリングの需要は一定ある、ということになります。

#検証
では検証していきましょう。
前出の[公式ドキュメント](https://docs.microsoft.com/ja-jp/azure/vpn-gateway/vpn-gateway-forced-tunneling-rm)ではPowerShellで仮想ネットワークやVPN構築からゴリゴリ行っていますが、VPN構築までは構築済みと考えて、そこからGUIでできる部分はGUIで、PowerShellでないとできない部分はPowerShellでと、作業を分けて構築しましょう。

##現状確認
まずは通常構成になっているかの確認です。
以前の記事、[NSGでWindows Updateを許可する方法](https://qiita.com/hidekko/items/9351f56a512bf193071b)で構築した環境のWindows 11が残っているので、これで確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/85125729-82d1-b9e4-d982-466520b93c5f.png)

オンプレミス環境からWindows 11にインターネット経由でRDP接続しました。
画像の<font color="red">赤枠</font>にご注目ください。
RDPの接続先グローバルIPアドレスと、いつもお世話になっている[確認くん](https://www.ugtop.com/spill.shtml)というサイトで確認したグローバルIPアドレスが合致していることがわかります。
これで通常の構成、つまり<font color="red">Azure上のVMであるこのWindows 11は、Azure上からインターネットに接続している</font>、ということがわかります。
またオンプレミス環境宛のICMP通信(Ping)も元気に返答がある状態なので、VPN接続ができていることも確認できます。

#設定
前出の[公式ドキュメント](https://docs.microsoft.com/ja-jp/azure/vpn-gateway/vpn-gateway-forced-tunneling-rm)内の以下の<font color="red">赤枠</font>部分は現在はGUIで設定可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/6a777a35-8141-c747-72f0-2f37c6324bef.png)
それでは設定していきましょう。

##GUI設定
[ルートテーブル]というサービスを呼び出し設定を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/196d9130-5c86-68f4-bb6b-7f67926f15a2.png)
ここでの肝は[リージョン]と[ゲートウェイのルートを伝達する]を[Yes]にすることです。
[リージョン]は強制トンネリングを設定したいサブネットが存在する仮想ネットワークの構築されているリージョンを選択します。
[ゲートウェイのルートを伝達する]は情報ボタンにホバーしてみると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/a407db4f-ed5b-dd22-143f-b17b9a02108e.png)

[関連付けられたサブネットのネットワークインターフェースへのオンプレミスのルートの伝達を回避するには[いいえ]を選択します。]と出てきます。
詳細情報の[リンク](https://docs.microsoft.com/ja-jp/azure/virtual-network/virtual-networks-udr-overview#next-hop-types-across-azure-tools)もあり、ますが、このリンクの記載は正直あまり関連性がありません。
このリンク先の項目の下の項目、[ボーダーゲートウェイプロトコル(BGPというルーティングプロトコルのこと)]の方がこのパラーメーターとの関係性が近いです。
詳細情報の[リンク](https://docs.microsoft.com/ja-jp/azure/virtual-network/virtual-networks-udr-overview#next-hop-types-across-azure-tools)の全体の流れと、この[ゲートウェイのルートを伝達する]のパラメーターとの関連性を私なりに解釈して説明すると、Azureの仮想ネットワークの持つBGPのルートテーブルをオンプレミスに広報するか否か、という設定値です。
今回スタティックでルートを設定するのであまり関連性が無いように見えますが、オンプレミス側のルート設定もBGPで設定するなら[Yes]が必須の設定となります。
ここまで確認が終ればもう[確認及び作成]からデプロイしましょう。

##GUIでのルーティング設定
先ほど作成したルートテーブルにルーティングを設定し、強制トンネリングを有効にしたいサブネットに関連付けます。
まずはルーティング設定から行います。
先ほど作成したルートテーブルを選択し、[ルート]を選択して[追加]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/b40bf36d-f228-20c7-0fc0-060297eb5bd8.png)

そしてこの設定がかなり大事です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/6d5d5437-62ba-44ce-b802-e4fb5dec5bd5.png)
<font color="red">[アドレス プレフィックス:0.0.0.0/0]</font>
<font color="red">[ネクストホップの種類:仮想ネットワークゲートウェイ]</font>
どっちも大事なので<font color="red">赤字</font>です。
それぞれの意味ですが、
・アドレスプレフィックス:0.0.0.0/0
これは宛先IPアドレスの指定です。
通常は192.168.0.1/32や172.16.0.0/24など、ホストやネットワークアドレスを指定する設定値です。
この設定値をここで行っているように0.0.0.0/0にするとどうなるか、と言うと、<font color="red">ルーター上に明示的に記載の無いアドレス全て</font>という意味になります。
ネットワークエンジニアにはお馴染みの設定値なんですけどね。
これがDefault GatewayのDefault、を意味する部分になります。
・ネクストホップの種類:仮想ネットワークゲートウェイ
こちらは読んで字の如く、ネクストホップにどこを指定するのか、という設定値です。
これを仮想ネットワークゲートウェイ、とすると、先の設定値と合わせて、<font color="red">0.0.0.0/0に合致するIPアドレスは全て仮想ネットワークゲートウェイに転送する</font>という意味になります。
これで<font color="red">Default Gatewayを仮想ネットワークゲートウェイに向ける</font>という今回の作業の前半戦は終了です。
『「Default Gateway」ってなんなの？』
という方に簡単にご説明すると、<font color="red">ルートテーブル上に明示的に記載の無いアドレスすべての転送先</font>ということになります。
これで[OK]をクリックして正しく設定が反映されたか確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/077a0dbe-b11e-9c1b-18fc-01b239448458.png)
続いて[サブネット]をクリックします。
[関連付け]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/9a12cc32-b5cb-f899-7fd8-1a5677e60d1b.png)
以下の画面で強制トンネリング設定を行いたい仮想ネットワーク及びサブネットを指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/49c4b235-be60-5592-6933-d8432ce1b3fd.png)
これでGUIでの設定は完了です。

そしてこの設定を行った瞬間にグローバルIPアドレス経由のRDPは切断されます。
Azure上のDefault Gatewayの設定が変わったので当然なのですが、事前に仕組みをわかっていないと焦りますね。
ちなみにこの状態でVMのローカルIPアドレス宛にRDP接続すると接続可能で、VMがインターネットに出れなくなっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/ae3be5b8-caa1-0bae-1758-1a833577c25e.png)


こんな状態ですね。
なんでVPNが接続されたままでVMがインターネット接続できないかというと、単純に本記事の設定が完了していないからなのですが、次の項目のPowerShell設定を行わないと、<font color="red">VMの存在するサブネットのDefault Gatewayは仮想ゲートウェイを向いているが、その更にネクストホップが存在しないから</font>なのです。

##PowerShell設定
ここからPowerShellでの設定になります。
PowerShellでの設定はとっても簡単。

```DefaultGateway設定変更.sh
$rgName = "[リソースグループ名]"
$LGName = "[ローカルネットワークゲートウェイ名]"
$vgName = "[仮想ネットワークゲートウェイ名]"

$LocalGateway = Get-AzLocalNetworkGateway -Name $LGName -ResourceGroupName $rgName
$VirtualGateway = Get-AzVirtualNetworkGateway -Name $vgName -ResourceGroupName $rgName
Set-AzVirtualNetworkGatewayDefaultSite -GatewayDefaultSite $LocalGateway -VirtualNetworkGateway $VirtualGateway
```
これだけです。
それぞれのコマンドを説明していきますと、最初の3行は言わずもがな変数設定です。
実際の設定コマンド、4行目の\$LocalGatewayですが、これはVPN接続設定時に作成する[ローカルネットワークゲートウェイ]というリソースを指定しています。
5行目、\$VirtualGatewayですが、これもVPN接続設定時に作成する[仮想ネットワークゲートウェイ]というリソースを指定しています。
この[仮想ネットワークゲートウェイ]は先のGUIでの手順で指定した<font color="red">[ネクストホップの種類:仮想ネットワークゲートウェイ]</font>の<font color="red">仮想ネットワークゲートウェイ]</font>と同一です。

そして本記事の最大の目玉の設定値です。

6行目
Set-AzVirtualNetworkGatewayDefaultSite -GatewayDefaultSite \$LocalGateway -VirtualNetworkGateway \$VirtualGateway
大事な部分を赤字で表現すると
Set-AzVirtualNetworkGatewayDefaultSite <font color="red">-GatewayDefaultSite $LocalGateway</font> -VirtualNetworkGateway \$VirtualGateway
ここです。
これは4行目で指定したローカルゲートウェイを5行目で指定した仮想ネットワークゲートウェイに対して、Default SiteにVPN接続先のオンプレミス環境を指定する、という設定値です。
Default SiteというのはAzure独自の概念なのですが、Site、つまりVPN接続先を、Default Gateway(のネクストホップ)として指定する、という設定値です。
6行目のコマンドは設定してから返ってくるまで1分～2分ほど時間がかかりますので待ちましょう。
これでGUIで設定したサブネットのDefault Gatewayの更にネクストホップとしてオンプレミスのSite、ローカルネットワークゲートウェイが指定されました！
ここまででAzure側の設定は完了ですが、実はオンプレミス側でも設定が必要な場合があります。

##オンプレミス側の設定
これはオンプレミス側でどのような機器を使っているかによりますが、主にFirewall機能とNAT機能の設定変更が必要な場合があります。
先のPowerShell設定ができても、Azure上のWindows 11はこのような状態です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/1cb609c2-1e73-3656-b5d9-e2a017549da9.png)

分かりやすくするために8.8.8.8宛にもICMP通信を起こしてみました。
弊社はCiscoで検証を行ったので、Cisco側の設定変更を例として挙げます。
まずはCiscoのグローバルIPアドレスを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/3f94ea93-8d77-e656-4182-f3385566a21d.png)

<font color="red">赤枠内</font>ですね。
今回も図らずもグローバルIPアドレスをQiitaに晒してしまいました。

そしてCiscoに追加するConfigは以下の通りです。

```Ciscoに追加するConfig.txt
access-list 1 permit 172.16.101.0 0.0.0.255

interface Tunnel[AzureとVPNを張っているトンネルインターフェース番号]
ip nat inside
ip virtual-reassembly in
```
enableやconfiguration terminal、write memoryは省略していますので忘れずに実行してください。
またOutBound方向のFirewall設定なども適宜設定してください。
そしてこのConfigを追加したところ、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/963abf52-8284-93a1-eb9f-b269c87c3b1c.png)
このように無事にCiscoの持つグローバルIPアドレスとAzure上のWindows 11がブラウザに表示している[確認くん](https://www.ugtop.com/spill.shtml)のグローバルIPアドレスが一致していることからAzure上のVM、今回であればWindows 11がオンプレミスのCisco経由でインターネットに出ていることがわかります。
これで強制トンネリング環境の構築ができました。

#設定解除方法
GUI設定は作成したルートテーブルをサブネットから外し、削除してください。
PowerShellは以下のコマンドの実行が必要です。

```DefaultGateway切り戻し設定変更.sh
$LGName = "cisco841m"
$vgName = "vgw-nsg-test01"

Remove-AzVirtualNetworkGatewayDefaultSite -VirtualNetworkGateway $VirtualGateway
```

検証が終ったら忘れずに切り戻ししておきましょう。

今日はここまで。