Paramiko 实现了 SSH2 协议,用于与远程机器建立经过认证和加密后的安全连接,与 SSL 不同的是,SSH 不需要权威机构签署的分层证书,采用分布式的方式管理。
简介
通过如下命令安装。
pip3 install paramiko -i https://pypi.tuna.tsinghua.edu.cn/simple/
接着直接介绍比较常用的场景。
示例
登录主机
import paramiko
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 登录主机
private = paramiko.RSAKey.from_private_key_file('/tmp/id_rsa')
ssh.connect(
hostname='127.0.0.1', port=22, # 设置主机地址和端口
username='foobar', # 设置登录用户名
password='passwd', # 采用用户名+密码方式登录
key=private, # 采用用户名+公钥方式登录
)
# 执行命令并获取结果
stdin, stdout, stderr = ssh.exec_command('ls')
result = stdout.read()
# 关闭连接
ssh.close()
另外,SSHClient()
里面有一个 transport
变量,用于设置连接,不过不建议使用。
import paramiko
transport = paramiko.Transport(('127.0.0.1', 22))
transport.connect(username='root', password='password')
ssh = paramiko.SSHClient()
ssh._transport = transport
stdin, stdout, stderr = ssh.exec_command('df')
print (str(stdout.read(),encoding='utf-8'))
transport.close()
还可以手动执行。
# 建立连接
trans = paramiko.Transport((ip, port))
trans.connect(username=username, password=password)
# 开启会话并设置超时时间
chan = trans.open_session()
chan.settimeout(session_timeout)
# 开启、激活远程Terminal
chan.get_pty()
chan.invoke_shell()
# 然后可以通过如下发送、接收
chan.send('command')
chan.recv(recv_buffer)
上传下载文件
import paramiko
transport = paramiko.Transport(('192.168.1.1', 22))
transport.connect(username='foobar', password='passwd')
sftp = paramiko.SFTPClient.from_transport(transport)
# 上传下载文件
sftp.put('/tmp/HelloWorld.py', '/tmp/HelloWorld.py')
sftp.get('/tmp/HelloWorld.py', '/tmp/HelloWorld.py')
transport.close()
执行命令 & 上传下载
有时需要同时执行命令和上传下载文件,那么可以只使用一个 SSHClient
,通过 get_transport()
来创建 Transport 对象。
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname='127.0.0.1', port=22, username='foobar', password='passwd')
trans = ssh_client.get_transport()
sftp = paramiko.SFTPClient.from_transport(trans)
sftp.get_channel()
sftp.put('source','target')
sftp.get('source','target')
stdin, stdout, stderr = ssh.exec_command('ls')
result = stdout.read()
ssh.close()
常见问题
private key file is encrypted
完整报错 paramiko.ssh_exception.PasswordRequiredException: private key file is encrypted
,如果密码没错误,可看下私钥文件,如果开头是 -----BEGIN OPENSSH PRIVATE KEY-----
,会导致 paramiko 无法识别。
此时需要在执行 ssh-keygen
命令时增加 -m PEM
参数,指定生成 RSA 格式的密钥对,对应开头是 -----BEGIN RSA PRIVATE KEY-----
格式。