1. はじめに
前回の記事では、Configファイルをインプットに、ネットワークConfig解析ツール「Batfish」で正常時の確認を行いました。
BatfishでNW障害時の影響分析を行う①
本記事では筐体障害、リンク障害時の確認と、正常時・障害時を比較した影響分析を行ってみたいと思います。
2. 筐体障害時の確認
2-1. 筐体障害発生
※前回の記事の「3. Batfishのセットアップ」まで終わっている前提とします。
正常時のスナップショットtest_snapshot
をフォークし、iosvl2-0
筐体障害発生時のスナップショットfail_access
を作成します。引数deactivate_nodes
には障害機器のホスト名iosvl2-0
を指定します。
FAIL_ACCESS_SNAPSHOT_NAME = "fail_access"
bf.fork_snapshot(BASE_SNAPSHOT_NAME,
FAIL_ACCESS_SNAPSHOT_NAME,
deactivate_nodes=["iosvl2-0"],
overwrite=True)
2-2. 通信経路確認
bidirectionalTraceroute()
を使用し、10.1.1.100
から10.4.1.100
宛ての疎通性および通信経路を確認します。
正常時の確認と異なるのは、answer()
の引数としてフォークしたスナップショットを明示指定している点です。
result_bdtr_dev_fail = bf.q.bidirectionalTraceroute(
startLocation='@enter(csr1000v-0[GigabitEthernet2])',
headers=HeaderConstraints(dstIps='10.4.1.100', srcIps='10.1.1.100')).answer(
snapshot=FAIL_ACCESS_SNAPSHOT_NAME).frame()
result_bdtr_dev_fail.Forward_Traces[0][0]
iosvl2-0
障害時は、iosvl2-1
経由に切り替わるのが想定結果です。ただし今回は、iosvl2-1
でACL許可設定漏れがあり、10.1.1.100
から10.4.1.100
宛ての通信が拒否される状態になっています。
行きの実行結果では想定通りDENIED_IN
となり、iosvl2-1
Vlan100に適用されているin方向ACLacl_test
で拒否されています。
戻りの実行結果も確認してみます。
result_bdtr_dev_fail.Reverse_Traces[0][0]
代わりに、traceroute()
で10.4.1.100
から10.1.1.100
宛ての疎通性および通信経路を確認してみます。
result_bdtr_dev_fail2 = bf.q.traceroute(
startLocation='@enter(iosvl2-3[GigabitEthernet0/2])',
headers=HeaderConstraints(dstIps='10.1.1.100', srcIps='10.4.1.100')).answer(
snapshot=FAIL_ACCESS_SNAPSHOT_NAME).frame()
result_bdtr_dev_fail2.Traces[0][0]
traceroute()
は片方向の通信がNGでも結果を返してくれるので、想定通りの通信経路が表示されました。3.でiosvl2-0
の代わりにiosvl2-1
を経由していることが分かります。
3. リンク障害時の確認
3-1. 単一リンク障害発生
正常時のスナップショットtest_snapshot
をフォークし、iosvl2-0
のGigabitEthernet0/2
リンク発生時のスナップショットfail_link
を作成します。
筐体障害時の引数はdeactivate_nodes
でしたが、リンク障害はdeactivate_interfaces
を使います。
FAIL_LINK_SNAPSHOT_NAME = "fail_link"
bf.fork_snapshot(BASE_SNAPSHOT_NAME,
FAIL_LINK_SNAPSHOT_NAME,
deactivate_interfaces=[Interface(hostname="iosvl2-0", interface="GigabitEthernet0/2")],
overwrite=True)
3-2. 単一リンク障害時の通信経路確認
スナップショット名以外は筐体障害時と同じです。
result_bdtr_link_fail = bf.q.bidirectionalTraceroute(
startLocation='@enter(csr1000v-0[GigabitEthernet2])',
headers=HeaderConstraints(dstIps='10.4.1.100', srcIps='10.1.1.100')).answer(
snapshot=FAIL_LINK_SNAPSHOT_NAME).frame()
result_bdtr_link_fail.Forward_Traces[0][0]
LAN側の単一リンク障害だけではVRRP切り替わりは発生しない設計のため、正常時と同様の結果となりました。
3-3. 多重リンク障害発生
正常時のスナップショットtest_snapshot
をフォークし、今度はiosvl2-0
のGigabitEthernet0/2, 1/0, 1/1
の多重リンク発生時のスナップショットfail_multiple_link
を作成します。
FAIL_MULTIPLE_LINK_SNAPSHOT_NAME = "fail_multiple_link"
bf.fork_snapshot(BASE_SNAPSHOT_NAME,
FAIL_MULTIPLE_LINK_SNAPSHOT_NAME,
deactivate_interfaces=[Interface(hostname="iosvl2-0", interface="GigabitEthernet0/2"),
Interface(hostname="iosvl2-0", interface="GigabitEthernet1/0"),
Interface(hostname="iosvl2-0", interface="GigabitEthernet1/1")],
overwrite=True)
3-4. 多重リンク障害時の通信経路確認
こちらもスナップショット名以外は筐体障害時と同じです。
result_bdtr_mlink_fail = bf.q.bidirectionalTraceroute(
startLocation='@enter(csr1000v-0[GigabitEthernet2])',
headers=HeaderConstraints(dstIps='10.4.1.100', srcIps='10.1.1.100')).answer(
snapshot=FAIL_MULTIPLE_LINK_SNAPSHOT_NAME).frame()
result_bdtr_mlink_fail.Forward_Traces[0][0]
LAN側IFがすべて塞がれてVRRP切り替わりが発生し、想定通り筐体障害時と同様の結果になりました。
4. 正常時・障害時を比較した影響分析
最後に、正常時と筐体障害時を比較し、前者で許可されるが、後者ではドロップされる通信を出力したいと思います。
QuestionはdifferentialReachability()
を使います。(参考) 通信経路確認で用いるQuestion
結果を見やすくするため、引数pathConstraints
で開始ノード、headers
で対象通信、maxTraces
でTrace出力結果数を絞っています。引数を指定しない場合、各機器から障害機器宛ての通信を含むすべての差分が出力されます。
result_diff_reachability = bf.q.differentialReachability(
pathConstraints=PathConstraints(startLocation = f'@enter({"csr1000v-0"}[{"GigabitEthernet1"}])'),
headers=HeaderConstraints(dstIps='10.4.1.100', srcIps='10.1.1.100'),
maxTraces=1).answer(
snapshot=FAIL_ACCESS_SNAPSHOT_NAME,
reference_snapshot=BASE_SNAPSHOT_NAME)
result_diff_reachability.frame()
結果は以下の通りです。Reference_Traces
(正常時)ではDELIVERED_TO_SUBNET
、Snapshot_Traces
(筐体障害時)ではDENIED
として差分出力されていることが分かります。
送信元と宛先を逆にした場合、正常時・障害時ともに通信可能なため差分出力されませんでした。
headers=HeaderConstraints(dstIps='10.1.1.100', srcIps='10.4.1.100'),
5. 最後に
今回は小規模なネットワークで、1パターンの通信経路のみで影響分析を実施しました。
一方で大規模ネットワークに対し、あらかじめ定義した筐体・リンク障害パターンで複数の通信経路確認も当然可能です。
Batfishのツールとしての性質上、複雑な設計、特殊な設定ではうまく解析できないケースもあるかもしれませんが、まずは「問題が見つかったらラッキー」くらいの感覚で使ってみるのも良いかも知れません。