Batfish Pendahuluan

gambar

Salah satu masalah jaringan modern adalah kerapuhannya. Banyak aturan penyaringan, kebijakan pertukaran informasi routing, protokol routing dinamis membuat jaringan membingungkan dan tunduk pada faktor manusia. Kecelakaan jaringan dapat terjadi secara tidak sengaja ketika membuat perubahan pada rute-peta atau ACL ( satu , dua ). Kami jelas tidak memiliki alat untuk mengevaluasi perilaku jaringan dengan konfigurasi baru sebelum melakukan perubahan pada produksi. Saya ingin tahu pasti apakah Jaringan A akan tersedia bagi saya jika saya menyaring beberapa pengumuman BGP yang diterima dari penyedia B? Rute apa yang akan ditempuh paket dari jaringan C ke server D jika pada salah satu tautan transit saya menggandakan metrik IGP? Batfish akan membantu kami menjawab ini dan banyak pertanyaan lainnya!

Ulasan Batfish


Batfish adalah alat pemodelan jaringan. Tujuan utamanya adalah untuk menguji perubahan konfigurasi sebelum membuatnya ke jaringan produksi. Batfish juga dapat digunakan untuk menganalisis dan memeriksa status jaringan saat ini. Proses CI / CD yang ada di dunia jaringan jelas tidak memiliki alat untuk menguji konfigurasi baru. Batfish memecahkan masalah ini.

Batfish tidak memerlukan akses langsung langsung ke peralatan jaringan yang ada, Batfish memodelkan perilaku jaringan berdasarkan data yang terkandung dalam file konfigurasi perangkat.

Batfish dapat:

  • menentukan status tetangga dari protokol routing dinamis dalam jaringan (BGP, IS-IS, OSPF)
  • menghitung RIB dari setiap elemen jaringan
  • periksa pengaturan NTP, AAA, MTU
  • memungkinkan menentukan apakah ACL memblokir jalur lalu lintas jaringan (analog paket-pelacak pada Cisco ASA)
  • periksa konektivitas end-to-end antara host dalam jaringan
  • menunjukkan jalur lalu lintas melalui jaringan (virtual tracing)


Platform yang didukung:

  • Arista
  • Aruba
  • AWS (VPC, ACL Jaringan, VPN GW, NAT GW, Internet GW, Grup Keamanan)
  • Cisco (NX-OS, IOS, IOS-XE, IOS-XR dan ASA)
  • Dell force10
  • Pengecoran
  • iptables
  • Juniper (MX, EX, QFX, SRX, T-series, PTX)
  • Tuan
  • Jaringan alto alto
  • Quagga / FRR
  • Quanta
  • Vyos

gambar

Batfish adalah aplikasi Java. Untuk pekerjaan mudah dengan itu ditulis Pybatfish - python SDK.

Mari kita lanjutkan berlatih. Saya akan menunjukkan kepada Anda kemungkinan Batfish dengan contoh.

Contoh


Kami mengelola dua sistem otonom: AS 41214 dan AS 10631. Seperti IGP, AS-41214 menggunakan IS-IS dan AS-10631 - OSPF. Di dalam setiap AS, IBGP-fullmesh digunakan. LDN-CORE-01 mengumumkan awalan BGP tetangganya 135.65.0.0/19, MSK-CORE-01 - 140.0.0.0/24. Pertukaran informasi routing antara sistem otonom terjadi di persimpangan HKI-CORE-01 - SPB-CORE-01.

HKI-CORE-01, STH-CORE-01 - Router Junos
LDN-CORE-01, AMS-CORE-01, SPB-CORE-01, MSK-CORE-01 - Router Cisco IOS



Instal wadah dengan Batfish dan python SDK:

docker pull batfish/allinone docker run batfish/allinone docker container exec -it <container> bash 

Mengenal perpustakaan melalui mode interaktif python:

 root@ea9a1559d88e:/# python3 -------------------- >>> from pybatfish.client.commands import bf_logger, bf_init_snapshot >>> from pybatfish.question.question import load_questions >>> from pybatfish.question import bfq >>> import logging >>> bf_logger.setLevel(logging.ERROR) >>> load_questions() >>> bf_init_snapshot('tmp/habr') 'ss_e8065858-a911-4f8a-b020-49c9b96d0381' 

bf_init_snapshot ('tmp / habr') - fungsi memuat file konfigurasi ke dalam Batfish dan menyiapkannya untuk dianalisis.

/ tmp / habr - direktori dengan file konfigurasi router.

 root@ea9a1559d88e:/tmp/habr# tree . `-- configs |-- AMS-CORE-01.cfg |-- HKI-CORE-01.cfg |-- LDN-CORE-01.cfg |-- MSK-CORE-01.cfg |-- SPB-CORE-01.cfg `-- STH-CORE-01.cfg 1 directory, 6 files 

Sekarang mari kita tentukan status sesi BGP pada router LDN-CORE-01:

 >>> bgp_peers = bfq.bgpSessionStatus(nodes='LDN-CORE-01').answer().frame() >>> bgp_peers Node VRF Local_AS Local_IP Remote_AS Remote_Node Remote_IP Session_Type Est_Status 0 ldn-core-01 default 41214 172.20.20.1 41214 sth-core-01 172.20.20.2 IBGP EST 1 ldn-core-01 default 41214 172.20.20.1 41214 ams-core-01 172.20.20.3 IBGP EST 2 ldn-core-01 default 41214 172.20.20.1 41214 hki-core-01 172.20.20.4 IBGP EST 

Nah bagaimana caranya? Kedengarannya seperti kebenaran?

 LDN-CORE-01#show ip bgp summary … Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd 172.20.20.2 4 41214 629 669 9 0 0 00:56:51 0 172.20.20.3 4 41214 826 827 9 0 0 01:10:18 0 172.20.20.4 4 41214 547 583 9 0 0 00:49:24 1 

Sekarang mari kita lihat apa rute IS-IS dalam RIB pada router HKI-CORE-01 menurut Batfish:

 >>> isis_routes = bfq.routes(nodes='HKI-CORE-01', protocols='isis').answer().frame() >>> isis_routes Node VRF Network Next_Hop Next_Hop_IP Protocol Admin_Distance Metric Tag 0 hki-core-01 default 172.20.20.3/32 ams-core-01 10.0.0.6 isisL2 18 20 None 1 hki-core-01 default 172.20.20.1/32 ams-core-01 10.0.0.6 isisL2 18 30 None 2 hki-core-01 default 172.20.20.2/32 sth-core-01 10.0.0.4 isisL2 18 10 None 3 hki-core-01 default 172.20.20.1/32 sth-core-01 10.0.0.4 isisL2 18 30 None 4 hki-core-01 default 10.0.0.0/31 sth-core-01 10.0.0.4 isisL2 18 20 None 5 hki-core-01 default 10.0.0.2/31 ams-core-01 10.0.0.6 isisL2 18 20 None 

Di baris perintah:

 showroute@HKI-CORE-01# run show route table inet.0 protocol isis inet.0: 18 destinations, 18 routes (18 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 10.0.0.0/31 *[IS-IS/18] 00:51:25, metric 20 > to 10.0.0.4 via ge-0/0/0.0 10.0.0.2/31 *[IS-IS/18] 00:51:45, metric 20 > to 10.0.0.6 via ge-0/0/1.0 172.20.20.1/32 *[IS-IS/18] 00:51:25, metric 30 to 10.0.0.4 via ge-0/0/0.0 > to 10.0.0.6 via ge-0/0/1.0 172.20.20.2/32 *[IS-IS/18] 00:51:25, metric 10 > to 10.0.0.4 via ge-0/0/0.0 172.20.20.3/32 *[IS-IS/18] 00:51:45, metric 20 > to 10.0.0.6 via ge-0/0/1.0 

Hebat! Saya kira sudah menjadi lebih jelas bagi Anda bahwa ada Batfish.

Di awal artikel, saya menulis bahwa Batfish dapat digunakan untuk memeriksa perubahan konfigurasi sebelum membuatnya ke jaringan "pertempuran". Sekarang saya mengusulkan untuk mempertimbangkan proses pengujian jaringan berdasarkan RobotFramework . Untuk melakukan ini, saya menulis modul kecil berdasarkan PyBatfish yang memungkinkan Anda melakukan pemeriksaan berikut:

  • Tentukan status sesi BGP di jaringan
  • Tentukan Status Tetangga IS-IS
  • Periksa konektivitas ujung ke ujung antara node pada jaringan dengan jejak jejak
  • Tentukan ukuran RIB pada router untuk protokol routing dinamis tertentu

LibraryBatfish.py
 import logging from pybatfish.client.commands import bf_logger, bf_init_snapshot from pybatfish.question.question import load_questions, list_questions from pybatfish.question import bfq from pybatfish.datamodel.flow import HeaderConstraints, PathConstraints from robot.api import logger class LibraryBatfish(object): def __init__(self, snapshot): bf_logger.setLevel(logging.ERROR) load_questions() bf_init_snapshot(snapshot) def check_bgp_peers(self): not_established_peers = list() bgp_peers = bfq.bgpSessionStatus().answer() for peer in bgp_peers.rows: if peer.get('Established_Status') != 'ESTABLISHED': not_established_peers.append(dict.fromkeys(peer.get('Local_IP').split(), peer.get('Remote_IP').get('value'))) if len(not_established_peers) == 0: return 1 else: logger.warn('BGP neighbors are not in an established state:') for neighborship in not_established_peers: for peer in neighborship: logger.warn('{} - {}'.format(peer, neighborship.get(peer))) return 0 def check_routes(self, node, protocol): routes = bfq.routes(nodes=node, protocols=protocol).answer() return len(routes.rows) def check_isis_neighbors(self, description): not_isis_enabled_links = list() for link in self._get_isis_enabled_links(description): if link not in self._get_isis_neighbors(): not_isis_enabled_links.append(link) if len(not_isis_enabled_links) == 0: return 1 else: for link in not_isis_enabled_links: logger.warn('{} {} has no IS-IS neighbor'.format(link.get('hostname'), link.get('interface'))) return 0 def ping(self, source_ip, destination_ip): ip_owners = bfq.ipOwners().answer() traceroute = self._get_traceroute_status(source_ip, destination_ip, ip_owners) reverse_traceroute = self._get_traceroute_status(destination_ip, source_ip, ip_owners) if traceroute == True and reverse_traceroute == True: self._show_trace(source_ip, destination_ip, ip_owners) return 1 else: logger.warn('Ping {} -> {} failed'.format(source_ip, destination_ip)) return 0 def _get_traceroute_status(self, source_ip, destination_ip, addresses): tracert = self._unidirectional_virtual_traceroute(source_ip, destination_ip, addresses) isAccepted = True if tracert != None: for trace in tracert.rows[0].get('Traces'): if trace.get('disposition') != 'ACCEPTED': isAccepted = False if isAccepted == True: return True else: return False def _get_paths(self, source_ip, destination_ip, addresses): tracert = self._unidirectional_virtual_traceroute(source_ip, destination_ip, addresses) traces = tracert.rows[0].get('Traces') paths = dict() path_number = 1 for trace in traces: if trace.get('disposition') == 'ACCEPTED': path = list() for hop in trace.get('hops'): path.append(hop.get('node').get('name')) paths[path_number] = path path_number += 1 return paths def _unidirectional_virtual_traceroute(self, source_ip, destination_ip, addresses): for address in addresses.rows: if address.get('IP') == source_ip: node = address.get('Node').get('name') int = address.get('Interface') headers = HeaderConstraints(srcIps=source_ip, dstIps=destination_ip, ipProtocols=['ICMP']) try: tracert = bfq.traceroute(startLocation="{}[{}]".format(node,int), headers=headers).answer() return tracert except: logger.warn('{} address has not been found'.format(source_ip)) def _get_isis_enabled_links(self, description='core-link'): isis_enabled_links = list() interfaces = bfq.interfaceProperties().answer() for int in interfaces.rows: if int.get('Description') != None and description in int.get('Description'): isis_enabled_links.append({'hostname' : int.get('Interface').get('hostname'), 'interface' : int.get('Interface').get('interface')}) return isis_enabled_links def _get_isis_neighbors(self): isis_neighbors = list() isis_adjacencies = bfq.edges(edgeType='isis').answer() for neighbor in isis_adjacencies.rows: isis_neighbors.append(neighbor.get('Interface')) return isis_neighbors def _show_trace(self, source_ip, destination_ip, addresses): logger.console('\nTraceroute to {} from {}'.format(destination_ip, source_ip)) paths = self._get_paths(source_ip, destination_ip, addresses) path_num = 1 for path in paths: n = 1 logger.console('\n Path N{}'.format(path_num)) for hop in paths.get(path): logger.console(' {} {}'.format(n, hop)) n += 1 path_num += 1 


batfish-test.robot
gambar

Skenario N1




Di bawah kendali saya masih jaringan yang sama. Misalkan saya harus memesan filter di perbatasan AS 41214 dan AS 10631 dan memblokir paket junction yang berisi alamat ip sumber atau tujuan dari kisaran BOGONS.

Jalankan tes sebelum membuat perubahan.

gambar

Tes lulus.

Kami akan membuat perubahan pada konfigurasi pengujian router HKI-CORE-01 - /tmp/habr/configs/HKI-CORE-01.cfg:

 set firewall family inet filter BOGONS term TERM010 from address 0.0.0.0/8 set firewall family inet filter BOGONS term TERM010 from address 10.0.0.0/8 set firewall family inet filter BOGONS term TERM010 from address 100.64.0.0/10 set firewall family inet filter BOGONS term TERM010 from address 127.0.0.0/8 set firewall family inet filter BOGONS term TERM010 from address 169.254.0.0/16 set firewall family inet filter BOGONS term TERM010 from address 172.16.0.0/12 set firewall family inet filter BOGONS term TERM010 from address 192.0.2.0/24 set firewall family inet filter BOGONS term TERM010 from address 192.88.99.0/24 set firewall family inet filter BOGONS term TERM010 from address 192.168.0.0/16 set firewall family inet filter BOGONS term TERM010 from address 198.18.0.0/15 set firewall family inet filter BOGONS term TERM010 from address 198.51.100.0/24 set firewall family inet filter BOGONS term TERM010 from address 203.0.113.0/24 set firewall family inet filter BOGONS term TERM010 from address 224.0.0.0/4 set firewall family inet filter BOGONS term TERM010 from address 240.0.0.0/4 set firewall family inet filter BOGONS term TERM010 then discard set firewall family inet filter BOGONS term PERMIT-IP-ANY-ANY then accept set interfaces ge-0/0/2.0 family inet filter input BOGONS set interfaces ge-0/0/2.0 family inet filter output BOGONS 

Jalankan tes.



Saya sangat dekat, tetapi seperti yang ditunjukkan oleh hasil pengujian, setelah perubahan BGP dibuat, lingkungan 192.168.30.0 - 192.168.30.1 tidak dalam keadaan Didirikan -> sebagai akibatnya, konektivitas IP antara titik 135.65.0.1 <-> 140.0.0.1 hilang. Apa yang salah Kami melihat dengan seksama pada konfigurasi HKI-CORE-01 dan melihat bahwa peering eBGP diinstal pada alamat pribadi:

 showroute@HKI-CORE-01# show interfaces ge-0/0/2 | display set set interfaces ge-0/0/2 description SPB-CORE-01 set interfaces ge-0/0/2 unit 0 family inet filter input BOGONS set interfaces ge-0/0/2 unit 0 family inet filter output BOGONS set interfaces ge-0/0/2 unit 0 family inet address 192.168.30.0/31 

Kesimpulan: perlu untuk mengubah alamat di persimpangan atau menambahkan subnet 192.168.30.0/31 ke pengecualian.

Saya akan menambahkan jaringan di persimpangan ke pengecualian, saya akan memperbarui /tmp/habr/configs/HKI-CORE-01.cfg lagi:

 set firewall family inet filter BOGONS term TERM005 from address 192.168.0.0/31 set firewall family inet filter BOGONS term TERM005 then accept 

Jalankan tes.



Sekarang lalu lintas yang tidak diinginkan tidak akan melalui antarmuka ebgp AS 41214 - AS 10631. Anda dapat dengan aman melakukan perubahan tanpa takut akan konsekuensi.

Skenario N2




Di sini saya perlu mengakhiri jaringan 150.0.0.0/24 pada router MSK-CORE-01 dan memastikan konektivitas antara titik-titik 135.65.0.1 dan 150.0.0.1

Saya menambahkan baris-baris berikut ke konfigurasi pengujian router MSK-CORE-01 - tmp / habr / configs / MSK-CORE-01.cfg:

 interface Loopback2 ip address 150.0.0.1 255.255.255.255 ! ip route 150.0.0.0 255.255.255.0 Null0 ! router bgp 10631 ! address-family ipv4 network 150.0.0.0 mask 255.255.255.0 ! 

Saya mengubah skrip tes dan menjalankan tes:

 git diff HEAD~ diff --git a/batfish-robot.robot b/batfish-robot.robot index 8d963c5..ce8cb6a 100644 --- a/batfish-robot.robot +++ b/batfish-robot.robot @@ -5,7 +5,7 @@ Library LibraryBatfish.py tmp/habr ${ISIS-ENABLED-LINK-DESCRIPTION} ISIS-LINK ${NODE} HKI-CORE-01 ${PROTOCOL} ebgp -${RIB-SIZE} 1 +${RIB-SIZE} 2 *** Test Cases *** ISIS @@ -27,3 +27,8 @@ Ping [Documentation] Test end-to-end ICMP connectivity & show traceroute ${result}= Ping 135.65.0.1 140.0.0.1 Should Be Equal As Integers ${result} 1 + +Ping2 + [Documentation] Test end-to-end ICMP connectivity & show traceroute + ${result}= Ping 135.65.0.1 150.0.0.1 + Should Be Equal As Integers ${result} 1 

Sekarang saya berharap untuk melihat dua rute eBGP pada router HKI-CORE-01, pemeriksaan konektivitas tambahan ditambahkan



Tidak ada koneksi antara 135.65.0.1 dan 150.0.0.1, apalagi, pada router HKI-CORE-01 hanya ada satu rute eBGP, bukan dua.

Periksa isi RIB pada HKI-CORE-01 saat menambahkan konfigurasi baru ke router MSK-CORE-01 :

 showroute@HKI-CORE-01# run show route table inet.0 protocol bgp inet.0: 20 destinations, 20 routes (19 active, 0 holddown, 1 hidden) + = Active Route, - = Last Active, * = Both 135.65.0.0/19 *[BGP/170] 02:25:38, MED 0, localpref 100, from 172.20.20.1 AS path: I, validation-state: unverified > to 10.0.0.4 via ge-0/0/0.0 to 10.0.0.6 via ge-0/0/1.0 140.0.0.0/24 *[BGP/170] 01:38:02, localpref 100 AS path: 10631 I, validation-state: unverified > to 192.168.30.1 via ge-0/0/2.0 showroute@HKI-CORE-01# run show route table inet.0 protocol bgp hidden detail inet.0: 20 destinations, 20 routes (19 active, 0 holddown, 1 hidden) 150.0.0.0/24 (1 entry, 0 announced) BGP /-101 Next hop type: Router, Next hop index: 563 Address: 0x940f43c Next-hop reference count: 4 Source: 192.168.30.1 Next hop: 192.168.30.1 via ge-0/0/2.0, selected Session Id: 0x9 State: <Hidden Ext> Local AS: 41214 Peer AS: 10631 Age: 1:42:03 Validation State: unverified Task: BGP_10631.192.168.30.1+179 AS path: 10631 I Localpref: 100 Router ID: 10.68.1.1 Hidden reason: rejected by import policy 

Perhatikan kebijakan impor untuk awalan yang diterima dari SPB-CORE-01 :

 set protocols bgp group AS10631 import FROM-AS10631 set protocols bgp group AS10631 neighbor 192.168.30.1 description SPB-CORE-01 set protocols bgp group AS10631 neighbor 192.168.30.1 peer-as 10631 set policy-options policy-statement FROM-AS10631 term TERM010 from route-filter 140.0.0.0/24 exact set policy-options policy-statement FROM-AS10631 term TERM010 then accept set policy-options policy-statement FROM-AS10631 term DENY then reject 

Aturan yang mengizinkan 150.0.0.0/24 tidak ada. Tambahkan ke konfigurasi tes dan jalankan tes:

 showroute@HKI-CORE-01# show | compare [edit policy-options policy-statement FROM-AS10631 term TERM010 from] route-filter 140.0.0.0/24 exact { ... } + route-filter 150.0.0.0/24 exact; [edit] 



Hebat, ada konektivitas antar jaringan, semua tes lulus! Jadi, Anda dapat membuat perubahan ini pada karya jaringan "tempur".

Kesimpulan


Menurut pendapat saya, Batfish adalah alat yang kuat dengan potensi besar. Cobalah dan lihat sendiri.

Jika topik ini menarik bagi Anda - bergabunglah dengan slack chat, pengembang Batfish akan dengan senang hati menjawab pertanyaan dan dengan cepat memperbaiki bug.

batfish-org.slack.com

Terima kasih atas perhatian anda

Referensi


www.batfish.org

www.youtube.com/channel/UCA-OUW_3IOt9U_s60KvmJYA

github.com/batfish/batfish

media.readthedocs.org/pdf/pybatfish/latest/pybatfish.pdf

github.com/showroute/batfish-habr

Source: https://habr.com/ru/post/id441532/


All Articles