使用Python的ProxyJump

问题描述

我想实现类似ssh -J user@host1 user@host2

功能

host1和host2都仅接受通过键盘交互而非公用密钥进行的身份验证,或常规密码身份验证。两台主机的密码相同。这些是我无法更改的限制,所以请不要使用“使用ssh键”答案:)

我已经在paramiko中进行了此操作(请参见下文),但是我愿意使用其他python模块来实现此目的。

import paramiko

...

client1 = paramiko.SSHClient()
client1.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client1.connect(host1,22,username,password=password)

transport = client1.get_transport()

dest_addr = (host2,22)
local_addr = ('127.0.0.1',22)
channel = transport.open_channel("direct-tcpip",dest_addr,local_addr)

client2 = paramiko.SSHClient()
client2.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client2.connect(host2,password=password,sock=channel)

但出现以下错误

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/paramiko/transport.py",line 1528,in auth_password
    return self.auth_interactive(username,handler)
  File "/usr/local/lib/python3.7/site-packages/paramiko/transport.py",line 1633,in auth_interactive
    return self.auth_handler.wait_for_response(my_event)
  File "/usr/local/lib/python3.7/site-packages/paramiko/auth_handler.py",line 250,in wait_for_response
    raise e
paramiko.ssh_exception.AuthenticationException: Authentication Failed.

During handling of the above exception,another exception occurred:

Traceback (most recent call last):
  File “./myscript”,line 50,in <module>
    client2(host2,sock=channel)
  File "/usr/local/lib/python3.7/site-packages/paramiko/client.py",line 446,in connect
    passphrase,File "/usr/local/lib/python3.7/site-packages/paramiko/client.py",line 764,in _auth
    raise saved_exception
  File "/usr/local/lib/python3.7/site-packages/paramiko/client.py",line 751,in _auth
    self._transport.auth_password(username,password)
  File "/usr/local/lib/python3.7/site-packages/paramiko/transport.py",line 1531,in auth_password
    raise e
  File "/usr/local/lib/python3.7/site-packages/paramiko/transport.py",line 1509,in auth_password
    return self.auth_handler.wait_for_response(my_event)
  File "/usr/local/lib/python3.7/site-packages/paramiko/auth_handler.py",in wait_for_response
    raise e
paramiko.ssh_exception.BadAuthenticationType: Bad authentication type; allowed types: ['publickey','keyboard-interactive']

当host1和host2都使用公钥身份验证时,整个过程工作正常,但是在此特定示例中,我需要使用交互式键盘

编辑:

无法连接到host2,这是paramiko日志文件内容

INF [20200907-20:39:41.318] thr=1   paramiko.transport: Connected (version 2.0,client X)
INF [20200907-20:39:41.803] thr=1   paramiko.transport: Authentication (publickey) Failed.
INF [20200907-20:39:41.960] thr=1   paramiko.transport: Authentication (publickey) Failed.
INF [20200907-20:39:42.685] thr=1   paramiko.transport: Authentication (keyboard-interactive) successful!
INF [20200907-20:39:42.877] thr=2   paramiko.transport: Connected (version 2.0,client X)
INF [20200907-20:39:43.283] thr=2   paramiko.transport: Authentication (publickey) Failed.
INF [20200907-20:39:43.444] thr=2   paramiko.transport: Authentication (publickey) Failed.
INF [20200907-20:39:43.795] thr=2   paramiko.transport: Authentication (keyboard-interactive) Failed.

解决方法

没关系,原来我的第二条连接线是错误的:

client2.connect(host2,username,password=password,sock=channel)

我没有指定第二个参数是什么

client2.connect(host2,username=username,sock=channel)

client2.connect(host2,22,sock=channel)

两项工作均符合预期。