- Модуль paramiko#
- Метод send#
- Метод recv#
- Метод close#
- Пример использования paramiko#
- Постраничный вывод команд#
- Как использовать Python для работы с SSH
- Использование библиотеки Paramiko
- Создание SSH-соединения
- Выполнение команд на удаленном сервере
- Закрытие SSH-соединения
- Использование библиотеки Fabric
- Создание SSH-соединения и выполнение команд с использованием Fabric
- Закрытие SSH-соединения в Fabric
- Заключение
- Python SSH Tutorial
- Installation
- Connect to SSH
- Connect using password
- Connect using SSH key
- Run commands over SSH
- Conclusion
- References
Модуль paramiko#
Paramiko — это реализация протокола SSHv2 на Python. Paramiko предоставляет функциональность клиента и сервера. В книге рассматривается только функциональность клиента.
Так как Paramiko не входит в стандартную библиотеку модулей Python, его нужно установить:
Подключение выполняется таким образом: сначала создается клиент и выполняются настройки клиента, затем выполняется подключение и получение интерактивной сессии:
In [2]: client = paramiko.SSHClient() In [3]: client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) In [4]: client.connect(hostname="192.168.100.1", username="cisco", password="cisco", . : look_for_keys=False, allow_agent=False) In [5]: ssh = client.invoke_shell()
SSHClient это класс, который представляет соединение к SSH-серверу. Он выполняет аутентификацию клиента. Следующая настройка set_missing_host_key_policy не является обязательной, она указывает какую политику использовать, когда выполнятся подключение к серверу, ключ которого неизвестен. Политика paramiko.AutoAddPolicy() автоматически добавляет новое имя хоста и ключ в локальный объект HostKeys.
Метод connect выполняет подключение к SSH-серверу и аутентифицирует подключение. Параметры:
- look_for_keys — по умолчанию paramiko выполняет аутентификацию по ключам. Чтобы отключить это, надо поставить флаг в False
- allow_agent — paramiko может подключаться к локальному SSH агенту ОС. Это нужно при работе с ключами, а так как в данном случае аутентификация выполняется по логину/паролю, это нужно отключить.
После выполнения предыдущей команды уже есть подключение к серверу. Метод invoke_shell позволяет установить интерактивную сессию SSH с сервером.
Метод send#
Метод send — отправляет указанную строку в сессию и возвращает количество отправленных байт или ноль если сессия закрыта и не удалось отправить команду:
In [7]: ssh.send("enable\n") Out[7]: 7 In [8]: ssh.send("cisco\n") Out[8]: 6 In [9]: ssh.send("sh ip int br\n") Out[9]: 13
В коде после send надо будет ставить time.sleep, особенно между send и recv. Так как это интерактивная сессия и команды набираются медленно, все работает и без пауз.
Метод recv#
Метод recv получает данные из сессии. В скобках указывается максимальное значение в байтах, которое нужно получить. Этот метод возвращает считанную строку.
In [10]: ssh.recv(3000) Out[10]: b'\r\nR1>enable\r\nPassword: \r\nR1#sh ip int br\r\nInterface IP-Address OK? Method Status Protocol\r\nEthernet0/0 192.168.100.1 YES NVRAM up up \r\nEthernet0/1 192.168.200.1 YES NVRAM up up \r\nEthernet0/2 unassigned YES NVRAM up up \r\nEthernet0/3 192.168.130.1 YES NVRAM up up \r\nLoopback22 10.2.2.2 YES manual up up \r\nLoopback33 unassigned YES unset up up \r\nLoopback45 unassigned YES unset up up \r\nLoopback55 5.5.5.5 YES manual up up \r\nR1#'
Метод close#
Метод close закрывает сессию:
Пример использования paramiko#
Пример использования paramiko (файл 3_paramiko.py):
import paramiko import time import socket from pprint import pprint def send_show_command( ip, username, password, enable, command, max_bytes=60000, short_pause=1, long_pause=5, ): cl = paramiko.SSHClient() cl.set_missing_host_key_policy(paramiko.AutoAddPolicy()) cl.connect( hostname=ip, username=username, password=password, look_for_keys=False, allow_agent=False, ) with cl.invoke_shell() as ssh: ssh.send("enable\n") ssh.send(f"enable>\n") time.sleep(short_pause) ssh.send("terminal length 0\n") time.sleep(short_pause) ssh.recv(max_bytes) result = <> for command in commands: ssh.send(f"command>\n") ssh.settimeout(5) output = "" while True: try: part = ssh.recv(max_bytes).decode("utf-8") output += part time.sleep(0.5) except socket.timeout: break result[command] = output return result if __name__ == "__main__": devices = ["192.168.100.1", "192.168.100.2", "192.168.100.3"] commands = ["sh clock", "sh arp"] result = send_show_command("192.168.100.1", "cisco", "cisco", "cisco", commands) pprint(result, width=120)
Результат выполнения скрипта:
'sh arp': 'sh arp\r\n' 'Protocol Address Age (min) Hardware Addr Type Interface\r\n' 'Internet 192.168.100.1 - aabb.cc00.6500 ARPA Ethernet0/0\r\n' 'Internet 192.168.100.2 124 aabb.cc00.6600 ARPA Ethernet0/0\r\n' 'Internet 192.168.100.3 183 aabb.cc00.6700 ARPA Ethernet0/0\r\n' 'Internet 192.168.100.100 208 aabb.cc80.c900 ARPA Ethernet0/0\r\n' 'Internet 192.168.101.1 - aabb.cc00.6500 ARPA Ethernet0/0\r\n' 'Internet 192.168.102.1 - aabb.cc00.6500 ARPA Ethernet0/0\r\n' 'Internet 192.168.130.1 - aabb.cc00.6530 ARPA Ethernet0/3\r\n' 'Internet 192.168.200.1 - 0203.e800.6510 ARPA Ethernet0/1\r\n' 'Internet 192.168.200.100 18 6ee2.6d8c.e75d ARPA Ethernet0/1\r\n' 'R1#', 'sh clock': 'sh clock\r\n*08:25:22.435 UTC Mon Jul 20 2020\r\nR1#'>
Постраничный вывод команд#
Пример использования paramiko для работы с постраничным выводом команд show (файл 3_paramiko_more.py):
import paramiko import time import socket from pprint import pprint import re def send_show_command( ip, username, password, enable, command, max_bytes=60000, short_pause=1, long_pause=5, ): cl = paramiko.SSHClient() cl.set_missing_host_key_policy(paramiko.AutoAddPolicy()) cl.connect( hostname=ip, username=username, password=password, look_for_keys=False, allow_agent=False, ) with cl.invoke_shell() as ssh: ssh.send("enable\n") ssh.send(enable + "\n") time.sleep(short_pause) ssh.recv(max_bytes) result = <> for command in commands: ssh.send(f"command>\n") ssh.settimeout(5) output = "" while True: try: page = ssh.recv(max_bytes).decode("utf-8") output += page time.sleep(0.5) except socket.timeout: break if "More" in page: ssh.send(" ") output = re.sub(" +--More--| +\x08+ +\x08+", "\n", output) result[command] = output return result if __name__ == "__main__": devices = ["192.168.100.1", "192.168.100.2", "192.168.100.3"] commands = ["sh run"] result = send_show_command("192.168.100.1", "cisco", "cisco", "cisco", commands) pprint(result, width=120)
Как использовать Python для работы с SSH
В данной статье мы рассмотрим, как использовать Python для работы с SSH (Secure Shell) – протоколом, используемым для безопасного удаленного управления системами и передачи данных между компьютерами.
Использование библиотеки Paramiko
Для работы с SSH в Python одной из наиболее популярных библиотек является Paramiko. Для установки этой библиотеки используйте следующую команду:
Создание SSH-соединения
Для создания SSH-соединения с удаленным сервером используйте следующий код:
import paramiko ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect('example.com', username='your_username', password='your_password')
🔒 Обратите внимание, что использование пароля для аутентификации может быть небезопасным. Лучше использовать ключи SSH для аутентификации.
Выполнение команд на удаленном сервере
После установления SSH-соединения можно выполнить команды на удаленном сервере. Вот пример выполнения команды ls :
stdin, stdout, stderr = ssh.exec_command('ls') print(stdout.read().decode())
Закрытие SSH-соединения
После выполнения всех необходимых операций не забудьте закрыть SSH-соединение:
Использование библиотеки Fabric
Еще одной популярной библиотекой для работы с SSH является Fabric. Она предоставляет высокоуровневый интерфейс для работы с SSH и упрощает выполнение многих операций. Для установки Fabric используйте следующую команду:
Создание SSH-соединения и выполнение команд с использованием Fabric
Вот пример использования Fabric для создания SSH-соединения и выполнения команды ls на удаленном сервере:
from fabric import Connection with Connection('example.com', user='your_username', connect_kwargs=) as conn: result = conn.run('ls') print(result.stdout.strip())
📝 Fabric также поддерживает использование ключей SSH для аутентификации, что является более безопасным вариантом.
Закрытие SSH-соединения в Fabric
Когда вы используете Fabric с контекстным менеджером with , SSH-соединение автоматически закрывается при выходе из блока кода.
Заключение
Теперь вы знаете, как использовать Python для работы с SSH с помощью таких библиотек, как Paramiko и Fabric. Это позволит вам безопасно управлять удаленными системами и выполнять различные операции с использованием Python-скриптов. Удачного кодирования! 🐍
Python SSH Tutorial
SSH (secure shell) is good for remotely managing machines using a secure connection. Typically you will log in to a server using the command-line ssh tool, or something like PuTTy or MobaXTerm. This guide will show you how to use Python to connect and run commands over SSH using the Paramiko package.
Installation
The easiest way to install paramiko is using pip .
python -m pip install paramiko
To install from source, clone from GitHub and then install using setup.py .
git clone https://github.com/paramiko/paramiko cd paramiko python setup.py install
Connect to SSH
Connect to an SSH server using paramiko.client.SSHClient.connect(). The hostname is the only required parameter.
connect(hostname, port=22, username=None, password=None, pkey=None, key_filename=None, timeout=None, allow_agent=True, look_for_keys=True, compress=False, sock=None, gss_auth=False, gss_kex=False, gss_deleg_creds=True, gss_host=None, banner_timeout=None, auth_timeout=None, gss_trust_dns=True, passphrase=None, disabled_algorithms=None)
One thing to consider is what trusted known host keys you have. You can use paramiko.client.SSHClient.load_system_host_keys() . You can also explicitly load a specific known hosts file with load_host_keys() and set the client to automatically accept and add unknown hosts with set_missing_host_key_policy() to paramiko.AutoAddPolicy . Use these options as needed. The AutoAddPolicy is not very secure since it will trust any remote host.
Connect using password
from paramiko import SSHClient client = SSHClient() #client.load_system_host_keys() #client.load_host_keys('~/.ssh/known_hosts') #client.set_missing_host_key_policy(AutoAddPolicy()) client.connect('example.com', username='user', password='secret') client.close()
Connect using SSH key
Using an SSH key is more secure than using a password. Call connect() just like using the password, but instead of providing the user password, we will provide a key_filename and maybe a passphrase for the key. The passphrase may not be needed if your private key file does not have a passphrase.
You can also omit the key file and let Paramiko try to find the right key automatically in your ~/.ssh/ directory. You can turn that on by calling client.look_for_keys(True) . The first example will show how to explicitly provide the key and passphrase and the second one will show how to look for keys.
# Explicitly provide key and passphrase from paramiko import SSHClient, AutoAddPolicy client = SSHClient() #client.load_system_host_keys() #client.load_host_keys('~/.ssh/known_hosts') #client.set_missing_host_key_policy(AutoAddPolicy()) client.connect('example.com', username='user', key_filename='mykey.pem', passphrase='mysshkeypassphrase') client.close()
This example show hows to look for keys in ~/.ssh/ automatically.
from paramiko import SSHClient client = SSHClient() #client.load_system_host_keys() #client.load_host_keys('~/.ssh/known_hosts') #client.set_missing_host_key_policy(AutoAddPolicy()) client.look_for_keys(True) client.connect('example.com', username='user') client.close()
Run commands over SSH
Once you have a connection open, you can execute any command just like you would if you were in a regular interactive SSH session.
This example shows how to:
- Run a command on the server
- Provide standard input data to command
- Read standard output and error from command
- Get the return code of the command
The command run in this example is the PHP interpreter with the code provided via standard input. The output is then printed out and the return code is checked.
from paramiko import SSHClient # Connect client = SSHClient() client.load_system_host_keys() client.connect('example.com', username='user', password='secret') # Run a command (execute PHP interpreter) stdin, stdout, stderr = client.exec_command('php') print(type(stdin)) # print(type(stdout)) # print(type(stderr)) # # Optionally, send data via STDIN, and shutdown when done stdin.write('') stdin.channel.shutdown_write() # Print output of command. Will wait for command to finish. print(f'STDOUT: ') print(f'STDERR: ') # Get return code from command (0 is default for success) print(f'Return code: ') # Because they are file objects, they need to be closed stdin.close() stdout.close() stderr.close() # Close the client itself client.close()
Conclusion
After reading this guide you should know how to connect to an SSH server using a password or SSH key. You should also know how to run a command, pass data to standard input, and read the output from standard output and error.