سمك السلور مقدمة

الصورة

واحدة من مشاكل الشبكات الحديثة هي هشاشتها. العديد من قواعد التصفية ، وسياسات تبادل المعلومات الخاصة بالتوجيه ، وبروتوكولات التوجيه الديناميكية تجعل الشبكات مربكة وتخضع للعوامل البشرية. يمكن أن يحدث تعطل الشبكة عن غير قصد عند إجراء تغييرات على خريطة الطريق أو ACL ( واحد أو اثنين ). نفتقر بالتأكيد إلى أداة لتقييم سلوك الشبكة بتكوين جديد قبل إجراء تغييرات على الإنتاج. أريد أن أعرف بالضبط ما إذا كانت الشبكة "أ" ستكون متاحة لي إذا قمت بتصفية بعض إعلانات BGP الواردة من الموفر ب؟ ما الطريق الذي ستنتقل به الحزم من الشبكة C إلى الخادم D إذا قمت بمضاعفة مقياس IGP على أحد روابط النقل؟ سوف تساعدنا أسماك القرش في الإجابة على هذه الأسئلة والعديد من الأسئلة الأخرى!

استعراض سمك السلور


أسماك القرش هي أداة لنمذجة الشبكة. الغرض الرئيسي منه هو اختبار تغييرات التكوين قبل تحويلها إلى شبكة الإنتاج. يمكن استخدام أسماك القرش أيضًا لتحليل الوضع الحالي للشبكة والتحقق منه. من الواضح أن عمليات CI / CD الحالية في عالم الشبكات تفتقر إلى أداة لاختبار التكوينات الجديدة. سمك السلور يحل هذه المشكلة.

لا يتطلب Batfish الوصول المباشر المباشر إلى معدات الشبكة الحالية ، يقوم Batfish بنماذج سلوك الشبكة استنادًا إلى البيانات الموجودة في ملفات تكوين الجهاز.

يمكن لسمكة البحر:

  • تحديد حالة الجوار لبروتوكولات التوجيه الديناميكية في الشبكة (BGP ، IS-IS ، OSPF)
  • حساب RIB لكل عنصر شبكة
  • تحقق من إعدادات NTP و AAA و MTU
  • السماح بتحديد ما إذا كانت قائمة التحكم في الوصول (ACL) تمنع مرور حركة مرور الشبكة (تمثيلية تتبع الحزمة على Cisco ASA)
  • تحقق من الاتصال من طرف إلى طرف بين المضيفين داخل الشبكة
  • عرض مسار حركة المرور عبر الشبكة (التتبع الافتراضي)


المنصات المدعومة:

  • أريستا
  • أروبا
  • AWS (VPCs ، ACLs للشبكة ، VPN GW ، NAT GW ، الإنترنت GW ، مجموعات الأمان)
  • Cisco (NX-OS و IOS و IOS-XE و IOS-XR و ASA)
  • Dell force10
  • مسبك
  • iptables
  • العرعر (MX ، EX ، QFX ، SRX ، سلسلة T ، PTX)
  • Mrv
  • شبكات بالو ألتو
  • Quagga / FRR
  • كوانتا
  • فيوس

الصورة

سمكة البحر هو تطبيق جافا. للعمل مريحة معها تمت كتابة Pybatfish - بيثون SDK.

دعنا ننتقل إلى الممارسة. سأريكم إمكانيات Batfish مع مثال.

مثال


ندير نظامين مستقلين: AS 41214 و AS 10631. كما IGP ، AS-41214 يستخدم IS-IS ، و AS-10631 - OSPF. داخل كل AS ، يتم استخدام IBGP-fullmesh. تعلن LDN-CORE-01 عن بادئة الجوار لـ BGP 135.65.0.0/19 ، MSK-CORE-01 - 140.0.0.0/24. يحدث تبادل معلومات التوجيه بين الأنظمة المستقلة عند تقاطع HKI-CORE-01 - SPB-CORE-01.

HKI-CORE-01 ، STH-CORE-01 - أجهزة توجيه Junos
LDN-CORE-01 ، AMS-CORE-01 ، SPB-CORE-01 ، MSK-CORE-01 - أجهزة توجيه Cisco IOS



تثبيت الحاوية مع Batfish والثعبان SDK:

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

تعرف على المكتبة من خلال الوضع التفاعلي بيثون:

 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') - تقوم الوظيفة بتحميل ملفات التكوين في Batfish وتعدها للتحليل.

/ tmp / habr - دليل مع ملفات تكوين جهاز التوجيه.

 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 

الآن دعونا نحدد حالة جلسات BGP على جهاز التوجيه 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 

حسنا كيف؟ يبدو وكأنه الحقيقة؟

 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 

الآن دعنا نرى ما هي طرق IS-IS الموجودة في RIB على جهاز التوجيه HKI-CORE-01 وفقًا لـ 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 

في سطر الأوامر:

 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 

عظيم! أفترض أنه أصبح أكثر وضوحا لك أن هناك سمكة الباتفيش.

في بداية المقال ، كتبت أنه يمكن استخدام Batfish للتحقق من تغييرات التكوين قبل إجرائها على شبكة "المعركة". الآن أقترح دراسة عملية اختبار الشبكة بناءً على RobotFramework . لهذا ، كتبت وحدة صغيرة قائمة على PyBatfish تسمح لك بإجراء الاختبارات التالية:

  • تحديد حالة جلسات BGP على الشبكة
  • تحديد حالة الجوار IS-IS
  • تحقق من الاتصال من طرف إلى طرف بين العقد على شبكة مع العرض التوضيحي التتبع
  • تحديد حجم RIB على جهاز التوجيه لبروتوكول توجيه ديناميكي معين

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
الصورة

السيناريو N1




تحت سيطرتي لا تزال نفس الشبكة. افترض أنني بحاجة إلى ترتيب الفلاتر على حدود AS 41214 و AS 10631 وحظرها في حزم الوصلات التي تحتوي على عناوين IP للمصدر أو الوجهة من نطاق BOGONS.

قم بإجراء الاختبار قبل إجراء التغييرات.

الصورة

مرت الاختبارات.

سنجري تغييرات على تكوين الاختبار لجهاز التوجيه 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 

قم بإجراء الاختبار.



لقد كنت قريبًا جدًا ، ولكن كما يوضح ناتج الاختبار ، بعد إجراء تغييرات BGP ، لم يكن الحي 192.168.30.0 - 192.168.30.1 في حالة التأسيس -> ونتيجة لذلك ، فقد اتصال IP بين النقاط 135.65.0.1 <-> 140.0.0.1. ما هو الخطأ؟ ننظر بعناية في تكوين HKI-CORE-01 ونرى أن نظير eBGP مثبت على عناوين خاصة:

 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 

الخلاصة: من الضروري تغيير العناوين عند التقاطع أو إضافة الشبكة الفرعية 192.168.30.0/31 إلى الاستثناء.

سأضيف شبكة عند التقاطع إلى الاستثناء ، سأقوم بتحديث /tmp/habr/configs/HKI-CORE-01.cfg مرة أخرى:

 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 

قم بإجراء الاختبار.



الآن لن تمر حركة المرور غير المرغوب فيها من خلال واجهة ebgp AS 41214 - AS 10631. يمكنك إجراء تغييرات بأمان دون خوف من العواقب.

السيناريو N2




أحتاج هنا إلى إنهاء الشبكة 150.0.0.0/24 على جهاز التوجيه MSK-CORE-01 وضمان الاتصال بين النقطتين 135.65.0.1 و 150.0.0.1

أقوم بإضافة الأسطر التالية إلى تكوين اختبار جهاز التوجيه 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 ! 

يمكنني تغيير البرنامج النصي للاختبار وتشغيل الاختبار:

 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 

الآن أتوقع رؤية طريقين eBGP على جهاز التوجيه HKI-CORE-01 ، تتم إضافة فحص اتصال إضافي



لا يوجد اتصال بين 135.65.0.1 و 150.0.0.1 ، علاوة على ذلك ، يوجد على جهاز التوجيه HKI-CORE-01 مسار eBGP واحد فقط ، بدلاً من مسارين.

تحقق من محتويات RIB على HKI-CORE-01 عند إضافة تكوين جديد إلى جهاز التوجيه 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 

لاحظ سياسة الاستيراد للبادئات الواردة من 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 

قاعدة السماح 150.0.0.0/24 مفقود. إضافته إلى تكوين الاختبار وتشغيل الاختبار:

 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] 



عظيم ، هناك اتصال بين الشبكات ، يتم اجتياز جميع الاختبارات! حتى تتمكن من إجراء هذه التغييرات على عمل شبكة "القتال".

الخاتمة


في رأيي ، باتفيش هو أداة قوية مع إمكانات هائلة. جربها وانظر لنفسك.

إذا كان هذا الموضوع مثيراً للاهتمام لك - الانضمام إلى الدردشة القصيرة ، سيسعد مطورو Batfish بالإجابة على أي أسئلة وإصلاح الأخطاء بسرعة.

batfish-org.slack.com

شكرا لاهتمامكم

المراجع


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


All Articles