Junos PyEZ në shembullin e detyrës për gjetjen e nënshtesave të lira ipv4

Artikulli mbi punĂ«n me Junos PyEZ — “Python microframework qĂ« lejon menaxhimin dhe automatizimin e pajisjeve qĂ« funksionojnĂ« me Junos OS” automatizimi dhe menaxhimi, gjithçka siç e duam. Shkrimi i skriptit tĂ« pĂ«rshkruar nĂ« kĂ«tĂ« artikull kishte disa qĂ«llime — studimi i Python dhe automatizimi i detyrave pĂ«r mbledhjen e informacionit ose ndryshimin e konfiguracionit nĂ« pajisjet qĂ« menaxhohen nga Junos OS. Zgjedhja e kĂ«saj kombinimi Python + Junos PyEZ u bĂ« pĂ«r shkak tĂ« prags sĂ« ulĂ«t tĂ« hyrjes nĂ« gjuhĂ«n e programimit Python dhe lehtĂ«sisĂ« sĂ« pĂ«rdorimit tĂ« bibliotekĂ«s Junos PyEZ, qĂ« nuk kĂ«rkon njohuri ekspertĂ«sh mbi Junos OS.

Detyra

Auditimi i nĂ«nrrjeteve tĂ« lira ipv4 qĂ« i pĂ«rkasin kompanisĂ«. Kritere qĂ« nĂ«nrrjeti Ă«shtĂ« i lirĂ« — Ă«shtĂ« mungesa e njĂ« regjistrimi pĂ«r tĂ« nĂ« rrugĂ«t nĂ« switch-in qĂ« funksionon si router nĂ«n menaxhimin e Junos OS.

Implementimi

Python + Junos PyEZ, ndonëse ishte një joshje të bëhej përmes paramiko dhe ssh.exec_command, si pasojë do të nevojitet që në pajisjen e sondazhuar të konfigurohet protokolli i menaxhimit të rrjetit netconf. Netconf funksionon me pajisjet përmes thirrjeve të procedurave të largëta (remote procedure call RPC) dhe përdor XML, në shembullin në fjalë, për të ofruar informacionin e marrë.

Instalimi i versionit aktual të Junos PyEZ nga PyPI, kryhet me komandën e mëposhtme:

$ pip install junos-eznc

Po ashtu mund të instalohet nga dega kryesore e projektit në GitHub me komandën e mëposhtme:

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

Dhe një opsion tjetër përmes

$ pip install -r requirements.txt 

kjo komandë do të instalohet bibliotekat që mungojnë në sistem të nevojshme për funksionimin. Në versionin tim requirements.txt kanë gjithsej dy, versionet e përcaktuara janë të fundit në momentin e shkrimit të skriptit:

junos-eznc
netaddr

Skripti automatikisht merr emrin e përdoruesit aktual në sistem, mund të kyçesh me emrin e një përdoruesi tjetër duke përdorur çelësin show_route.py -u , getpass.getpass merr fjalëkalimin nga stdin kështu që fjalëkalimi nuk do të mbetet në sistem. Për t'u lidhur me pajisjen gjithashtu do të nevojitet të shkruhet sipas kërkesës hostname-i ose adresa ip. Të gjitha të dhënat e nevojshme për autorizimin në pajisje janë të marra.

Junos PyEZ mbështet lidhjen me pajisjet që funksionojnë me Junos OS duke përdorur konsolën, telnet ose netconf përmes ssh. Në artikull shqyrtohet varianti më i fundit.

Për t'u lidhur me pajisjen përdoret klasa Device e modulit jnpr.junos

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

Kërkesa për të gjitha rrugët e njohura nga routeri kryhet përmes thirrjeve për procedura të largëta, siç është më e përshtatshme për ju.

data = dev.rpc.get_route_information()

Komanda e ngjashme në Junos OS

user@router> show route | display xml

Duke shtuar në fund të komandës rpc, do të marrim etiketën e kërkesës dhe mund ta përputhim atë me emrin e metodës RPC; në këtë mënyrë mund të zbulojmë edhe emra të tjerë interesantë. Vlen të përmendet se sintaksa e shkrimit të etiketës së kërkesës ndryshon nga emri i metodës, do të thotë se duhet të zëvendësojmë shenjat e hendekëve me nënviza.

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

Këtë pjesë tjetër e kam rrethuar në një cikël while, për të shmangur kryerjen e kërkesës për routerin nëse duhet të kontrolloj në një subnet tjetër nga ato që routeri tashmë i njeh. Vlen të përmendet se routeri në të cilin po kërkoj njeh rrugët vetëm nëpërmjet OSPF, prandaj për routerin kufitar është më e mira të ndryshoj pak kërkesën, për të shkurtuar kohën e funksionimit të skriptit.

data = dev.rpc.get_ospf_route_information()

Tani do të kthehem në përmbajtjen e ciklit while

Fillimisht përdoruesit do t'i kërkohet të fusë subnet me maskë dhe jo më shumë se tre oktete nga ky subnet, kjo është e nevojshme për të caktuar gamën e kërkimit. Nuk më pëlqen shumë kjo realizim për caktimin e kriterit dhe gamës së kërkimit, por deri tani nuk kam gjetur një zgjidhje më të mirë. Më pas, nga lista e marrë e subnet-eve route_list, duke përdorur variablin që përmban jo më shumë se tre oktete, zgjedh subnetet që më interesojnë.

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

Përmes IPNetwork, modulit netaddr, marr subnetet në formën e një liste ipv4 adresash.

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

Duke përdorur IPNetwork nga rrjeti i futur nga përdoruesi, me maskë, marr gamën e adresave dhe formoj një listë të gjitha adresave nga kjo gamë për ta krahasuar me listën e adresave të zëna.

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

Lista e marrë e adresave të lira e nxjerr në formën e subneteve.

print(netaddr.IPSet(freeip))

Më poshtë është skripti plotësisht, testuar në switch-at e përdorur si router, modelet 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

Burimi: habr.com

Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster