2016-06-01 1 views
1

J'ai le code pour trouver le nom de la « classe d'accès » sur la « ligne vty »à l'aide CiscoConfParse trouver ACL appliquée à VTY puis vérifier ACL pour la déclaration de journal

Après que je suis en mesure de trouver l'ACL, mais je veux vérifier chaque ligne de l'ACL pour vérifier que les instructions 'deny' et 'permit' ont le mot-clé 'log'. Et imprimez un rapport d'OPEN s'il n'y a pas d'instruction 'log' ou NOT A FINDING s'il y a une instruction 'log' sur l'entrée.

Et c'est là que je ne sais pas comment analyser les instructions ACL, si je peux utiliser quelque chose de CiscoConfParse ou plus python standard pour faire le travail?

#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() 

est le fichier de configuration d'exemple ici, je me sers avec l'ACL sur le VTY

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 

Répondre

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) 

Quand je lance sur votre config je reçois cette sortie:

(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 
> 

je me suis permis d'ajouter à vos besoins ... Je FLAG lignes vty qui ne disposent pas d'une ACL. Maintenant, vous pourriez demander "Pourquoi a-t-il dit que 'line vty 5 15' n'a pas d'ACL, parce que je l'ai mis dans la config? Parce que j'ai utilisé re_match_iter_typed(), qui ne recherche que les enfants de la ligne parent ... lorsque vous entrez une config comme celui-ci, CiscoConfParse n'associera l'accès classe avec la ligne vty parent sur 5 15, parce que la ligne d'accès de classe ne sont pas dentelée plus line vty 5 15:

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

L'indentation est importante (beaucoup) pour CiscoConfParse ... vous devez connaître vos entrées ... si vous ne pouvez pas compter sur les personnes pour indenter leurs configs, alors utilisez la méthode dans la réponse de Kirk :-)

+0

super, merci beaucoup. J'aime que j'ai maintenant ces deux exemples, cela m'aide beaucoup à la fois dans ma connaissance de python et de ciscoconfparse. Excellent! –

1

J'ai écrit une preuve de concept sur ce point:

#!/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() 

Au niveau général , Je trouve d'abord le nom de l'ACL. Je passe ensuite par chaque ligne de l'ACL à la recherche de permis ou de refus, puis le mot-clé de journal. A partir de là, je crée deux listes: "log_lines" et "no_log_lines". Enfin, j'imprime ces deux à l'écran.

FYI, il serait utile lors de l'affichage du code comme ci-dessus de supprimer le code commenté. Il encombre juste ce que vous faites.

+0

Merci monsieur! Je suis tellement pris et perdu parfois dans les boucles et ne pas reculer et regarder le problème à résoudre ... –

+0

@garrybaker, FYI ... vous pouvez utiliser ['re_match_typed()'] (http: //www.pennington .net/py/ciscoconfparse/api_IOSCfgLine.html # models_cisco.IOSCfgLine.re_match_typed) pour extraire le nom de l'ACL sans avoir besoin de 'match.group (1)' ... vous pouvez aussi utiliser ['re_match_iter_typed()'] (http : //www.pennington.net/py/ciscoconfparse/api_IOSCfgLine.html#models_cisco.IOSCfgLine.re_match_iter_typed) pour parcourir automatiquement les enfants d'un objet ... J'ai illustré dans ma réponse –