
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

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:/
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
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
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
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
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.

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
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
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

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.comTerima kasih atas perhatian anda
Referensi
www.batfish.orgwww.youtube.com/channel/UCA-OUW_3IOt9U_s60KvmJYAgithub.com/batfish/batfishmedia.readthedocs.org/pdf/pybatfish/latest/pybatfish.pdfgithub.com/showroute/batfish-habr