私钥权限须设为600且用from_private_key_file加载,SFTP需显式close transport和sftp,大文件传输要加超时重试及进度回调。

私钥文件权限不合规会导致 paramiko 认证失败
paramiko 默认拒绝读取权限过于宽松的私钥文件(比如 644 或 755),直接报错 ParamikoAuthenticationException: Invalid key 或静默失败。这不是 bug,而是 OpenSSH 兼容性策略:私钥必须对非所有者不可读写。
实操建议:
- Linux/macOS 下用
chmod 600 /path/to/id_rsa严格设权,别跳过这步 - Windows 上虽无 POSIX 权限,但 paramiko 仍会检查文件是否“看起来像公开可读”,建议用
os.chmod(path, 0o600)主动设权(即使无效,也能避免部分版本误判) - 不要把私钥硬编码进脚本或放项目根目录——容易被 git 提交、日志泄露
用 paramiko.RSAKey.from_private_key_file() 而非 from_private_key()
from_private_key() 接收的是已加载的密钥对象(如 io.StringIO 流),而日常场景中你拿到的是磁盘路径。直接传路径进去会抛 ValueError: Not a valid private key file。
正确做法是明确使用 from_private_key_file(),它支持密码解密和自动格式识别(PEM/OpenSSH):
立即学习“Python免费学习笔记(深入)”;
from paramiko import RSAKey <p>key = RSAKey.from_private_key_file( "/home/user/.ssh/id_rsa", password="my_passphrase" # 若私钥有密码,必须传;若无,可省略或传 None )
注意:password 参数不能是空字符串 "",否则会被当作“需要密码但没提供”而失败。
SFTP 连接必须显式关闭,否则文件推送可能卡住或丢数据
paramiko 的 SFTPClient 不是上下文管理器,with 语句无法自动清理连接。常见错误是只调 sftp.put() 就结束脚本,导致 TCP 连接未释放、远端文件写入未 flush、甚至下次运行时因连接数超限被拒绝。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
安全写法必须包含三步:
- 用
transport = paramiko.Transport((host, port))建连 -
transport.connect(username=user, pkey=key)认证 - 获取
sftp = paramiko.SFTPClient.from_transport(transport)后,操作完务必调sftp.close()和transport.close()
漏掉任一 close 都可能导致资源泄漏,尤其在循环推送多个文件时更明显。
大文件推送要加超时和重试,否则易因网络抖动中断
默认 SFTP 传输无重试、无进度反馈,sftp.put() 卡住后只会抛 socket.timeout 或 SSHException,且不保证断点续传。
基础加固建议:
- 初始化 transport 时设
transport.set_keepalive(30)防空闲断连 -
sftp.put()加callback函数观察进度,加confirm=True确保服务端落盘 - 包裹在
try/except中捕获IOError、socket.timeout、SSHException,失败后 sleep + retry(最多 2 次)
别依赖 paramiko 自带的“自动重连”——它根本不存在。
真正麻烦的不是代码怎么写,而是私钥生命周期管理:谁生成、谁保管、谁轮换、出事怎么审计。脚本里写死路径或密码,哪怕只用一次,也等于埋了个定时炸弹。

















