🍇

ARS + NVA(Quagga) で Azure ExpressRoute を経由したオンプレミス拠点間の通信

2023/07/15に公開2

はじめに

複数のオンプレミスの拠点が、複数の ExpressRoute 回線で Azure と接続されているという場合で、オンプレミス拠点間の通信をどう実現するか、検討します。


複数のオンプレミス拠点が ExpressRoute で Azure と繋がっている構成

推奨される方法

まず、原則としては、 公開ドキュメント でも記載されている通り、

  • ExpressRoute をトランジットルーターとして構成することはできません。
  • トランジット ルーティング サービスについては、接続プロバイダーに依存する必要があります。

ということで、オンプレミスの異なる拠点間を通信させる場合、基本的にはAzure 外での折り返しを(プロバイダー様/WAN回線網内での折り返しを)検討するのが推奨です。


WAN回線網内での折り返し

それでもやはりオンプレミス拠点間の通信を ExpressRoute 経由で行いたい! という場合には、ExpressRoute Global Reach というオプションを利用することで、オンプレミス拠点間の通信を ExpressRoute を経由して行うことができます。
ちなみに、Virtual WAN を利用する場合でも同様に Global Reach を用いなければ、オンプレミス拠点間の通信はできません。(公開ドキュメント


ExpressRoute Global Reach

なお ExpressRoute Global Reach は、異なる Location 間(上記例のように、Tokyo と Tokyo2 など)の場合でしか利用することはできないという制限があります。
同一 Location の場合には、ExpressRoute Global Reach は利用できないため、基本的には Azure を介してのオンプレミス間の通信はできません。
Location (ExpressRoute の場所) については、詳しくは 公開ドキュメント を参照していただければと思いますが、日本で選択できるのは、2023年7月現在 Tokyo, Tokyo2, Tokyo3, Osaka の 4箇所 となっています。


同一Location では ExpressRoute Global Reach は利用できない

ということで、
改めて推奨を整理すると

  • トランジット ルーティング サービスについては、接続プロバイダー様のサービスを利用することが推奨。
  • 接続プロバイダー様のWANの外にある一部ブランチオフィスを接続する場合等、接続プロバイダー様のサービスを補完する目的で ExpressRoute Global Reach がある。
  • ExpressRoute Global Reach は、異なる Location 間の通信を実現することができるが、同一 Location の場合には利用できない。

ということになります。

でもなんとか、無理やりでも、方法ない・・・?

接続プロバイダー様のトランジットサービスも、Global Reach も使えない場合、もう残された手はないでしょうか…?

決して推奨したい方法ではありませんが、Azure Route Server + NVA (今回はQuaggaを使います) で、一応、 接続することはできます。

こちらの 公開ドキュメント に、参考となる情報があります。
ということで今回は、NVA が、疎通をさせたい オンプレミス 2拠点のプレフィックスを含むスーパーネット(一番極端な例では 0.0.0.0/0) をアドバタイズすることで、本来は広報されないはずの対向オンプレミス拠点の経路情報を流し、オンプレミス拠点間の通信を実現させてみたいと思います。

やってみる

Azure Route Server (ARS) を作成する

まずは Azure Route Server の作成から開始します。

https://learn.microsoft.com/ja-jp/azure/route-server/quickstart-configure-route-server-portal

Azure Portal から [ルートサーバ―] と検索して、ルートサーバーを作成します。

ルート サーバーの作成ページで、必要な情報を入力して作成を行います。
リソースグループ や 仮想ネットワーク は、ExpressRoute Gateway がある リソースグループ や 仮想ネットワーク を選択します。
また、サブネット名は必ず RouteServerSubnet で /29 以上である必要があります。(無い場合には作成する画面に遷移できます。)

作成にはある程度(今回は 16分程でした)時間がかかります。
作成が完了したら、Route Server の IP アドレスを確認しておきます。

NVA (Quagga VM) の作成 と 設定

今回は、NVA として Quagga を導入した VM を構築してみます。

https://learn.microsoft.com/ja-jp/azure/route-server/tutorial-configure-route-server-with-quagga#configure-quagga-virtual-machine

Azure Portal から 仮想マシンの作成 を行います。
OS は Ubuntu 20.04 LTS を選択しました。

作成が完了して、SSH でログインできるようになったら、接続をして Quagga をインストールしていきます。

Quagga のインストール用スクリプトは、公開ドキュメントに記載されていますが、以下にも置いておきます。
ただし、インストールする際には編集が必要な箇所があります。
以下の変数部分、各変数の用途に応じて、適宜変更してください。
例には、今回の構成で設定した値を記載しています。

  • bgp_routerId  : QuaagaVMのPrivateIP  (例:10.200.0.4)
  • bgp_network1-3 :広報するネットワーク (例:10.100.0.0/19)
  • routeserver_IP1-2 :BGP neighbor / RouteServerのIP (例:10.200.2.4, 10.200.2.5)

Quagga のインストール用スクリプト - 全文 -
Quagga のインストール用スクリプト
#!/bin/bash

## NOTE:
## before running the script, customize the values of variables suitable for your deployment. 
## asn_quagga: Autonomous system number assigned to quagga
## bgp_routerId: IP address of quagga VM
## bgp_network1: first network advertised from quagga to the router server (inclusive of subnetmask)
## bgp_network2: second network advertised from quagga to the router server (inclusive of subnetmask)
## bgp_network3: third network advertised from quagga to the router server (inclusive of subnetmask)
## routeserver_IP1: first IP address of the router server 
## routeserver_IP2: second IP address of the router server

asn_quagga=65001
bgp_routerId=10.200.0.5
bgp_network1=10.100.0.0/19
routeserver_IP1=10.200.2.4
routeserver_IP2=10.200.2.5


sudo apt-get -y update

## Install the Quagga routing daemon
echo "Installing quagga"
sudo apt-get -y install quagga

##  run the updates and ensure the packages are up to date and there is no new version available for the packages
sudo apt-get -y update --fix-missing

## Enable IPv4 forwarding
echo "net.ipv4.conf.all.forwarding=1" | sudo tee -a /etc/sysctl.conf 
echo "net.ipv4.conf.default.forwarding=1" | sudo tee -a /etc/sysctl.conf 
sysctl -p

## Create a folder for the quagga logs
echo "creating folder for quagga logs"
sudo mkdir -p /var/log/quagga && sudo chown quagga:quagga /var/log/quagga
sudo touch /var/log/zebra.log
sudo chown quagga:quagga /var/log/zebra.log

## Create the configuration files for Quagga daemon
echo "creating empty quagga config files"
sudo touch /etc/quagga/babeld.conf
sudo touch /etc/quagga/bgpd.conf
sudo touch /etc/quagga/isisd.conf
sudo touch /etc/quagga/ospf6d.conf
sudo touch /etc/quagga/ospfd.conf
sudo touch /etc/quagga/ripd.conf
sudo touch /etc/quagga/ripngd.conf
sudo touch /etc/quagga/vtysh.conf
sudo touch /etc/quagga/zebra.conf

## Change the ownership and permission for configuration files, under /etc/quagga folder
echo "assign to quagga user the ownership of config files"
sudo chown quagga:quagga /etc/quagga/babeld.conf && sudo chmod 640 /etc/quagga/babeld.conf
sudo chown quagga:quagga /etc/quagga/bgpd.conf && sudo chmod 640 /etc/quagga/bgpd.conf
sudo chown quagga:quagga /etc/quagga/isisd.conf && sudo chmod 640 /etc/quagga/isisd.conf
sudo chown quagga:quagga /etc/quagga/ospf6d.conf && sudo chmod 640 /etc/quagga/ospf6d.conf
sudo chown quagga:quagga /etc/quagga/ospfd.conf && sudo chmod 640 /etc/quagga/ospfd.conf
sudo chown quagga:quagga /etc/quagga/ripd.conf && sudo chmod 640 /etc/quagga/ripd.conf
sudo chown quagga:quagga /etc/quagga/ripngd.conf && sudo chmod 640 /etc/quagga/ripngd.conf
sudo chown quagga:quaggavty /etc/quagga/vtysh.conf && sudo chmod 660 /etc/quagga/vtysh.conf
sudo chown quagga:quagga /etc/quagga/zebra.conf && sudo chmod 640 /etc/quagga/zebra.conf

## initial startup configuration for Quagga daemons are required
echo "Setting up daemon startup config"
echo 'zebra=yes' > /etc/quagga/daemons
echo 'bgpd=yes' >> /etc/quagga/daemons
echo 'ospfd=no' >> /etc/quagga/daemons
echo 'ospf6d=no' >> /etc/quagga/daemons
echo 'ripd=no' >> /etc/quagga/daemons
echo 'ripngd=no' >> /etc/quagga/daemons
echo 'isisd=no' >> /etc/quagga/daemons
echo 'babeld=no' >> /etc/quagga/daemons

echo "add zebra config"
cat <<EOF > /etc/quagga/zebra.conf
!
interface eth0
!
interface lo
!
ip forwarding
!
line vty
!
EOF


echo "add quagga config"
cat <<EOF > /etc/quagga/bgpd.conf
!
router bgp $asn_quagga
 bgp router-id $bgp_routerId
 network $bgp_network1
 neighbor $routeserver_IP1 remote-as 65515
 neighbor $routeserver_IP1 soft-reconfiguration inbound
 neighbor $routeserver_IP2 remote-as 65515
 neighbor $routeserver_IP2 soft-reconfiguration inbound
!
 address-family ipv6
 exit-address-family
 exit
!
line vty
!
EOF

## to start daemons at system startup
echo "enable zebra and quagga daemons at system startup"
systemctl enable zebra.service
systemctl enable bgpd.service

## run the daemons
echo "start zebra and quagga daemons"
systemctl start zebra 
systemctl start bgpd  

編集したら、全文コピーし、張り付けて実行します。こんな感じ。

1分もかからずに完了するかと思います。
Quagga をインストールしたら、vtysh と入力し、Quagga のコンソールに入ります。
show run コマンドで、設定を確認可能です。
もし変更が必要な場合は、conf t (configure terminal) で設定変更モードへ入れますので、設定変更したいインタフェース等を <Router> – <BGP> – <ASN> で指定などすれば、設定変更が可能です。

Quagga のコンソールから抜ける場合は、exit と入力します。

ARS の設定

Quagga の設定が完了したら、ARS の設定を行います。

Quagga との BGP ピアの設定を行います。
左側メニュー [ピア] を選択し、[+追加] から追加が可能です。
Quagga に設定した BGP の ASN と、Quagga の IPアドレス を入力し、[OK] をクリックします。

5分程で、プロビジョニングが完了しました。

続いて、ExpressRoute Gateway とのピアリングを行います。
左側メニュー [構成] を選択し、ブランチ間 を 有効 にします。
ブランチ間 を 有効 とすることで、同一VNet内の ExpressRoute ゲートウェイ や VPN ゲートウェイ と、ルート交換ができます

これで構成は終わりです。

確認

オンプレミス拠点1 (10.100.10.0/24) と オンプレミス拠点2 (10.100.20.0/24) 間の通信を確認してみましょう。
Azure側(10.200.1.0/24 GatewaySubnet)を介して、通信できていることが確認できました。

tracert 拠点1 → 拠点2
C:\Windows\System32>tracert -d 10.100.10.10
10.100.10.10 へのルートをトレースしています。経由するホップ数は最大 30 です

  1    <1 ms    <1 ms    <1 ms  10.100.20.1
  2     *        *        *     要求がタイムアウトしました。
  3     4 ms     5 ms     4 ms  10.200.1.6
  4     *        *        *     要求がタイムアウトしました。
  5     5 ms     5 ms     4 ms  10.100.10.10

トレースを完了しました。
tracert 拠点2 → 拠点1
C:\Windows\System32>tracert -d 10.100.20.2
10.100.20.2 へのルートをトレースしています。経由するホップ数は最大 30 です

  1    <1 ms    <1 ms    <1 ms  10.100.10.1
  2     *        *        *     要求がタイムアウトしました。
  3     5 ms     5 ms     4 ms  10.200.1.4
  4     *        *        *     要求がタイムアウトしました。
  5     5 ms     21 ms    6 ms  10.100.20.2

トレースを完了しました。

まとめ

今回は、Azure Route Server と NVA(Quagga) を利用して、オンプレミス拠点間の通信を確認してみました。
今回の構成は、NVA が スーパーネット(今回の例では 10.100.0.0/19) を広報しており、意図しない(例えば VNet からの)通信を引き付ける可能性があります。

なお、他の実現パターンとしては、公開ドキュメントでは以下、

https://learn.microsoft.com/ja-jp/azure/azure-vmware/concepts-network-design-considerations#transit-spoke-virtual-network-topology

また、以下なども参考になります。

https://zenn.dev/microsoft/articles/spoke-hairpin

ただし、構成が複雑になる点や、NVA が停止するとオンプレミス拠点間の通信ができなくなってしまう点など、不安がある構成ですので、改めて、接続プロバイダー様のサービスの利用と、Global Reach をおススメさせて頂きます。

以下、ルートテーブル等の情報

オンプレミス拠点 の ルーター の ルートテーブル を確認してみます。
Quagga で広報した 10.100.0.0/19 が Azure から受け取れていることが確認できました。

オンプレミス拠点 の ルーター の ルートテーブル と BGP
オンプレミスルータ(拠点2) show ip route の結果
Router#show ip route
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2
       i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
       ia - IS-IS inter area, * - candidate default, U - per-user static route
       o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP
       a - application route
       + - replicated route, % - next hop override

Gateway of last resort is not set

      10.0.0.0/8 is variably subnetted, 4 subnets, 4 masks
B        10.100.0.0/19 [20/0] via 172.16.0.10, 01:06:05
C        10.100.20.0/24 is directly connected, Vlan20
L        10.100.20.1/32 is directly connected, Vlan20
B        10.200.0.0/16 [20/0] via 172.16.0.10, 03:43:06
      172.16.0.0/16 is variably subnetted, 2 subnets, 2 masks
C        172.16.0.8/30 is directly connected, GigabitEthernet9.722
L        172.16.0.9/32 is directly connected, GigabitEthernet9.722
Router#
Router#
オンプレミスルーター(拠点2) show bgp の結果
Router#show bgp
BGP table version is 4, local router ID is 172.16.0.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,
              x best-external, a additional-path, c RIB-compressed,
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found

     Network          Next Hop            Metric LocPrf Weight Path
 *>  10.100.0.0/19    172.16.0.10                            0 12076 i
 *>  10.100.20.0/24   0.0.0.0                  0         32768 i
 *>  10.200.0.0/16    172.16.0.10                            0 12076 i
Router#

また、Quagga の show ip bgp の結果を確認してみます。
オンプレミス拠点1 および オンプレミス拠点2 のルーターから広報された 10.100.10.0/24 と 10.100.20.0/24 が、Route Server (AS 65515) および ExpressRoute (AS 12076) の先にある確認できます。

Quaggat の ルートテーブル と BGP
show ip route
quaggavm01# show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,
       O - OSPF, I - IS-IS, B - BGP, P - PIM, A - Babel, N - NHRP,
       > - selected route, * - FIB route

K>* 0.0.0.0/0 via 10.200.0.1, eth0, src 10.200.0.5
C>* 10.200.0.0/24 is directly connected, eth0
C>* 127.0.0.0/8 is directly connected, lo
K>* 168.63.129.16/32 via 10.200.0.1, eth0, src 10.200.0.5
K>* 169.254.169.254/32 via 10.200.0.1, eth0, src 10.200.0.5
quaggavm01#
show ip bgp の結果
quaggavm01#
quaggavm01# show ip bgp
BGP table version is 0, local router ID is 10.200.0.5
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
              i internal, r RIB-failure, S Stale, R Removed
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
*> 10.100.0.0/19    0.0.0.0                  0         32768 i
   10.100.10.0/24   10.200.2.4                             0 65515 12076 65150 i
                    10.200.2.5                             0 65515 12076 65150 i
   10.100.20.0/24   10.200.2.4                             0 65515 12076 65151 i
                    10.200.2.5                             0 65515 12076 65151 i
   10.200.0.0/16    10.200.2.4                             0 65515 i
                    10.200.2.5                             0 65515 i

quaggavm01#

ExpressRoute 回線のルートテーブルも残しておきます。

ExpressRoute Circuit(拠点2) の ルートテーブル

参考URL

https://zenn.dev/microsoft/articles/spoke-hairpin

https://learn.microsoft.com/ja-jp/azure/azure-vmware/concepts-network-design-considerations#supernet-design-topology

https://learn.microsoft.com/ja-jp/azure/azure-vmware/concepts-network-design-considerations#transit-spoke-virtual-network-topology

https://learn.microsoft.com/ja-jp/azure/route-server/tutorial-configure-route-server-with-quagga

https://learn.microsoft.com/ja-jp/azure/route-server/quickstart-configure-route-server-portal

Microsoft (有志)

Discussion