Cisco ASA, автоматизация поиска нужных строк в аксес-листе с помощью python

от автора

Если вы работаете в крупном дата-центре и ваша задача заключается в поддержке межсетевых экранов (Cisco ASA), то вы наверняка сталкивались с огромным количеством строк в их конфигурациях. Эти конфигурации могут включать тысячи объектов и правил доступа (Access Lists).

Для выполнения задач аудита вам иногда нужно найти все правила доступа для определённого сервера, например, с IP-адресом A.B.C.D. В других случаях требуется добавить новое правило доступа, но перед этим необходимо убедиться, что уже существует аналогичное правило. Например, если существует группа клиентов, подключающихся к какому-то серверу, вам нужно найти соответствующее правило и добавить нового клиента в эту группу.

Для решения таких задач существуют коммерческие продукты, такие как Algosec, Tufin и др. Однако несколько Python-скриптов могут выполнить эти задачи не менее эффективно. Далее я покажу примеры таких программ на Python.

Напомню, что Python предустановлен в любой версии Linux и доступен бесплатно.

Я разделил процесс на несколько простых шагов:

  1. Преобразование аксес-листов и сетевых объектов в CSV-файл.

  2. Поиск всех правил, разрешающих доступ от адреса 10.0.3.10 к адресу 5.5.15.100. Для этого необходимо найти все подсети, содержащие данные IP-адреса.

В аксес листе Cisco ASA можно указать IP адреса источника и назначения, но также можно указывать сетевой объект или группу объектов. Группа объектов может включать в себя другие группы объектов. Если выполнить команду show access-list, то увидим расшифровку всех объектов в IP префиксы, что упрощает конвертацию в CSV файл

ciscoasa# show access-list access-list gl1 line 1 extended permit tcp object-group og1 object-group og12 eq ssh (hitcnt=0) 0xf57a470f   access-list gl1 line 1 extended permit tcp 10.0.3.0 255.255.255.0 host 10.0.0.3 eq ssh (hitcnt=0) 0x23c38b59   access-list gl1 line 1 extended permit tcp 10.0.3.0 255.255.255.0 10.0.0.0 255.255.255.0 eq ssh (hitcnt=0) 0x3bc77b3d   access-list gl1 line 1 extended permit tcp 10.0.41.0 255.255.255.0 host 10.0.0.3 eq ssh (hitcnt=0) 0xed8dff32   access-list gl1 line 1 extended permit tcp 10.0.41.0 255.255.255.0 10.0.0.0 255.255.255.0 eq ssh (hitcnt=0) 0xcde224d1 access-list gl1 line 2 extended permit tcp host 10.0.0.3 host 100.100.100.1 eq www (hitcnt=0) 0xf80a10d6 access-list gl1 line 3 extended permit tcp object on1 object on2 eq ssh (hitcnt=0) 0x70f8adb4   access-list gl1 line 3 extended permit tcp host 10.0.0.3 10.0.0.0 255.255.255.0 eq ssh (hitcnt=0) 0x70f8adb4 access-list gl2 line 1 extended permit tcp object-group og1 object-group og12 eq https (hitcnt=0) 0xd0d468b5   access-list gl2 line 1 extended permit tcp 10.0.3.0 255.255.255.0 host 10.0.0.3 eq https (hitcnt=0) 0xae19c8fe   access-list gl2 line 1 extended permit tcp 10.0.3.0 255.255.255.0 10.0.0.0 255.255.255.0 eq https (hitcnt=0) 0x93b63bc0   access-list gl2 line 1 extended permit tcp 10.0.41.0 255.255.255.0 host 10.0.0.3 eq https (hitcnt=0) 0x07c7a712   access-list gl2 line 1 extended permit tcp 10.0.41.0 255.255.255.0 10.0.0.0 255.255.255.0 eq https (hitcnt=0) 0xa7ced8a9 access-list gl2 line 2 extended permit ip object-group og1 object-group og12 (hitcnt=0) 0x516db3da   access-list gl2 line 2 extended permit ip 10.0.3.0 255.255.255.0 host 10.0.0.3 (hitcnt=0) 0x258b842a   access-list gl2 line 2 extended permit ip 10.0.3.0 255.255.255.0 10.0.0.0 255.255.255.0 (hitcnt=0) 0xd82afa19   access-list gl2 line 2 extended permit ip 10.0.41.0 255.255.255.0 host 10.0.0.3 (hitcnt=0) 0x3d4864ae   access-list gl2 line 2 extended permit ip 10.0.41.0 255.255.255.0 10.0.0.0 255.255.255.0 (hitcnt=0) 0xf4e436ba access-list gl2 line 3 extended permit tcp object on1 object on2 eq 121 (hitcnt=0) 0xac470d2c   access-list gl2 line 3 extended permit tcp host 10.0.0.3 10.0.0.0 255.255.255.0 eq 121 (hitcnt=0) 0xac470d2c access-list gl2 line 4 extended permit tcp host 10.0.0.3 10.0.0.0 255.255.255.0 eq ssh (hitcnt=0) 0x5ce66931 access-list gl2 line 5 extended permit tcp object on4_16 object on4_8 eq https (hitcnt=0) 0xd1faa964   access-list gl2 line 5 extended permit tcp 10.0.0.0 255.255.0.0 10.0.0.0 255.0.0.0 eq https (hitcnt=0) 0xd1faa964 access-list gl2 line 6 extended permit tcp object on4_16 object-group og5 eq https (hitcnt=0) 0x99c5cc7d   access-list gl2 line 6 extended permit tcp 10.0.0.0 255.255.0.0 host 1.1.1.1 eq https (hitcnt=0) 0xe802825a   access-list gl2 line 6 extended permit tcp 10.0.0.0 255.255.0.0 host 5.5.5.1 eq https (hitcnt=0) 0x80a1e5b3   access-list gl2 line 6 extended permit tcp 10.0.0.0 255.255.0.0 5.5.15.0 255.255.255.0 eq https (hitcnt=0) 0x25de07fd 

далее python преобразует аксес лист в CSV файл:

gl1,1,10.0.3.0,255.255.255.0,10.0.0.3,255.255.255.255,ssh gl1,1,10.0.3.0,255.255.255.0,10.0.0.0,255.255.255.0,ssh gl1,1,10.0.41.0,255.255.255.0,10.0.0.3,255.255.255.255,ssh gl1,1,10.0.41.0,255.255.255.0,10.0.0.0,255.255.255.0,ssh gl1,2,10.0.0.3,255.255.255.255,100.100.100.1,255.255.255.255,www gl1,3,10.0.0.3,255.255.255.255,10.0.0.0,255.255.255.0,ssh gl2,1,10.0.3.0,255.255.255.0,10.0.0.3,255.255.255.255,https gl2,1,10.0.3.0,255.255.255.0,10.0.0.0,255.255.255.0,https gl2,1,10.0.41.0,255.255.255.0,10.0.0.3,255.255.255.255,https gl2,1,10.0.41.0,255.255.255.0,10.0.0.0,255.255.255.0,https gl2,2,10.0.3.0,255.255.255.0,10.0.0.3,255.255.255.255,ip gl2,2,10.0.3.0,255.255.255.0,10.0.0.0,255.255.255.0,ip gl2,2,10.0.41.0,255.255.255.0,10.0.0.3,255.255.255.255,ip gl2,2,10.0.41.0,255.255.255.0,10.0.0.0,255.255.255.0,ip gl2,3,10.0.0.3,255.255.255.255,10.0.0.0,255.255.255.0,121 gl2,4,10.0.0.3,255.255.255.255,10.0.0.0,255.255.255.0,ssh gl2,5,10.0.0.0,255.255.0.0,10.0.0.0,255.0.0.0,https gl2,6,10.0.0.0,255.255.0.0,1.1.1.1,255.255.255.255,https gl2,6,10.0.0.0,255.255.0.0,5.5.5.1,255.255.255.255,https gl2,6,10.0.0.0,255.255.0.0,5.5.15.0,255.255.255.0,https

Обычным текстовым поиском можно найти искомый IP адрес, но нельзя найти все префиксы в которые входит этот IP адрес. Для этой цели есть библиотека ipaddress. Следующий Python скрипт делает этот поиск:

#!/usr/bin/python3 #  usage " python asa_ip_check.py fw_name src_ip dst_ip"  import csv import ipaddress import sys from sys import argv  args = sys.argv csv_file_src = args[1]+'.csv'    # " ip_src = args[2]                 #  ip_dst = args[3]                                  #app = args[4]  with open(csv_file_src, 'r') as file:           # ip_src     reader = csv.reader(file, delimiter=",")     for row in reader:         if (ipaddress.ip_address(ip_src) in ipaddress.ip_network(f"{row[2]}/{row[3]}", strict=False) and ipaddress.ip_address(ip_dst) in ipaddress.ip_network(f"{row[4]}/{row[5]}", strict=False)):             print ( ip_src ," and ", ip_dst , ' in ', row) 

В какой строке разрешен доступ от адреса 10.0.3.10 к адресу 5.5.15.100 ?

E:\asa_rules_test>python asa_ip_check.py asa 10.0.3.10 5.5.15.100 10.0.3.10  and  5.5.15.100  in  ['gl2', '6', '10.0.0.0', '255.255.0.0', '5.5.15.0', '255.255.255.0', 'https']

далее python преобразующий выход команды show access-list в CSV файл

 #!/usr/bin/python3 #  usage " python asa_acl_to_csv.py fw_name " it will open configuration file fw_name.conf  import csv import sys from sys import argv  args = sys.argv  # Set the input and output file names input_file = args[1] + '.conf'                           # asa show access-list to file fw_name.conf output_file = args[1] + '.csv'                           # address-set  to   fw_name.csv"  # Open the input and output files with open(input_file, "r") as f, open(output_file, "w", newline="") as out_file:     reader = csv.reader(f, delimiter=" ")     writer = csv.writer(out_file)      add_name = None     for row in reader:          aclname = ''         aclline = ''         aclsrc  = ''         aclspr  = ''         acldst  = ''         acldpr  = ''         aclapp  = ''         try:             if ( not ("object" in row) and not ("object-group" in row) and not ("remark" in row) ):                 if ((row[0] == "access-list") and (row[2] == "line") and (row[5] == "permit") ):                     aclname = row[1]                     aclline = row[3]                     if (row[7] == "host"):                         aclsrc  = row[8]                         aclspr  = '255.255.255.255'                         if (row[9] == "host"):                             acldst  = row[10]                             acldpr  = '255.255.255.255'                             aclapp  = row[12]                         else:                             acldst  = row[9]                             acldpr  = row[10]                             aclapp  = row[12]                                                 else:                         aclsrc  = row[7]                         aclspr  = row[8]                         if (row[9] == "host"):                             acldst  = row[10]                             acldpr  = '255.255.255.255'                             aclapp  = row[12]                              else:                             acldst  = row[9]                             acldpr  = row[10]                             aclapp  = row[12]                     if (row[6] == "ip"):                             aclapp  = row[6]                                       elif ((row[2] == "access-list") and (row[4] == "line") and (row[7] == "permit") ):                     aclname = row[3]                     aclline = row[5]                          if (row[9] == "host"):                         aclsrc  = row[10]                         aclspr  = '255.255.255.255'                         if (row[11] == "host"):                             acldst  = row[12]                             acldpr  = '255.255.255.255'                               else:                             acldst  = row[11]                             acldpr  = row[12]                             aclapp  = row[14]                                                 else:                         aclsrc  = row[9]                         aclspr  = row[10]                         if (row[11] == "host"):                             acldst  = row[12]                             acldpr  = '255.255.255.255'                             aclapp  = row[14]                              else:                             acldst  = row[11]                             acldpr  = row[12]                                                     aclapp  = row[14]                     if (row[8] == "ip"):                             aclapp  = row[8]                                                                     print(aclname,aclline,aclsrc,aclspr,acldst,acldpr,aclapp)                 writer.writerow([aclname,aclline,aclsrc,aclspr,acldst,acldpr,aclapp])          except:             print(row) out_file.close()


ссылка на оригинал статьи https://habr.com/ru/articles/834874/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *