Conecte-se aos dispositivos Junos usando o Junos PyEZ
RESUMO Conecte-se a um dispositivo Junos ou a um servidor de console conectado usando diferentes métodos e protocolos de conexão em um aplicativo Junos PyEZ.
O Junos PyEZ é uma microframetra para Python que permite que você gerencie dispositivos Junos. O Junos PyEZ modela cada dispositivo como uma instância da classe jnpr.junos.device.Device . A Device
classe permite que você se conecte a um dispositivo Junos usando uma conexão de console serial, telnet ou estabelecendo uma sessão NETCONF sobre SSH. Além disso, o Junos PyEZ também oferece suporte à conexão ao dispositivo por meio de uma conexão telnet ou SSH com um servidor de console. Um servidor de console, também conhecido como servidor terminal, é um dispositivo especializado que fornece uma conexão de rede à porta de console de gerenciamento fora da banda de um dispositivo.
Este tópico fornece uma visão geral dos métodos de conexão suportados pelo Junos PyEZ e explica como usar os diferentes métodos para se conectar a um dispositivo Junos. Os exemplos do Junos PyEZ usam vários métodos de autenticação, mas para obter informações detalhadas sobre a autenticação de um usuário, veja Authenticate Junos PyEZ Users.
Visão geral dos métodos de conexão
O Junos PyEZ permite que você se conecte a um dispositivo Junos usando uma conexão de console serial, telnet ou uma sessão NETCONF sobre SSH. Você deve usar uma conexão de console serial quando estiver fisicamente conectado à porta CONSOLE em um dispositivo. Você pode usar a telnet ou a SSH para se conectar à interface de gerenciamento do dispositivo ou a um servidor de console conectado à porta CONSOLE do dispositivo. Além disso, o Junos PyEZ oferece suporte a conexões SSH de saída, nas quais o dispositivo Junos inicia a conexão com o aplicativo de gerenciamento de clientes.
Dispositivos novos ou zeroizados que tenham configurações padrão de fábrica exigem acesso por meio de uma conexão de console. Assim, você pode usar o Junos PyEZ para configurar inicialmente um dispositivo que ainda não está configurado para acesso remoto usando uma conexão de console serial quando você está diretamente conectado ao dispositivo ou usando telnet ou SSH através de um servidor de console que está conectado ao dispositivo.
Por padrão, o Junos PyEZ usa o SSH para se conectar a um dispositivo. Para especificar um tipo de conexão diferente, você deve incluir o mode
parâmetro na lista de Device
argumentos. Para telenet para um dispositivo, inclua o mode='telnet'
argumento. Para se conectar a um dispositivo usando uma conexão de console serial, inclua o mode='serial'
argumento. A Tabela 1 resume os métodos de conexão Junos PyEZ, seus valores padrão para determinados parâmetros, qualquer configuração do Junos OS exigida e a versão Junos PyEZ na qual o suporte para esse método de conexão foi introduzido pela primeira vez.
Modo de conexão |
Valor do |
Porta padrão |
Configuração necessária do Junos OS |
Primeira versão do Junos PyEZ com suporte |
---|---|---|---|---|
NETCONF sobre SSH (padrão) |
– |
830 |
[edit system services] netconf { ssh; } |
1.0.0 |
Conexão de console em série |
Série |
/dev/ttyUSB0 |
– |
2.0.0 (*nix) 2.4.0 (Windows) |
Dispositivo Telnet para Junos |
Telnet |
23 |
[edit system services] telnet; |
2.0.0 |
Telnet através de um servidor de console |
Telnet |
23 |
– |
2.0.0 |
SSH por meio de um servidor de console |
– |
22 |
– |
2.2.0 |
SSH de saída |
– |
– |
[edit system services] outbound-ssh { ... } |
2.2.0 |
Antes de acessar a interface de gerenciamento de um dispositivo usando telnet ou NETCONF sobre SSH, você deve primeiro habilitar o serviço apropriado no nível hierárquico [edit system services]
. Para obter mais informações, veja Configurar nós gerenciados do Junos PyEZ. Como a telnet usa senhas de texto claro (portanto, criando uma vulnerabilidade de segurança em potencial), recomendamos que você use SSH.
É responsabilidade do usuário obter as credenciais de autenticação de nome de usuário e senha de maneira segura e apropriada para o ambiente. É a melhor prática solicitar essas credenciais de autenticação durante cada invocação do script, em vez de armazenar as credenciais em um formato não criptografado.
O Junos PyEZ oferece suporte ao uso de gerenciadores de contexto (with
... as
sintaxe) para todos os métodos de conexão. Quando você usa um gerente de contexto, o Junos PyEZ liga automaticamente para os métodos e close()
os open()
métodos para se conectar e desconectar do dispositivo. Se você não usar um gerente de contexto, você deve chamar explicitamente os métodos e close()
os open()
métodos em sua aplicação. Recomendamos que você use um gerente de contexto para conexões de console, pois o gerente de contexto lida automaticamente com o fechamento da conexão, e a falha em fechar a conexão pode levar a resultados imprevisíveis.
Entender as propriedades de conexão do Junos PyEZ
Quando você se conecta a um dispositivo Junos, o Junos PyEZ armazena informações sobre a conexão atual como propriedades da Device
instância. A Tabela 2 descreve as propriedades de conexão disponíveis.
Propriedade |
Descrição |
---|---|
|
Boolean especificando o estado atual da conexão. Retorna |
|
String especificando o nome de host do dispositivo ao qual o aplicativo está conectado. |
|
Boolean retornando |
|
Inteiro ou string especificando a porta usada para a conexão. |
|
String especificando o nome do mecanismo de roteamento ao qual o aplicativo está conectado. |
|
Inteiro especificando o valor de tempo limite do RPC em segundos. |
|
Integer representa o número de segundos desde que o mecanismo de roteamento atual foi inicializado. Esta propriedade está disponível a partir do Junos PyEZ Release 2.1.5. |
|
String especificando o usuário que acessa o dispositivo Junos. |
Por exemplo, depois de se conectar a um dispositivo, você pode consultar a connected
propriedade para devolver o estado atual da conexão. Um SessionListener
monitora a sessão e responde a erros de transporte aumentando uma TransportError
exceção e configurando a Device.connected
propriedade para False
.
O código de amostra a seguir imprime o valor da connected
propriedade após a conexão a um dispositivo Junos e novamente após o fechamento da sessão.
from jnpr.junos import Device dev = Device(host='router.example.net') dev.open() print (dev.connected) dev.close() print (dev.connected)
Quando você executa o programa, a connected
propriedade retorna True
enquanto o aplicativo está conectado ao dispositivo e retorna False
após o fechamento da conexão.
user@host:~$ python connect.py True False
Conecte-se a um dispositivo usando SSH
A classe Junos PyEZ Device
oferece suporte ao uso de SSH para se conectar a um dispositivo Junos. Você pode estabelecer uma sessão netconf sobre SSH com a interface de gerenciamento do dispositivo ou estabelecer uma conexão SSH com um servidor de console que está diretamente conectado à porta CONSOLE do dispositivo. O servidor SSH deve ser capaz de autenticar o usuário usando mecanismos padrão de autenticação de SSH, conforme descrito no Authenticate Junos PyEZ Users. Para estabelecer uma sessão de NETCONF sobre SSH, você também deve satisfazer os requisitos descritos nos nós gerenciados do Junos PyEZ.
O Junos PyEZ consulta automaticamente o arquivo de configuração SSH padrão em ~/.ssh/config, se houver. Ao usar o SSH para se conectar a um dispositivo Junos ou a um servidor de console conectado ao dispositivo, o Junos PyEZ primeiro tenta a autenticação pública baseada em chave SSH e depois tenta a autenticação baseada em senha. Quando a autenticação baseada em senha é usada, a senha fornecida é usada como senha do dispositivo. Quando as chaves SSH estão em uso, a senha fornecida é usada como senha para desbloquear a chave privada. Se a chave privada SSH tiver uma senha vazia, uma senha não será necessária. No entanto, as chaves privadas SSH com senhas vazias não são recomendadas.
Para estabelecer uma sessão netconf sobre SSH com um dispositivo Junos e publicar os fatos do dispositivo em um aplicativo Junos PyEZ usando Python 3:
O programa de amostra em sua totalidade é apresentado aqui:
import sys from getpass import getpass from jnpr.junos import Device from jnpr.junos.exception import ConnectError hostname = input("Device hostname: ") junos_username = input("Junos OS username: ") junos_password = getpass("Junos OS or SSH key password: ") dev = Device(host=hostname, user=junos_username, passwd=junos_password) try: dev.open() except ConnectError as err: print ("Cannot connect to device: {0}".format(err)) sys.exit(1) except Exception as err: print (err) sys.exit(1) print (dev.facts) dev.close()
Como alternativa, você pode usar um gerente de contexto ao se conectar ao dispositivo, que chama open()
e close()
métodos automaticamente. Por exemplo:
import sys from getpass import getpass from jnpr.junos import Device from jnpr.junos.exception import ConnectError hostname = input("Device hostname: ") junos_username = input("Junos OS username: ") junos_password = getpass("Junos OS or SSH key password: ") try: with Device(host=hostname, user=junos_username, passwd=junos_password) as dev: print (dev.facts) except ConnectError as err: print ("Cannot connect to device: {0}".format(err)) sys.exit(1) except Exception as err: print (err) sys.exit(1)
O Junos PyEZ também permite que um cliente se conecte a um dispositivo Junos por meio de uma conexão SSH com um servidor de console. Neste caso, você deve especificar as credenciais de login para o servidor do console, incluindo os argumentos e cs_passwd
a Device
cs_user
lista de argumentos. Quando as chaves SSH estiverem em uso, defina o cs_passwd
argumento para a variável que contém a senha para a chave privada.
O servidor do console se conecta ao dispositivo Junos através de uma conexão serial, que pode ser lenta. As conexões Junos PyEZ por um servidor de console têm um valor de tempo limite de conexão padrão de 0,5 segundos. Como resultado, você pode precisar aumentar o intervalo de tempo de conexão incluindo o Device
timeout=seconds
argumento para permitir tempo suficiente para o aplicativo do cliente estabelecer a conexão.
O exemplo do Python 3 a seguir autentica com o servidor do console e, em seguida, com o dispositivo Junos. O tempo limite de conexão é definido para seis segundos para que o cliente tenha tempo suficiente para estabelecer a conexão.
import sys from getpass import getpass from jnpr.junos import Device from jnpr.junos.exception import ConnectError hostname = input("Console server hostname: ") cs_username = input("Console server username: ") cs_password = getpass("Console server or SSH key password: ") junos_username = input("Junos OS username: ") junos_password = getpass("Junos OS password: ") try: with Device(host=hostname, user=junos_username, passwd=junos_password, cs_user=cs_username, cs_passwd=cs_password, timeout=6) as dev: print (dev.facts) except ConnectError as err: print ("Cannot connect to device: {0}".format(err)) sys.exit(1) except Exception as err: print (err) sys.exit(1)
O Junos PyEZ consulta automaticamente o arquivo de configuração SSH padrão em ~/.ssh/config, se houver. No entanto, você pode especificar um arquivo de configuração SSH diferente ao criar a instância do dispositivo, incluindo o ssh_config
parâmetro na Device
lista de argumentos. Por exemplo:
ssh_config_file = "~/.ssh/config_dc" dev = Device(host='198.51.100.1', ssh_config=ssh_config_file)
O Junos PyEZ também oferece suporte para o ProxyCommand, que permite que você acesse um dispositivo alvo por meio de um host intermediário que oferece suporte à netcat. Isso é útil quando você só pode fazer login no dispositivo alvo por meio do host intermediário.
Para configurar o ProxyCommand, adicione as informações apropriadas ao arquivo de configuração SSH. Por exemplo:
[user1@server ~]$ cat ~/.ssh/config Host 198.51.100.1 User user1 ProxyCommand ssh -l user1 198.51.100.2 nc %h 22 2>/dev/null
Conecte-se a um dispositivo usando SSH de saída
Você pode configurar um dispositivo Junos para iniciar uma conexão TCP/IP com um aplicativo de gerenciamento de clientes que seria bloqueado se o cliente tentasse iniciar a conexão (por exemplo, se o dispositivo estiver por trás de um firewall). A outbound-ssh
configuração instrui o dispositivo a criar uma conexão TCP/IP com o aplicativo de gerenciamento de clientes e encaminhar a identidade do dispositivo. Assim que a conexão é estabelecida, o aplicativo de gerenciamento atua como cliente e inicia a sequência de SSH, e o dispositivo Junos atua como servidor e autentica o cliente.
Assim que você configura e confirma o SSH de saída no dispositivo Junos, o dispositivo começa a iniciar uma conexão SSH de saída com base na configuração comprometida. O dispositivo tenta repetidamente criar essa conexão até ser bem sucedido. Se a conexão entre o dispositivo e o aplicativo de gerenciamento do cliente for perdida, o dispositivo novamente tenta criar uma nova conexão SSH de saída até ser bem-sucedido. Essa conexão é mantida até que a configuração SSH de saída seja excluída ou desativada.
Para configurar o dispositivo Junos para conexões SSH de saída, inclua a outbound-ssh
declaração no nível de [edit system services]
hierarquia. No exemplo a seguir, o dispositivo Junos tenta iniciar uma conexão com o host em 198.51.100.101 na porta 2200:
user@router1> show configuration system services outbound-ssh client nms1 { device-id router1; secret "$9$h1/ceWbs4UDkGD/Cpu1I-Vb"; ## SECRET-DATA services netconf; 198.51.100.101 port 2200; }
Para estabelecer uma conexão com o dispositivo Junos usando SSH de saída, o aplicativo Junos PyEZ define o sock_fd
argumento no Device
construtor igual ao descritor de arquivo de um soquete existente e omite o argumento ou o host
define.None
O exemplo do Junos PyEZ a seguir ouve a porta TCP configurada para sessões de SSH recebidas dos dispositivos Junos. O aplicativo aceita uma conexão de entrada e recupera o descritor de arquivos do socket para essa conexão, que é usada para o valor do sock_fd
argumento. O aplicativo cliente estabelece a conexão SSH com o dispositivo, coleta e imprime os fatos do dispositivo, desconecta-se do dispositivo e aguarda por mais conexões.
import socket from jnpr.junos import Device from jnpr.junos.exception import ConnectError from getpass import getpass from pprint import pprint """ Listen on TCP port 2200 for incoming SSH session with a Junos device. Upon connecting, collect and print the devices facts, then disconnect from that device and wait for more connections. """ def launch_junos_proxy(client, addr): val = { 'MSG-ID': None, 'MSG-VER': None, 'DEVICE-ID': None, 'HOST-KEY': None, 'HMAC': None } msg = '' count = 0 while count < 5: c = client.recv(1) c = c.decode("utf-8") msg += str(c) if c == '\n': count += 1 for line in msg.splitlines(): (key, value) = line.split(': ') val[key] = value print("{}: {}".format(key, val[key])) return client.fileno() def main(): PORT = 2200 junos_username = input('Junos OS username: ') junos_password = getpass('Junos OS password: ') s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(('', PORT)) s.listen(5) print('\nListening on port %d for incoming sessions ...' % (PORT)) sock_fd = 0 while True: client, addr = s.accept() print('\nGot a connection from %s:%d' % (addr[0], addr[1])) sock_fd = launch_junos_proxy(client, addr) print('Logging in ...') try: with Device(host=None, sock_fd=sock_fd, user=junos_username, passwd=junos_password) as dev: pprint(dev.facts) except ConnectError as err: print ("Cannot connect to device: {0}".format(err)) if __name__ == "__main__": main()
user@nms1:~$ python3 junos-pyez-outbound-ssh.py Junos OS username: user Junos OS password: Listening on port 2200 for incoming sessions ... Got a connection from 10.10.0.5:57881 MSG-ID : DEVICE-CONN-INFO MSG-VER : V1 DEVICE-ID : router1 HOST-KEY : ssh-rsa AAAAB...0aF4Mk= HMAC : 4e61201ec27a8312104f63bfaf77a4478a892c82 Logging in ... {'2RE': True, 'HOME': '/var/home/user', 'RE0': {'last_reboot_reason': 'Router rebooted after a normal shutdown.', 'mastership_state': 'master', 'model': 'RE-MX-104', 'status': 'OK', 'up_time': '2 days, 6 hours, 22 minutes, 22 seconds'}, 'RE1': {'last_reboot_reason': 'Router rebooted after a normal shutdown.', 'mastership_state': 'backup', 'model': 'RE-MX-104', 'status': 'OK', 'up_time': '2 days, 6 hours, 22 minutes, 12 seconds'}, 'RE_hw_mi': False, 'current_re': ['re0', 'master', 'node', 'fwdd', 'member', 'pfem'], 'domain': 'example.com', 'fqdn': 'router1.example.com', 'hostname': 'router1', ...
Para obter informações detalhadas sobre a configuração do SSH de saída em dispositivos Junos, consulte Configurar o Serviço SSH de saída.
Conecte-se a um dispositivo usando a Telnet
A classe Junos PyEZ Device
oferece suporte à conexão a um dispositivo Junos usando telnet, que fornece acesso não criptografado ao dispositivo de rede. Você pode telenet para a interface de gerenciamento do dispositivo ou para um servidor de console que está diretamente conectado à porta CONSOLE do dispositivo. Você deve configurar o serviço Telnet no nível de [edit system services]
hierarquia em todos os dispositivos que exigem acesso à interface de gerenciamento. O acesso ao dispositivo por meio de um servidor de console permite que você configure inicialmente um dispositivo novo ou zeroizado que ainda não esteja configurado para acesso remoto.
Para usar o Junos PyEZ para telenet em um dispositivo Junos, você deve incluir mode='telnet'
na lista de Device
argumentos e incluir opcionalmente o port
parâmetro para especificar uma porta. Quando você especifica mode='telnet'
, mas omite o port
parâmetro, o valor para port
padrões é de 23. Quando o aplicativo se conecta por meio de um servidor de console, especifique a porta pela qual o servidor do console se conecta ao dispositivo Junos.
Usar o Junos PyEZ para telenet em um dispositivo Junos e publicar os fatos do dispositivo em um aplicativo Junos PyEZ usando Python 3:
O programa de amostra em sua totalidade é apresentado aqui:
import sys from getpass import getpass from jnpr.junos import Device hostname = input("Device hostname: ") junos_username = input("Junos OS username: ") junos_password = getpass("Junos OS password: ") dev = Device(host=hostname, user=junos_username, passwd=junos_password, mode='telnet', port='23') try: dev.open() except Exception as err: print (err) sys.exit(1) print (dev.facts) dev.close()
Como alternativa, você pode usar um gerenciador de contexto ao se conectar ao dispositivo, que lida com a abertura e fechamento da conexão. Por exemplo:
import sys from getpass import getpass from jnpr.junos import Device hostname = input("Device hostname: ") junos_username = input("Junos OS username: ") junos_password = getpass("Junos OS password: ") try: with Device(host=hostname, user=junos_username, passwd=junos_password, mode='telnet', port='23') as dev: print (dev.facts) except Exception as err: print (err) sys.exit(1)
Em alguns casos, quando você se conecta a um servidor de console que emite uma mensagem de banner, você pode ser obrigado a pressionar Enter após a mensagem para chegar ao prompt de login. Se um aplicativo Junos PyEZ abrir uma sessão de Telnet com um servidor de console que exige que o usuário pressione Enter após uma mensagem de banner, o aplicativo pode não receber o prompt de login, o que pode fazer com que a conexão seja paralisada.
A partir do Junos PyEZ Release 2.6.2, o Junos PyEZ lida automaticamente com o banner do servidor do console. No Junos PyEZ Releases 2.1.0 a 2.6.1, um aplicativo Junos PyEZ pode incluir console_has_banner=True
na lista de argumentos a Device
telnet para um servidor de console que emite uma mensagem de banner.
dev = Device(host=hostname, user=username, passwd=password, mode='telnet', console_has_banner=True)
Quando você inclui o console_has_banner=True
argumento e o aplicativo não recebe um prompt de login na conexão inicial, o aplicativo espera por 5 segundos e depois emite um caractere newline (\n
) para que o servidor do console emita o prompt de login. Se você omitir o argumento e a conexão estiver travada, o aplicativo em vez disso emite o <close-session/>
RPC para encerrar a conexão.
Conecte-se a um dispositivo usando uma conexão de console serial
A classe Junos PyEZ Device
permite que você se conecte a um dispositivo Junos usando uma conexão de console serial, o que é útil quando você deve configurar inicialmente um dispositivo novo ou zeroizado que ainda não está configurado para acesso remoto. Para usar esse método de conexão, você deve estar fisicamente conectado ao dispositivo por meio da porta CONSOLE . Para obter instruções detalhadas sobre a conexão à porta CONSOLE em seu dispositivo, veja a documentação de hardware do seu dispositivo específico.
O Junos PyEZ oferece suporte ao uso de gerentes de contexto para conexões de console serial. Recomendamos que você use um gerente de contexto para conexões de console, porque o gerente de contexto lida automaticamente com a abertura e o fechamento da conexão. A falha em fechar a conexão pode levar a resultados imprevisíveis.
Para usar o Junos PyEZ para se conectar a um dispositivo Junos por meio de uma conexão de console serial, você deve incluir mode='serial'
na lista de Device
argumentos e incluir opcionalmente o port
parâmetro para especificar uma porta. Quando você especifica mode='serial'
, mas omite o port
parâmetro, o valor para port
padrões é /dev/ttyUSB0
de .
Para se conectar a um dispositivo Junos usando uma conexão de console serial e também carregar e comprometer uma configuração no dispositivo em um aplicativo Junos PyEZ usando Python 3:
O programa de amostra em sua totalidade é apresentado aqui:
import sys from getpass import getpass from jnpr.junos import Device from jnpr.junos.utils.config import Config junos_username = input("Junos OS username: ") junos_password = getpass("Junos OS password: ") try: with Device(mode='serial', port='port', user=junos_username, passwd=junos_password) as dev: print (dev.facts) cu = Config(dev) cu.lock() cu.load(path='/tmp/config_mx.conf') cu.commit() cu.unlock() except Exception as err: print (err) sys.exit(1)