一、前言
在日常的运维、自动化部署、远程管理、日志采集、文件同步等任务中,SSH 是不可或缺的安全远程连接协议。Python 提供了多种方式实现 SSH 操作,其中 Paramiko 是最成熟、功能最全面的纯 Python SSH2 实现库之一。
相比直接调用系统 ssh
命令,Paramiko 拥有以下优势:
- 跨平台:纯 Python 实现,Windows、Linux、Mac 都可用。
- 安全性高:支持多种加密算法、密钥认证。
- 功能全面:支持远程命令执行、文件传输(SFTP)、端口转发等。
- 可集成性强:可直接嵌入到 Python 程序中,无需依赖外部命令。
本文将带你从基础到进阶,全面掌握 Paramiko 的使用。
二、Paramiko 简介与安装
2.1 Paramiko 是什么?
Paramiko 是一个 Python 实现的 SSHv2 协议库,名字来源于 “paranoid”(偏执的)和 “mico”(意为小巧),强调安全性和轻量化。它依赖 cryptography
库进行加密操作,支持多种身份验证方式(密码、私钥等)。
主要功能:
- 建立 SSH 连接
- 执行远程命令
- 文件传输(SFTP)
- 端口转发
2.2 安装
pip install paramiko
如果需要加速加密算法,可以安装 bcrypt
:
pip install bcrypt
安装完成后,可以在 Python 中导入:
import paramiko
三、核心组件
Paramiko 提供了几个关键类,掌握它们是使用的基础。
类名 | 作用 |
---|---|
SSHClient | 建立 SSH 连接、执行命令、传输文件 |
SFTPClient | 基于 SSH 的 SFTP 文件传输 |
AutoAddPolicy | 自动接受未知主机密钥 |
RSAKey / Ed25519Key | 加载私钥文件进行身份认证 |
四、SSH 基础操作
4.1 建立 SSH 连接并执行命令
import paramiko
# 创建 SSHClient 实例
ssh = paramiko.SSHClient()
# 自动添加主机密钥(避免首次连接时报错)
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接到远程服务器
ssh.connect(
hostname="192.168.1.100",
port=22,
username="root",
password="123456"
)
# 执行命令
stdin, stdout, stderr = ssh.exec_command("ls -l /home")
# 获取输出
print(stdout.read().decode())
print(stderr.read().decode())
# 关闭连接
ssh.close()
说明:
stdin
:命令的标准输入stdout
:命令的标准输出stderr
:命令的错误输出
4.2 使用私钥认证
private_key = paramiko.RSAKey.from_private_key_file("/home/user/.ssh/id_rsa")
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(
hostname="192.168.1.100",
port=22,
username="root",
pkey=private_key
)
stdin, stdout, stderr = ssh.exec_command("uptime")
print(stdout.read().decode())
ssh.close()
五、SFTP 文件传输
5.1 上传文件
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname="192.168.1.100", username="root", password="123456")
sftp = ssh.open_sftp()
sftp.put("local_file.txt", "/root/remote_file.txt")
sftp.close()
ssh.close()
5.2 下载文件
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname="192.168.1.100", username="root", password="123456")
sftp = ssh.open_sftp()
sftp.get("/root/remote_file.txt", "downloaded.txt")
sftp.close()
ssh.close()
六、异常处理与超时设置
Paramiko 常见异常:
paramiko.ssh_exception.AuthenticationException
:认证失败paramiko.ssh_exception.SSHException
:连接失败socket.timeout
:超时
示例:
import paramiko
import socket
try:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(
hostname="192.168.1.100",
username="root",
password="wrong_password",
timeout=5
)
except paramiko.AuthenticationException:
print("认证失败,请检查用户名或密码")
except paramiko.SSHException as e:
print(f"SSH 连接错误: {e}")
except socket.timeout:
print("连接超时")
finally:
ssh.close()
七、执行交互式命令(实时输出)
如果你执行的命令需要实时显示输出(如 tail -f
),可以这样:
import paramiko
import time
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname="192.168.1.100", username="root", password="123456")
transport = ssh.get_transport()
channel = transport.open_session()
channel.exec_command("tail -f /var/log/syslog")
while True:
if channel.recv_ready():
print(channel.recv(1024).decode(), end="")
time.sleep(0.5)
八、多服务器批量执行
servers = [
{"host": "192.168.1.100", "user": "root", "pwd": "123456"},
{"host": "192.168.1.101", "user": "root", "pwd": "123456"},
]
for server in servers:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(server["host"], username=server["user"], password=server["pwd"])
stdin, stdout, stderr = ssh.exec_command("uptime")
print(f"{server['host']} => {stdout.read().decode().strip()}")
ssh.close()
九、端口转发(隧道)
9.1 本地转发
Paramiko 可以像 ssh -L
一样做本地端口转发,把本地端口映射到远程服务。
import paramiko
from paramiko.forward import forward_tunnel
transport = paramiko.Transport(("192.168.1.100", 22))
transport.connect(username="root", password="123456")
# 将本地 8080 转发到远程 127.0.0.1:80
forward_tunnel(local_port=8080, remote_host="127.0.0.1", remote_port=80, transport=transport)
十、性能优化建议
- 复用连接:批量任务时不要每次都重新连接,使用同一个
SSHClient
。 - 加密算法优化:可在 Transport 中限制加密算法以加快速度。
- 并发执行:结合
threading
或concurrent.futures
。 - 大文件传输:使用
sftp.putfo()
传输内存流避免磁盘 I/O。
十一、安全注意事项
- 避免明文密码存储,优先使用私钥认证。
- 在生产环境不要使用
AutoAddPolicy()
,应手动管理known_hosts
。 - 传输敏感数据时确保网络安全,或额外加密文件。
十二、实战案例:自动化部署脚本
import paramiko
def ssh_exec(host, user, pwd, cmd):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=host, username=user, password=pwd)
stdin, stdout, stderr = ssh.exec_command(cmd)
output = stdout.read().decode()
ssh.close()
return output
if __name__ == "__main__":
servers = ["192.168.1.100", "192.168.1.101"]
for ip in servers:
print(f"部署到 {ip}")
print(ssh_exec(ip, "root", "123456", "systemctl restart myapp"))
十三、总结
Paramiko 作为 Python 中最成熟的 SSH 库,不仅能执行远程命令,还能传输文件、实现端口转发等功能。在自动化运维、批量管理、多机部署等场景下,它都能大显身手。
不过在生产环境中,应特别注意安全配置与连接管理,避免因方便而忽视安全性。