Автоматизация ввода в SecureCRT с помощью скриптов

У сетевых инженеров часто возникает задача, выполнить copy/past определенных фрагментов из блокнота в консоль. Копировать приходиться обычно несколько параметров: Username/Password и что-либо еще. Ускорить этот процесс позволяет использование скриптов. НО задачи написание скрипта и выполнение скрипта суммарно должны занять меньше времени, чем настройка вручную, иначе скрипты бесполезны.

Для чего нужна эта статья. Эта статья из цикла Fast Start и направлена на экономию времени сетевым инженерам, при настройке оборудования (одной задачи) на нескольких устройствах. Используется ПО SecureCRT и встроенный функционал выполнение скриптов.

Содержание

Введение

В программу SecureCRT из коробки встроен механизм выполнения скриптов. Для чего нужны скрипты в терминале:

  • Автоматизированный ввод и вывод, и минимальная проверка корректности ввода/вывода.
  • Ускорить выполнение рутинных задач – уменьшение пауз между настройкой оборудования. (Де факто уменьшение пауз, вызванных временем для выполнения действий по copy/past на одном и том же оборудовании, при 3-х и более фрагментов команд для применения на оборудовании.)

В данном документе рассмотрены задачи:

  • Создание простейших скриптов.
  • Запуск скриптов на SecureCRT.
  • Примеры использования простых и продвинутых скриптов. (Практика из реальной жизни.)

Создание простейших скриптов.

Простейшие скрипты используют всего две команды Send и WaitForString. Этого функционала хватит на 90% (и более) выполняемых задач.

Скрипты могут работать на языке Python, JS, VBS (Visual Basic), Perl и т. д.

Python

# $language = "Python"
# $interface = "1.0"
def main():
  crt.Screen.Synchronous = True
  crt.Screen.Send("r")
  crt.Screen.WaitForString("name")
  crt.Screen.Send("adminr")
  crt.Screen.WaitForString("Password:")
  crt.Screen.Send("Password")
  crt.Screen.Synchronous = False
main()

Обычно файл с расширением «*.py»

VBS

# $language = "VBScript"
# $interface = "1.0"
Sub Main
  crt.Screen.Synchronous = True
  crt.Screen.Send vbcr
  crt.Screen.WaitForString "name"
  crt.Screen.Send "cisco" & vbcr
  crt.Screen.WaitForString "assword"
  crt.Screen.Send "cisco" & vbcr
  crt.Screen.Synchronous = False
End Sub

Обычно файл с расширением «*.vbs»

Создание скрипта с помощью записи скрипта.

Позволяет автоматизировать процесс написания скрипта. Вы запускаете запись скрипта. SecureCRT записывает команды и последующий ответ оборудования и выводит Вам готовый скрипт.

а. Запустить запись скрипта:
Меню SecureCRT => Script => Start Recording Script
б. Выполнить действия с консолью (выполнить действия по настройке в CLI).
в. Закончить запись скрипта:
Меню SecureCRT => Script => Stop Recording Script…
Сохранить файл со скриптом.

Пример выполненных команд и сохраненного скрипта:

Автоматизация ввода в SecureCRT с помощью скриптов

Запуск скриптов на SecureCRT.

После создания/редактирования скрипта, возникает закономерный вопрос: Как применить скрипт?
Существует несколько способов:

  • Запуск вручную из меню Script
  • Автоматический запуск после подключения (logon script)
  • Автоматический logon без использования скрипта
  • Запуск вручную с помощью кнопки в SecureCRT (кнопку еще предстоит создать и добавить в SecureCRT)

Запуск вручную из меню Script

Меню SecureCRT => Script => Run…
— Последние 10 скриптов запоминаются и доступны для быстрого запуска:
Меню SecureCRT => Script => 1 «Имя файла со скриптом»
Меню SecureCRT => Script => 2 «Имя файла со скриптом»
Меню SecureCRT => Script => 3 «Имя файла со скриптом»
Меню SecureCRT => Script => 4 «Имя файла со скриптом»
Меню SecureCRT => Script => 5 «Имя файла со скриптом»

Автоматический запуск после подключения (logon script)

Настройки автоматического скрипта логирования настраиваются для сохраненной сессии: Connection => Logon Actions => Logon script

Автоматизация ввода в SecureCRT с помощью скриптов

Автоматический logon без использования скрипта

Существует возможность автоматического ввода имени пользователя пароля без написания скрипта, используя только встроенный функционал SecureCRT. В настройках соединения «Connection» => Logon Actions => Automate logon – необходимо заполнить несколько связок – которые подразумевают собой пары: «Ожидаемый текст» + «Посылаемые символы на этот текст» таких пар может быть много. (Пример: 1-я пара ожидание ввода имени пользователя, вторая ожидание ввода пароля, третья ожидание приглашения в привилегированный режим, четвертая пароль от привилегированного режима.)

Пример автоматического logon на Cisco ASA:

Автоматизация ввода в SecureCRT с помощью скриптов

Запуск вручную с помощью кнопки в SecureCRT (кнопку еще предстоит создать и добавить в SecureCRT)

В SecureCRT можно задать скрипт – кнопке. Кнопка добавляется на специально созданную для этой цели панель.

а. Добавляем панель в интерфейс: Меню SecureCRT => View => Button Bar
б. Добавляем кнопку на панель и добавляем скрипт. – Правой кнопкой мышки щелкаем на панель Button Bar и в контекстном меню выбираем пункт «New button…».
в. В диалоговом окне «Map Button» в поле «Action» Выбираем действие (function) «Run Script».
Указываем подпись к кнопке. Цвет для иконки кнопки. Заканчиваем настройки нажатием Ok.

Автоматизация ввода в SecureCRT с помощью скриптов

Примечание:

Панель с кнопками очень полезный функционал.

1. Есть возможность при Logon к определенной сессии указывать какую панель по умолчанию открывать к этой вкладке.

2. Есть возможность для стандартных действий с оборудованием задать заранее заданные действия: показать show version, show running-config, сохранить конфигурацию.

Автоматизация ввода в SecureCRT с помощью скриптов
К данным кнопкам не привязан ни какой скрипт. Только строка с действиями:

Автоматизация ввода в SecureCRT с помощью скриптов
Настройка – чтобы при переключении на сессию открывалась необходимая панель с кнопками производиться в настройках сессии:

Автоматизация ввода в SecureCRT с помощью скриптов
Для заказчика имеет смысл настроить индивидуальные скрипты для Login и переход на панель с частыми командами для вендора.

Автоматизация ввода в SecureCRT с помощью скриптов
При нажатии на кнопку Go Cisco – панель переключается на Cisco Button Bar.

Автоматизация ввода в SecureCRT с помощью скриптов

Примеры использования простых и продвинутых скриптов. (Практика из реальной жизни.)

Простых скриптов хватает почти на все случае жизни. Но один раз мне понадобилось чуть усложнить скрипт – для ускорения работы. Это усложнение – всего лишь запрашивало дополнительные данные в диалоговом окне у пользователя.

Запрос данных у пользователя с помощью диалогового окна

У меня в скрипте запросов данных было 2. Это Hostname и 4-й октет IP адреса. Для выполнения этого действия – я загуглил как это сделать и нашел на официальном сайте SecureCRT (vandyke). – функционал называется prompt.

	crt.Screen.WaitForString("-Vlanif200]")
	hostnamestr = crt.Dialog.Prompt("Enter hostname:", "hostname", "", False)
	ipaddressstr = crt.Dialog.Prompt("Enter ip address:", "ip", "", False)
	crt.Screen.Send("ip address 10.10.10.")
	crt.Screen.Send(ipaddressstr)
	crt.Screen.Send(" 23r")
	crt.Screen.Send("quitr")
	crt.Screen.Send("sysname ")
	crt.Screen.Send(hostnamestr)
	crt.Screen.Send("r") 

Эта часть скрипта запрашивала Hostname и цифры из последнего октета. Т. к. оборудования было 15 шт. И данные были представлены в таблице, то я копировал из таблицы значения и вставлял в диалоговые окна. Дальше скрипт работал самостоятельно.

FTP копирование на сетевое оборудование.

Данный скрипт запускал у меня командное окно (shell) и копировал данные по FTP. По завершению закрывал сессию. Использовать блокнот для этого невозможно, т. к. копирование идет очень долго и данные в буфере FTP не будут столько храниться:

# $language = "Python"
# $interface = "1.0"

# Connect to a telnet server and automate the initial login sequence.
# Note that synchronous mode is enabled to prevent server output from
# potentially being missed.

def main():
	crt.Screen.Synchronous = True
	crt.Screen.Send("ftp 192.168.1.1r")
	crt.Screen.WaitForString("Name")
	crt.Screen.Send("adminr")
	crt.Screen.WaitForString("Password:")
	crt.Screen.Send("Passwordr")
	crt.Screen.WaitForString("ftp")
	crt.Screen.Send("binaryr")
	crt.Screen.WaitForString("ftp")
	crt.Screen.Send("put S5720LI-V200R011SPH016.patr")
	crt.Screen.WaitForString("ftp")
	crt.Screen.Send("quitr")
	crt.Screen.Synchronous = False
main()

Ввод username/password с помощью скрипта

У одного заказчика доступ к сетевому оборудованию напрямую был закрыт. Зайти на оборудование можно было сначала подключившись к Шлюзу по умолчанию, а с него потом на оборудование подключенное к нему. Для подключения использовался ssh клиент встроенный в IOS/ПО оборудования. Соответственно имя пользователя и пароль запрашивались в консоли. С помощью скрипта ниже, имя пользователя и пароль вводились автоматически:

# $language = "Python"
# $interface = "1.0"

# Connect to a telnet server and automate the initial login sequence.
# Note that synchronous mode is enabled to prevent server output from
# potentially being missed.

def main():
	crt.Screen.Synchronous = True
	crt.Screen.Send("snmpadminr")
	crt.Screen.WaitForString("assword:")
	crt.Screen.Send("Passwordr")
	crt.Screen.Synchronous = False
main()

Примечание: Скрипта было 2. Один для учетной записи администратора, второй для учетной записи eSIGHT.

Скрипт с возможностью напрямую дописывать данные во время выполнения скрипта.

Задачей было добавить на всем сетевом оборудовании статический маршрут. Но шлюз в интернет на каждом оборудовании был свой (и он отличался от шлюза по умолчанию). Следующий скрипт выводил таблицу маршрутизации, вводил в режим конфигурирования недописывал до конца команду (IP адрес шлюза в интернет) – эту часть дописывал я. После того как я нажимал Enter, скрипт продолжал выполнение команды.

# $language = "Python"
# $interface = "1.0"

# Connect to a telnet server and automate the initial login sequence.
# Note that synchronous mode is enabled to prevent server output from
# potentially being missed.

def main():
	crt.Screen.Synchronous = True
	crt.Screen.Send("Zdes-mogla-bit-vasha-reklamar")
	crt.Screen.WaitForString("#")
	crt.Screen.Send("show run | inc ip router")
	crt.Screen.WaitForString("#")
	crt.Screen.Send("conf tr")
	crt.Screen.WaitForString("(config)#")
	crt.Screen.Send("ip route 10.10.10.8 255.255.255.252 ")
	crt.Screen.WaitForString("(config)#")
	crt.Screen.Send("endr")
	crt.Screen.WaitForString("#")
	crt.Screen.Send("copy run star")
	crt.Screen.WaitForString("[startup-config]?")
	crt.Screen.Send("r")
	crt.Screen.WaitForString("#")
	crt.Screen.Send("exitr")
	crt.Screen.Synchronous = False
main()

В данном скрипте в строчке: crt.Screen.Send(«ip route 10.10.10.8 255.255.255.252 „) не дописан IP адрес шлюза и отсутствует символ перевода каретки. Скрипт ждет появления следующей строчки с символами «(config)#» Данные символы появлялись после ввода мной ip адреса и enter.

Заключение:

При написании скрипта и выполнении, должно непременно выполняться правило: Время написания скрипта и выполнения скрипта ни когда не должно быть больше, времени теоретически затраченного на выполнения этой же работы вручную (copy/paste из блокнота, написание и отладка playbook для ansible, написание и отладка скрипта python). Т. е. использование скрипта должно экономить время, а не тратить время на одноразовую автоматизацию процессов (Т. е. когда скрипт уникальный и повторения больше не будет). Но если скрипт уникальный и автоматизация со скриптом и написание/отладка скрипта занимает времени меньше чем выполнение любым другим способом (ansible, command window), то скрипт — лучшее решение.
Отладка скрипта. Скрипт растет постепенно, отладка происходит на обкате на первом, втором, третьем устройстве и к четвертому скрипт скорее всего будет полностью рабочим.

Запуск скрипта (с вводом username+password) с помощью мышки обычно происходит быстрее, чем копирование из блокнота Username и Password. Но не безопасно с точки зрения безопасности.
Другой (реальный) пример когда использование скрипта: Прямого доступа на сетевое оборудование у Вас нет. Но есть необходимость донастроить все сетевое оборудование (завести в систему мониторинга, донастроить дополнительный Username/password/snmpv3username/password). Есть доступ когда вы заходите на Core коммутатор, с него открываете SSH на другое оборудование. Почему нельзя использовать средства Ansible. — Потому что мы упираемся в ограничение по количеству допустимых одновременных сессий на сетевом оборудовании (line vty 0 4, user-interface vty 0 4) (другой вопрос как в Ansible заводить разное оборудование с одним и тем же SSH первым хопом).

Скрипт уменьшает время при длительных операциях – например копирование файлов по FTP. После окончания копирования скрипт сразу начинает работать. Человеку потребуется увидеть окончание копирования, потом осознать окончание копирования, потом ввести соответствующие команды. Скрипт это делает объективно быстрее.

Скрипты применимы там, где невозможно использовать средства массовой доставки данных: Консоль. Или когда часть данных для оборудования уникальна: hostname, management ip address. Или когда писать программу и отладку к ней сложнее, чем дописать данные полученные с оборудования во время работы скрипта. — Пример со скриптом по прописыванию маршрута, когда на каждом оборудование IP адрес интернет провайдера свой. (Мои коллеги писали такие скрипты — когда DMVPN spoke было за 3 сотни. Необходимо было изменить настройки DMVPN).

Пример из практики: Задание первоначальных настроек на новом коммутаторе через консольные порты:

А. Вставил консольный кабель в устройство.
Б. Запустил скрипт
В. Дождался выполнения скрипта
Г. Переткнул консольный кабель в следующее устройство.
Д. Если свитч не последний, перейти к пункту Б.

Итого по итогам работы скрипта:

  • на оборудовании задан начальный пароль.
  • введен Username
  • введен уникальный IP адрес устройства.

P. S. операцию пришлось повторять. Т. к. по Default ssh оказался не настроен/выключен. (Да это моя ошибка.)

Использованные источники.

1. О создании скриптов
2. Примеры скриптов

Приложение 1: Примеры скриптов.


Пример длинного скрипта, с двумя запросами: Hostname и IP адресом. Создавался для преднастройки оборудования через консоль (9600 бод). А также для подготовки подключения оборудования к сети.

# $language = "Python"
# $interface = "1.0"

# Connect to a telnet server and automate the initial login sequence.
# Note that synchronous mode is enabled to prevent server output from
# potentially being missed.

def main():
	crt.Screen.Synchronous = True
	crt.Screen.Send("r")
	crt.Screen.WaitForString("name")
	crt.Screen.Send("adminr")
	crt.Screen.WaitForString("Password:")
	crt.Screen.Send("Passwordr")
	crt.Screen.Send("sysr")
	crt.Screen.WaitForString("]")
	crt.Screen.Send("interface Vlanif 1r")
	crt.Screen.WaitForString("Vlanif1]")
	crt.Screen.Send("undo ip addressr")
	crt.Screen.Send("shutdownr")
	crt.Screen.Send("vlan 100r")
	crt.Screen.Send(" description description1r")
	crt.Screen.Send(" name description1r")
	crt.Screen.Send("vlan 110r")
	crt.Screen.Send(" description description2r")
	crt.Screen.Send(" name description2r")
	crt.Screen.Send("vlan 120r")
	crt.Screen.Send(" description description3r")
	crt.Screen.Send(" name description3r")
	crt.Screen.Send("vlan 130r")
	crt.Screen.Send(" description description4r")
	crt.Screen.Send(" name description4r")
	crt.Screen.Send("vlan 140r")
	crt.Screen.Send(" description description5r")
	crt.Screen.Send(" name description5r")
	crt.Screen.Send("vlan 150r")
	crt.Screen.Send(" description description6r")
	crt.Screen.Send(" name description6r")
	crt.Screen.Send("vlan 160r")
	crt.Screen.Send(" description description7r")
	crt.Screen.Send(" name description7r")
	crt.Screen.Send("vlan 170r")
	crt.Screen.Send(" description description8r")
	crt.Screen.Send(" name description8r")               
	crt.Screen.Send("vlan 180r")
	crt.Screen.Send(" description description9r")
	crt.Screen.Send(" name description9r")
	crt.Screen.Send("vlan 200r")
	crt.Screen.Send(" description description10r")
	crt.Screen.Send(" name description10r")
	crt.Screen.Send("vlan 300r")
	crt.Screen.Send(" description description11r")
	crt.Screen.Send(" name description11r")
	crt.Screen.Send("quitr")
	crt.Screen.WaitForString("]")
	crt.Screen.Send("stp region-configurationr")
	crt.Screen.Send("region-name descr")
	crt.Screen.Send("active region-configurationr")
	crt.Screen.WaitForString("mst-region]")
	crt.Screen.Send("quitr")
	crt.Screen.Send("stp instance 0 priority 57344r")
	crt.Screen.WaitForString("]")
	crt.Screen.Send("interface range GigabitEthernet 0/0/1 to GigabitEthernet 0/0/42r")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("description Usersr")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("port link-type hybridr")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("voice-vlan 100 enabler")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("voice-vlan legacy enabler")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("port hybrid pvid vlan 120r")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("port hybrid tagged vlan 100r")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("port hybrid untagged vlan 120r")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("stp edged-port enabler")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("trust 8021pr")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("storm-control broadcast min-rate 1000 max-rate 1500r")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("storm-control multicast min-rate 1000 max-rate 1500r")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("storm-control action blockr")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("storm-control enable trapr")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("quitr")
	crt.Screen.Send("interface range GigabitEthernet 0/0/43 to GigabitEthernet 0/0/48r")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("description Printersr")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("port link-type accessr")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("port default vlan 130r")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("stp edged-port enabler")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("trust 8021pr")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("storm-control broadcast min-rate 1000 max-rate 1500r")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("storm-control multicast min-rate 1000 max-rate 1500r")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("storm-control action blockr")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("storm-control enable trapr")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("quitr")
	crt.Screen.Send("interface range XGigabitEthernet 0/0/1 to XGigabitEthernet 0/0/2r")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("description uplinkr")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("port link-type trunkr")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("port trunk allow-pass vlan 100 110 120 130 140 150 160 170 180 200r")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("port trunk allow-pass vlan 300r")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("storm-control broadcast min-rate 1000 max-rate 1500r")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("storm-control multicast min-rate 1000 max-rate 1500r")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("storm-control action blockr")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("storm-control enable trapr")
	crt.Screen.WaitForString("port-group]")
	crt.Screen.Send("quitr")
	crt.Screen.Send("ntp-service unicast-server 10.10.10.4r")
	crt.Screen.Send("ntp-service unicast-server 10.10.10.2r")
	crt.Screen.Send("ntp-service unicast-server 10.10.10.134r")
	crt.Screen.Send("ip route-static 0.0.0.0 0.0.0.0 10.10.10.254r")
	crt.Screen.Send("interface Vlanif 200r")
	crt.Screen.WaitForString("-Vlanif200]")
	crt.Screen.Send("r")
	crt.Screen.WaitForString("-Vlanif200]")
	crt.Screen.Send("r")
	crt.Screen.WaitForString("-Vlanif200]")
	crt.Screen.Send("r")
	crt.Screen.WaitForString("-Vlanif200]")
	crt.Screen.Send("r")
	crt.Screen.WaitForString("-Vlanif200]")
	crt.Screen.Send("r")
	crt.Screen.WaitForString("-Vlanif200]")
	crt.Screen.Send("r")
	crt.Screen.WaitForString("-Vlanif200]")
	crt.Screen.Send("r")
	crt.Screen.WaitForString("-Vlanif200]")
        hostnamestr = crt.Dialog.Prompt("Enter hostname:", "hostname", "", False)
        ipaddressstr = crt.Dialog.Prompt("Enter ip address:", "ip", "", False)
	crt.Screen.Send("ip address 10.10.10.")
	crt.Screen.Send(ipaddressstr)
	crt.Screen.Send(" 24r")
	crt.Screen.Send("quitr")
	crt.Screen.Send("sysname ")
	crt.Screen.Send(hostnamestr)
	crt.Screen.Send("r")
	crt.Screen.WaitForString("]")
	crt.Screen.Synchronous = False
main()

Такие скрипты обычно не нужны, но количество оборудования – 15 шт. Позволило ускорить настройку. Дальше настраивать оборудование было быстрее с помощью SecureCRT Command window.

Настройка учетной записи для ssh.

Другой пример. Настройка также через консоль.

# $language = "Python"
# $interface = "1.0"

# Connect to a telnet server and automate the initial login sequence.
# Note that synchronous mode is enabled to prevent server output from
# potentially being missed.

def main():
	crt.Screen.Synchronous = True
	crt.Screen.Send("r")
	crt.Screen.WaitForString("name")
	crt.Screen.Send("adminr")
	crt.Screen.WaitForString("Password:")
	crt.Screen.Send("Passwordr")
	crt.Screen.WaitForString(">")
	crt.Screen.Send("sysr")
	crt.Screen.Send("stelnet server enabler")
	crt.Screen.Send("aaar")
	crt.Screen.Send("local-user admin service-type terminal ftp http sshr")
	crt.Screen.Send("quitr")
	crt.Screen.Send("user-interface vty 0 4r")
	crt.Screen.Send("authentication-mode aaar")
	crt.Screen.Send("quitr")
	crt.Screen.Send("quitr")
	crt.Screen.Synchronous = False
main()


О SecureCRT:Платное ПО: от 99$ (самая маленькая цена только на SecureCRT на один год)
Официальный сайт
1 раз покупается лицензия на ПО, с поддержкой (для обновления), потом ПО используется с этой лицензией неограниченное время.

Работает на операционных системах Mac OS X и Windows.

Есть поддержка скриптов (эта статья)
Есть Command Window
Serial/Telnet/SSH1/SSH2/Shell Операционной системы

Источник: habr.com