Junos PyEZ ipv4 vabade alamvõrkude otsimise ülesande näite põhjal

Artikkel Junos PyEZ-ist — "Pythoni mikro raamistik, mis võimaldab teil hallata ja automatiseerida seadmeid, mis töötavad Junos OS-i peal" automatiseerimisest ja haldamisest, just nagu me armastame. Käesolevas artiklis välja toodud skripti kirjutamisel oli mitu eesmärki — Pythoniga tutvumine ja ülesannete automatiseerimine seoses teabe kogumise või konfiguratsiooni muutmisega Junos OS-i juhtimise all olevatel seadmetel. Python + Junos PyEZ kombinatsiooni valik tehti Python programmeerimiskeele madala sissepääsu künnise ja Junos PyEZ teegi lihtsa kasutatavuse tõttu, mis ei nõua ekspertteadmisi Junos OS-ist.

Ülesanne

IPv4 alampoodide audit, mis kuuluvad ettevõttele. Kriteerium alampoe vabana pidamiseks on selle puudumine marsruutides lülitil, mis täidab ruutimise rolli Junos OS-i all.

Rakendamine

Python + Junos PyEZ, kuigi oli kiusatus kasutada paramiko ja ssh.exec_command, kuna tuleb seadmel, mida küsitakse, seadistada seadmete võrguhalduse protokoll netconf. Netconf töötab seadmetega kaugete protseduurikutsude (remote procedure call RPC) kaudu ja kasutab antud näites XML-i, et esitada saadud teavet.

Junos PyEZ praeguse versiooni paigaldamine PyPI-st toimub järgmise käsu abil:

$ pip install junos-eznc

Saate paigaldada ka projekti põhivoolust GitHubis järgmise käsu abil:

$ pip install git+https://github.com/Juniper/py-junos-eznc.git

Ja veel üks variant läbi

$ pip install -r requirements.txt 

see käsk paigaldab süsteemis puuduvad teegid, mis on vajalikud tööks. Minu versioonis requirements.txt on neid kokku kaks, versioonid on viimased artikli kirjutamise hetkel:

junos-eznc
netaddr

Skript võtab vaikimisi kasutaja nime süsteemis, näiteks teise kasutaja alla sisselogimiseks saab kasutada võtme show_route.py -u getpass.getpass võtab parooli stdin-ist, nii et parool ei jää süsteemi. Seadmega ühenduse saamiseks peate samuti sisestama selle hostname'i või IP-aadressi. Kõik vajalikud autentimise alused seadmes on saadud.

Junos PyEZ toetab ühenduse loomist seadmetega, mis töötavad Junos OS-i peal, kasutades konsooli, telneti või netconf-i ssh kaudu. Artiklis käsitletakse viimast varianti.

Seadmega ühenduse saamiseks kasutatakse mooduli jnpr.junos klassi Device

with jnpr.junos.Device(host=router,
                           user=args.name,
                           passwd=password) as dev:

Küsimus kõigi sektsiooni teadaolevate marsruutide kohta, kasutades kaugprotseduuride väljakutseid, olenevalt sellest, mis on mugavam.

data = dev.rpc.get_route_information()

Sarnane käsk Junos OS-is

user@router> show route | display xml

Käskides rpc lisada, saame päringute silti ja saame seda siduda RPC meetodi nimega, selle meetodi abil saame teada ka teisi huvipakkuvaid nimesid. Tuleb märkida, et päringu silti kirjutamise süntaks erineb meetodi nimest; nimelt tuleb asendada sidekriipsud alamtäppidega.

user@router> show route | display xml rpc
route_list = data.xpath("//rt-destination/text()")

Ostasin ülejäänud osa while-tsüklisse, et vältida korduvat päringut ruuterile, kui pean kontrollima teises alamvõrgus, millest ruuter juba teab. Tuleb mainida, et ruuter, millelt ma küsin, teab marsRoute ainult OSPF-i kaudu, seega oleks paremal piiratud ruuteril parem päringut natuke muuta, et vähendada skripti tööaega.

data = dev.rpc.get_ospf_route_information()

Nüüd pöördume tagasi while-tsükli sisu poole

Alguses palutakse kasutajal sisestada alamvõrk maskiga ja mitte rohkem kui kolm oktetti sellest alamvõrgust, see on vajalik otsingupiiri määramiseks. Selline otsingutingimuste ja -piiri määramine ei meeldi mulle väga, kuid ma pole leidnud paremat lahendust. Edasi valin saadud alajõudude loendist route_list, kasutades muutujat, mis sisaldab mitte rohkem kui kolme oktetti, mind huvitavaid alamvõrke.

tmp = re.search(r'^%sS*' % subnet_search, route_list[i])

IPNetworki kaudu, netaddr mooduli abil, saan alamvõrgud ipv4 aadresside loendina.

range_subnet = netaddr.IPNetwork(tmp.group(0))

Kasutades kasutaja sisestatud võrgust maskiga, saan aadresside vahemiku ja koostan selle vahemiku kõigi aadresside loendi, et võrrelda seda hõivatud aadresside loendiga.

for i in set(net_list).difference(set(busyip)):
        freeip.append(i)

Kinnitatud vabade aadresside loendi väljastan alamvõrkude kujul.

print(netaddr.IPSet(freeip))

Allpool on skript täpselt, see testiti lülititel, mis tegutsevad ruuterina, mudelid ex4550, ex4600.


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
import getpass
import netaddr
import re
import sys

import jnpr.junos

parser = argparse.ArgumentParser()
parser.add_argument('-u', '--user',
                    action='store',
                    dest='name',
                    help='Enter login from tacacs if it differs from the '
                         'username in the system.')
args = parser.parse_args()

if not args.name:
    args.name = getpass.getuser()    # Return the “login name” of the user.
router = input("Full routers name: ")
password = getpass.getpass("Password: ")

try:
    # Authenticates to a device running Junos, for get information about routs
    # into xml format and selects by tag.
    route_list = []
    with jnpr.junos.Device(host=router,
                           user=args.name,
                           passwd=password) as dev:
        data = dev.rpc.get_route_information()
    route_list = data.xpath("//rt-destination/text()")
except (jnpr.junos.exception.ConnectRefusedError,
        jnpr.junos.exception.ConnectUnknownHostError) as err:
    print("Equipment name or password wrong.")
    sys.exit(1)

while True:
    subnet = input("Net with mask: ")
    subnet_search = input("Input no more three octet: ")
    # Gets a list of busy IP addresses from the received subnets.
    busyip = []
    for i in range(len(route_list)):
        tmp = re.search(r'^%sS*' % subnet_search, route_list[i])
        if tmp:
            range_subnet = netaddr.IPNetwork(tmp.group(0))
            for ip in range_subnet:
                busyip.append("%s" % ip)
    range_subnet = netaddr.IPNetwork(subnet)
    # Gets list ip adresses from subnetworks lists.
    net_list = []
    for ip in range_subnet:
        net_list.append("%s" % ip)
    # Сomparing lists.
    freeip = []
    for i in set(net_list).difference(set(busyip)):
        freeip.append(i)
    print(netaddr.IPSet(freeip))

    request = input("To run request again enter yes or y, "
                    "press 'enter', complete request: ")
    if request in ("yes", "y"):
        continue
    else:
        print('Bye')
        break

Allikas: habr.com

Osta usaldusväärne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster