Как поднять туннель ssh через Paramiko
У меня возникла проблема при создании ssh туннеля через Paramiko. А именно, мне необходимо создать туннель следующего вида "ssh -L127.0.0.1:12222:host_2:22 user@host_1".
Пробовал решить задачу следующим образом:
def test_tunnel():
mykey = paramiko.RSAKey.from_private_key_file('C:/Users/Alexandr/.ssh/id_rsa')
with SSHTunnelForwarder(
('host_1', 22),
ssh_username='ssh_user1',
ssh_pkey=mykey,
remote_bind_address=("host_2", 12222),
local_bind_address=('127.0.0.1', 12222)
) as tunnel:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname='127.0.0.1', port=12222, username='ssh_user2')
(stdin, stdout, stderr) = ssh.exec_command("hostname")
result = stdout.read() + stderr.read()
ssh.close()
Однако при выполнении этого кода, он падает с ошибкой:
FAILED [100%]2020-04-27 10:04:13,250| ERROR | Secsh channel 0 open FAILED: No route to host: Connect failed
2020-04-27 10:04:13,251| ERROR | Could not establish connection from ('127.0.0.1', 12222) to remote side of the tunnel
2020-04-27 10:04:13,251| ERROR | Exception: Error reading SSH protocol banner
2020-04-27 10:04:13,253| ERROR | Traceback (most recent call last):
2020-04-27 10:04:13,253| ERROR | File "D:\Project\my_pr\venv\lib\site-packages\paramiko\transport.py", line 2211, in _check_banner
2020-04-27 10:04:13,254| ERROR | buf = self.packetizer.readline(timeout)
2020-04-27 10:04:13,254| ERROR | File "D:\Project\my_pr\venv\lib\site-packages\paramiko\packet.py", line 380, in readline
2020-04-27 10:04:13,254| ERROR | buf += self._read_timeout(timeout)
2020-04-27 10:04:13,255| ERROR | File "D:\Project\my_pr\venv\lib\site-packages\paramiko\packet.py", line 609, in _read_timeout
2020-04-27 10:04:13,255| ERROR | raise EOFError()
2020-04-27 10:04:13,255| ERROR | EOFError
2020-04-27 10:04:13,255| ERROR |
2020-04-27 10:04:13,255| ERROR | During handling of the above exception, another exception occurred:
2020-04-27 10:04:13,256| ERROR |
2020-04-27 10:04:13,256| ERROR | Traceback (most recent call last):
2020-04-27 10:04:13,256| ERROR | File "D:\Project\my_pr\venv\lib\site-packages\paramiko\transport.py", line 2039, in run
2020-04-27 10:04:13,256| ERROR | self._check_banner()
2020-04-27 10:04:13,256| ERROR | File "D:\Project\my_pr\venv\lib\site-packages\paramiko\transport.py", line 2216, in _check_banner
2020-04-27 10:04:13,257| ERROR | "Error reading SSH protocol banner" + str(e)
2020-04-27 10:04:13,257| ERROR | paramiko.ssh_exception.SSHException: Error reading SSH protocol banner
2020-04-27 10:04:13,257| ERROR |
Ошибка возникает на строке ssh.connect(hostname='127.0.0.1', port=12222, username='ssh_user2').
В чем моя ошибка?
P.S. При поднятии туннеля (ssh -L127.0.0.1:12222:host_2:22 user@host_1) руками и выполнении кода:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname='127.0.0.1', port=12222, username='ssh_user2')
(stdin, stdout, stderr) = ssh.exec_command("hostname")
result = stdout.read() + stderr.read()
ssh.close()
он отрабатывает как нужно, т.е. проблема возникает на этапе создания туннеля.
Ответы (2 шт):
paramiko.ssh_exception.SSHException: Error reading SSH protocol banner
Это происходит, если сервер принимает соединение, но демон ssh не отвечает в течение 15 секунд. Это может быть перегрузка сети, неисправные коммутаторы и т. Д., Но обычно это означает, что целевой сервер отключен или его sshd завис. Восстановление это подождать и попробовать еще раз. Если вы контролируете сервер, самое время проверить его работоспособность
можно указать тайм-аут для banner:
client = SSHClient()
client.connect('ssh.example.com', banner_timeout=200)
так же вы можете попробовать этот пример отсюда
import paramiko
import sshtunnel
with sshtunnel.open_tunnel(
(REMOTE_SERVER_IP, 443),
ssh_username="",
ssh_pkey="/var/ssh/rsa_key",
ssh_private_key_password="secret",
remote_bind_address=(PRIVATE_SERVER_IP, 22),
local_bind_address=('0.0.0.0', 10022)
) as tunnel:
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('127.0.0.1', 10022)
# do some operations with client session
client.close()
print('FINISH!')
Я нашел ошибку в собственном коде. В строке remote_bind_address=("host_2", 12222) был указан не верный порт. Для данного случая необходимо было указать порт 22.