
рдЖрдзреБрдирд┐рдХ рдиреЗрдЯрд╡рд░реНрдХ рдХреА рд╕рдорд╕реНрдпрд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдЙрдирдХреА рдирд╛рдЬреБрдХрддрд╛ рд╣реИред рдХрдИ рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рдирд┐рдпрдо, рд╕реВрдЪрдирд╛ рд╡рд┐рдирд┐рдордп рдиреАрддрд┐рдпрд╛рдВ, рдбрд╛рдпрдирд╛рдорд┐рдХ рд░реВрдЯрд┐рдВрдЧ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдиреЗрдЯрд╡рд░реНрдХ рдХреЛ рднреНрд░рдорд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдорд╛рдирд╡ рдХрд╛рд░рдХреЛрдВ рдХреЗ рдЕрдзреАрди рд╣реЛрддреЗ рд╣реИрдВред рд░реВрдЯ-рдореИрдк рдпрд╛ ACL (
рдПрдХ ,
рджреЛ ) рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХрд░рддреЗ рд╕рдордп рдПрдХ рдиреЗрдЯрд╡рд░реНрдХ рджреБрд░реНрдШрдЯрдирд╛ рдЕрдирдЬрд╛рдиреЗ рдореЗрдВ рд╣реЛ рд╕рдХрддреА рд╣реИред рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЙрддреНрдкрд╛рджрди рдореЗрдВ рдмрджрд▓рд╛рд╡ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдПрдХ рдирдП рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЗ рд╕рд╛рде рдиреЗрдЯрд╡рд░реНрдХ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдкрдХрд░рдг рдХреА рдХрдореА рд╣реИред рдореИрдВ рдареАрдХ рд╕реЗ рдЬрд╛рдирдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдХреНрдпрд╛ рдкреНрд░рджрд╛рддрд╛ рдмреА рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдмреАрдЬреАрдкреА рдШреЛрд╖рдгрд╛рдУрдВ рдореЗрдВ рд╕реЗ рдХреБрдЫ рдХреЛ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░рдиреЗ рдкрд░ рдиреЗрдЯрд╡рд░реНрдХ рдП рдореЗрд░реЗ рдкрд╛рд╕ рдЙрдкрд▓рдмреНрдз рд╣реЛрдЧрд╛? рдкреИрдХреЗрдЯреНрд╕ рдиреЗрдЯрд╡рд░реНрдХ C рд╕реЗ рд╕рд░реНрд╡рд░ D рддрдХ рдХрд┐рд╕ рдорд╛рд░реНрдЧ рд╕реЗ рдЬрд╛рдПрдВрдЧреЗ рдЕрдЧрд░ рдХрд┐рд╕реА рдПрдХ рдЯреНрд░рд╛рдВрдЬрд┐рдЯ рд▓рд┐рдВрдХ рдкрд░ рдореИрдВ IGP рдореАрдЯреНрд░рд┐рдХ рджреЛрдЧреБрдирд╛ рдХрд░ рджреЗрддрд╛ рд╣реВрдВ? рдмреИрдЯрдлрд┐рд╢ рд╣рдореЗрдВ рдЗрди рдФрд░ рдХрдИ рдЕрдиреНрдп рд╕рд╡рд╛рд▓реЛрдВ рдХреЗ рдЬрд╡рд╛рдм рджреЗрдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧреА!
рдмреИрдЯрдлрд┐рд╢ рдХреА рд╕рдореАрдХреНрд╖рд╛
рдмреИрдЯрдлрд┐рд╢ рдПрдХ рдиреЗрдЯрд╡рд░реНрдХ рдореЙрдбрд▓рд┐рдВрдЧ рдЯреВрд▓ рд╣реИред рдЗрд╕рдХрд╛ рдореБрдЦреНрдп рдЙрджреНрджреЗрд╢реНрдп рдЙрддреНрдкрд╛рджрди рдиреЗрдЯрд╡рд░реНрдХ рдХреЗ рд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рдмрдирд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рд╣реИред рдмреИрдЯрдлрд┐рд╢ рдХрд╛ рдЙрдкрдпреЛрдЧ рдиреЗрдЯрд╡рд░реНрдХ рдХреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдФрд░ рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднреА рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдиреЗрдЯрд╡рд░реНрдХ рдХреА рджреБрдирд┐рдпрд╛ рдореЗрдВ рдореМрдЬреВрджрд╛ CI / CD рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдореЗрдВ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдирдП рд╡рд┐рдиреНрдпрд╛рд╕реЛрдВ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдкрдХрд░рдг рдХрд╛ рдЕрднрд╛рд╡ рд╣реИред рдмреИрдЯрдлрд┐рд╢ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рддреА рд╣реИред
рдмреИрдЯрдлрд┐рд╢ рдХреЛ рдореМрдЬреВрджрд╛ рдиреЗрдЯрд╡рд░реНрдХ рдЙрдкрдХрд░рдг рддрдХ рд╕реАрдзреЗ рд╕реАрдзреЗ рдкрд╣реБрдВрдЪ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ, рдмреИрдЯрдлрд┐рд╢ рдбрд┐рд╡рд╛рдЗрд╕ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓реЛрдВ рдореЗрдВ рдирд┐рд╣рд┐рдд рдбреЗрдЯрд╛ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдиреЗрдЯрд╡рд░реНрдХ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдореЙрдбрд▓ рдХрд░рддрд╛ рд╣реИред
рдмреИрдЯрдлрд┐рд╢ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
- рдиреЗрдЯрд╡рд░реНрдХ рдореЗрдВ рдЧрддрд┐рд╢реАрд▓ рд░реВрдЯрд┐рдВрдЧ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреА рдкрдбрд╝реЛрд╕реА рд╕реНрдерд┐рддрд┐ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВ (рдмреАрдЬреАрдкреА, рдЖрдИрдПрд╕-рдЖрдИрдПрд╕, рдУрдПрд╕рдкреАрдПрдл)
- рдкреНрд░рддреНрдпреЗрдХ рдиреЗрдЯрд╡рд░реНрдХ рддрддреНрд╡ рдХреЗ рдЖрд░рдЖрдИрдмреА рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВ
- NTP, AAA, MTU рд╕реЗрдЯрд┐рдВрдЧ рдЬрд╛рдВрдЪреЗрдВ
- рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдВ рдХрд┐ рдХреНрдпрд╛ рдПрд╕реАрдПрд▓ рдиреЗрдЯрд╡рд░реНрдХ рдЯреНрд░реИрдлрд┐рдХ рдХреЗ рдорд╛рд░реНрдЧ рдХреЛ рдЕрд╡рд░реБрджреНрдз рдХрд░рддрд╛ рд╣реИ (рд╕рд┐рд╕реНрдХреЛ рдПрдПрд╕рдП рдкрд░ рдкреИрдХреЗрдЯ-рдЯреНрд░реЗрд╕рд░ рдХрд╛ рдПрдирд╛рд▓реЙрдЧ)
- рдиреЗрдЯрд╡рд░реНрдХ рдХреЗ рднреАрддрд░ рдореЗрдЬрдмрд╛рди рдХреЗ рдмреАрдЪ рдПрдВрдб-рдЯреВ-рдПрдВрдб рдХрдиреЗрдХреНрдЯрд┐рд╡рд┐рдЯреА рдХреЗ рд▓рд┐рдП рдЬрд╛рдБрдЪ рдХрд░реЗрдВ
- рдиреЗрдЯрд╡рд░реНрдХ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЯреНрд░реИрдлрд╝рд┐рдХ рдХрд╛ рдорд╛рд░реНрдЧ рджрд┐рдЦрд╛рдПрдВ (рд╡рд░реНрдЪреБрдЕрд▓ рдЯреНрд░реЗрд╕рд┐рдВрдЧ)
рд╕рдорд░реНрдерд┐рдд рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо:
- рдЕрдиреНрди рдпрд╛ рдШрд╛рд╕ рдХреА рдмрд╛рд▓
- рдЕрд░реВрдмрд╛
- AWS (VPCs, рдиреЗрдЯрд╡рд░реНрдХ ACLs, VPN GW, NAT GW, рдЗрдВрдЯрд░рдиреЗрдЯ GW, рд╕реБрд░рдХреНрд╖рд╛ рд╕рдореВрд╣)
- рд╕рд┐рд╕реНрдХреЛ (NX-OS, IOS, IOS-XE, IOS-XR рдФрд░ ASA)
- рдбреЗрд▓ рдмрд▓ 10
- рдлрд╛рдЙрдВрдбреНрд░реА
- iptables
- рдЬреБрдирд┐рдкрд░ (рдПрдордПрдХреНрд╕, рдИрдПрдХреНрд╕, рдХреНрдпреВрдПрдлрдПрдХреНрд╕, рдПрд╕рдЖрд░рдПрдХреНрд╕, рдЯреА-рд╕реАрд░реАрдЬрд╝, рдкреАрдЯреАрдПрдХреНрд╕)
- MRV
- рдкрд╛рд▓реЛ рдЕрд▓реНрдЯреЛ рдиреЗрдЯрд╡рд░реНрдХ
- рдХреБрдЧреНрдЧрд╛ / рдПрдлрдЖрд░рдЖрд░
- рдХреНрд╡рд╛рдВрдЯрд╛
- VyOS

рдмреИрдЯрдлрд┐рд╢ рдПрдХ рдЬрд╛рд╡рд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╣реИред рдЗрд╕рдХреЗ рд╕рд╛рде рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдХрд╛рдо рдХреЗ рд▓рд┐рдП рдкрд╛рдпрдмреЗрдЯрдлрд╝рд┐рд╢ - рдЕрдЬрдЧрд░ рдПрд╕рдбреАрдХреЗ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛ред
рдЕрднреНрдпрд╛рд╕ рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВред рдореИрдВ рдЖрдкрдХреЛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рдмреИрдЯрдлрд┐рд╢ рдХреА рд╕рдВрднрд╛рд╡рдирд╛рдУрдВ рдХреЛ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ред
рдЙрджрд╛рд╣рд░рдг
рд╣рдо рджреЛ рд╕реНрд╡рд╛рдпрддреНрдд рдкреНрд░рдгрд╛рд▓рд┐рдпреЛрдВ рдХрд╛ рдкреНрд░рдмрдВрдзрди рдХрд░рддреЗ рд╣реИрдВ: 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 рдХреА рдШреЛрд╖рдгрд╛ рдХреАред рд╕реНрд╡рд╛рдпрддреНрдд рдкреНрд░рдгрд╛рд▓рд┐рдпреЛрдВ рдХреЗ рдмреАрдЪ рд░реВрдЯрд┐рдВрдЧ рд╕реВрдЪрдирд╛рдУрдВ рдХрд╛ рдЖрджрд╛рди-рдкреНрд░рджрд╛рди рдПрдЪрдХреЗрдЖрдИ-рдХреЛрд░ -01 - рдПрд╕рдкреАрдмреА-рдХреЛрд░ -01 рдХреЗ рдЬрдВрдХреНрд╢рди рдкрд░ рд╣реЛрддрд╛ рд╣реИред
HKI-CORE-01, STH-CORE-01 - рдЬреВрдиреЛрд╕ рд░реВрдЯрд░реНрд╕
LDN-CORE-01, AMS-CORE-01, SPB-CORE-01, MSK-CORE-01 - рд╕рд┐рд╕реНрдХреЛ IOS рд░реВрдЯрд░реНрд╕

рдмрдЯрдлрд╝рд┐рд╢ рдФрд░ рдЕрдЬрдЧрд░ рдПрд╕рдбреАрдХреЗ рдХреЗ рд╕рд╛рде рдХрдВрдЯреЗрдирд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ:
docker pull batfish/allinone docker run batfish/allinone docker container exec -it <container> bash
рдкрд╛рдпрдерди рдЗрдВрдЯрд░реЗрдХреНрдЯрд┐рд╡ рдореЛрдб рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП:
root@ea9a1559d88e:/
bf_init_snapshot ('tmp / habr') - рдлрд╝рдВрдХреНрд╢рди
рдмреИрдЯрдлрд╝рд┐рд╢ рдореЗрдВ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рд▓реЛрдб рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рдХрд░рддрд╛ рд╣реИред
/ tmp / habr - рд░рд╛рдЙрдЯрд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ред
root@ea9a1559d88e:/tmp/habr
рдЕрдм LDN-CORE-01 рд░рд╛рдЙрдЯрд░ рдкрд░ BGP рд╕рддреНрд░реЛрдВ рдХреА рд╕реНрдерд┐рддрд┐ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ:
>>> 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
рдЕрдм рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдЖрдИрдПрд╕рдЖрдИ-рдЖрдИрдПрд╕ рдорд╛рд░реНрдЧ рдмрд╛рдмреАрдлрд╝рд┐рд╢ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдПрдЪрдЖрдИрдЖрдИ-рдХреЛрд░ -01 рд░рд╛рдЙрдЯрд░ рдкрд░ рдЖрд░рдЖрдИрдмреА рдореЗрдВ рдХреНрдпрд╛ рд╣реИрдВ:
>>> 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
рдмрд╣реБрдд рдмрдврд╝рд┐рдпрд╛! рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЖрдкрдХреЗ рд▓рд┐рдП рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдмреИрдЯрдлрд┐рд╢ рд╣реИред
рд▓реЗрдЦ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ, рдореИрдВрдиреЗ рд▓рд┐рдЦрд╛ рдХрд┐ рдмреИрдЯрдлрд┐рд╢ рдХрд╛ рдЙрдкрдпреЛрдЧ "рд▓рдбрд╝рд╛рдИ" рдиреЗрдЯрд╡рд░реНрдХ рдкрд░ рд▓рд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЕрдм рдореИрдВ
рд░реЛрдмреЛрдЯрдлреНрд░реЗрдорд╡рд░реНрдХ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рдиреЗрдЯрд╡рд░реНрдХ рдкрд░реАрдХреНрд╖рдг рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд░рддрд╛
рд╣реВрдВ ред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ PyBatfish рдкрд░ рдЖрдзрд╛рд░рд┐рдд рдПрдХ рдЫреЛрдЯрд╛ рдореЙрдбреНрдпреВрд▓ рд▓рд┐рдЦрд╛ рдЬреЛ рдЖрдкрдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ:
- рдиреЗрдЯрд╡рд░реНрдХ рдкрд░ рдмреАрдЬреАрдкреА рд╕рддреНрд░реЛрдВ рдХреА рд╕реНрдерд┐рддрд┐ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВ
- рдЖрдИрдПрд╕-рдЖрдИрдПрд╕ рдкрдбрд╝реЛрд╕реА рдХреА рд╕реНрдерд┐рддрд┐ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВ
- рдЯреНрд░реЗрд╕ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд╕рд╛рде рдиреЗрдЯрд╡рд░реНрдХ рдкрд░ рдиреЛрдбреНрд╕ рдХреЗ рдмреАрдЪ рдПрдВрдб-рдЯреВ-рдПрдВрдб рдХрдиреЗрдХреНрдЯрд┐рд╡рд┐рдЯреА рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдВ
- рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдбрд╛рдпрдирд╛рдорд┐рдХ рд░реВрдЯрд┐рдВрдЧ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рд▓рд┐рдП рд░рд╛рдЙрдЯрд░ рдкрд░ рдЖрд░рдЖрдИрдмреА рдХрд╛ рдЖрдХрд╛рд░ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВ
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
рдкрд░рд┐рджреГрд╢реНрдп N рез

рдореЗрд░реЗ рдирд┐рдпрдВрддреНрд░рдг рдореЗрдВ рдЕрдм рднреА рд╡рд╣реА рдиреЗрдЯрд╡рд░реНрдХ рд╣реИред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдореБрдЭреЗ
41214 рдФрд░
AS 10631 рдХреА рд╕реАрдорд╛ рдкрд░ рдлрд┐рд▓реНрдЯрд░ рд▓рдЧрд╛рдиреЗ рдХреА
рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдФрд░ 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
рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдПрдВред

рдореИрдВ рдмрд╣реБрдд рдХрд░реАрдм рдерд╛, рд▓реЗрдХрд┐рди рдкрд░реАрдХреНрд╖рдг рдЖрдЙрдЯрдкреБрдЯ рд╢реЛ рдХреЗ рд░реВрдк рдореЗрдВ, рдмреАрдЬреАрдкреА рдореЗрдВ рдХрд┐рдП рдЧрдП рдмрджрд▓рд╛рд╡реЛрдВ рдХреЗ рдмрд╛рдж, рдкрдбрд╝реЛрд╕ 192.168.30.0 - 192.168.30.1 рд╕реНрдерд╛рдкрд┐рдд рд░рд╛рдЬреНрдп рдореЗрдВ рдирд╣реАрдВ рд╣реИ -> рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдЕрдВрдХ 135.65.1.1 <-> 140.0.0.1 рдХреЗ рдмреАрдЪ рдЖрдИрдкреА рдХрдиреЗрдХреНрдЯрд┐рд╡рд┐рдЯреА рдЦреЛ рдЬрд╛рддреА рд╣реИред рдХреНрдпрд╛ рдЧрд▓рдд рд╣реИ? рд╣рдо
HKI-CORE-01 рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЛ рдзреНрдпрд╛рди рд╕реЗ рджреЗрдЦрддреЗ рд╣реИрдВ рдФрд░ рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ eBGP peering рдирд┐рдЬреА рдкрддреЗ рдкрд░ рд╕реНрдерд╛рдкрд┐рдд рд╣реИ:
showroute@HKI-CORE-01
рдирд┐рд╖реНрдХрд░реНрд╖: рдЬрдВрдХреНрд╢рди рдкрд░ рдкрддреЛрдВ рдХреЛ рдмрджрд▓рдирд╛ рдпрд╛ рдЕрдкрд╡рд╛рдж рдХреЗ рд▓рд┐рдП 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 рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдирд╣реАрдВ рдЬрд╛рдПрдЧрд╛ 41214 - AS 10631 рдХреЗ рд░реВрдк рдореЗрдВред рдЖрдк рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рдбрд░ рдХреЗ рдмрд┐рдирд╛ рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рдмрджрд▓рд╛рд╡ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдкрд░рд┐рджреГрд╢реНрдп N2

рдпрд╣рд╛рдВ рдореБрдЭреЗ
MSK-CORE-01 рд░рд╛рдЙрдЯрд░ рдкрд░ рдиреЗрдЯрд╡рд░реНрдХ 150.0.0.0/24 рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░рдиреЗ рдФрд░ рдЕрдВрдХ 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
рдЕрдм рдореБрдЭреЗ HKI-CORE-01 рд░рд╛рдЙрдЯрд░ рдкрд░ рджреЛ eBGP рдорд╛рд░реНрдЧреЛрдВ рдХреЛ рджреЗрдЦрдиреЗ рдХреА рдЙрдореНрдореАрдж рд╣реИ, рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдХрдиреЗрдХреНрдЯрд┐рд╡рд┐рдЯреА рдЪреЗрдХ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рд╣реИ
135.65.0.1 рдФрд░ 150.0.0.1 рдХреЗ рдмреАрдЪ рдХреЛрдИ рд╕рдВрдмрдВрдз рдирд╣реАрдВ рд╣реИ, рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛,
HKI-CORE-01 рд░рд╛рдЙрдЯрд░ рдкрд░ рджреЛ рдХреЗ рдмрдЬрд╛рдп рдХреЗрд╡рд▓ рдПрдХ рдИрдЬреАрдЬреАрдкреА рдорд╛рд░реНрдЧ рд╣реИред
MSK-CORE-01 рд░рд╛рдЙрдЯрд░ рдореЗрдВ рдПрдХ рдирдпрд╛ рд╡рд┐рдиреНрдпрд╛рд╕ рдЬреЛрдбрд╝рдиреЗ рдкрд░
HKI-CORE-01 рдкрд░ RIB рдХреА рд╕рд╛рдордЧреНрд░реА рдХреА рдЬрд╛рдБрдЪ рдХрд░реЗрдВ:
showroute@HKI-CORE-01
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

рдорд╣рд╛рди, рдиреЗрдЯрд╡рд░реНрдХ рдХреЗ рдмреАрдЪ рдХрдиреЗрдХреНрдЯрд┐рд╡рд┐рдЯреА рд╣реИ, рд╕рднреА рдкрд░реАрдХреНрд╖рдг рдкрд╛рд░рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ! рддреЛ рдЖрдк рдЗрди рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ "рдореБрдХрд╛рдмрд▓рд╛" рдиреЗрдЯрд╡рд░реНрдХ рдХреЗ рдХрд╛рдо рдореЗрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдирд┐рд╖реНрдХрд░реНрд╖
рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдмрддреНрддреАрдлрд╝рд┐рд╢ рдПрдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдЙрдкрдХрд░рдг рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдмрдбрд╝реА рдХреНрд╖рдорддрд╛ рд╣реИред рдЗрд╕реЗ рдЖрдЬрд╝рдорд╛рдПрдВ рдФрд░ рдЕрдкрдиреЗ рд▓рд┐рдП рджреЗрдЦреЗрдВред
рдпрджрд┐ рдпрд╣ рд╡рд┐рд╖рдп рдЖрдкрдХреЗ рд▓рд┐рдП рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ - рд╕реБрд╕реНрдд рдЪреИрдЯ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрдВ, рддреЛ рдмреИрдЯрдлрд╝рд┐рд╢ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХрд┐рд╕реА рднреА рдкреНрд░рд╢реНрди рдХрд╛ рдЙрддреНрддрд░ рджреЗрдиреЗ рдФрд░ рдХреАрдбрд╝реЗ рдХреЛ рдЬрд▓реНрджреА рдареАрдХ рдХрд░рдиреЗ рдореЗрдВ рдкреНрд░рд╕рдиреНрди рд╣реЛрдВрдЧреЗред
batfish-org.slack.comрдЖрдкрдХрд╛ рдзреНрдпрд╛рди рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред
рд╕рдВрджрд░реНрдн
www.batfish.orgwww.youtube.com/channel/UCA-OUW_3IOt9U_s60KvmJYAgithub.com/batfish/batfishmedia.readthedocs.org/pdf/pybatfish/latest/pybatfish.pdfgithub.com/showroute/batfish-habr