Paramiko 完全指南
目录
- Paramiko 概述
- 核心功能与模块框架
- 安装与依赖
- 基础用法与案例详解
- SSH 连接与命令执行
- 密钥认证
- SFTP 文件传输
- 交互式会话
- 端口转发
- 高级功能与实战技巧
- 常见问题与解决方案
- 总结与资源推荐
1. Paramiko 概述
是什么?
Paramiko 是一个纯 Python 实现的 SSHv2 协议库,支持:
- 远程命令执行
- 安全文件传输(SFTP)
- 端口转发与隧道
- RSA/DSA 密钥认证
应用场景
- 自动化运维:批量执行服务器命令(部署、日志分析)。
- 安全文件传输:替代
scp
/sftp
命令行工具。 - 网络设备管理:管理路由器、交换机等支持 SSH 的设备。
- 内网穿透:通过 SSH 隧道访问隔离网络资源。
2. 核心功能与模块框架
核心模块
模块/类 | 功能描述 |
---|---|
SSHClient | 封装 SSH 会话,管理连接与命令执行 |
SFTPClient | 提供 SFTP 文件操作接口 |
Transport | 底层连接管理,支持复用与扩展协议 |
Channel | SSH 通道,实现交互式会话或端口转发 |
RSAKey /DSSKey | 处理密钥的生成与加载 |
工作流程
- 建立连接:
SSHClient.connect()
- 认证方式:密码、密钥或混合认证
- 执行操作:命令、文件传输、端口转发
- 关闭连接:显式调用
close()
或使用with
语句
3. 安装与依赖
安装命令
pip install paramiko
系统依赖(Linux)
sudo apt-get install libssl-dev # 确保加密库支持
4. 基础用法与案例详解
案例 1:SSH 连接与命令执行
import paramiko# 创建客户端并设置自动添加主机密钥(生产环境慎用)
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())try:# 连接远程主机ssh.connect(hostname='192.168.1.100',username='user',password='password',timeout=5)# 执行命令并获取输出stdin, stdout, stderr = ssh.exec_command('ls -l /tmp')output = stdout.read().decode('utf-8')error = stderr.read().decode('utf-8')print(f"Output:\n{output}\nError:\n{error}")except paramiko.AuthenticationException:print("认证失败!")
finally:ssh.close()
关键点
AutoAddPolicy
:自动信任未知主机密钥(仅限测试环境)。stdin/stdout/stderr
:分别对应命令的输入、输出和错误流。decode('utf-8')
:将字节流转换为字符串,解决编码问题。
案例 2:密钥认证
import paramiko# 加载加密的 RSA 私钥
private_key = paramiko.RSAKey.from_private_key_file(filename='~/.ssh/id_rsa',password='your_key_password' # 若密钥有密码
)ssh = paramiko.SSHClient()
ssh.connect(hostname='host',username='user',pkey=private_key
)
注意事项
- 私钥文件权限需为
600
:chmod 600 ~/.ssh/id_rsa
- 支持
.pem
和 OpenSSH 格式密钥。
案例 3:SFTP 文件传输
with paramiko.SSHClient() as ssh:ssh.connect('host', username='user', password='pass')sftp = ssh.open_sftp()# 上传文件sftp.put('local_file.txt', '/remote/path/file.txt')# 下载文件sftp.get('/remote/path/file.txt', 'local_download.txt')# 遍历目录for file in sftp.listdir('/tmp'):print(file)
扩展功能
sftp.mkdir()
:创建远程目录sftp.stat()
:获取文件属性
案例 4:交互式 Shell 会话
channel = ssh.invoke_shell() # 创建交互式通道
channel.send('ls -l\n') # 发送命令# 等待响应并读取输出
while not channel.recv_ready():time.sleep(0.1) # 避免 CPU 空转
output = channel.recv(1024).decode()
print(output)
关键参数
recv(1024)
:每次读取 1024 字节的缓冲区。get_pty=True
:为命令分配伪终端(解决sudo
交互问题)。
案例 5:本地端口转发
transport = paramiko.Transport(('host', 22))
transport.connect(username='user', password='pass')# 将本地 8080 端口转发到远程主机的 80 端口
transport.request_port_forward('localhost', 8080, '', 80)# 此时访问 localhost:8080 将转发到远程 80 端口
业务场景
- 访问内网 Web 服务(如
http://localhost:8080
→ 远程80
端口)。 - 绕过防火墙限制。
5. 高级功能与实战技巧
1. 复用 Transport 连接
transport = paramiko.Transport(('host', 22))
transport.connect(...)# 复用 Transport 创建 SFTP
sftp = paramiko.SFTPClient.from_transport(transport)# 复用 Transport 执行命令
ssh = paramiko.SSHClient()
ssh._transport = transport
2. 使用 SSH 配置文件
from paramiko.config import SSHConfigconfig = SSHConfig()
with open(os.path.expanduser("~/.ssh/config")) as f:config.parse(f)host_info = config.lookup('myhost')
ssh.connect(hostname=host_info['hostname'],username=host_info['user'],key_filename=host_info['identityfile'][0]
)
3. 超时与重试机制
from retry import retry@retry(tries=3, delay=2)
def connect_with_retry():ssh.connect(..., timeout=10)
6. 常见问题与解决方案
问题 1:认证失败
- 原因:密码错误、密钥权限问题、密钥格式不兼容。
- 解决:
chmod 600 ~/.ssh/id_rsa # 修复密钥权限 ssh-keygen -p -m PEM -f ~/.ssh/id_rsa # 转换密钥为 PEM 格式
问题 2:sudo
命令卡住
- 原因:未分配伪终端(PTY)。
- 解决:
stdin, stdout, stderr = ssh.exec_command('sudo cmd', get_pty=True) stdin.write('password\n') stdin.flush() # 必须刷新缓冲区
问题 3:中文乱码
- 原因:远程输出编码非 UTF-8。
- 解决:
output = stdout.read().decode('gbk', errors='ignore') # Windows 主机
问题 4:连接超时
- 原因:网络阻塞或防火墙限制。
- 解决:
ssh.connect(..., timeout=10) # 显式设置超时
7. 总结
核心要点
- 安全优先:生产环境避免
AutoAddPolicy
,严格校验主机密钥。 - 资源管理:使用
with
语句或finally
确保连接关闭。 - 性能优化:复用连接、设置超时、合理处理编码。