1. Paramiko 模块
Paramiko 是 Python 的一个模块,实现了 SSH2 协议,用于与远程服务器的安全通讯,支持 密码 和 证书 的安全连接。
Paramiko 支持 SSH 客户端 和 SFTP 客户端。
Paramiko 模块相关网站:
- PyPI 项目地址: https://pypi.org/project/paramiko/
- GitHub 仓库地址: https://github.com/paramiko/paramiko/
- Paramiko 文档主页: http://docs.paramiko.org/en/stable/
- API 文档: http://docs.paramiko.org/
安装 paramiko
模块:
$ python3 -m pip install paramiko
2. SSH 客户端
SSH 连接远程 Linux 主机并执行命令获取结果:
import paramiko
import base64
# 创建 SSH 客户端
ssh_client = paramiko.SSHClient()
# 添加已知的远程 Linux 主机的 host_key(SSH 公钥)
#
# SSH 公钥在 Linux 主机的 "/etc/ssh/" 目录下查找
#
# 公钥的类型一般有一下几种:
# ssh_host_rsa_key.pub -> paramiko.RSAKey
# ssh_host_ecdsa_key.pub -> paramiko.ECDSAKey
# ssh_host_ed25519_key.pub -> paramiko.Ed25519Key
#
rsa_pub_key = paramiko.RSAKey(data=base64.b64decode("AAA..."))
ssh_client.get_host_keys().add("hostname", "ssh-rsa", rsa_pub_key)
# 如果 SSH 端口不是默认的 22, 则添加的 hostname 中需要添加端口, 格式如下:
# ssh_client.get_host_keys().add("[hostname]:port", "ssh-rsa", rsa_pub_key)
# 也可以设置自动添加未知的 host_key(这样简单方便, 但不安全)
# ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 也可以从文件中加载 host_keys
# ssh_client.get_host_keys().load("known_hosts.txt")
# 可以加载使用系统本地的 known_hosts, 文件默认位置: "~/.ssh/known_hosts"
# ssh_client.load_system_host_keys()
# 已加载或已添加的 host_keys 可以保存到文件中, 下次可以直接从文件中加载
# ssh_client.get_host_keys().save("known_hosts.txt")
# 连接 Linux 主机时, 远程主机会下发 host_key(SSH 公钥, 用于加密通讯),
# 如果在 system_host_keys() 和 ssh_client.get_host_keys() 中均没有
# 找到与该远程主机相同的 host_key, 说明该主机可能是不安全的, 将抛出异常:
# SSHException: Server 'hostname' not found in known_hosts
# 连接远程 Linux 主机
ssh_client.connect(hostname="hostname", # 主机名, 端口默认 port=22
username="username", # 用户名
password="password") # 用户密码
# 执行命令, 返回三个参数, 分别对应 标准输入、标准输出、错误输出 三个 IO 通道
stdin, stdout, stderr = ssh_client.exec_command("uname -a")
# 读取 标准输出 和 错误输出 的内容
print(stdout.read().decode("utf-8"))
print(stderr.read().decode("utf-8"))
# 关闭 SSH 客户端
ssh_client.close()
3. SFTP 客户端
SFTP 客户端主要使用 Transport
和 SFTPClient
两个对象。
SFTPClient API: http://docs.paramiko.org/en/stable/api/sftp.html
传输对象 Transport:
# 创建传输对象
t = paramiko.Transport(("hostname", 22)) # <paramiko.Transport>
# 连接服务器
t.connect(username="username", password="password")
# 如果需要安全连接服务器(可以传入 hostkey 校验服务端的 hostkey)
# rsa_pub_key = paramiko.RSAKey(data=base64.b64decode("AAA..."))
# t.connect(hostkey=rsa_pub_key, username="username", password="password")
# 关闭传输对象
# t.close()
SFTP 客户端对象 SFTPClient:
# 根据传输对象, 创建 SFTP 客户端
sftp = paramiko.SFTPClient.from_transport(t) # <paramiko.sftp_client.SFTPClient>
# 列出目录下的文件或文件夹, 返回 列表
listdir(path)
# 上传文件
sftp.put(localpath, remotepath)
# 下载文件
sftp.get(remotepath, localpath)
# 打开远程文件(所有文件均视为二进制文件)
with sftp.open(filename, mode="r") as f:
print(f.read())
# 创建文件夹
sftp.mkdir(path)
# 删除文件夹
sftp.rmdir(path)
# 删除文件
sftp.remove(path)
# 重命名
sftp.rename(oldpath, newpath)
# 创建符号链接
sftp.symlink(target_path, path)
# 改变当前路径
sftp.chdir(path)
# 获取当前路径
sftp.getcwd()
# 改变权限
sftp.chmod(path, mode)
# 改变拥有者
sftp.chown(path, uid, gid)
# 获取文件或文件夹的属性信息(权限、拥有者、大小、修改时间等)
attr = sftp.stat(path)
print(attr.st_mode,
attr.st_gid,
attr.st_uid,
attr.st_size,
attr.st_atime,
attr.st_mtime)
# 获取文件或文件夹的属性信息(不遵循符号链接/别名的相应调用, stat 为遵循)
attr = sftp.lstat(path)
# 列出目录下的所有文件或文件夹的属性信息(权限、拥有者、大小、修改时间等)
for attr in sftp.listdir_attr("."):
print(attr)
# 关闭 SFTP 客户端
sftp.close()
上传下载文件 代码示例:
import paramiko
# 创建传输对象
t = paramiko.Transport(("hostname", 22))
# 连接服务器
t.connect(username="username", password="password")
# 创建 SFTP 客户端
sftp = paramiko.SFTPClient.from_transport(t)
# 上传文件
sftp.put("localpath", "remotepath")
# 下载文件
sftp.get("remotepath", "localpath")
# 关闭 SFTP 客户端
sftp.close()
# 关闭传输对象
t.close()