Однажды моей команде довелось организовывать несложную кустовую схему шифрования для компании, у которой было более 2,5 тысяч офисов продаж и около ста региональных центров. Всё техническое описание решения легко излагалось в таблице Excel размером 2 800 строк на 25 столбцов, но где было взять столько эникейщиков, которые бы настроили оборудование без ошибок?  Если бы эта история была про оборудование, не поддерживающее автоматизацию ни в каком формате, именно так нам и пришлось бы поступить: развернуть некий стенд и найти десяток студентов для тестирования корректности настроек. Мы же имели дело с криптошлюзами S-Terra, и в нашем случае всё упиралось в знание Ubuntu и автоматизации по протоколу SSH. Автоматизировать нужно было два отдельных момента: загрузку конфигурации Cisco-like и инициализацию устройств. Для этого мы решили использовать систему управления конфигурациями Ansible.  В статье я расскажу, как мы пытались скрестить Ansible с криптошлюзами S-Terra, и что из этого вышло. Надеюсь, наш опыт будет полезным тем, кто возьмётся за подобный проект на базе решения S-Terra и будет искать способ ускорить конфигурирование оборудования и свести на нет человеческий фактор. Одним из вариантов, которые мы рассматривали, было написать собственные скрипты на основе инструментов Netmiko или Paramiko с использованием модуля TextFSM. С одной стороны, это могла быть хорошая возможность отработать на практике знания, полученные при прочтении книги Наташи Самойленко «Python для сетевых инженеров». С другой, несколько лет назад я участвовал в подобной активности и помню, как намучился тогда с обработкой вывода, парсингом и подключением по SSH. Так что в итоге мы признали этот вариант решения слишком долгим и сложным, а к тому же и плохо масштабируемым. Альтернативным вариантом было использовать бесплатное решение Ansible. В его пользу говорило наличие различных модулей под Cisco и Linux, а также огромная база знаний. Удобным было ещё и то, что в этом случае мы могли не вливать полный файл конфигурации, а отслеживать этапы: настройка интерфейсов, маршрутизации, Crypto, мониторинга и так далее. В итоге этот вариант и выбрали. Поскольку у Ansible не было готовых модулей под продукты S-Terra, мы решили декомпозировать задачу: а именно разбить playbook на play Cisco-like и play Linux. Для начала мы попробовали отдельные task для выполнения отдельных конфигураций, а позже play для выполнения конфигураций в оболочке Cisco-like. Когда мы обкатали первую заливку конфигурации, то пришли к выводу, что наиболее удобно будет делать файлы переменных для каждого устройства в hostvars. Конечно, можно было вывести пароли, переменные мониторинга и серверов инфраструктуры в groupvars, но тогда мы потеряли бы гибкость, а заказчику во многом нужны были индивидуальные настройки. В итоге файл переменных для каждой точки стал выглядеть примерно так: Каждая role использовала свою группу переменных (MAPS, ACL, route и т.д.), которая представляла собой отдельный dict и/или list в формате json. Часть переменных, например, Interfaces, использовались на всём протяжении playbook. В качестве основного проектного документа мы приняли файл с расширением .xlsx. Для того, чтобы не перебирать каждый раз ячейки таблицы и не тратить на это огромное количество времени, мы разбили скрипты на три части. Первая часть выгружала нужную информацию из .xlsx в SQL. Это было необходимо для получения выгрузки данных из строк по определенным фильтрам. Про модуль pandas, который помог бы решить эту задачу более простым путём, на момент создания скрипта я не знал.  Вторая часть скриптов проверяла SQL на ошибки: отсутствие пересечений, корректность peer и другие. Всего у нас получилось семь функций проверки. Как говорится, не ошибается тот, кто ничего не делает, и тут это правило работало на 100%. Третья часть включала в себя основной скрипт формирования конфигурации и скрипт для формирования изменений. Первый представлял собой группу функций, формирующих переменные для print(template.format(var1,….)), которые в свою очередь являются dict и/или list в формате json в конфигурации для Ansible. Второй мы сделали, так как со временем у нас появилась потребность парсинга (textFSM) файлов Cisco-like конфига уже установленных устройств S-Terra и формирования изменений (diff_conf). Вроде всё сделали красиво, но тут нас ждал первый булыжник — уровни вложенности переменных в Ansible. Оказалось, что при использовании модуля cisco.ios.ios_acls сделать перебор переменных аналогично [списку [списков]] не получится. Пролистав N страниц в интернете и протестировав несколько вариантов, мы пришли к использованию конструкции loop + subelements. Я думаю, что боль использования модуля cisco.ios.ios_acls понимает любой сетевой инженер, который с ним работал. На мой взгляд, так неудобно сделать мог только человек, который никогда это не настраивал. Наши ощущения можно сравнить со случаем, когда решение по маршрутизации трафика в организации реализуется не на основе динамической маршрутизации, а на основе запуска файлов с расширением .bat, меняющих def route на host: администратор сделал, а на сетевом инженере сэкономили. К сожалению, ход с конструкцией loop + subelements не решил проблему с использованием правил для /32 сетей, так как в Cisco-like их надо вводить как host, а как запустить when по внутреннему списку, я так и не придумал. Тогда я впервые вспомнил фразу из одной статьи «Ansible — это не язык программирования, это инструмент автоматизации». Пришлось потом это реализовывать отдельной role. Второй булыжник был в том, что модули Ansible работали не совсем так, как нам хотелось бы это видеть. Модуль sudo так и не получилось запустить на Linux S-Terra, модули ACL и cisco.ios.ios_config не могли в цикле анализировать конфигурацию, удалять лишнее и дополнять недостающее (описанная выше ситуация с host). Так мы пришли к выводу, что всё нужно тестировать, причём очень внимательно и скрупулёзно. Третий булыжник ждал нас в ситуации перехода с одной учётки на другую, когда настроили что-то под root в Linux и теперь то же самое надо сделать под cscons в Cisco-like, а для этого нужно поменять переменные внутри одного playbook. Тут, конечно, всё оказалось гораздо проще, спасибо статье, из которой я вообще очень много почерпнул для общего понимания работы системы. После второго прочтения я всё-таки понял, почему playbook, а не play. Где же здесь book? Ведь переменные используются в пределах одного play, и если их нужно переопросить для SSH-сессии, то есть снова забрать значения из vars, то необходимо сделать новый play. На самом деле до сих пор не понимаю, где и как настраиваются параметры SSH-сессии и почему нельзя было сделать в ansible.conf список параметров, аналогичный Netmiko, но это я просто чего-то не понимаю.  Четвертый булыжник был уже на этапе настройки. При заливке S-Terra с большим количеством MAP, задаваемых в используемом нами формате, Ansible лавинообразно начинал потреблять RAM. Как он умудрился 50-килобайтовый текстовый файлик конфига превратить в 1Гбайт RAM, я не знаю. Но это был очень неожиданный сюрприз. Пришлось выделять 8Гбайт памяти. Наверное, это тоже можно было как-то решить, но я не придумал, что именно надо вбить в Google для поиска решения проблемы. Впрочем, на этом булыжники закончились и началось довольно приятное сосуществование: конфигурации получились понятными и читаемыми, а все названия стандартизованными. Всплывающие ошибки были достаточно читаемы и связаны с ошибками скрипта создания конфигураций. К тому же мы сэкономили кучу времени и нервов при загрузке custom-скриптов SNMP, ведь за этим бы последовало многочисленное копирование файлов, запуск большого количества скриптов, выполнение проверок и конфигурирование cron. В итоге мы подготовили к установке почти три тысячи устройств.  Когда я слышу слово «инициализация», мне тут же вспоминается любимый лозунг безопасников «Инженер должен … страдать». Потому как на ПАК серии ниже 3 000 нужно руками вбивать случайную последовательность для генерации Гаммы. Поклонники популярного в начале 2000-ых способа обучения слепому набору текста «СОЛО на клавиатуре» были бы в восторге от такого решения. Что мы сделали: на S-Terra G-7000 создали нужное количество gamma и загрузили их на SCP-сервер. Далее получили лицензии в текстовом формате от вендора S-Terra и написали скрипт на Python для управления криптошлюзами через COM-порт. Тут мы столкнулись только с одной проблемой — статикой при переключении USB-COM конвертера. Из-за неё у нас появлялись дополнительные символы при вводе пароля учётки Administrator. В процессе запуска на объектах мы также сформировали группу plays и roles для сбора данных о состоянии устройств S-Terra, проверки прохождения пакетов по шифрованным каналам, доступности инфраструктуры заказчика, сбора lic параметров и S/N. Такое управление сетью оказалось довольно удобным.  Если изначально за день нам удавалось настроить два-четыре устройства, и при этом было достаточно много ошибок, то по итогам автоматизации мы ускорили настройку конфигурации криптошлюзов S-Terra серий G-100, G-1000 и G-2000 до 30 устройств в день, а серий G-3000 и G-7000 — до 15 устройств в день. В случае с последними основное ограничение было только в распаковывании больших коробок и настройке «Аккорда».   Автор: Олег Рябикин, руководитель группы сетевой безопасности «Solar Интеграция» компании «Ростелеком-Солар»