[Microsoft][Cloud][Network] ローカルブレイクアウト失敗と立て直し

やっぱりトラブる。

前回の記事でやりたいことがやっとできた、めでたしめでたしと行きたかったのだけど、トラブルが起きたことにあとになって気づくと。

ことの発端はAzure ADの同期処理で、あの経路設定を入れてから何故か数日間に渡って同期ができていない。これはなぜか?ということで調べるのだけど、その原因がわからない。わからんなーわからんなーと思って調べてみると、どうも内部サーバセグメントからの発信においてMicrosoftの通信だけがどーしてもうまく外に出られない。Azure PortalにもいけないしOffice Portalにもいけない。

で、よくよく調べて分かったことが以下のようなこと。

OSPFがうまく制御できてないことに気づく。。。

実は私、OSPFが未だによく分かって無いところが多く、今回の場合DMZ帯にあるネットワークデバイスに対してSophos UTMからOSPF経路が伝達し、戻りパケットの経路が正しく構成されてなかったようで、具体的にはMicrosoft向けの通信で非対称ルートが構成されてしまったようです。

そのため、SYNチェックでパケットが弾かれてしまい、正しく通信できない状況が発生していました。急ごしらえの対応として、問題の発生したサーバに対してプロキシ設定を構成して対処しましたが、このままプロキシ設定で凌ぐのは無理があるなぁということで、ちょっと見直しをしました。

ちなみにこれ、恐らくちゃんとルートフィルター構成したらOSPFでももう少しまともに動くと思います。でも、ここ最近自宅サーバいじりに関しては少々コンディションが悪く、思考力がちょっと足りませんで・・・・

明示的に経路伝達するプロトコルを使おう

というわけで、余計なデバイスに経路伝搬しないように、OSPFではなく別のプロトコルを使おうと考えまして、iBGPを使うことにしました。実は昔Kubernetes + Project Calico の構成で外部からコンテナへアクセスできるように、以下の図のようなことをやった過去があります。

VyOS使った思い出

これで対応した時の思い出をもとに、各Router設定とスクリプト修正を行いました。

今回取り組む内容

こうしました。

やろうとしていること

VyOS側の設定

当時使ってたVyOSはKubernetesクラスタを解体したときにシャットダウンしていたのですが、まだ消さずにいました。よって、これを使ってBGPを実装することに。打ち込んだコマンドは以下の通り。

edit protocols bgp 65010
set parameters router-id 192.168.100.41
set neighbor 192.168.100.5 remote-as 65010
set neighbor 192.168.100.5 soft-reconfiguration inbound
set network 192.168.100.0/24
commit
save

ここで言う192.168.100.41はVyOSルーター、192.168.100.5はUntangleを指しています。なお、ブレイクアウトして送り込みたいNext-hopは192.168.100.4。Sophos UTM9を指しています。こいつが固定IPアドレスを持っているというわけでして。

Untangle FirewallとPeerを張る

こちらは、Untangle FirewallのGUIへログインし、Config⇒Advancedタブ⇒Dynamic Routingタブ⇒BGPタブへ移動して、以下のような感じの画面に移動する。ちょうど画面はPeer設定を追加するところでありますね。なお、この時OSPFの設定は無効化しています。

VyOS側でBGPの状態を確認する。

で、Untangle側で設定を保存すると、設定が反映されてpeerが張れます。VyOS側で確認した所、こんなふうになりました。

vyos@zenmai:~$ show ip bgp summary
BGP router identifier 192.168.100.41, local AS number 65010
IPv4 Unicast - max multipaths: ebgp 1 ibgp 1
RIB entries 139, using 13 KiB of memory
Peers 1, using 4560 bytes of memory

Neighbor        V    AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
192.168.100.5   4 65010     420     425        0    0    0 06:57:23        1

Total number of neighbors 1

Up TimeがカウントされていればとりあえずEstablished出来てそうです。

スクリプトの手直し

そして、前回構築したスクリプトを修正。

    cswitch_writer.write("configure\n")
    removeCount = 0
    addCount = 0

    for (action, ip) in removeFlatIps:
        addr_v4 = ipaddress.IPv4Network(ip)
        netaddr_v4 = addr_v4.network_address
        netmsk_v4 = addr_v4.netmask
        cswitch_writer.write("delete protocols static route " + str(addr_v4) + "\n")
        removeCount = removeCount + 1

    for (action, ip) in addFlatIps:
        addr_v4 = ipaddress.IPv4Network(ip)
        netaddr_v4 = addr_v4.network_address
        netmsk_v4 = addr_v4.netmask
        cswitch_writer.write("set protocols static route " + str(addr_v4) + " next-hop " + nexthop_v4addr + " distance 10 " + "\n")
        addCount = addCount + 1

    cswitch_writer.write("save\n")
    cswitch_writer.write("commit\n")

前回、IOSでは「ネットワークアドレス + サブネットマスク」形式でルートテーブルの追加を行ったわけですが、今回VyOSの場合はCIDR形式なので、IOSの時みたいなアドレス変換処理が不要です。そのため、コマンドに投入するネットワークアドレスはもとのCIDR形式のものを文字列変換して打ち込むだけになります。

また、Nexthopの指定は文字列としてnext-hopと言う文字列を挟む必要がありますので、その点を追加しているぐらいです。最後にsave/commitを記載していますが、こいつは不要でした。NAPALM上でcommit処理をする際にきちんとこうした処理も行っていることが確認できました。

次に修正するのはNAPALM処理周りです。実はほとんど変更していません。

    driver = napalm.get_network_driver('vyos')
    device = driver(
        hostname=cswitch_hostip,
        username=cswitch_username,
        password=cswitch_password)

    device.open()

    device.load_merge_candidate(filename=cmdfile_changes_tmp)
    pprint(device.compare_config())

    device.commit_config()
    device.close()

ネットワークドライバをvyosに変更したこと。ログイン設定のoptionを外したこと。この2点だけです。ただ、vyosドライバはこないだの時点ではまだインストールされていないんで、以下のコマンドでインストールしています。

pip3 install napalm-vyos

なお、インポートするライブラリの記載を変更する必要はありません。NAPALMが読み込まれていればとりあえず大丈夫です。

実行結果として、以下のように静的経路が追加されました。

S>* 13.64.196.27/32 [10/0] via 192.168.100.4, eth0
S>* 13.64.198.19/32 [10/0] via 192.168.100.4, eth0
S>* 13.64.198.97/32 [10/0] via 192.168.100.4, eth0
S>* 13.64.199.41/32 [10/0] via 192.168.100.4, eth0
S>* 13.76.218.117/32 [10/0] via 192.168.100.4, eth0
S>* 13.76.219.191/32 [10/0] via 192.168.100.4, eth0
S>* 13.76.219.210/32 [10/0] via 192.168.100.4, eth0
S>* 13.91.61.249/32 [10/0] via 192.168.100.4, eth0
S>* 13.91.98.185/32 [10/0] via 192.168.100.4, eth0
S>* 13.93.216.68/32 [10/0] via 192.168.100.4, eth0
S>* 13.93.233.42/32 [10/0] via 192.168.100.4, eth0
S>* 23.97.61.137/32 [10/0] via 192.168.100.4, eth0
S>* 23.97.150.21/32 [10/0] via 192.168.100.4, eth0
S>* 23.97.209.97/32 [10/0] via 192.168.100.4, eth0
S>* 23.99.109.44/32 [10/0] via 192.168.100.4, eth0
S>* 23.99.109.64/32 [10/0] via 192.168.100.4, eth0
S>* 23.99.116.116/32 [10/0] via 192.168.100.4, eth0
S>* 23.99.121.207/32 [10/0] via 192.168.100.4, eth0
S>* 23.100.86.91/32 [10/0] via 192.168.100.4, eth0
S>* 23.101.14.229/32 [10/0] via 192.168.100.4, eth0
S>* 23.101.30.126/32 [10/0] via 192.168.100.4, eth0
S>* 23.102.4.253/32 [10/0] via 192.168.100.4, eth0
S>* 23.103.144.0/20 [10/0] via 192.168.100.4, eth0
S>* 40.76.1.176/32 [10/0] via 192.168.100.4, eth0
S>* 40.76.8.142/32 [10/0] via 192.168.100.4, eth0
S>* 40.76.12.4/32 [10/0] via 192.168.100.4, eth0
S>* 40.76.12.162/32 [10/0] via 192.168.100.4, eth0
S>* 40.92.0.0/15 [10/0] via 192.168.100.4, eth0
S>* 40.107.0.0/16 [10/0] via 192.168.100.4, eth0
S>* 40.113.8.255/32 [10/0] via 192.168.100.4, eth0
S>* 40.113.10.78/32 [10/0] via 192.168.100.4, eth0
S>* 40.113.11.93/32 [10/0] via 192.168.100.4, eth0
S>* 40.113.14.159/32 [10/0] via 192.168.100.4, eth0
S>* 40.117.144.240/32 [10/0] via 192.168.100.4, eth0
S>* 40.117.151.29/32 [10/0] via 192.168.100.4, eth0
S>* 40.118.211.172/32 [10/0] via 192.168.100.4, eth0
S>* 40.121.144.182/32 [10/0] via 192.168.100.4, eth0
S>* 40.122.168.103/32 [10/0] via 192.168.100.4, eth0
S>* 52.108.0.0/14 [10/0] via 192.168.100.4, eth0
S>* 65.52.148.27/32 [10/0] via 192.168.100.4, eth0
S>* 65.52.160.218/32 [10/0] via 192.168.100.4, eth0
S>* 65.52.184.75/32 [10/0] via 192.168.100.4, eth0
S>* 65.52.196.64/32 [10/0] via 192.168.100.4, eth0
S>* 70.37.97.234/32 [10/0] via 192.168.100.4, eth0
S>* 94.245.108.85/32 [10/0] via 192.168.100.4, eth0
:
:
以下略

はい。バリバリ登録されました。そのうえで今度はスクリプトログを眺める。

2019-08-31 17:03:08.561766 INFO Start endpoint get function
2019-08-31 17:03:09.659487 INFO New version of Office 365 worldwide commercial service instance endpoints detected
2019-08-31 17:03:10.828163 INFO Version check completed. Latest version is 0000000000.
2019-08-31 17:03:10.921781 INFO Routing data construction completed. Add 72, Remove 805 routes.
2019-08-31 17:03:10.922125 INFO L3SW Configuration data output completed.
2019-08-31 17:03:10.922359 INFO L3SW SSH connection start.
2019-08-31 17:04:43.883854 INFO L3SW configure changes completed.
2019-08-31 17:05:00.165448 INFO L3SW write config completed.

とりあえず無事そう。多分。Untangle Firewall側も以下の通り経路が伝わったようです。

 = IPv4 Table main = 
13.64.196.27 via 192.168.100.4 dev eth1 proto zebra metric 20 
13.64.198.19 via 192.168.100.4 dev eth1 proto zebra metric 20 
13.64.198.97 via 192.168.100.4 dev eth1 proto zebra metric 20 
13.64.199.41 via 192.168.100.4 dev eth1 proto zebra metric 20 
13.76.218.117 via 192.168.100.4 dev eth1 proto zebra metric 20 
13.76.219.191 via 192.168.100.4 dev eth1 proto zebra metric 20 
13.76.219.210 via 192.168.100.4 dev eth1 proto zebra metric 20 
13.91.61.249 via 192.168.100.4 dev eth1 proto zebra metric 20 
13.91.98.185 via 192.168.100.4 dev eth1 proto zebra metric 20 
13.93.216.68 via 192.168.100.4 dev eth1 proto zebra metric 20 
13.93.233.42 via 192.168.100.4 dev eth1 proto zebra metric 20 
23.97.61.137 via 192.168.100.4 dev eth1 proto zebra metric 20 
23.97.150.21 via 192.168.100.4 dev eth1 proto zebra metric 20 
23.97.209.97 via 192.168.100.4 dev eth1 proto zebra metric 20 
23.99.109.44 via 192.168.100.4 dev eth1 proto zebra metric 20 
23.99.109.64 via 192.168.100.4 dev eth1 proto zebra metric 20 
23.99.116.116 via 192.168.100.4 dev eth1 proto zebra metric 20 
23.99.121.207 via 192.168.100.4 dev eth1 proto zebra metric 20 
23.100.86.91 via 192.168.100.4 dev eth1 proto zebra metric 20 
23.101.14.229 via 192.168.100.4 dev eth1 proto zebra metric 20 
23.101.30.126 via 192.168.100.4 dev eth1 proto zebra metric 20 
23.102.4.253 via 192.168.100.4 dev eth1 proto zebra metric 20 
23.103.144.0/20 via 192.168.100.4 dev eth1 proto zebra metric 20 
40.76.1.176 via 192.168.100.4 dev eth1 proto zebra metric 20 
40.76.8.142 via 192.168.100.4 dev eth1 proto zebra metric 20 
40.76.12.4 via 192.168.100.4 dev eth1 proto zebra metric 20 
40.76.12.162 via 192.168.100.4 dev eth1 proto zebra metric 20 
40.92.0.0/15 via 192.168.100.4 dev eth1 proto zebra metric 20 
40.107.0.0/16 via 192.168.100.4 dev eth1 proto zebra metric 20 
40.113.8.255 via 192.168.100.4 dev eth1 proto zebra metric 20 
40.113.10.78 via 192.168.100.4 dev eth1 proto zebra metric 20 
40.113.11.93 via 192.168.100.4 dev eth1 proto zebra metric 20 
40.113.14.159 via 192.168.100.4 dev eth1 proto zebra metric 20 
40.117.144.240 via 192.168.100.4 dev eth1 proto zebra metric 20 
40.117.151.29 via 192.168.100.4 dev eth1 proto zebra metric 20 
40.118.211.172 via 192.168.100.4 dev eth1 proto zebra metric 20 
40.121.144.182 via 192.168.100.4 dev eth1 proto zebra metric 20 
40.122.168.103 via 192.168.100.4 dev eth1 proto zebra metric 20 
52.108.0.0/14 via 192.168.100.4 dev eth1 proto zebra metric 20 
65.52.148.27 via 192.168.100.4 dev eth1 proto zebra metric 20 
65.52.160.218 via 192.168.100.4 dev eth1 proto zebra metric 20 
65.52.184.75 via 192.168.100.4 dev eth1 proto zebra metric 20 
65.52.196.64 via 192.168.100.4 dev eth1 proto zebra metric 20 
70.37.97.234 via 192.168.100.4 dev eth1 proto zebra metric 20 
94.245.108.85 via 192.168.100.4 dev eth1 proto zebra metric 20 
:
:
以下略

はい、経路が登録できました。BGPはRedistributeしない設定にしているため、この経路は他のところへ伝搬することはありませんので、周辺への影響も多分・・・・ないとおもう・・・かなぁ・・・うん。

ひとまずこの状況下でUntangle配下のセグメントからアクセスしても無事ブレイク・アウトされてましたし、内部サービスセグメントからも普通どおりに通信することが出来るようになりました。色々考慮漏れが表に出たケースだなぁと思いながらポチポチ現在情報整理をやっている感じです。