如何使用Paramiko免密登录SSH服务器及相关问题
问题解决与疑问解答
一、SSHClient免密登录失败的修复
PowerShell能免密登录说明本地密钥已被服务器信任,但Paramiko的SSHClient默认未正确加载私钥,可手动指定私钥路径解决:
import paramiko ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 替换为你的私钥实际路径,如~/.ssh/id_rsa private_key = paramiko.RSAKey.from_private_key_file('/path/to/your/private/key') ssh.connect('myMachine', username='root', pkey=private_key) # 执行命令并获取完整结果 stdin, stdout, stderr = ssh.exec_command('touch /tmp/huhu.txt') exit_status = stdout.channel.recv_exit_status() # 获取命令返回值 print(stdout.read().decode(), stderr.read().decode()) ssh.close()
若私钥带密码,需在from_private_key_file中传入password参数。
二、Transport方式的问题修复
你用Transport执行命令后无法获取结果,是因为未等待命令执行完成并读取通道输出,修改代码如下:
import paramiko t = paramiko.Transport(("localhost", 2022)) t.connect() t.auth_none("root") # 仅服务器允许无密码登录时有效,正常建议用密钥认证 x = t.open_session() x.exec_command("touch /tmp/huhu.txt") # 等待命令执行完成并获取结果 exit_status = x.recv_exit_status() stdout = x.makefile('rb').read().decode() stderr = x.makefile_stderr('rb').read().decode() print(stdout, stderr, exit_status) t.close()
正常场景下建议用密钥认证替代auth_none,示例:
private_key = paramiko.RSAKey.from_private_key_file('/path/to/key') t.connect(username='root', pkey=private_key)
三、疑问解答
- 是否可将现有Transport作为SSHClient的源?
可以。SSHClient底层基于Transport实现,可通过关联私有属性_transport复用已有Transport,但官方不推荐直接操作私有属性(未来版本可能变动),示例:
import paramiko t = paramiko.Transport(("myMachine", 22)) private_key = paramiko.RSAKey.from_private_key_file('/path/to/key') t.connect(username='root', pkey=private_key) ssh = paramiko.SSHClient() ssh._transport = t # 之后可正常使用SSHClient的exec_command等方法 stdin, stdout, stderr = ssh.exec_command('ls /tmp') print(stdout.read().decode())
- 这是否为标准实现方式?
你之前直接用Transport连接的方式并非标准推荐流程。Paramiko官方建议优先使用SSHClient,它封装了会话管理、密钥加载、主机密钥验证等完整功能,更稳定且符合SSH标准使用逻辑。Transport属于底层操作,仅适合需要自定义会话细节(如多通道复用、特殊认证流程)的场景。
内容的提问来源于stack exchange,提问作者Cutton Eye
相关产品推荐
相关产品推荐

