2016-06-01 14 views
1

Ich habe den Code, um den Namen der Zugangs-Klasse "zu finden auf der‚Linie vty‘CiscoConfParse mit ACL VTY angewandt zu finden und dann ACL prüft für Log-Anweisung

Danach ich in der Lage bin zu finden die ACL, aber dann möchte ich jede Zeile der ACL überprüfen, um zu überprüfen, ob die Anweisungen "deny" und "permit" das Schlüsselwort "log" haben. Und drucken Sie einen Bericht von OPEN, wenn es keine 'Protokoll' Anweisung gibt oder NOT A FINDING, wenn eine 'Protokoll' Anweisung für den Eintrag vorhanden ist.

Und das ist, wo ich ratlos für die ACL-Anweisungen zu analysieren, ob ich etwas von CiscoConfParse oder mehr Standard-Python verwenden können, um die Aufgabe zu erledigen?

#Importing the necessary modules. 
import sys 
from sys import argv 
#Importing the necessary modules. 
from ciscoconfparse import CiscoConfParse 
import sys 
import argparse 

def check_VTY_ACL_NET1637(): 
## Search for LINE VTY access-list name then check if that ACL has log keyword 
# 
    for VTY_ACL in parse.find_children_w_parents('line vty', 'access-class'): 
     #print(VTY_ACL[14]) 
     VTY_ACL = VTY_ACL.lstrip('access-class ') 
     #print (VTY_ACL) 
     VTY_ACL_2 = VTY_ACL.rstrip(' in') 
     #print(VTY_ACL_R) 
     #has_ACL_in = VTY_ACL.find_lines(r'access-class') 
     #print(has_ACL_in) 
     #for IP_ACL_LIST in parse.find_objects_w_child(VTY_ACL_R, 'log'): 
     #for IP_ACL_LIST in parse.find_lines(VTY_ACL_R): 
     for IP_ACL_LIST in parse.find_parents_w_child(VTY_ACL_2, ''): 
      #print(IP_ACL_LIST) 
      #IP_ACL_ACE = parse.has_line_with(' log') 
      IP_ACL_ACE = parse.find_children_w_parents(IP_ACL_LIST, '') 
      #print(IP_ACL_ACE) 
      has_log_keyword = parse.has_line_with(r' log') 
      #print(has_log_keyword) 
      # 
      #has_log_keyword = has_log_keyword.split() 
      for log in IP_ACL_ACE: 
       #print (log) 
       #has_not_log_keyword = parse.has_line_with(r'. log') 
       #print(has_not_log_keyword) 
       keyword_log = 'log' 
       keyword_permit = 'permit' 
       keyword_deny = 'deny' 
       log = log.split() 
       print (log) 
       if (not keyword_log): 
        print('OPEN LINE VTY') 
       else: 
        print("Not a Finding: 'NET-VLAN-023'") 


# Main starting of script 
def start(): 
script, input_file = argv 
global parse 
parse = CiscoConfParse (input_file) 
print("Opening config file: %r\n" % input_file) 
check_VTY_ACL_NET1637() 

def main(): 
args = sys.argv[1:] 
if len(args) == 1: 
    start() 
#else: 
    #usage() 

if __name__ == "__main__": 
main() 

hier ist die Beispielkonfigurationsdatei I mit der ACL auf dem VTY bin mit

Current configuration : 25432 bytes 
! 
ip access-list extended SSH2-IN 
remark ///\\\///\\\///\\\///\\\///\\\///\\\/// 
remark ///\\\***DEC 8 2015***///\\\ 
remark SomeSite //VoSIP // 
remark ****************************************** 
permit ip 10.227.2.128 0.0.0.63 any 
permit tcp 43.81.133.0 0.0.0.255 any eq 22 log 
deny ip any any 
! 
line vty 0 4 
access-class SSH2-IN in 
line vty 5 15 
access-class SSH2-IN in 
! 
end 

Antwort

1
from ciscoconfparse import CiscoConfParse 

input_file = 'some_site.conf' 
parse = CiscoConfParse(input_file) 

## Build a list of vty ACLs here (and flag if a vty doesn't have one) 
vty_acl_names = set([]) 
for vtyobj in parse.find_objects(r'^line\svty'): 

    vty_acl_name = vtyobj.re_match_iter_typed('access-class\s+(\S+)\s+in', 
     result_type=str, default="") 

    if not vty_acl_name: 
     print "FAIL: '{0}' doesn't have an ACL".format(vtyobj.text) 
    else: 
     vty_acl_names.add(vty_acl_name) 

## Check ACL log compliance here (and ensure the ACL is even in the config) 
for vty_acl_name in vty_acl_names: 
    try: 
     aclobj = parse.find_objects(r'ip\s+access-list\s+extended\s+{0}'.format(vty_acl_name))[0] 
    except IndexError: 
     print "FAIL: ACL {0} is applied to a vty, but it's missing from the config!".format(vty_acl_name) 
    ## NOTE: this only works if you are using extended ACLs on the VTY 
    for ace in aclobj.children: 

     if 'remark' in ace.text: 
      continue 
     if 'log' in ace.text: 
      print "NOT A FINDING - ACL {0}, ACE: {1}".format(vty_acl_name, ace.text) 
     else: 
      print "OPEN (no log) - ACL {0}, ACE: {1}".format(vty_acl_name, ace.text) 

Wenn ich es auf der Config laufen bekomme ich diese Ausgabe:

(py27_default) [email protected] C:\Users\mpenning 
> python garrybaker.py 
FAIL: 'line vty 5 15' doesn't have an ACL 
OPEN (no log) - ACL SSH2-IN, ACE: permit ip 10.227.2.128 0.0.0.63 any 
NOT A FINDING - ACL SSH2-IN, ACE: permit tcp 43.81.133.0 0.0.0.255 any eq 22 log 
OPEN (no log) - ACL SSH2-IN, ACE: deny ip any any 

(py27_default) [email protected] C:\Users\mpenning 
> 

ich die Freiheit, auf Ihre Anforderungen der Zugabe nahm ... Ich Flagge vty Linien, die keine ACL haben.

Jetzt könnten Sie fragen: "Warum hat es gesagt, dass 'line vty 5 15' keine ACL hat, weil ich es in die Konfig? Es ist, weil ich re_match_iter_typed() verwendet, die nur Kinder der Elternlinie durchsucht ... wenn Sie Eingabe eine Config wie diese, assoziiert CiscoConfParse nicht die Zugriffsklasse mit der Mutter vty Linie auf 5 15, weil die Zugriffsklasse Linie mehr als line vty 5 15 nicht gegliederte ist:

line vty 0 4 
access-class SSH2-IN in 
line vty 5 15 
access-class SSH2-IN in 
! 

Einrückung (sehr wichtig) für CiscoConfParse ... Sie müssen Ihre Eingaben kennen ... Wenn Sie nicht davon ausgehen können, dass Leute ihre Configs einrücken, dann benutzen Sie die Methode in Kirks Antwort :-)

+0

groß dargestellt, vielen Dank. Ich mag, dass ich jetzt diese beiden Beispiele habe, es hilft mir sehr in meinem Wissen über Python und Ciscoconfarse. Ausgezeichnet! –

1

ich auf diese ein Proof of Concept up schrieb:

#!/usr/bin/env python 

import re 
from ciscoconfparse import CiscoConfParse 

def main(): 
    cisco_file = 'cisco_ipsec.txt' 
    cisco_cfg = CiscoConfParse(cisco_file) 
    vty_acl = cisco_cfg.find_objects(r'access-class') 

    # Find the ACL name 
    acl_name = '' 
    for entry in vty_acl: 
     if 'line vty' in entry.parent.text: 
      match = re.search(r'access-class (.*) in', entry.text) 
      if not acl_name: 
       acl_name = match.group(1) 
      else: 
       new_acl_name = match.group(1) 
       if new_acl_name != acl_name: 
        raise ValueError("ACL names do not match") 

    if not acl_name: 
     raise ValueError("ACL not found under line vty") 

    the_acl = r"ip access-list extended {}".format(acl_name) 
    acl_object = cisco_cfg.find_objects(the_acl)[0] 

    # Parse the ACL lines looking for 'log' keyword  
    log_lines = [] 
    no_log_lines = [] 
    for line in acl_object.all_children: 
     if 'permit' in line.text or 'deny' in line.text: 
      if 'log' in line.text: 
       log_lines.append(line.text) 
      else: 
       no_log_lines.append(line.text) 

    print "\nLines with log" 
    print '#' * 50 
    for line in log_lines: 
     print line 
    print '#' * 50 

    print "\nLines without log" 
    print '#' * 50 
    for line in no_log_lines: 
     print line 
    print '#' * 50 
    print 


if __name__ == "__main__": 
    main() 

Auf einer allgemeinen Ebene , Finde ich zuerst den ACL-Namen. Ich gehe dann durch jede Zeile der ACL auf der Suche nach Erlaubnis oder verweigern und dann das Schlüsselwort log. Daraus erstelle ich zwei Listen: "log_lines" und "no_log_lines". Zum Schluss drucke ich diese beiden den Bildschirm aus.

FYI, es würde helfen, wenn Sie Code wie den oben genannten auskommentierten Code ausstreifen. Es stopft nur, was Sie tun.

+0

Danke, mein Herr! Ich bin so gefangen und verloren manchmal in Schleifen und nicht zurückzutreten und auf das Problem zu lösen ... –

+0

@garrybaker, FYI ... Sie können ['re_match_typed()'] (http: //www.pennington .net/py/ciscoconfparse/api_IOSCfgLine.html # models_cisco.IOSCfgLine.re_match_typed) um den Namen der ACL zu extrahieren, ohne 'match.group (1)' ... zu benötigen, können Sie auch ['re_match_iter_typed()'] (http : //www.pennington.net/py/ciscoconfparse/api_IOSCfgLine.html#models_cisco.IOSCfgLine.re_match_iter_typed) um automatisch über die Kinder eines Objekts zu iterieren ... Ich habe das in meiner Antwort –