5 de mar. de 2018

Programação de Redes - Utilizando o módulo Netmiko

Olá Pessoal Bom Dia, hoje vamos falar sobre o módulo “netmiko”, dito módulo nos permite conetar, enviar comandos e configurar roteadores sejam Cisco, JunOS etc via SSH.



Instalando NetMiko

O módulo netmiko utiliza por baixo dos panos o módulo SSH “paramiko”, porém ele é um módulo já pronto para trabalhar com roteadores.

O primeiro passo é a instalação do módulo “netmiko”. Para isso vamos utilizar o utilitário “pip”:

Na nossa VM executar:

sudo apt-get update
sudo apt-get -y install python-dev
sudo apt-get -y install libffi-dev
sudo apt-get -y install libssl-dev
sudo apt-get -y install python-pip


Pronto, com isso o “pip” esta instalado. O “pip” é uma ferramente que serve para instalar e gerenciar módulos python.

Instalando “netmiko” e suas dependências:


sudo pip install --upgrade setuptools
sudo pip install ipaddress
sudo pip install cryptography
sudo pip install paramiko
sudo pip install netmiko
sudo pip install –-upgrade pip enum34

Com o “netmiko” instalado vamos criar uma topologia de teste com 2 roteadores, rodando OSPF entre eles:




O Cloud1, representa a nossa interface de loopback "tap0" na nossa VM e ela tem como ip "192.168.200.2".

As configurações dos nossos roteadores são:

IOU1:

conf t
hostname IOU1
!
ip domain-name iou1.com
username cisco password cisco
enable password cisco
crypto key generate rsa
The name for the keys will be: IOU1.iou1.com
Choose the size of the key modulus in the range of 360 to 4096 for your
  General Purpose Keys. Choosing a key modulus greater than 512 may take
  a few minutes.

How many bits in the modulus [512]:1024
!
ip ssh version 2
!
line vty 0 4
login local
transport input ssh
!
int e0/0
ip address 192.168.200.1 255.255.255.0
no shut
!
int lo0
ip address 1.1.1.1 255.255.255.0
!
int e0/1
ip address 10.10.10.1 255.255.255.0
no shut
!
router ospf 1
router-id 0.0.0.1
network 0.0.0.0 255.255.255.255


IOU2:

conf t
hostname IOU1
!
!
ip domain-name iou2.com
username cisco password cisco
enable password cisco
crypto key generate rsa
The name for the keys will be: IOU1.iou1.com
Choose the size of the key modulus in the range of 360 to 4096 for your
  General Purpose Keys. Choosing a key modulus greater than 512 may take
  a few minutes.

How many bits in the modulus [512]:1024
!
ip ssh version 2
!
line vty 0 4
login local
transport input ssh
!
int lo0
ip address 2.2.2.2 255.255.255.0
!
int e0/1
ip address 10.10.10.2 255.255.255.0
no shut
!
router ospf 1
router-id 0.0.0.2
network 0.0.0.0 255.255.255.255


Também vamos adicionar duas rotas na nossa VM, para poder ter conetividade aos roteadores:


jose@rejane:~$ sudo route add -host 1.1.1.1 gw 192.168.200.1
jose@rejane:~$ sudo route add -host 2.2.2.2 gw 192.168.200.1
jose@rejane:~$ ping 1.1.1.1
jose@rejane:~$ ping 1.1.1.1
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
64 bytes from 1.1.1.1: icmp_seq=1 ttl=255 time=0.508 ms
64 bytes from 1.1.1.1: icmp_seq=2 ttl=255 time=0.489 ms
^C
--- 1.1.1.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.489/0.498/0.508/0.024 ms
jose@rejane:~$ ping 2.2.2.2
PING 2.2.2.2 (2.2.2.2) 56(84) bytes of data.
64 bytes from 2.2.2.2: icmp_seq=1 ttl=254 time=0.752 ms
64 bytes from 2.2.2.2: icmp_seq=2 ttl=254 time=0.507 ms
^C
--- 2.2.2.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.507/0.629/0.752/0.125 ms
jose@rejane:~$ 


Utilizando o NetMiko


O primeiro passo é importar a função ConnectHandler, do módulo “netmiko”:

from netmiko import ConnectHandler

A função “ConnectHandler”, vai ser a encarregada de seleccionar a classe correta dentro do módulo netmiko baseado no tipo de dispositivo, IOS, IOS-XR , JunOS etc.

Vamos executar uma conexão SSH ao roteador IOU1, para isso eu vou especificar os parâmetros: tipo de dispositivo,ip, usuário, senha, senha de enable, timeout da conexão SSH. Existem outros parâmetros com os quais podemos brincar, porém de momento esses são mais do que necessários.

O parâmetro timeout=10, quer dizer que vamos tentar nós conetar ao dispositivo e esperar no máximo 10 segundos por uma resposta, caso não se estabeleça uma conexão em 10segundos da erro de timeout.


>>> from netmiko import ConnectHandler
>>> iou1_connect = ConnectHandler(device_type='cisco_ios',ip='1.1.1.1',username='cisco',password='cisco',secret='cisco',timeout=10)
>>>


Com isso uma sessão SSH foi estabelecida ao roteador IOU1, podemos verificar mandando um “sh users”, no roteador:

IOU1#sh users
Line User Host(s) Idle Location
* 0 con 0 idle 00:00:00
2 vty 0 cisco idle 00:00:24 192.168.200.2
Interface User Mode Idle Peer Address
IOU1#


Podemos ver a classe, e quais métodos tem o objeto “iou1_connect”:


>>> type(iou1_connect)
<class 'netmiko.cisco.cisco_ios.CiscoIosSSH'>
>>>
>>> dir(iou1_connect)
['RESPONSE_RETURN', 'RETURN', 'TELNET_RETURN', '__class__', '__delattr__', '__dict__', '__doc__', '__enter__', '__exit__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_autodetect_fs', '_build_ssh_client', '_connect_params_dict', '_lock_netmiko_session', '_modify_connection_params', '_read_channel', '_read_channel_expect', '_read_channel_timing', '_sanitize_output', '_session_locker', '_test_channel_read', '_timeout_exceeded', '_unlock_netmiko_session', '_use_ssh_config', '_write_channel', 'allow_agent', 'alt_host_keys', 'alt_key_file', 'ansi_escape_codes', 'base_prompt', 'blocking_timeout', 'check_config_mode', 'check_enable_mode', 'cleanup', 'clear_buffer', 'commit', 'config_mode', 'device_type', 'disable_paging', 'disconnect', 'enable', 'establish_connection', 'exit_config_mode', 'exit_enable_mode', 'find_prompt', 'global_delay_factor', 'host', 'ip', 'is_alive', 'keepalive', 'key_file', 'key_policy', 'normalize_cmd', 'normalize_linefeeds', 'password', 'port', 'protocol', 'read_channel', 'read_until_pattern', 'read_until_prompt', 'read_until_prompt_or_pattern', 'remote_conn', 'remote_conn_pre', 'secret', 'select_delay_factor', 'send_command', 'send_command_expect', 'send_command_timing', 'send_config_from_file', 'send_config_set', 'serial_login', 'serial_settings', 'session_preparation', 'session_timeout', 'set_base_prompt', 'set_terminal_width', 'special_login_handler', 'ssh_config_file', 'strip_ansi_escape_codes', 'strip_backspaces', 'strip_command', 'strip_prompt', 'system_host_keys', 'telnet_login', 'timeout', 'use_keys', 'username', 'verbose', 'write_channel']
>>>

O objeto “iou1_connect”, é um objeto da classe CiscoIosSSH, e ele tem uma variedade de métodos disponivéis como “send_command()”, “find_prompt()” etc

Vamos testar o método “find_prompt()”:

>>> iou1_connect.find_prompt()
u'IOU1>'
>>>

Ele devolve o prompt do roteador, como estou conetado via um usuário que não é do enable ele devolve o prompt “>”:

Trocando para enable:

>>> iou1_connect.enable()
u'enable\r\nPassword: \r\nIOU1#'
>>> iou1_connect.find_prompt()
u'IOU1#'
>>>

Beleza, agora somos enable, vamos enviar o comando “sh ip int bri” agora:

>>> output=iou1_connect.send_command('sh ip int bri')
>>> print output
Interface IP-Address OK? Method Status Protocol
Ethernet0/0 192.168.200.1 YES manual up up
Ethernet0/1 10.10.10.1 YES manual up up
Ethernet0/2 unassigned YES NVRAM administratively down down
Ethernet0/3 unassigned YES NVRAM administratively down down
Ethernet1/0 unassigned YES NVRAM administratively down down
Ethernet1/1 unassigned YES NVRAM administratively down down
Ethernet1/2 unassigned YES NVRAM administratively down down
Ethernet1/3 unassigned YES NVRAM administratively down down
Serial2/0 unassigned YES NVRAM administratively down down
Serial2/1 unassigned YES NVRAM administratively down down
Serial2/2 unassigned YES NVRAM administratively down down
Serial2/3 unassigned YES NVRAM administratively down down
Serial3/0 unassigned YES NVRAM administratively down down
Serial3/1 unassigned YES NVRAM administratively down down
Serial3/2 unassigned YES NVRAM administratively down down
Serial3/3 unassigned YES NVRAM administratively down down
Loopback0 1.1.1.1 YES manual up up
Loopback1 unassigned YES unset up up
>>>

Show!, agora vamos sair do enable e fechar a conexão.

>>> iou1_connect.exit_enable_mode()
u'disable\r\nIOU1>'
>>> iou1_connect.disconnect()
>>>

Agora vamos tentar configurar o nosso roteador. Vamos criar uma interface lookpback2 em IOU1 e colocar ela na área 4 do nosso OSPF. Para enviar uma serie de comandos de configuração, precisamos definir uma lista, contendo a sequência dos comandos de configuração.

>>> iou1_connect = ConnectHandler(device_type='cisco_ios',ip='1.1.1.1',username='cisco',password='cisco',secret='cisco',timeout=10)
>>>
>>> config_commands = ['int lo2','ip address 11.11.11.11 255.255.255.0','ip ospf 1 area 4','ip ospf network point-to-point']
>>>
>>> iou1_connect.enable()
u'enable\r\nPassword: \r\nIOU1#'
>>> output=iou1_connect.send_config_set(config_commands)
>>> print output
config term
Enter configuration commands, one per line. End with CNTL/Z.
IOU1(config)#int lo2
IOU1(config-if)#ip address 11.11.11.11 255.255.255.0
IOU1(config-if)#ip ospf 1 area 4
IOU1(config-if)#ip ospf network point-to-point
IOU1(config-if)#end
IOU1#
>>> iou1_connect.exit_enable_mode()
u'disable\r\nIOU1>'
>>> iou1_connect.disconnect()
>>>

Verificando no roteador IOU1:

IOU1#sh run | section Loopback2
interface Loopback2
 ip address 11.11.11.11 255.255.255.0
 ip ospf network point-to-point
 ip ospf 1 area 4
IOU1#


Verificando a rota no IOU2:


IOU2#sh ip route ospf | Inc ^O
O        1.1.1.1 [110/11] via 10.10.10.1, 00:49:25, Ethernet0/1
O IA     11.11.11.0 [110/11] via 10.10.10.1, 00:00:48, Ethernet0/1
O     192.168.200.0/24 [110/20] via 10.10.10.1, 00:49:25, Ethernet0/1
IOU2#


Perfeito, o nosso roteador foi configurado corretamente.

Por hoje é isso pessoal, agora sabemos como utilizar o netmiko :). Próximo post vamos utilizar ele para fazer uma rotina de backup dos nossos roteadores.

Abçs
Jose
















2 comentários:

  1. Fiz a compra porém mando emails para o Sr. Adilson para ter acesso ao Google Drive e não tenho resposta... Poderia ajudar-me com essa pendência?

    ResponderExcluir
  2. Boa Tarde Misael,

    Para que as imagens não vazem para a Internet eu não compartilho o link da pasta, pois dessa forma, qualquer um poderia abrir.

    Me passe um e-mail Gmail ou atrelado ao Google para que eu compartilhe a pasta contigo.

    Me contate pelo e-mail: adilson.aflorentino@gmail.com

    Att,

    ResponderExcluir