Os engenheiros de rede frequentemente enfrentam a tarefa de realizar o copy/paste de determinados trechos do bloco de notas para o console. Geralmente, precisam copiar vários parâmetros: Nome de usuário/Senha e algo mais. O uso de scripts pode acelerar esse processo. NO ENTANTO, a programação e a execução do script, juntas, devem levar menos tempo do que a configuração manual; caso contrário, os scripts são inúteis.
Para que serve este artigo. Este artigo faz parte da série Fast Start e é voltado para economizar tempo dos engenheiros de rede ao configurar equipamentos (uma tarefa) em vários dispositivos. Utiliza o software SecureCRT e a funcionalidade integrada de execução de scripts.
Conteúdo
Introdução
O SecureCRT vem com um mecanismo embutido de execução de scripts. Para que servem os scripts no terminal:
- Entrada e saída automatizadas, com mínima verificação de correção da entrada/saída.
- Acelerar a execução de tarefas rotineiras - redução dos intervalos entre as configurações do equipamento. (De fato, redução dos intervalos causados pelo tempo para a execução de ações de copy/paste no mesmo equipamento, ao usar 3 ou mais trechos de comandos para aplicar no equipamento.)
Este documento aborda as seguintes tarefas:
- Criação de scripts simples.
- Execução de scripts no SecureCRT.
- Exemplos de uso de scripts simples e avançados. (Prática do mundo real.)
Criação de scripts simples.
Scripts simples utilizam apenas dois comandos: Send e WaitForString. Essa funcionalidade é suficiente para 90% (ou mais) das tarefas realizadas.
Os scripts podem funcionar nas linguagens Python, JS, VBS (Visual Basic), Perl, etc.
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()
Normalmente, um arquivo com a extensão '*.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
Normalmente, um arquivo com a extensão '*.vbs'
Criação de um script usando gravação de script.
Permite automatizar o processo de escrita de um script. Você inicia a gravação do script. O SecureCRT grava os comandos e a resposta subsequente do equipamento e fornece um script pronto.
a. Iniciar a gravação do script:
Menu SecureCRT => Script => Iniciar Gravação do Script
b. Execute ações no console (realize ações de configuração no CLI).
c. Encerrar a gravação do script:
Menu SecureCRT => Script => Parar Gravação do Script…
Salvar o arquivo com o script.
Exemplo de comandos executados e script salvo:

Execução de scripts no SecureCRT.
Após a criação/edição do script, surge a questão natural: Como aplicar o script?
Existem várias maneiras:
- Execução manual pelo menu Script
- Execução automática após a conexão (script de logon)
- Logon automático sem o uso de script
- Execução manual com um botão no SecureCRT (o botão ainda precisa ser criado e adicionado ao SecureCRT)
Execução manual pelo menu Script
Menu SecureCRT => Script => Executar…
— Os últimos 10 scripts são lembrados e estão disponíveis para execução rápida:
Menu SecureCRT => Script => 1 'Nome do arquivo do script'
Menu SecureCRT => Script => 2 'Nome do arquivo do script'
Menu SecureCRT => Script => 3 'Nome do arquivo do script'
Menu SecureCRT => Script => 4 'Nome do arquivo do script'
Menu SecureCRT => Script => 5 'Nome do arquivo do script'
Execução automática após a conexão (script de logon)
As configurações de registro de script automático são ajustadas para a sessão salva: Conexão => Ações de Logon => Script de Logon

Logon automático sem o uso de script
Há a possibilidade de inserção automática do nome de usuário e da senha sem escrever um script, usando apenas a funcionalidade integrada do SecureCRT. Nas configurações de conexão 'Conexão' => Ações de Logon => Automatizar logon – é necessário preencher vários pares que consistem em: 'Texto Esperado' + 'Símbolos Enviados para esse texto', podendo haver muitos pares. (Exemplo: 1º par espera a entrada do nome de usuário, 2º espera a entrada da senha, 3º espera um convite para modo privilegiado, 4º a senha do modo privilegiado.)
Exemplo de logon automático no Cisco ASA:

Execução manual com um botão no SecureCRT (o botão ainda precisa ser criado e adicionado ao SecureCRT)
No SecureCRT, um script pode ser atribuído a um botão. O botão é adicionado a uma barra especialmente criada para esse fim.
a. Adicionar a barra à interface: Menu SecureCRT => Exibir => Barra de Botões
b. Adicionar um botão à barra e associar o script. – Clique com o botão direito na barra de botões e no menu de contexto escolha 'Novo botão…'.
c. Na janela de diálogo 'Mapear Botão', no campo 'Ação', escolhemos a ação (função) 'Executar Script'.
Indicamos a legenda para o botão. A cor para o ícone do botão. Finalizamos as configurações clicando em Ok.

Nota:
O painel de botões é uma funcionalidade muito útil.
1. Existe a possibilidade de, ao realizar Login em uma determinada sessão, indicar qual painel abrir por padrão nessa aba.
2. É possível definir ações pré-estabelecidas para ações padrão com o equipamento: mostrar show version, show running-config, salvar configuração.

Esses botões não estão vinculados a nenhum script. Apenas uma linha com as ações:

Configuração – para que ao alternar para a sessão o painel necessário com os botões seja aberto, é feita nas configurações da sessão:

Para o cliente, faz sentido configurar scripts individuais para Login e transição para o painel com comandos frequentes para o fornecedor.
![]()
Ao clicar no botão Go Cisco, o painel muda para a Cisco Button Bar.

Exemplos de uso de scripts simples e avançados. (Prática do mundo real.)
Scripts simples são suficientes para quase todas as situações. Mas uma vez eu precisei complicar um pouco o script – para acelerar o trabalho. Essa complicação – apenas pedia dados adicionais em uma caixa de diálogo do usuário.
Solicitação de dados do usuário através de uma caixa de diálogo
No meu script de solicitações de dados, havia 2. Isso era o Hostname e o quarto octeto do endereço IP. Para realizar essa ação – eu pesquisei como fazer isso e encontrei no site oficial da SecureCRT (vandyke). – a funcionalidade é chamada de prompt.
crt.Screen.WaitForString("-Vlanif200]")
hostnamestr = crt.Dialog.Prompt("Digite o hostname:", "hostname", "", False)
ipaddressstr = crt.Dialog.Prompt("Digite o endereço IP:", "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")
Essa parte do script pedia o Hostname e os números do último octeto. Como havia 15 dispositivos e os dados estavam apresentados em uma tabela, eu copiava os valores da tabela e colava nas caixas de diálogo. Depois disso, o script funcionava sozinho.
Cópia FTP em equipamentos de rede.
Esse script abria um shell e copiava dados via FTP. Ao concluir, fechava a sessão. Não é possível usar o bloco de notas para isso, pois a cópia leva muito tempo e os dados no buffer FTP não são mantidos por tanto tempo:
# $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()
Inserção de nome de usuário/senha através de script
Um cliente teve o acesso ao equipamento de rede diretamente bloqueado. Para acessar o equipamento, era necessário primeiro conectar-se ao Gateway padrão e, a partir dele, conectar-se ao equipamento que estava conectado. Para a conexão, era utilizado um cliente ssh incorporado no IOS/Software do equipamento. Portanto, o nome de usuário e a senha eram solicitados no console. Com o script abaixo, o nome de usuário e a senha eram inseridos automaticamente:
# $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()
Nota: Havia 2 scripts. Um para a conta de administrador e outro para a conta eSIGHT.
Script com a possibilidade de adicionar diretamente dados durante a execução do script.
O objetivo era adicionar uma rota estática em todo o equipamento de rede. Mas o gateway para a internet em cada equipamento era próprio (e diferente do gateway padrão). O seguinte script exibia a tabela de roteamento, entrava no modo de configuração e não completava o comando (endereço IP do gateway da internet) – esta parte era completada por mim. Após eu pressionar Enter, o script continuava a execução do comando.
# $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()
Neste script na linha: crt.Screen.Send(«ip route 10.10.10.8 255.255.255.252 „) o endereço IP do gateway não foi completado e falta o símbolo de nova linha. O script aguarda a próxima linha com os símbolos «(config)#». Esses símbolos apareciam após eu inserir o endereço IP e pressionar enter.
Conclusão:
Ao escrever e executar o script, deve-se sempre respeitar a regra: O tempo para escrever o script e executar o script nunca deve ser maior que o tempo teoricamente gasto para executar esse mesmo trabalho manualmente (copy/paste do bloco de notas, escrita e depuração de playbook para ansible, escrita e depuração de script em python). Ou seja, o uso do script deve economizar tempo e não gastar tempo na automação única de processos (ou seja, quando o script é único e não haverá repetições). Mas se o script é único e a automação com o script e a escrita/depuração do script leva menos tempo do que executar de qualquer outra maneira (ansible, janela de comando), então o script é a melhor solução.
Depuração do script. O script cresce gradualmente, a depuração ocorre na prática no primeiro, segundo e terceiro dispositivo, e no quarto o script provavelmente estará totalmente funcional.
Executar o script (com entrada de username+password) com o mouse geralmente é mais rápido do que copiar o Username e Password do bloco de notas. Mas não é seguro do ponto de vista de segurança.
Outro exemplo (real) de quando usar o script: você não tem acesso direto ao equipamento de rede. Mas é necessário ajustar todo o equipamento de rede (integrá-lo ao sistema de monitoramento, ajustar Username/password/snmpv3username/password adicionais). Você tem acesso quando entra no switch Core, de onde abre SSH para outro equipamento. Por que não é possível utilizar ferramentas como o Ansible? — Porque esbarramos na limitação do número de sessões simultâneas permitidas no equipamento de rede (line vty 0 4, user-interface vty 0 4) (outro ponto é como no Ansible conectar diferentes equipamentos com o mesmo SSH na primeira hop).
O script reduz o tempo em operações longas – por exemplo, a cópia de arquivos via FTP. Assim que a cópia termina, o script começa a funcionar imediatamente. A pessoa precisaria ver o término da cópia, depois perceber que a cópia terminou, e então inserir os comandos correspondentes. O script faz isso de forma objetivamente mais rápida.
Os scripts são aplicáveis onde não é possível usar métodos de entrega em massa de dados: Console. Ou quando parte dos dados para o equipamento é única: hostname, endereço IP de gerenciamento. Ou quando escrever um programa e depurá-lo é mais complicado do que adicionar os dados obtidos do equipamento durante a execução do script. — Um exemplo com um script para definir um roteamento, quando cada equipamento tem seu próprio endereço IP do provedor de internet. (Meus colegas escreveram tais scripts – quando o DMVPN spoke tinha mais de 300. Era necessário modificar as configurações do DMVPN).
Exemplo prático: Configuração inicial em um novo switch através das portas de console:
A. Conectei o cabo de console ao dispositivo.
B. Executei o script.
C. Esperei a execução do script.
D. Desconectei o cabo de console do próximo dispositivo.
E. Se o switch não for o último, volte ao ponto B.
Portanto, como resultado do trabalho do script:
- uma senha inicial foi definida no equipamento.
- Username foi inserido.
- um endereço IP único do dispositivo foi inserido.
P. S. a operação teve que ser repetida. Pois por padrão o SSH estava desconfigurado/desativado. (Sim, esse foi meu erro.)
Fontes utilizadas.
1.
2.
Apêndice 1: Exemplos de scripts.
Exemplo de um longo script, com duas solicitações: Nome do Host e Endereço IP. Criado para a pré-configuração de equipamentos através do console (9600 bps). Além disso, para preparar a conexão dos equipamentos à rede.
# $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()
Esses scripts geralmente não são necessários, mas com a quantidade de equipamentos – 15 unidades. Isso ajudou a acelerar a configuração. A partir daí, foi mais rápido configurar os equipamentos usando a janela de comando do SecureCRT.
Configuração da conta para ssh.
Outro exemplo. Configuração também através do console.
# $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()
Sobre o SecureCRT:Software pago: a partir de 99$ (o menor preço para SecureCRT por um ano)
A licença do software é comprada uma vez, com suporte (para atualização), e depois o software é usado com essa licença por tempo ilimitado.
Funciona nos sistemas operacionais Mac OS X e Windows.
Suporte a scripts (este artigo)
Há
Serial/Telnet/SSH1/SSH2/Shell do sistema operacional
Fonte: habr.com
