はじめに
前の記事でセットアップしたBatfishを活用します。
今回はACLの分析、トレースルート、config差分の確認を実施します。
前の記事
1.ACLの分析
ACLを読み込み
①無意味なフィルターのチェック
②特定IPからの通信の許可/拒否のチェック
③特定サブネットからの通信の許可/拒否のチェック
を行います。
1.0 前提作業
後に紹介する①~③の解析実施の前に、
configの読み込みなどのセットアップを行います。
コード
# ここのパスを自分が格納したフォルダパスに変更する
SNAPSHOT_PATH = "networks/example-filters/current"
# 後は手を付けない
%run startup.py
bf = Session(host="localhost")
bf.set_network("network-example-filters")
SNAPSHOT_NAME = "current"
bf.init_snapshot(SNAPSHOT_PATH, name=SNAPSHOT_NAME, overwrite=True)
1.1 無意味フィルターのチェック
ここから本題になります。
10 deny 192.168.100.0/24
20 permit 192.168.100.254/32
30 permit any
この20番のような意味の無いフィルターをチェックします。
コード
# Find unreachable lines in filters of rtr-with-acl
aclAns = bf.q.filterLineReachability(nodes="rtr-with-acl").answer()
show(aclAns.frame().sort_values(by="Unreachable_Line"))
結果の見方
670行目が540行目によって意味の無い行
790行目が500行目によって意味の無い行
となっていることが分かります。
670行目はDifferent_Action欄がTrueとなっていますが、
これは670行目で意図したpermitが、540行目のdenyで否定されていることを示しており、
より深刻なミスであることを表します。
1.2 特定IPからの疎通の確認
特定の送信元から特定の送信先への通信が許可されるかを解析します。
コード
flow_name = HeaderConstraints(srcIps="10.10.10.1",#送信元アドレス
dstIps="218.8.104.58",#宛先アドレス
applications=["dns"])#アプリケーション
answer = bf.q.testFilters(headers=flow_name,
nodes="rtr-with-acl",#解析するACLを持つ機器のホスト名
filters="acl_in").answer()#解析するACLの名前
show(answer.frame())
結果の見方
表のAction欄にPermit or Denyが表示
Line_Content欄にPermit Denyの決め手になった行が表示。
1.3 特定サブネットからの疎通の確認
できること
特定のサブネットから特定の送信先への通信が許可されるかを解析します。
コード
traffic_name = HeaderConstraints(srcIps="10.10.10.0/24",#送信元サブネットを記入
dstIps="218.8.104.58",#宛先IPを記入
applications=["dns"])#アプリケーションを指定
answer = bf.q.searchFilters(headers=traffic_name,
action="deny", #"deny"or"permit"を記入
filters="acl_in").answer()
show(answer.frame())
結果の見方
Action(deny, permit)に指定した内容に合致する条件があれば、
Line_content、Trace欄に表示される。
上記の場合、460行目に10.0.0.42/32を対象にdenyがあることが分かる。
2.トレースルートの実施
格納したconfigからトレースルートを実施します。
2.0 下準備&configの指定
格納したconfigのパスをSNAPSHOT_PATHで指定。
今回はデフォルトで指定されているconfigを使用。
コード
SNAPSHOT_PATH = "networks/example" #config格納のパスを指定
# Import packages
%run startup.py
bf = Session(host="localhost")
NETWORK_NAME = "example_network"
SNAPSHOT_NAME = "example_snapshot"
bf.set_network(NETWORK_NAME)
bf.init_snapshot(SNAPSHOT_PATH, name=SNAPSHOT_NAME, overwrite=True)
2.1 トレースルートの実施
ここから本題です。トレースルートを実施します。
コード
# start the traceroute from the Loopback0 interface of as3core1 to host1
headers = HeaderConstraints(dstIps='host1') #宛先のIP or ホスト名を指定
tracert = bf.q.traceroute(startLocation="as3core1[Loopback0]", headers=headers).answer().frame() #開始ホスト名[開始ポート]を指定
show(tracert)
結果の見方
Traces列にDenied_INと記載されており、最終的にdenyされることが分かります。
計4ルートでtracerouteが行われており、
どれもhost1で拒否されることが分かります。
3.configの差分の確認
2つのconfigの内容に違いがないかの確認をします。
なお、ここでいう内容の違いとは単なる記載の仕方の違いを指さず、
動作として違うもののみを表します。
3.0 下準備
読み込みたい2つのconfigを貼り付けます。
今回はoriginal_aclと、その圧縮版のcomposed_aclを読み込みます。
original_acl = """
ip access-list acl
10 deny icmp any any redirect
20 permit udp 117.186.185.0/24 range 49152 65535 117.186.185.0/24 eq 3784
30 permit udp 117.186.185.0/24 range 49152 65535 117.186.185.0/24 eq 3785
40 permit tcp 11.36.216.170/32 11.36.216.169/32 eq bgp
50 permit tcp 11.36.216.176/32 11.36.216.179/32 eq bgp
60 permit tcp 204.150.33.175/32 204.150.33.83/32 eq bgp
70 permit tcp 205.248.59.64/32 205.248.59.67/32 eq bgp
80 permit tcp 205.248.58.190/32 205.248.58.188/32 eq bgp
90 deny udp 10.10.10.42/32 218.8.104.58/32 eq domain
100 permit udp 10.10.10.0/24 218.8.104.58/32 eq domain
110 deny ip 54.0.0.0/8 any
120 deny ip 163.157.0.0/16 any
130 deny ip 166.144.0.0/12 any
140 deny ip 198.170.50.0/24 any
150 deny ip 198.120.0.0/16 any
160 deny ip 11.36.192.0/19 any
170 deny ip 11.125.64.0/19 any
180 permit ip 166.146.58.184/32 any
190 deny ip 218.66.57.0/24 any
200 deny ip 218.66.56.0/24 any
210 deny ip 218.67.71.0/24 any
220 deny ip 218.67.72.0/24 any
230 deny ip 218.67.96.0/22 any
240 deny ip 8.89.120.0/22 any
250 deny ip 54.203.159.1/32 any
260 permit ip 218.8.104.0/25 any
270 permit ip 218.8.104.128/25 any
280 permit ip 218.8.103.0/24 any
290 deny ip 144.49.45.40/32 any
300 deny ip 163.255.18.63/32 any
310 deny ip 202.45.130.141/32 any
320 deny ip 212.26.132.18/32 any
330 deny ip 218.111.16.132/32 any
340 deny ip 218.246.165.90/32 any
350 deny ip 29.228.179.210/32 any
360 deny ip 194.181.135.214/32 any
370 deny ip 10.64.90.249/32 any
380 deny ip 207.70.46.217/32 any
390 deny ip 219.185.241.117/32 any
400 deny ip 2.80.3.219/32 any
410 deny ip 27.212.145.150/32 any
420 deny ip 131.159.53.215/32 any
430 deny ip 214.220.213.107/32 any
440 deny ip 196.64.84.239/32 any
450 deny ip 28.69.250.136/32 any
460 deny ip 200.45.87.238/32 any
470 deny ip any 11.125.89.32/30
480 deny ip any 11.125.89.36/30
490 deny ip any 11.125.89.40/30
500 deny ip any 11.125.89.44/30
510 permit icmp any any echo-reply
520 deny ip any 11.36.199.216/30
530 deny ip any 11.36.199.36/30
540 deny ip any 11.36.199.2/30
550 deny ip any 11.36.199.52/30
560 deny ip any 11.36.199.20/30
570 deny ip any 11.125.82.216/30
580 deny ip any 11.125.82.220/32
590 deny ip any 11.125.82.36/30
600 deny ip any 11.125.82.12/30
610 deny ip any 11.125.80.136/30
620 deny ip any 11.125.80.141/32
630 deny ip any 11.125.87.48/30
640 deny ip any 11.125.87.168/30
650 deny ip any 11.125.87.173/32
660 deny ip any 11.125.90.56/30
670 deny ip any 11.125.90.240/30
680 deny ip any 11.125.74.224/30
690 deny ip any 11.125.91.132/30
700 deny ip any 11.125.89.132/30
710 deny ip any 11.125.89.12/30
720 deny ip any 11.125.92.108/30
730 deny ip any 11.125.92.104/32
740 deny ip any 11.125.92.28/30
750 deny ip any 11.125.92.27/32
760 deny ip any 11.125.92.160/30
770 deny ip any 11.125.92.164/32
780 deny ip any 11.125.92.204/30
790 deny ip any 11.125.92.202/32
800 deny ip any 11.125.93.192/29
810 deny ip any 11.125.95.204/30
820 deny ip any 11.125.95.224/30
830 deny ip any 11.125.95.180/30
840 deny ip any 11.125.95.156/30
850 deny tcp any any
860 deny icmp any any
870 deny udp any any
880 deny ip any any
"""
compressed_acl = """
ip access-list acl
10 deny icmp any any redirect
20 permit udp 117.186.185.0/24 range 49152 65535 117.186.185.0/24 range 3784 3785
! 30 MERGED WITH LINE ABOVE
40 permit tcp 11.36.216.170/32 11.36.216.169/32 eq bgp
50 permit tcp 11.36.216.176/32 11.36.216.179/32 eq bgp
60 permit tcp 204.150.33.175/32 204.150.33.83/32 eq bgp
70 permit tcp 205.248.59.64/32 205.248.59.67/32 eq bgp
! 80 DECOMMISSIONED BGP SESSION
90 deny udp 10.10.10.42/32 218.8.104.58/32 eq domain
100 permit udp 10.10.10.0/24 218.8.104.58/32 eq domain
110 deny ip 54.0.0.0/8 any
120 deny ip 163.157.0.0/16 any
130 deny ip 166.144.0.0/12 any
140 deny ip 198.170.50.0/24 any
150 deny ip 198.120.0.0/16 any
160 deny ip 11.36.192.0/19 any
170 deny ip 11.125.64.0/19 any
! 180 REMOVED UNREACHABLE LINE
190 deny ip 218.66.56.0/23 any
! 200 MERGED WITH LINE ABOVE
210 deny ip 218.67.71.0/23 any
! 220 MERGED WITH LINE ABOVE
230 deny ip 218.67.96.0/22 any
240 deny ip 8.89.120.0/22 any
! 250 REMOVED UNREACHABLE LINE
260 permit ip 218.8.104.0/24 any
! 270 MERGED WITH LINE ABOVE
280 permit ip 218.8.103.0/24 any
290 deny ip 144.49.45.40/32 any
300 deny ip 163.255.18.63/32 any
310 deny ip 202.45.130.141/32 any
320 deny ip 212.26.132.18/32 any
330 deny ip 218.111.16.132/32 any
340 deny ip 218.246.165.90/32 any
350 deny ip 29.228.179.210/32 any
360 deny ip 194.181.135.214/32 any
370 deny ip 10.64.90.249/32 any
380 deny ip 207.70.46.217/32 any
390 deny ip 219.185.241.117/32 any
400 deny ip 2.80.3.219/32 any
410 deny ip 27.212.145.150/32 any
420 deny ip 131.159.53.215/32 any
430 deny ip 214.220.213.107/32 any
440 deny ip 196.64.84.239/32 any
450 deny ip 28.69.250.136/32 any
460 deny ip 200.45.87.238/32 any
470 deny ip any 11.125.89.32/28
510 permit icmp any any echo-reply
! 520-870 REMOVED UNNECESSARY DENIES
880 deny ip any any
"""
3.1 Config差分の確認
コード
# Import packages
%run startup.py
bf = Session(host="localhost")
# Initialize a snapshot with the original ACL
original_snapshot = bf.init_snapshot_from_text(
original_acl,
platform="cisco-nx",
snapshot_name="original",
overwrite=True)
# Initialize a snapshot with the compressed ACL
compressed_snapshot = bf.init_snapshot_from_text(
compressed_acl,
platform="cisco-nx",
snapshot_name="compressed",
overwrite=True)
# Now, compare the two ACLs in the two snapshots
answer = bf.q.compareFilters().answer(snapshot=compressed_snapshot, reference_snapshot=original_snapshot)
show(answer.frame())
結果の見方
2つのConfigには3つの違いがあることが判明しました。
composed_aclの210行目が、original_aclの510行目の一部を拒否
composed_aclの510行目が、original_aclの220行目の一部を許可
composed_aclの880行目が、original_aclの80行目の一部を拒否
compressed_aclの210行目を見ると
210 deny ip 218.67.71.0/23 any
と記載されていますが、
original_aclの210行目、220行目を見ると
210 deny ip 218.67.71.0/24 any
220 deny ip 218.67.72.0/24 any
と記載されており、微妙に範囲が異なっていることが分かります。
218.67.71.0/23
⇒ 218.67.70.0 ~ 218.67.71.255
210 deny ip 218.67.71.0/24 any
220 deny ip 218.67.72.0/24 any
⇒ 218.67.71.0 ~ 218.67.72.255
これが結果に出てきたようです。
おわりに
本記事は公式のサンプルConfigを利用したものです。
面白い機能は様々ありますので、
是非公式のテキストも読んでみてください。