Paramiko - это реализация протокола SSHv2 на Python. Paramiko предоставляет функциональность клиента и сервера. Мы будем рассматривать только функциональность клиента.
Так как Paramiko не входит в стандартную библиотеку модулей Python, его нужно установить:
pip install paramiko
Пример использования Paramiko (файл 3_paramiko.py):
import paramiko import getpass import sys import time COMMAND = sys.argv[1] USER = input('Username: ') PASSWORD = getpass.getpass() ENABLE_PASS = getpass.getpass(prompt='Enter enable password: ') DEVICES_IP = ['192.168.100.1','192.168.100.2','192.168.100.3'] for IP in DEVICES_IP: print('Connection to device {}'.format( IP )) client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(hostname=IP, username=USER, password=PASSWORD, look_for_keys=False, allow_agent=False) with client.invoke_shell() as ssh: ssh.send('enable\n') ssh.send(ENABLE_PASS + '\n') time.sleep(1) ssh.send('terminal length 0\n') time.sleep(1) ssh.recv(1000).decode('utf-8') ssh.send(COMMAND + '\n') time.sleep(2) result = ssh.recv(5000).decode('utf-8') print(result)
Комментарии к скрипту:
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
set_missing_host_key_policy
- устанавливает, какую политику использовать, когда выполнятся подключение к серверу, ключ которого неизвестен.paramiko.AutoAddPolicy()
- политика, которая автоматически добавляет новое имя хоста и ключ в локальный объект HostKeys.client.connect(IP, username=USER, password=PASSWORD, look_for_keys=False, allow_agent=False)
client.connect
- метод, который выполняет подключение к SSH-серверу и аутентифицирует подключениеhostname
- имя хоста или IP-адресusername
- имя пользователяpassword
- парольlook_for_keys
- по умолчанию paramiko выполняет аутентификацию по ключам. Чтобы отключить это, надо поставить флаг в Falseallow_agent
- paramiko может подключаться к локальному SSH агенту ОС. Это нужно при работе с ключами, а так как в данном случае аутентификация выполняется по логину/паролю, это нужно отключить.with client.invoke_shell() as ssh
invoke_shell
позволяет установить интерактивную сессию SSH с сервером.ssh.send
- отправляет указанную строку в сессиюssh.recv
- получает данные из сессии. В скобках указывается максимальное значение в байтах, которое можно получить. Этот метод возвращает считанную строкуtime.sleep
Так выглядит результат выполнения скрипта:
$ python 3_paramiko.py "sh ip int br" Username: cisco Password: Enter enable secret: Connection to device 192.168.100.1 R1>enable Password: R1#terminal length 0 R1# sh ip int br Interface IP-Address OK? Method Status Protocol FastEthernet0/0 192.168.100.1 YES NVRAM up up FastEthernet0/1 unassigned YES NVRAM up up FastEthernet0/1.10 10.1.10.1 YES manual up up FastEthernet0/1.20 10.1.20.1 YES manual up up FastEthernet0/1.30 10.1.30.1 YES manual up up FastEthernet0/1.40 10.1.40.1 YES manual up up FastEthernet0/1.50 10.1.50.1 YES manual up up FastEthernet0/1.60 10.1.60.1 YES manual up up FastEthernet0/1.70 10.1.70.1 YES manual up up R1# Connection to device 192.168.100.2 R2>enable Password: R2#terminal length 0 R2# sh ip int br FastEthernet0/0 192.168.100.2 YES NVRAM up up FastEthernet0/1 unassigned YES NVRAM up up FastEthernet0/1.10 10.2.10.1 YES manual up up FastEthernet0/1.20 10.2.20.1 YES manual up up FastEthernet0/1.30 10.2.30.1 YES manual up up FastEthernet0/1.40 10.2.40.1 YES manual up up FastEthernet0/1.50 10.2.50.1 YES manual up up FastEthernet0/1.60 10.2.60.1 YES manual up up FastEthernet0/1.70 10.2.70.1 YES manual up up R2# Connection to device 192.168.100.3 R3>enable Password: R3#terminal length 0 R3# sh ip int br Interface IP-Address OK? Method Status Protocol FastEthernet0/0 192.168.100.3 YES NVRAM up up FastEthernet0/1 unassigned YES NVRAM up up FastEthernet0/1.10 10.3.10.1 YES manual up up FastEthernet0/1.20 10.3.20.1 YES manual up up FastEthernet0/1.30 10.3.30.1 YES manual up up FastEthernet0/1.40 10.3.40.1 YES manual up up FastEthernet0/1.50 10.3.50.1 YES manual up up FastEthernet0/1.60 10.3.60.1 YES manual up up FastEthernet0/1.70 10.3.70.1 YES manual up up R3#
Обратите внимание, что в вывод попал и процесс ввода пароля enable, и команда terminal length.
Это связано с тем, что paramiko собирает весь вывод в буфер. И, при вызове метода recv
(например, ssh.recv(1000)
), paramiko возвращает всё, что есть в буфере. После выполнения recv
буфер пуст.
Поэтому, если нужно получить только вывод команды sh ip int br, то надо оставить recv
, но не делать print:
ssh.send('enable\n') ssh.send(ENABLE_PASS + '\n') time.sleep(1) ssh.send('terminal length 0\n') time.sleep(1) #Тут мы вызываем recv, но не выводим содержимое буфера ssh.recv(1000) ssh.send(COMMAND + '\n') time.sleep(3) result = ssh.recv(5000).decode('utf-8') print(result)