Погодин Евгений — ИТ Заметки
🌐Cisco Обновлено 13.10.2026

Cisco с нуля 24. EEM и первые шаги автоматизации

Note

Команды сверены с официальной документацией Cisco (руководства по настройке Cisco IOS XE 17.x для Catalyst 9000 и маршрутизаторов ISR; отличия классической IOS 15.x отмечены в тексте). Перед работой на боевом оборудовании проверьте их на тестовом стенде или сделайте резервную копию.

Последняя статья второй части посвящена тому, чтобы перестать делать руками то, что устройство или скрипт сделают сами. Мы разберём два уровня автоматизации. Первый находится на самом оборудовании: Embedded Event Manager (EEM), встроенный механизм «если случилось событие, выполни действия». Второй работает снаружи: скрипты на Python и системы вроде Ansible заходят на устройства по SSH и выполняют команды. В конце коротко обзор программируемости IOS XE (NETCONF, RESTCONF, YANG) и шаблонов конфигурации.

После прочтения вы сможете:

  • сформулировать правила безопасной автоматизации и следовать им;
  • написать три апплета EEM: реакцию на падение WAN, еженедельную копию конфигурации и защиту от опасной команды;
  • проверять и отлаживать апплеты, понимать их ограничения и риски;
  • собрать резервные копии конфигураций списка устройств скриптом Netmiko и коротким playbook Ansible;
  • понимать, что такое NETCONF, RESTCONF, YANG и Guest Shell, и какие меры безопасности нужны при их включении.

Что понадобится

  • Статья самостоятельная, но желательно знать статью 02 (SSH, время, журнал) и статью 12 (резервные копии, archive, reload in).
  • Состояние сети: у R1 работают SSH-доступ пользователя admin-lab с уровнем привилегий 15 и интерфейс GigabitEthernet0/0/0 (WAN) с адресом 203.0.113.2. Время на R1 синхронизировано (show ntp status), потому что расписание EEM зависит от часов. Журнал отправляется на 192.0.2.20 (logging host).
  • Тестовое устройство или стенд (GNS3, EVE-NG, Cisco Modeling Labs; набор команд EEM в Packet Tracer ограничен, поэтому для этой статьи он подходит плохо). Поведение EEM на стенде может отличаться от реального оборудования, поэтому окончательную проверку делайте на устройстве той же серии.
  • Консольный доступ к R1: часть примеров может отрезать вас от сети.
  • Для разделов про внешнюю автоматизацию: компьютер с Python 3 и доступом по SSH к устройствам из VLAN 99 (подробности о доступе и списках на линиях VTY, а также о межсетевом экране даны в разделе «Внешняя автоматизация»).

Note

Адреса управления в примерах зависят от того, делали ли вы статью 13. Без HSRP: R1 192.168.99.1, SW1 192.168.99.2. После статьи 13: 192.168.99.1 стал виртуальным адресом (его держит активный маршрутизатор, R1 или R3), реальный адрес R1 192.168.99.2, а SW1 переехал на 192.168.99.4. Скриптам нужны реальные адреса, иначе при смене активного маршрутизатора под именем R1 вы получите то один, то другой аппарат. В примерах ниже указаны адреса без HSRP, а после-HSRP значения даны в комментариях.

Tip

Если вы идёте по серии подряд, то перед этой статьёй желательно включить AAA, мониторинг и межсетевой экран на зонах (ZBFW, Zone-Based Firewall): автоматизация даёт широкие права, и защищать её нужно заранее. Остальные статьи второй части для этой темы не обязательны.

Зачем автоматизировать и три главных правила

Автоматизация нужна по четырём причинам:

  • Повторяемость. Один и тот же набор команд выполняется на десяти устройствах одинаково.
  • Меньше ошибок. Скрипт не опечатается в маске и не забудет end.
  • Документирование. Скрипт или шаблон сам описывает, что и где настроено, и его можно хранить в системе контроля версий.
  • Скорость. Работа, которая занимала вечер, занимает минуты.

Но автоматизация ускоряет и ошибки: неверная строка применяется ко всем устройствам сразу. Поэтому придерживайтесь трёх правил:

  1. Сначала чтение, потом запись. Начните со скриптов, которые только выполняют show и сохраняют результат. Когда они стабильно работают, переходите к изменениям.
  2. Всегда тестовое устройство. Каждый апплет и скрипт сначала запускайте на стенде, затем на одном некритичном боевом устройстве, и только потом на остальных.
  3. Бэкап и план отката перед записью. Снимок archive config, копия конфигурации на сервере, reload in 10 и консоль под рукой (статья 12). Для скриптов, которые что-то меняют, нужен «сухой прогон»: режим, где команды только показываются.

EEM: как это устроено

EEM состоит из «детекторов событий», которые следят за устройством, и политик, которые описывают реакцию. Политики бывают двух видов: апплеты (задаются прямо в конфигурации командами CLI) и скрипты на Tcl (скриптовом языке, на котором пишут более сложные политики). Мы используем апплеты.

Структура апплета:

  • event manager applet ИМЯ в режиме глобальной конфигурации открывает режим (config-applet).
  • Команда event задаёт, на что реагировать. В апплете может быть только одна команда event.
  • Команды action описывают, что делать. Их может быть много. У каждой есть метка (1.0, 2.0): действия выполняются в порядке сортировки меток как строк, поэтому 10.0 оказывается раньше 2.0. Если действий больше девяти, используйте метки с ведущим нулём (01.0, 02.0), как советует руководство Cisco.
  • Если выйти из режима апплета, не задав event, устройство предупредит, что с апплетом не связано событие.
  • Руководство по настройке допускает правку апплета без удаления: существующий апплет заменяется только при выходе из режима (config-applet), и тогда старая версия снимается с регистрации, а новая регистрируется. Справочник команд советует перед правкой выполнить no event manager applet ИМЯ. Если после правки апплет ведёт себя странно, удалите его и создайте заново.

Часто используются такие события:

Команда На что реагирует
event syslog pattern Сообщение журнала, подходящее под регулярное выражение. Параметры occurs и period задают, сколько совпадений за какое время нужно.
event timer cron cron-entry Расписание в формате cron (так называется планировщик задач, где время запуска записывается пятью полями): минута, час, день месяца, месяц, день недели (воскресенье это 0). Есть также countdown, absolute, watchdog.
event cli pattern Ввод команды, подходящей под шаблон.
event track Изменение состояния объекта отслеживания (track). Объекты IP SLA рассмотрены в статье 21. Номер объекта берите из show track своего устройства: в разных статьях серии номера могут различаться.
event snmp Значение объекта SNMP, которое опрашивается по интервалу.
event none Ничего: апплет запускается вручную командой event manager run. Удобно для проверки.

Шаблоны в event syslog и event cli записываются регулярными выражениями. Регулярное выражение — это шаблон поиска в тексте: . означает любой символ, * означает «сколько угодно раз», поэтому .* — любая последовательность символов (в том числе пустая). ^ привязывает совпадение к началу строки, | означает «или». Остальное в наших шаблонах обычный текст, который должен встретиться как есть.

Команда event interface для задачи «интерфейс упал» не подходит: она срабатывает по порогам счётчиков (ошибки, скорость), а не по смене состояния. Для смены состояния используйте event syslog или event track.

Основные действия:

  • action N cli command "..." выполняет команду CLI. Вывод команды попадает в переменную $_cli_result.
  • action N syslog msg "..." записывает сообщение в журнал; можно указать priority.
  • action N mail server ... to ... from ... subject ... body ... отправляет письмо.
  • action N comment "..." ничего не делает и служит комментарием для человека.
  • action N if ... / else / end задаёт условия. В статье они не нужны: сначала освойте линейные апплеты.

Практические ограничения, которые нужно знать сразу:

  • Время выполнения апплета ограничено параметром maxrun; по умолчанию это 20 секунд. Если команда ждёт ответа дольше, апплет прерывается.
  • Для action cli EEM занимает линию VTY из пула line vty. По справочнику Cisco, если EEM уже занимает одну линию VTY, новое соединение для следующего action cli не создаётся при менее чем трёх свободных линиях: так остаются линии для вашего собственного доступа. Это ещё одна причина не занимать все линии VTY.
  • В примерах руководства Cisco первым действием action cli идёт enable; в справочнике не уточняется, с какими правами и в каком режиме начинается сессия апплета. Поэтому всегда указывайте enable явно, а настройки делайте через action cli command "configure terminal".
  • Набор детекторов и действий зависит от версии и платформы. На классической IOS 15.x (Catalyst 2960-X/3850, ISR G2) основа та же, но проверьте нужные команды через event ? и action ? на своём устройстве.

Пример 1. Падение WAN-интерфейса

Задача: когда GigabitEthernet0/0/0 на R1 теряет канал, записать об этом событие в журнал с понятным текстом (его увидит syslog-сервер и система мониторинга).

Устройство пишет при смене состояния интерфейса сообщения такого вида: %LINK-3-UPDOWN: Interface GigabitEthernet0/0/0, changed state to down (физический уровень) и %LINEPROTO-5-UPDOWN: Line protocol on Interface GigabitEthernet0/0/0, changed state to down (протокол канального уровня). Нас интересует первое. Шаблон LINK-3-UPDOWN не совпадёт со вторым сообщением, потому что в нём стоит LINEPROTO.

Шаблон в справочнике Cisco записан в фигурных скобках: {.*UPDOWN.*Ethernet1/0.*}. В примерах Cisco шаблон syslog записывается в фигурных скобках, а шаблон cli (в нём бывают пробелы) берётся в кавычки; см. пример 3.

Команды и комментарии в конфигурации пишите только латиницей: CLI устройства надёжно принимает лишь ASCII, а кириллица при вставке из терминала может превратиться в мусор.

enable
configure terminal
event manager applet WAN-DOWN
 event syslog pattern {.*LINK-3-UPDOWN.*GigabitEthernet0/0/0.*changed state to down.*}
 action 1.0 comment "R1: WAN down handler, writes event to syslog"
 action 2.0 syslog priority warnings msg "EEM: WAN GigabitEthernet0/0/0 is down"
end

Следите за рекурсией. По справочнику, сообщения, записанные из апплета командой action syslog, не исключаются из проверки EEM-событий syslog. Если шаблон совпадёт с текстом собственного сообщения, апплет запустит сам себя бесконечно. Здесь текст сообщения («EEM: WAN ... is down») не содержит LINK-3-UPDOWN, поэтому петли нет. Делайте шаблоны узкими и проверяйте, не совпадут ли они с вашим же msg.

Как проверить, что апплет зарегистрирован:

enable
show event manager policy registered

Пример вывода (значения Event Type и формат времени зависят от версии):

No.  Class   Type    Event Type  Trap  Time Registered           Name
1    applet  user    syslog      Off   Tue Oct 13 12:24:10 2026  WAN-DOWN

Warning

Команда shutdown на интерфейсе этот апплет, скорее всего, не вызовет. При административном отключении устройство обычно пишет другое сообщение (%LINK-5-CHANGED: ... changed state to administratively down), и шаблон LINK-3-UPDOWN на него не реагирует. Шаблон рассчитан на реальную потерю линка: отключите кабель на стенде или остановите порт на стороне провайдера. Обрыв WAN отключает R1 от провайдера и обрывает NAT и туннели: проверяйте только на стенде или в согласованное окно, с консолью и reload in 10. Действия апплета без риска проверяются на event none (раздел «Проверка и отладка» ниже), но шаблон остаётся непроверенным до реального срабатывания.

После срабатывания в show logging | include EEM вы увидите запись, а на syslog-сервере 192.0.2.20 она появится, если канал до него жив. И здесь важная оговорка: при падении WAN сообщение до внешнего сервера может не дойти. Поэтому такие события полезно дополнительно хранить локально (буфер журнала) и смотреть состояние через мониторинг (статья 21).

Вариант: письмо вместо журнала

Командой action mail апплет может отправить письмо. Справочник Cisco приводит форму action label mail server адрес to кому from от_кого subject тема body текст. Адрес SMTP-сервера для канона учебной сети не задан, поэтому он записан заглушкой:

enable
configure terminal
event manager applet WAN-DOWN
 action 3.0 mail server <SMTP_SERVER> to noc@lab.example from r1@lab.example subject "R1: WAN down" body "GigabitEthernet0/0/0 changed state to down"
end

Перед вставкой замените <SMTP_SERVER> на адрес вашего почтового релея (SMTP-сервера, который принимает письма от устройства и пересылает их дальше): с заглушкой команда не заработает. Блок добавляет действие в уже созданный апплет. Учтите: если упал именно WAN, а сервер почты за ним, письмо не уйдёт. Не вписывайте имя и пароль SMTP-пользователя в строку сервера (формат пользователь:пароль@сервер допустим, но пароль окажется в открытом виде в конфигурации). Используйте внутренний почтовый релей, который принимает почту от устройства без пароля, либо отдельную учётную запись с минимальными правами. Для защищённой отправки (secure tls) нужны доверенные сертификаты SMTP-сервера на устройстве; детали смотрите в документе Cisco «Utilize EEM to automate secure emails».

Вариант: «флапает» канал

Параметры occurs и period позволяют реагировать не на каждое событие, а на серию. Например, срабатывать, если канал упал три раза за 300 секунд:

enable
configure terminal
event manager applet WAN-FLAP
 event syslog pattern {.*LINK-3-UPDOWN.*GigabitEthernet0/0/0.*changed state to down.*} occurs 3 period 300
 action 1.0 syslog priority errors msg "EEM: WAN GigabitEthernet0/0/0 flaps, check the cable and the provider"
end

Пример 2. Еженедельная копия конфигурации

Задача: каждое воскресенье в 03:00 сохранять конфигурацию. Событие event timer cron записывается как пять полей cron; 0 3 * * 0 означает «минута 0, час 3, любой день месяца, любой месяц, воскресенье».

Здесь есть ограничение, о котором надо знать заранее: команда copy задаёт интерактивные вопросы (подтверждение имени файла, перезапись, пароль). Апплет не человек, на вопросы он не ответит. Есть два способа справиться:

  • Команда file prompt quiet в глобальной конфигурации уменьшает число подтверждений при файловых операциях. Она влияет только на подтверждения: если не хватает данных, устройство всё равно спросит. Поэтому, например, пароль для scp: таким способом не передать.
  • Для команд, которые всё же задают вопрос, у action cli есть параметр pattern: регулярное выражение, которое совпадает с текстом приглашения, после чего следующим action cli отправляется ответ. Если шаблон составлен неверно, действие будет ждать до истечения maxrun.

В примере копия делается локально, во flash. Это не заменяет внешнюю копию, но надёжно работает без паролей. Замените flash: на bootflash:, если у вашего маршрутизатора основной накопитель называется так (проверьте через show file systems).

enable
configure terminal
event manager applet WEEKLY-BACKUP
 event timer cron cron-entry 0 3 * * 0 name WEEKLY-BACKUP
 action 1.0 cli command "enable"
 action 2.0 cli command "configure terminal"
 action 3.0 cli command "file prompt quiet"
 action 4.0 cli command "end"
 action 5.0 cli command "copy running-config flash:R1-weekly.cfg"
 action 6.0 cli command "configure terminal"
 action 7.0 cli command "file prompt alert"
 action 8.0 cli command "end"
 action 9.0 syslog msg "EEM: weekly running-config copy attempted, check dir flash:"
end

Что здесь важно:

  • file prompt quiet меняет глобальную настройку устройства, а не только поведение апплета. Поэтому шаги 6–8 возвращают значение по умолчанию alert (по справочнику: подтверждение запрашивается только для разрушающих операций). Если до апплета в конфигурации стояло другое значение file prompt (например, quiet или noisy), верните именно его, а не alert. Если апплет прервётся посреди работы, устройство останется в режиме quiet. Проверьте это командой show running-config | include file prompt.
  • Файл R1-weekly.cfg каждую неделю перезаписывается. Если вам нужна история версий, используйте archive (path, maximum, статья 12), а в апплете вызывайте action 5.0 cli command "archive config". Для этого в конфигурации должен быть настроен archive с path (статья 12); задаёт ли эта команда вопросы внутри апплета, в справочнике EEM не сказано, поэтому проверьте её на стенде.
  • Копия на сервер. Копирование на scp://admin-lab@192.0.2.10/... требует пароля, а хранить его в апплете нельзя (он будет виден в конфигурации и в show running-config). TFTP не требует пароля, но передаёт конфигурацию без шифрования: допустим только в изолированной лаборатории, и вопросы команды copy (например, имя файла) придётся проверять на стенде. Для рабочей сети лучше использовать механизм archive с kron, описанный в статье сайта про автоматическое копирование конфигурации, либо забирать копии снаружи скриптом (разделы ниже).

Как проверить: не ждите воскресенья. Сначала временно замените событие на таймер обратного отсчёта (в справочнике есть пример event timer countdown time 360.006 name six-minutes), запустите, проверьте результат, а потом верните расписание:

enable
configure terminal
event manager applet WEEKLY-BACKUP
 event timer countdown time 60 name WEEKLY-BACKUP
end

Через минуту выполните dir flash:: должен появиться файл R1-weekly.cfg с ненулевым размером. Сообщение апплета в журнале пишется независимо от результата копирования, поэтому доверяйте файлу, а не журналу; при неудаче поищите причину (нет места, неверное имя накопителя) в show logging. Затем верните cron-расписание. Строка event в апплете допускается только одна, и обычно новая заменяет прежнюю, а действия сохраняются (в документации Cisco замена события повторным входом в апплет прямо не описана). Поэтому после правки проверьте результат командой show running-config | section event manager; при сомнениях выполните no event manager applet WEEKLY-BACKUP и создайте апплет заново, повторив блок выше целиком.

enable
configure terminal
event manager applet WEEKLY-BACKUP
 event timer cron cron-entry 0 3 * * 0 name WEEKLY-BACKUP
end

Также проверьте show clock: расписание срабатывает по часам устройства, поэтому часовой пояс и NTP должны быть настроены.

Пример 3. Защита от опасной команды

EEM умеет перехватывать вводимые команды. Параметр skip yes означает, что совпавшая команда не выполняется, а sync no разрешает не ждать окончания апплета. Так можно, например, запретить случайное стирание стартовой конфигурации.

Caution

Перехват команд опасен. В справочнике Cisco прямо сказано: если шаблон совпадает с командами конфигурации и указано skip yes, можно получить неожиданные результаты, так как совпавшая команда не будет выполнена. Не пишите шаблоны, которые затрагивают configure, end, exit, write memory, reload: вы можете лишиться возможности сохранить конфигурацию или выйти из режима. Работайте только с консоли на стенде и держите под рукой команду no event manager applet ИМЯ.

enable
configure terminal
event manager applet BLOCK-ERASE
 event cli pattern "^write erase|^erase startup-config" sync no skip yes
 action 1.0 syslog priority warnings msg "EEM: write erase blocked"
end

Как проверить на стенде: введите write erase. Команда не должна выполниться, а в журнале должна появиться запись. Если команда выполнилась, шаблон составлен неверно или не совпал с формой команды. Проверьте на стенде и сокращённый ввод (wr er): перехватывается ли он этим шаблоном, зависит от версии, и считать это гарантированным нельзя. Пример не покрывает другие разрушительные команды (erase nvram:, delete, format и подобные): это страховка от одной типичной ошибки, а не полный запрет.

Это не защита от злоумышленника: пользователь с правами настройки сам удалит апплет. Это страховка от человеческой ошибки. Для настоящего ограничения команд используйте авторизацию команд на AAA-сервере (статья 20).

Режим sync yes (устройство ждёт апплет и по статусу выхода решает, выполнять ли команду) в статье не рассматривается. Cisco предупреждает, что при неправильном статусе выхода команда может быть пропущена, и устройство придётся перезагружать.

Сохранение после проверки

Апплеты, созданные в running-config, исчезнут при перезагрузке, если их не сохранить. Проверив все три на стенде, убедитесь, что конфигурация содержит именно то, что нужно (в том числе что file prompt вернулся к прежнему значению), и только затем сохраните её:

enable
show running-config | section event manager
show running-config | include file prompt
copy running-config startup-config

Как проверить: после перезагрузки стенда show event manager policy registered снова показывает ваши апплеты.

Проверка и отладка

Основные команды:

enable
show event manager policy registered
show event manager history events
show event manager environment all
show logging | include EEM
  • show event manager policy registered показывает зарегистрированные апплеты и тип события.
  • show event manager history events показывает историю срабатываний; размер истории по умолчанию 50 записей, и это же максимум: командой event manager history size events N его можно только уменьшить (допустимый диапазон 1-50).
  • show event manager environment all показывает переменные окружения EEM.

В реальном выводе колонок может быть больше (например, Proc), а под строкой апплета в policy registered может стоять дополнительная строка с шаблоном или расписанием события.

Пример вывода show event manager history events (значения вымышленные, состав колонок зависит от версии):

No. Job ID  Status   Time of Event             Event Type  Name
1   1       success  Tue Oct 13 12:24:40 2026  syslog      applet: WAN-DOWN

Проверка апплета без ожидания события. Создайте апплет с event none и запустите вручную: это проверяет действия, но не шаблон события.

enable
configure terminal
event manager applet TEST-LOG
 event none
 action 1.0 syslog msg "EEM: manual test"
end
event manager run TEST-LOG
show logging | include EEM

Если апплет «не срабатывает», проверьте по порядку: зарегистрирован ли он (policy registered), не пуста ли строка event, совпадает ли шаблон с реальным текстом сообщения (сравните со строкой в show logging), настроено ли время для cron, не истёк ли maxrun, есть ли свободные линии VTY для action cli, и не отказывает ли AAA (если он включён, поищите отказы авторизации в show logging: при недоступном сервере апплет может не запуститься, см. раздел «Безопасность EEM»).

Для отладки действий существуют команды debug event manager. Набор вариантов зависит от версии и платформы: посмотрите их через debug event manager ? на своём устройстве и используйте только те, что там есть. Вариант для действий cli (debug event manager action cli) встречается в справочнике отладочных команд Cisco IOS и в материалах сообщества Cisco, но его наличие и синтаксис зависят от версии: проверьте через debug event manager ?. Правила те же, что в статье 12: включайте отладку ненадолго, не на нагруженном устройстве, и обязательно выключайте командой undebug all.

Безопасность EEM

  • Апплет — это код, исполняемый на устройстве. Кто может изменять конфигурацию (уровень привилегий 15), тот может создать апплет, выполняющий любые команды. Ограничивайте число таких пользователей и ведите учёт действий через AAA (статья 20).
  • AAA и запуск апплетов. Если на устройстве включён AAA (статья 20), то по справочнику Cisco при запуске политики устройство обращается к AAA-серверу за авторизацией. Сервер 192.0.2.30 в учебной схеме находится за WAN, поэтому именно в сценарии «упал WAN» апплет может не получить разрешения и не выполниться, хотя в show event manager policy registered он значится. Ключевое слово authorization bypass в команде event manager applet пропускает это обращение и запускает политику сразу. Это компромисс: апплет станет надёжнее, но запуск перестанет проверяться сервером, поэтому применяйте его только к апплетам, которые вы сами написали и проверили. Для команд внутри апплета (action cli) справочник рекомендует отдельные именованные списки методов AAA, в которых авторизация команд не требуется; как это настроить, смотрите в руководстве по AAA для своей версии. В справочнике Cisco есть также команда event manager session cli username (имя пользователя для CLI-сеансов EEM при включённом AAA); её синтаксис и действие проверьте по справочнику своей версии, в статье она не используется. С какими именно правами выполняются команды action cli, в справочнике не уточняется, поэтому не полагайтесь на «урезанные» права апплета.
  • Межсетевой экран. Если включён ZBFW из статьи 23, трафик, который R1 создаёт сам, идёт через зону self. В той статье политика SELF-OUT пропускает только DNS, NTP, syslog, SCP и ICMP, поэтому письмо из action mail (TCP 25 или порт вашего релея) будет отброшено: добавьте строку для релея в ACL-SELF-OUT и проверьте счётчики class-default в show policy-map type inspect zone-pair.
  • Пароли не хранить. Текст апплета и переменные event manager environment видны в show running-config. Не помещайте туда пароли, ключи SNMP и учётные данные SMTP. То, что нужно скрыть, должно оставаться вне устройства.
  • Не нагружайте и не перегружайте. Апплет, запускаемый частым событием (например, каждым сообщением журнала), может создать большую нагрузку. action reload существует, но перезагрузка без человека опасна: не используйте её в учебных и первых рабочих апплетах.
  • Документируйте. Каждый апплет должен иметь комментарий action N comment и описание в вашей документации: через год никто не вспомнит, откуда берётся странное сообщение в журнале.

Внешняя автоматизация: SSH и Python

Tip

Python и Ansible — отдельный уровень. Если вы управляете одним-двумя устройствами, вам достаточно EEM и резервных копий из статьи 12; внешняя автоматизация окупается, когда устройств десятки. Разделы про Netmiko, Ansible, Jinja2, NETCONF/RESTCONF и Guest Shell можно читать по мере необходимости, независимо друг от друга.

Апплеты хороши для реакций на самом устройстве. Но собрать копии со всех устройств, проверить одну настройку на сотне коммутаторов или применить одинаковые изменения лучше с внешнего сервера. Здесь используются сторонние программы, не связанные с Cisco. Их версии и параметры меняются, поэтому перед использованием проверяйте их по актуальной документации. Блоки bash, python и yaml (а также шаблон Jinja2) ниже выполняются на сервере автоматизации, а не на устройстве Cisco.

Самый простой путь для стенда: запускать скрипты с компьютера в VLAN 99. Два условия доступа к R1:

  • Адрес компьютера должен быть разрешён в access-class 10 на линиях VTY (статья 02): там разрешена сеть 192.168.99.0/24. Для другого адреса добавьте permit host <АДРЕС> в access-list 10 (статья 08), под reload in 10 и с консоли.
  • Если включён ZBFW (Zone-Based Firewall, межсетевой экран на зонах; статья 23), SSH из VLAN 99 к самому R1 пропускает ACL-SELF-ADMIN. Внешний узел 192.0.2.50 приходит из зоны OUTSIDE: ему нужна строка в ACL-OUT-ADMIN (в статье 23 она уже есть для SSH), а также маршрут к серверной сети (VPN до сервера в этой серии не разбирается; туннель из статьи 18 связывает только R1 и RB). Остальные службы собраны в разделе «Дополнение для других статей серии» статьи 23.

Netmiko

Netmiko — это библиотека Python с открытой лицензией, которая подключается к устройству по SSH и работает с приглашением и режимами. Устанавливается командой pip install netmiko. Основные вызовы: ConnectHandler(**device), send_command() для команд просмотра, send_config_set() для списка команд конфигурации, save_config() для сохранения. Тип устройства задаётся в device_type; в примере cisco_ios (для IOS XE у библиотеки есть и отдельный тип, сверьтесь с её документацией).

Пароль не записывайте в код. Берите его из переменной окружения:

export CISCO_USER=admin-lab
read -s -p "Password: " CISCO_PASSWORD; export CISCO_PASSWORD

Так пароль не попадёт в историю команд оболочки. Для автоматизации лучше завести отдельную учётную запись (с правами только на чтение, где это возможно) и перейти на SSH-ключи.

Скрипт «только чтение»: сохраняет show running-config каждого устройства из списка в файл с датой.

import os
from datetime import date
from pathlib import Path

from netmiko import ConnectHandler
from netmiko.exceptions import NetmikoAuthenticationException, NetmikoTimeoutException

# Адреса без HSRP. После статьи 13 используйте реальные адреса:
# {"R1": "192.168.99.2", "SW1": "192.168.99.4"} (адрес .1 виртуальный)
DEVICES = {"R1": "192.168.99.1", "SW1": "192.168.99.2"}

out_dir = Path("backups")
out_dir.mkdir(exist_ok=True)

username = os.environ["CISCO_USER"]
password = os.environ["CISCO_PASSWORD"]

for name, host in DEVICES.items():
    device = {
        "device_type": "cisco_ios",
        "host": host,
        "username": username,
        "password": password,
    }
    try:
        with ConnectHandler(**device) as conn:
            config = conn.send_command("show running-config")
    except (NetmikoTimeoutException, NetmikoAuthenticationException) as err:
        print(f"{name}: ошибка подключения: {err}")
        continue
    path = out_dir / f"{name}-{date.today()}.cfg"
    path.write_text(config, encoding="utf-8")
    print(f"{name}: сохранено в {path}, символов: {len(config)}")

Замечания:

  • Пользователь admin-lab имеет уровень привилегий 15, поэтому после входа устройство сразу показывает приглашение R1#. Если вы входите пользователем с низким уровнем, нужен пароль enable: его передают параметром secret и вызывают conn.enable() (проверьте по документации Netmiko).
  • Защита login block-for из статьи 02 действует и на скрипты: при неверном пароле в переменной окружения каждый запуск скрипта добавляет неудачные попытки на каждом устройстве, и после пяти за минуту на нём включится «тихий период», когда входы закрыты. Сначала проверьте вход вручную, а адрес, с которого работают скрипты, добавьте в access-list 10 (его же использует login quiet-mode access-class). То же относится к Ansible.
  • Файлы конфигурации содержат хэши паролей, строки SNMP и схему сети. Ограничьте права на папку backups и не храните её в публичных репозиториях.
  • Пароль в переменной окружения лучше, чем в коде, но он виден процессам пользователя. Для серьёзной работы используйте SSH-ключи (в Netmiko есть параметры use_keys и key_file; сверьте с документацией) или хранилище секретов.
  • Как проверить: в папке backups должны появиться файлы с ненулевым размером, а начало файла должно совпадать с выводом show running-config на устройстве. Скрипт ничего не меняет, поэтому его безопасно запускать повторно.

Скрипт записи (send_config_set) делайте с «сухим прогоном» по умолчанию:

import os
import sys

from netmiko import ConnectHandler

COMMANDS = ["logging host 192.0.2.20", "logging trap informational"]
HOSTS = ["192.168.99.1"]  # начните с одного тестового устройства (после статьи 13: реальный адрес R1, 192.168.99.2)

apply_changes = "--apply" in sys.argv

for host in HOSTS:
    device = {
        "device_type": "cisco_ios",
        "host": host,
        "username": os.environ["CISCO_USER"],
        "password": os.environ["CISCO_PASSWORD"],
    }
    with ConnectHandler(**device) as conn:
        print(f"--- {host}: до изменений")
        print(conn.send_command("show running-config | include ^logging"))
        if not apply_changes:
            print("Сухой прогон: изменения не применены. Для применения добавьте --apply.")
            continue
        print(conn.send_config_set(COMMANDS))
        print(f"--- {host}: после изменений")
        print(conn.send_command("show running-config | include ^logging"))
        # Сохраняйте конфигурацию только убедившись, что всё в порядке:
        # conn.save_config()

По умолчанию save_config() отправляет команду write mem. Как и вручную, сохраняйте конфигурацию только после проверки (см. раздел про reload in в статье 12).

Ansible

Ansible — это система автоматизации, которая описывает желаемые действия в файлах формата YAML (такой файл называется playbook, «сценарий») и применяет их ко всем устройствам из инвентаря. Для Cisco IOS есть коллекция cisco.ios:

ansible-galaxy collection install cisco.ios

Модули: cisco.ios.ios_command (выполняет команды просмотра, команды режима конфигурации не поддерживает) и cisco.ios.ios_config (изменяет конфигурацию; умеет backup, parents, lines, save_when). Модули поддерживаются как коллекция Ansible: сверяйте параметры с их документацией.

Инвентарь inventory.yml:

all:
  children:
    cisco:
      hosts:
        R1:
          ansible_host: 192.168.99.1  # после статьи 13: 192.168.99.2
        SW1:
          ansible_host: 192.168.99.2  # после статьи 13: 192.168.99.4
      vars:
        ansible_connection: ansible.netcommon.network_cli
        ansible_network_os: cisco.ios.ios
        ansible_user: admin-lab
        ansible_password: "{{ vault_cisco_password }}"

Пароль хранится не в инвентаре, а в зашифрованном файле ansible-vault (например, group_vars/cisco/vault.yml с переменной vault_cisco_password). Playbook backup.yml:

- name: Резервные копии конфигураций Cisco
  hosts: cisco
  gather_facts: false
  tasks:
    - name: Сохранить конфигурацию в каталог backups
      cisco.ios.ios_config:
        backup: true
        backup_options:
          dir_path: ./backups

Запуск: ansible-playbook -i inventory.yml backup.yml --ask-vault-pass. Как и в Netmiko, начинайте с чтения. Затем можно добавить задачу с параметрами lines и parents. Строки в lines пишите в той форме, в которой они выводятся в show running-config: сокращённые команды не идемпотентны, то есть при повторном запуске Ansible увидит «изменение» там, где его нет.

Шаблоны конфигурации (Jinja2)

Когда однотипных устройств много, настройки отделяют от данных: в шаблоне остаются места для подстановки, в таблице или файле переменных лежат значения устройств. Шаблонизатор Jinja2 использует {{ переменная }} для вывода значения, {% ... %} для циклов и условий и {# ... #} для комментариев. Фрагмент (пример шаблона, а не вывода устройства):

hostname {{ hostname }}
{% for server in syslog_servers %}
logging host {{ server }}
{% endfor %}

Подставив hostname: R1 и список серверов, вы получите готовые команды для send_config_set. В Ansible шаблон применяется модулем ansible.builtin.template. Результат проверяйте глазами до применения.

Программируемость IOS XE: обзор

Современные устройства IOS XE можно настраивать не только командами CLI, но и через программные интерфейсы. Структура настроек и состояния устройства описывается моделями YANG: YANG — это язык описания данных, своего рода «схема» того, какие параметры бывают и как они вложены друг в друга. Передают данные по этим моделям два протокола: NETCONF (порт 830 поверх SSH) и RESTCONF (поверх HTTPS; REST — это стиль работы с данными обычными HTTP-запросами GET, PUT и т. д.; описан в RFC 8040). Для начала достаточно понимать, что это и как не навредить.

Tip

Этот раздел и Guest Shell ниже можно пропустить, пока вам хватает CLI, скриптов по SSH и Ansible: NETCONF и RESTCONF нужны, когда вы переходите к системам управления сетью, работающим с моделями YANG.

Warning

Блоки ниже включают дополнительные сервисы управления, а аутентификация NETCONF и RESTCONF через AAA меняет проверку входа и может отрезать вас от устройства. Не включайте их «на пробу» на боевом оборудовании. Перед началом убедитесь, что есть локальный пользователь с уровнем привилегий 15 (как admin-lab в статье 02), SSH-сервер настроен (SSH версии 2, статья 02) и под рукой консоль. Перед блоком отдельно выполните reload in 10 и подтвердите запрос (в блок команду не включайте: она задаёт вопрос). Проверив, что вход и сервис работают, отмените перезагрузку командой reload cancel. Ограничение доступа к сервисам продумайте до их включения, а не после.

Включение NETCONF (по руководству Cisco для IOS XE 17.x: нужны AAA, локальный пользователь уровня 15 и настроенный SSH-сервер). Сначала узнайте, включён ли AAA:

enable
show running-config | include aaa

Если в выводе есть aaa new-model и списки default (например, после статьи 20 с TACACS+), не вводите три строки aaa из следующего блока: они перепишут ваши списки default и могут лишить входа через сервер. В этом случае выполните только блок с netconf-yang, а согласование списков аутентификации и авторизации для NETCONF сверьте с руководством.

Если AAA не включён, а учётные записи локальные (пользователь, как admin-lab, уже создан), введите:

enable
configure terminal
aaa new-model
aaa authentication login default local
aaa authorization exec default local
netconf-yang
end

Если AAA уже включён:

enable
configure terminal
netconf-yang
end

Как проверить: show netconf-yang sessions (список сессий) и show platform software yang-management process (состояние процессов управления; команда зависит от платформы). Откройте вторую SSH-сессию и убедитесь, что вход по-прежнему работает, и только потом отменяйте reload in.

Включение RESTCONF. По руководству достаточно двух команд: restconf и ip http secure-server. Аутентификация настраивается через AAA, как и для NETCONF: либо уже настроенные списки (статья 20), либо три строки aaa из блока выше. В статье 02 мы отключали HTTP-серверы (no ip http server, no ip http secure-server), поэтому ip http secure-server здесь заново открывает HTTPS-сервис, по умолчанию доступный на всех интерфейсах, в том числе на WAN. Эта команда поднимает не только RESTCONF, но и встроенный веб-интерфейс устройства, поэтому ограничение по источнику обязательно; версии TLS и наборы шифров настройте по руководству к своей версии.

Important

Выполняйте блоки ниже только после того, как HTTPS на самом маршрутизаторе закрыт от посторонних: либо зонами (статья 23, трафик из WAN к самому маршрутизатору запрещён), либо входящим списком доступа на WAN-интерфейсе (статья 08). Пускать нужно только сервер автоматизации и сеть MGMT. Ограничить HTTP/HTTPS-сервер самого маршрутизатора можно списком доступа (синтаксис по документу Cisco TAC «Filter Traffic Destined to Cisco IOS XE», он описан для IOS XE 16 и 17; на классической IOS 15.x и старых версиях вместо ipv4 и имени используется номер стандартного списка, проверьте ip http ?):

enable
configure terminal
ip access-list standard MGMT-HTTPS
 permit 192.168.99.0 0.0.0.255
 permit host 192.0.2.50
 deny any log
exit
ip http access-class ipv4 MGMT-HTTPS
end

Команда ip http access-class действует на HTTP/HTTPS-сервер, то есть на RESTCONF, но не на порт 830 (NETCONF): в документе Cisco о нём не сказано. Для порта 830 нужен интерфейсный список доступа или зона. Если включён ZBFW из статьи 23, то по её политике на R1 пропускается только SSH, поэтому нужны дополнительные строки:

  • для узла в VLAN 99 добавьте в ACL-SELF-ADMIN строки permit tcp 192.168.99.0 0.0.0.255 any eq 830 и permit tcp 192.168.99.0 0.0.0.255 any eq 443;
  • для внешнего узла 192.0.2.50 (зона OUTSIDE) в статье 23 RESTCONF уже открыт строкой для tcp 443 в ACL-OUT-MGMT; для NETCONF добавьте в тот же список строку permit tcp host 192.0.2.50 host 203.0.113.2 eq 830.

Когда доступ ограничен, включайте RESTCONF. Перед этим убедитесь, что вход на HTTPS-сервер вообще работает (клиентом RESTCONF с локальным пользователем уровня 15): если вход отклоняется, сверьте способ аутентификации HTTP-сервера с руководством по HTTP-серверу вашей версии.

enable
configure terminal
restconf
ip http secure-server
end

В части примеров настройки RESTCONF встречаются также ip http authentication local (проверка входа в HTTP-сервер по локальным учётным записям) и no ip http server (отключение незащищённого HTTP). В руководстве по RESTCONF эти строки не описаны, поэтому не добавляйте их «на всякий случай»: сверьтесь с руководством для своей версии. no ip http server у вас уже настроено по статье 02, если вы её выполняли.

Меры безопасности для обоих интерфейсов:

  • Включайте только то, чем реально пользуетесь. Лишний сервис управления — это дополнительная поверхность атаки.
  • Не открывайте порт 830 и HTTPS управления в Интернет: ограничивайте источники (списки доступа, зоны, сеть MGMT). Незащищённый HTTP-сервер не включайте, используйте только HTTPS.
  • Доступ только у пользователей с минимальным нужным кругом: для NETCONF требуется уровень 15, значит, учётная запись для автоматизации очень мощная. Выдайте отдельную, храните её секреты в хранилище и пишите её действия в журнал AAA.
  • Ограничения: по руководству Cisco, NETCONF не поддерживается на устройствах с конфигурацией dual IOSd (две копии процесса IOS на одном устройстве) или с программным резервированием (например, режим с двумя Route Processor); если не уверены, проверьте это в руководстве по своей платформе; для RESTCONF проверьте то же самое в руководстве по программируемости вашей версии. Часть функций (например, уведомления) в RESTCONF может отсутствовать.

Tip

Guest Shell можно пропустить: для первых шагов хватает EEM, Netmiko и Ansible.

Отдельная возможность: Guest Shell (контейнер Linux на устройстве, в котором можно запускать Python 3 и bash). Поддерживается не везде, и список платформ зависит от версии руководства: в руководстве для 17.3 в таблице названы, в частности, Catalyst 9200/9300/9400/9500/9600, Catalyst 8200/8300/8500, ISR 4000 (и ISR 1000), ASR 1000, CSR 1000v, а также Catalyst 3650/3850. Для Catalyst 9200L прямо сказано, что Guest Shell не поддерживается. Точный список платформ смотрите в руководстве для своей версии. В руководствах для классической IOS 15.x Guest Shell не описан. Последовательность по руководству такая. В режиме глобальной конфигурации включается платформа приложений командой iox, затем в app-hosting appid guestshell задаётся сетевой доступ контейнера, и здесь платформы различаются. На Catalyst 9200/9300/9400/9500/9600 по руководству используется app-vnic management guest-interface 0, то есть контейнер выходит в сеть через интерфейс управления. На маршрутизаторах (ISR 4000, Catalyst 8000) вместо этого создаётся интерфейс VirtualPortGroup 0 с адресом и в app-hosting appid guestshell настраивается app-vnic gateway1 virtualportgroup 0 guest-interface 0 с адресом контейнера (guest-ipaddress) и шлюзом (app-default-gateway); точные команды и адреса берите из руководства своей платформы, VirtualPortGroup поддерживается только на маршрутизаторах. После выхода из режима конфигурации в привилегированном режиме выполняется guestshell enable, а Python запускается командой guestshell run python3. Точная последовательность и сетевые параметры зависят от платформы. Доступ только у пользователя уровня 15, требуются память и место на flash. Для начала используйте Guest Shell только на тестовом устройстве, а подробности смотрите в руководстве по программируемости.

Итог серии: что оставить на рабочей сети

Статьи второй части задумывались как самостоятельные лабораторные, поэтому не все их настройки сочетаются на одном R1. Прежде чем переносить что-то на боевое оборудование, сверьтесь с таблицей.

Что С чем не сочетается или чем заменяется
HSRP (13): второй провайдер у R3 Два провайдера на R1 (15, 16): это разные стенды, не собирайте их на одной схеме без отдельного проектирования.
EIGRP (14) Заменяет OSPF из статьи 11: выберите один протокол и в других статьях подставьте свой.
GRE (17) и IPsec VTI (18) Обычно выбирают один из двух вариантов связи с филиалом; для рабочей сети нужен вариант с шифрованием.
GigabitEthernet0/0/2 В одних статьях это стык с R2, в других второй провайдер: проверьте show ip interface brief и при необходимости возьмите свободный порт.
IPv6 (22) и ZBFW (23) Не включайте их вместе, пока не опишете для IPv6 отдельные классы и политики (служебный ICMPv6 и DHCPv6 иначе попадут под class-default): см. предупреждения в обеих статьях.

Короткий чек-лист для рабочей сети: сначала доступ и защита (SSH с access-class и список доступа на WAN, статья 08; AAA с проверенным локальным запасным входом, статья 20; NTP, журнал и SNMPv3, статья 21; зоны, статья 23), затем резервные копии вне устройства (статья 12), и только потом всё остальное: по одному изменению, с копией перед каждым и сохранением после проверки.

Типичные ошибки

  • Апплет без enable. Первое действие action cli должно быть enable, а настройка делается после configure terminal (подробности в разделе «EEM: как это устроено»). Без явного enable команды могут не выполниться из-за неверного режима или прав.
  • Зацикливание событий. Шаблон event syslog, который совпадает с сообщением собственного action syslog, запускает апплет бесконечно и забивает журнал и процессор. Делайте шаблоны узкими и проверяйте текст собственных сообщений.
  • Пароль в апплете или скрипте. Пароль виден в show running-config, в репозитории и в истории команд. Используйте переменные окружения, хранилище секретов (ansible-vault), SSH-ключи.
  • Автоматизация без тестового стенда. Неотлаженный апплет с skip yes может заблокировать нужные команды, а скрипт записи применить ошибку сразу на всех устройствах. Работайте по схеме: стенд, один боевой узел, остальные; включайте сухой прогон.
  • Забытое глобальное изменение. file prompt quiet, оставленный апплетом, остаётся в конфигурации устройства. Возвращайте настройки в исходное состояние и проверяйте их.
  • Метки действий без выравнивания. Из-за сортировки как строки действие 10.0 выполнится раньше 2.0. Нумеруйте с ведущим нулём, если действий больше девяти.

Что дальше

Итоговую таблицу совместимости и чек-лист для рабочей сети смотрите в разделе «Итог серии» выше.

Ещё по теме «Cisco»