Junos PyEZ në shembullin e një detyre për të gjetur nënrrjetet e lira ipv4

NjĂ« artikull rreth punĂ«s me Junos PyEZ — “Python microframework qĂ« ju lejon tĂ« menaxhoni dhe automatizoni pajisjet qĂ« funksionojnĂ« me Junos OS” automatizimi dhe menaxhimi, ashtu siç na pĂ«lqen. Shkrimi i skenarit tĂ« pĂ«rshkruar nĂ« kĂ«tĂ« artikull kishte disa qĂ«llime — tĂ« studiohej Python dhe tĂ« automatizoheshin detyrat pĂ«r mbledhjen e informacionit ose ndryshimin e konfiguracionit nĂ« pajisjet qĂ« funksionojnĂ« me Junos OS. Zgjedhja e lidhjes Python + Junos PyEZ u bĂ« pĂ«r shkak tĂ« pragut tĂ« ulĂ«t tĂ« hyrjes nĂ« gjuhĂ«n e programimit Python dhe thjeshtĂ«sisĂ« sĂ« pĂ«rdorimit tĂ« bibliotekĂ«s Junos PyEZ, e cila nuk kĂ«rkon njohuri ekspertĂ«sh pĂ«r Junos OS.

Detyra

Auditimi i subneteve tĂ« lira ipv4 qĂ« i pĂ«rkasin kompanisĂ«. Kritere pĂ«r tĂ« pĂ«rcaktuar qĂ« subneti Ă«shtĂ« i lirĂ« — Ă«shtĂ« mungesa e njĂ« regjistrimi pĂ«r tĂ« nĂ« itineraret nĂ« switch-in qĂ« ka rolin e router-it nĂ«n administrimin e Junos OS.

Realizimi

Python + Junos PyEZ, ndonëse kishte tundimin të bëhej përmes paramiko dhe ssh.exec_command, si pasojë do të nevojitet ndarja e protokollit të menaxhimit të pajisjeve netconf në pajisjen e pyetur. Netconf punon me pajisjet përmes thirrjeve të procedurave të largëta (remote procedure call RPC) dhe përdor XML, në shembullin e shqyrtuar, për të ofruar informacionin e marrë.

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

$ pip install junos-eznc

Gjithashtu 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ë mundësi tjetër është përmes

$ pip install -r requirements.txt 

kjo komandë do të instalojë bibliotekat që mungojnë në sistem të nevojshme për funksionim. Në versionin tim requirements.txt ka vetëm dy, versionet e caktuara janë të fundit në momentin e shkrimit të skenarit:

junos-eznc
netaddr

Skenari fillimisht merr emrin e përdoruesit aktual në sistem, mund të kyçeni nën 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ë lidhur me pajisjen gjithashtu do të nevojitet të futni sipas kërkesës hostname-in ose adresën IP të saj. Të dhënat e nevojshme për autorizimin në pajisje janë marrë.

Junos PyEZ mbështet lidhjen me pajisjet që funksionojnë me Junos OS duke përdorur konsolën, telnet ose netconf përmes ssh. Në artikullin e shqyrtuar është trajtuar opsioni i fundit.

Për të 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ërkohet informacion për të gjitha itineraret e njohura nga routeri përmes thirrjes së procedurave të largëta ose thirrjen e procedurave të largëta, siç preferohet.

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 të lidhim atë me emrin e metodës RPC, në këtë mënyrë mund të zbulojmë edhe emra të tjerë interesant. Duhet theksuar se sintaksa e shkruajtur e etiketës së kërkesës ndryshon nga emri i metodës, saktësisht duhet të zëvendësohen shenjat e defisëve me thekse të ulëta.

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

Pjesa tjetër e kam vendosur në një cikël while, për të mos kryer përsëri kërkesën në router, nëse do të kontrollohet në një subnet tjetër të njohur nga routeri. Duhet përmendur se router-i nga i cili kërkoj, njeh itineraret vetëm përmes OSPF, kështu që për router-in kufitar është më mirë të ndryshoni pak kërkesën për të reduktuar kohën e punës së skenarit.

data = dev.rpc.get_ospf_route_information()

Tani le të kthehemi në përmbajtjen e ciklit while

Fillimisht përdoruesit do t'i kërkohet të fusë subnetin me maskë dhe jo më shumë se tre oktet nga rrjeti i këtij subneti, kjo është e domosdoshme për të vendosur gamën e kërkimit. Nuk më pëlqen shumë kjo realizim për të vendosur kriterin dhe gamën e kërkimit, por derisa nuk kam gjetur ndonjë zgjidhje më të mirë. Më pas nga lista e marrë e subneteve route_list, duke përdorur variablën që përmban jo më shumë se tre oktet, 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ë të gjitha adresave nga kjo gamë për t'i 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 shfaq në formën e subneteve.

print(netaddr.IPSet(freeip))

Më poshtë është skenari i plotë, është testuar në switches që përdoren si routera, modele 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

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