🙌

S2S VPN でオンプレからのインターネット接続を Azure Firewall にブレークアウトする

2022/12/20に公開

これは何か

オンプレミスと Azure を接続するために VPN を利用できます。その際に一元的にアクセス制御をするために Azure 上のリソースだけでなく、オンプレミスからの通信についても Azure Firewall を通したいことがあります。本記事ではその方法を紹介します。

やりたいこと

  • オンプレミスと Azure を VPN(Site-to-Site) で接続したい
  • オンプレミスからインターネットへの通信も Azure Firewall を通したい
  • (おまけ) Azure 仮想マシン上の Squid を使ってインターネットへ出たい

構成のイメージ

方法

大きく分けて以下の 3 ステップで展開します。

  1. オンプレミスとAzure を VPN 接続する
  2. Azure Firewall を展開する
  3. Route Server を展開する

1. オンプレミスとAzure を VPN 接続する

VPN Gateway の展開後とオンプレミスのルーターと接続します。VPN Gateway の展開は時間がかかること以外は特筆することはありませんが、BGP と Active-Active を有効にしておきます。

以下は VPN Gateway の設定です。

以下はローカル ネットワーク ゲートウェイの設定です。

オンプレミスのルーター側では VPN をデフォルトゲートウェイにしておく必要があります。以下参考までに RTX810 の設定です。

こちらは IPSec の設定です。共有キーと VPN Gateway のグローバル IP アドレスを環境に合わせて設定します。

tunnel select 5
 tunnel name vngw-arm
 ipsec tunnel 5
  ipsec sa policy 5 5 esp aes256-cbc sha256-hmac anti-replay-check=off
  ipsec ike version 5 2
  ipsec ike duration child-sa 5 27000
  ipsec ike duration ike-sa 5 28800
  ipsec ike encryption 5 aes256-cbc
  ipsec ike group 5 modp1024
  ipsec ike hash 5 sha256
  ipsec ike keepalive use 5 on rfc4306
  ipsec ike local address 5 192.168.1.1
  ipsec ike local name 5 <オンプレミスのグローバル IP アドレス> ipv4-addr
  ipsec ike nat-traversal 5 on
  ipsec ike backward-compatibility 5 2
  ipsec ike pfs 5 on
  ipsec ike message-id-control 5 on
  ipsec ike child-exchange type 5 2
  ipsec ike pre-shared-key 5 text <共有キー>
  ipsec ike remote address 5 <VPN Gateway のグローバル IP アドレス>
  ipsec ike remote name 5 <VPN Gateway のグローバル IP アドレス> ipv4-addr
  ipsec ike negotiation receive 5 off
 ip tunnel tcp mss limit auto
 tunnel enable 5

BGP の設定です。オンプレミス側の BGP AS は 65050、VPN Gateway 側は 65515 としています。

bgp use on
bgp autonomous-system 65050
bgp log neighbor packet
bgp neighbor 1 65515 172.26.1.4 hold-time=30 gateway=tunnel5 local-address=192.168.1.1 ignore-capability=on
bgp router id 192.168.1.1
bgp import filter 1 include 192.168.0.0/16
bgp import 65515 static filter 1
bgp export filter 100 include 0.0.0.0/0
bgp export 65515 filter 100

ルーティングの設定です。VPN Gateway の BGP ピアのアドレス(172.26.1.4) にルーティングできるようにスタティックルートを書いておきます。 VPN Gateway の構成の画面から確認できます。

また、以下の設定ではフィルタ型ルーティングを使って、特定のホスト(192.168.2.112) からの通信を IPSec をデフォルトゲートウェイとして使うようにしています。

ip route default gateway tunnel 5 filter 5 gateway pp 1 filter 20 21 22 40 41 gateway pp 1 filter 9 12 11 gateway tunnel 1 filter 11
ip route 172.26.1.4 gateway tunnel 5
ip filter 5 pass 192.168.2.112/32 * * * *

2. Azure Firewall を展開する

Azure Firewall の展開はいつも通り行います。

3. Route Server を展開する

いよいよ Route Serve を展開します。Route Server の展開と同時に Route Server にルートを流し込むための NVA として FRRouting をインストールした仮想マシンも展開します。

FRRouting は以下の cloud-init でインストールします。以下の例では、Terraform の変数に FRRouting の設定ファイルの URL を指定しインストールと同時に設定もしています(設定例はこちら)。

また、「おまけ」で書いている Squid を使ったプロキシ通信をするために Squid もインストールしています。

#cloud-config
packages_update: true
packages_upgrade: true
packages:
  - squid
runcmd:
  - sed -i.org 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/' /etc/sysctl.conf
  - sysctl -p
  - curl -s https://deb.frrouting.org/frr/keys.asc | apt-key add -
  - FRRVER="frr-stable"
  - echo deb https://deb.frrouting.org/frr $(lsb_release -s -c) $FRRVER | tee -a /etc/apt/sources.list.d/frr.list
  - apt update && apt -y install frr frr-pythontools
  - sed -i.org 's/bgpd=no/bgpd=yes/' /etc/frr/daemons
  - curl -L ${var.frr_config_url} -o /etc/frr/frr.conf
  - systemctl restart frr
  - sudo sed -i.org 's/#http_access allow localnet/http_access allow localnet/' /etc/squid/squid.conf
  - sudo sed -i.org.2 -r 's/^#(acl localnet)/\1/g' /etc/squid/squid.conf
  - systemctl restart squid

以下は FRRouting の設定例です。

frr version 8.4.1
frr defaults traditional
log file /var/log/frr/debug.log
log stdout
log syslog
no ip forwarding
no ipv6 forwarding
service integrated-vtysh-config
!
ip route 172.26.3.0/24 172.26.0.1
!
router bgp 65001
 bgp router-id 172.26.0.4
 neighbor 172.26.3.4 remote-as 65515
 neighbor 172.26.3.4 ebgp-multihop 255
 neighbor 172.26.3.5 remote-as 65515
 neighbor 172.26.3.5 ebgp-multihop 255
 !
 address-family ipv4 unicast
  network 0.0.0.0/0
  neighbor 172.26.3.4 soft-reconfiguration inbound
  neighbor 172.26.3.4 route-map rmap-bogon-asns in
  neighbor 172.26.3.4 route-map rmap-azure-asns out
  neighbor 172.26.3.5 soft-reconfiguration inbound
  neighbor 172.26.3.5 route-map rmap-bogon-asns in
  neighbor 172.26.3.5 route-map rmap-azure-asns out
 exit-address-family
exit
!
bgp as-path access-list azure-asns seq 5 permit _65515_
bgp as-path access-list bogon-asns seq 5 permit _0_
bgp as-path access-list bogon-asns seq 10 permit _23456_
bgp as-path access-list bogon-asns seq 15 permit _1310[0-6][0-9]_|_13107[0-1]_
bgp as-path access-list bogon-asns seq 20 deny _65515_
bgp as-path access-list bogon-asns seq 25 permit ^65
!
route-map rmap-bogon-asns deny 5
 match as-path bogon-asns
exit
!
route-map rmap-bogon-asns permit 10
exit
!
route-map rmap-azure-asns deny 5
 match as-path azure-asns
exit
!
route-map rmap-azure-asns permit 10
 set ip next-hop 172.26.4.4
exit
!

結果

オンプレミス VM

tsubasa@ubuntu2004:~$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:15:5d:02:72:16 brd ff:ff:ff:ff:ff:ff
    inet 192.168.2.112/24 brd 192.168.2.255 scope global dynamic eth0 <----- フィルタでルーティングしている IP アドレス
       valid_lft 143025sec preferred_lft 143025sec
    inet6 2409:11:1ac0:c00:215:5dff:fe02:7216/64 scope global dynamic mngtmpaddr noprefixroute
       valid_lft 2591979sec preferred_lft 604779sec
    inet6 fe80::215:5dff:fe02:7216/64 scope link
       valid_lft forever preferred_lft forever
tsubasa@ubuntu2004:~$ curl ifconfig.me
20.18.215.19tsubasa@ubuntu2004:~$ <----- Azure Firewall の Public IP アドレス

Azure Firewall

Azure Firewall のログを見てみると、curl した際のログが記録されています。

AzureDiagnostics
| where msg_s contains "192."

オンプレミス ルーター(RTX)

172.26.0.0/16 が BGP で学習されていることが分かります。

RTX810# show ip route
Destination         Gateway          Interface       Kind  Additional Info.
default             -                 TUNNEL[5]    static  filter:5 <----- 特定のホストからのデフォルトルートフィルタで VPN にルート
default             -                    PP[01]    static  filter:20,21,22,40,41
default             -                    PP[01]    static  filter:9,12,11
default             -                 TUNNEL[1]    static  filter:11
172.26.0.0/16       -                 TUNNEL[5]       BGP  path=65515 <----- VPN Gateway から学習したルート
172.26.1.4/32       -                 TUNNEL[5]    static
192.168.1.0/24      192.168.1.1           VLAN1  implicit
192.168.2.0/24      192.168.2.2           VLAN2  implicit
192.168.3.0/24      192.168.1.122         VLAN1    static

BGP のピアが VPN Gateway の IP アドレスになっており、学習したルート、広報しているルートが確認できます。

RTX810# show status bgp neighbor
BGP neighbor is 172.26.1.4, remote AS 65515, local AS 65050, external link
  BGP version 4, remote router ID 172.26.1.4
  BGP state = Established, up for 00:04:30 <----- Established になっている
  Last read 00:00:06, hold time is 30, keepalive interval is 10 seconds
  Received 33 messages, 0 notifications, 0 in queue
  Sent 31 messages, 0 notifications, 0 in queue
  Connection established 1; dropped 0
  Last reset never
Local host: 192.168.1.1, Local port: 179
Foreign host: 172.26.1.4, Foreign port: 50467

RTX810# show status bgp neighbor 172.26.1.4 advertised-routes
Total routes: 3
*: valid route
  Network            Next Hop        Metric LocPrf Path
* 192.168.1.0/24     192.168.1.1                   65050 IGP
* 192.168.2.0/24     192.168.1.1                   65050 IGP
* 192.168.3.0/24     192.168.1.1                   65050 IGP


RTX810# show status bgp neighbor 172.26.1.4 received-routes
Total routes: 1
*: valid route
  Network            Next Hop        Metric LocPrf Path
* 172.26.0.0/16      0.0.0.0                       65515 IGP <----- VPN Gateway から学習したルート

VPN Gateway

BGP ピアの画面を見るとデフォルトルートが Route Server から学習したルートが確認できます。

NVA(FRRouting)

NIC の Effective routes を見るとデフォルトルートが Azure Firewall に向いていることが分かります。

FRRouring で BGP のルートを確認すると、0.0.0.0 を Azure Firewall を Next Hop として広報していることが分かります。

# 広報しているルート
vmnva# show ip bgp nei 172.26.3.4 advertised-routes
BGP table version is 5, local router ID is 172.26.0.4, vrf id 0
Default local pref 100, local AS 65001
Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
               i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes:  i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found

   Network          Next Hop            Metric LocPrf Weight Path
*> 0.0.0.0/0        172.26.4.4               0         32768 i <----- Azure Firewall を Next Hop として広報

Total number of prefixes 1

# 学習したルート
vmnva# show ip bgp nei 172.26.3.4 received-routes
BGP table version is 5, local router ID is 172.26.0.4, vrf id 0
Default local pref 100, local AS 65001
Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
               i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes:  i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found

   Network          Next Hop            Metric LocPrf Weight Path
*> 172.26.0.0/16    172.26.3.4                             0 65515 i
*> 192.168.1.0/24   172.26.3.4                             0 65515 65050 i
*> 192.168.2.0/24   172.26.3.4                             0 65515 65050 i
*> 192.168.3.0/24   172.26.3.4                             0 65515 65050 i

Total number of prefixes 4

参考までにこちらはルーティングテーブルです。

vmnva# show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,
       O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
       T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
       f - OpenFabric,
       > - selected route, * - FIB route, q - queued, r - rejected, b - backup
       t - trapped, o - offload failure

K>* 0.0.0.0/0 [0/100] via 172.26.0.1, eth0, src 172.26.0.4, 06:01:21
K>* 168.63.129.16/32 [0/100] via 172.26.0.1, eth0, src 172.26.0.4, 06:01:21
K>* 169.254.169.254/32 [0/100] via 172.26.0.1, eth0, src 172.26.0.4, 06:01:21
B>  172.26.0.0/16 [20/0] via 172.26.3.4 (recursive), weight 1, 06:01:16
  *                        via 172.26.0.1, eth0, weight 1, 06:01:16
                         via 172.26.3.5 (recursive), weight 1, 06:01:16
                           via 172.26.0.1, eth0, weight 1, 06:01:16
C>* 172.26.0.0/24 is directly connected, eth0, 06:01:21
S>* 172.26.3.0/24 [1/0] via 172.26.0.1, eth0, weight 1, 06:01:21
B>  192.168.1.0/24 [20/0] via 172.26.3.4 (recursive), weight 1, 05:44:08
  *                         via 172.26.0.1, eth0, weight 1, 05:44:08
                          via 172.26.3.5 (recursive), weight 1, 05:44:08
                            via 172.26.0.1, eth0, weight 1, 05:44:08
B>  192.168.2.0/24 [20/0] via 172.26.3.4 (recursive), weight 1, 05:44:08
  *                         via 172.26.0.1, eth0, weight 1, 05:44:08
                          via 172.26.3.5 (recursive), weight 1, 05:44:08
                            via 172.26.0.1, eth0, weight 1, 05:44:08
B>  192.168.3.0/24 [20/0] via 172.26.3.4 (recursive), weight 1, 05:44:08
  *                         via 172.26.0.1, eth0, weight 1, 05:44:08
                          via 172.26.3.5 (recursive), weight 1, 05:44:08
                            via 172.26.0.1, eth0, weight 1, 05:44:08

Route Server

Route Server の学習したルートを見てみます。

> $routes = @{
    RouteServerName = 'rs-example'
    ResourceGroupName = 'rg-azfw-vpngw-1220'
    PeerName = 'example-rs-bgpconnection'
}

> Get-AzRouteServerPeerLearnedRoute @routes | ft
LocalAddress Network   NextHop    SourcePeer Origin AsPath Weight
------------ -------   -------    ---------- ------ ------ ------
172.26.3.5   0.0.0.0/0 172.26.4.4 172.26.0.4 EBgp   65001   32768
172.26.3.4   0.0.0.0/0 172.26.4.4 172.26.0.4 EBgp   65001   32768

メトリックからは学習したルートの数が確認できます。NVA である 172.26.0.4 から 1つのルートを学習しています。

おまけ

Terraform

ここまで紹介してきた構成の Azure 側は以下の Terrform で展開できます。

Route Server / VPN Gateway / Azure Firewall の展開は若干デリケートな操作なので失敗することもありますがやり直すとうまくいくことがあります。。
途中で失敗した場合、リソースを一度削除するか、terraform import でリソースをインポートしてみてください。

Terraform は onprem_s2s-internet-via-azfw にあります。

Terraform で展開すると以下のリソースが作成されます。

terraform.tfvars で以下の変数を設定してください。必要に応じて、FRRouting の設定ファイルの URL を設定してください。デフォルトではこちらの設定ファイルを使用します。

terraform.tfvars
# リソース グループ名とリージョン
rg = {
  name     = "rg-azfw-vpngw-1220d"
  location = "japaneast"
}

# オンプレミス側の設定
onprem_network = {
  bgp_peering_address = "192.168.1.1"
  gateway_address     = "xxx.xxx.xxx.xxx"
  shared_key          = "share"
  bgp_asn             = 65050
}

# NVA VM 用の SSH 公開鍵
ssh_public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAAD......"

Squid

NVA VM には、FRRouting 以外に、Squid もインストールされます。

curl ifconfig.me -x http://172.26.0.4:3128 の様なコマンドでプロキシから出ていくことができます。
当然ながらデフォルトルートが Azure Firewall を向いていると IP アドレスは同じになります。

Microsoft (有志)

Discussion