本文目录导读:

要实现Python脚本SFTP免密登录,主要有两种方法:SSH密钥认证 和 使用ssh配置文件,最常用和推荐的是SSH密钥认证方式。
SSH密钥认证(推荐)
生成SSH密钥对
# 在本地生成RSA密钥对 ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N ""
将公钥上传到服务器
# 方式1:使用ssh-copy-id ssh-copy-id username@remote_host # 方式2:手动复制 cat ~/.ssh/id_rsa.pub | ssh username@remote_host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
使用Paramiko实现免密登录
import paramiko
def sftp_with_key(host, port, username, key_file=None):
"""
使用SSH密钥进行SFTP连接
"""
try:
# 创建SSH客户端
ssh = paramiko.SSHClient()
# 自动添加未知主机密钥
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 方法1:使用默认密钥文件(~/.ssh/id_rsa)
if key_file is None:
ssh.connect(
hostname=host,
port=port,
username=username
)
# 方法2:指定密钥文件路径
else:
private_key = paramiko.RSAKey.from_private_key_file(key_file)
ssh.connect(
hostname=host,
port=port,
username=username,
pkey=private_key
)
# 创建SFTP客户端
sftp = ssh.open_sftp()
print("SFTP连接成功!")
# 示例操作
sftp.chdir('/remote/path') # 切换目录
files = sftp.listdir() # 列出文件
print(f"远程目录文件: {files}")
# 上传文件示例
# sftp.put('local_file.txt', 'remote_file.txt')
# 下载文件示例
# sftp.get('remote_file.txt', 'local_file.txt')
# 关闭连接
sftp.close()
ssh.close()
return True
except Exception as e:
print(f"连接失败: {str(e)}")
return False
# 使用示例
if __name__ == "__main__":
# 使用默认密钥
sftp_with_key(
host="192.168.1.100",
port=22,
username="your_username"
)
# 或指定密钥文件
# sftp_with_key(
# host="192.168.1.100",
# port=22,
# username="your_username",
# key_file="/path/to/id_rsa"
# )
更完善的封装版本
import paramiko
import os
from typing import Optional, List
class SFTPManager:
"""SFTP连接管理器"""
def __init__(self, host: str, port: int = 22, username: str = None,
key_file: str = None, password: str = None):
self.host = host
self.port = port
self.username = username
self.key_file = key_file or os.path.expanduser("~/.ssh/id_rsa")
self.password = password
self.ssh = None
self.sftp = None
def connect(self) -> bool:
"""建立SFTP连接"""
try:
self.ssh = paramiko.SSHClient()
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 优先使用密钥认证
if os.path.exists(self.key_file):
try:
private_key = paramiko.RSAKey.from_private_key_file(self.key_file)
self.ssh.connect(
hostname=self.host,
port=self.port,
username=self.username,
pkey=private_key
)
except:
# 密钥认证失败,尝试密码认证
if self.password:
self.ssh.connect(
hostname=self.host,
port=self.port,
username=self.username,
password=self.password
)
else:
raise
elif self.password:
self.ssh.connect(
hostname=self.host,
port=self.port,
username=self.username,
password=self.password
)
else:
raise Exception("未提供认证方式(密钥或密码)")
self.sftp = self.ssh.open_sftp()
return True
except Exception as e:
print(f"连接失败: {e}")
return False
def disconnect(self):
"""断开连接"""
if self.sftp:
self.sftp.close()
if self.ssh:
self.ssh.close()
def upload_file(self, local_path: str, remote_path: str) -> bool:
"""上传文件"""
try:
self.sftp.put(local_path, remote_path)
return True
except Exception as e:
print(f"上传失败: {e}")
return False
def download_file(self, remote_path: str, local_path: str) -> bool:
"""下载文件"""
try:
self.sftp.get(remote_path, local_path)
return True
except Exception as e:
print(f"下载失败: {e}")
return False
def list_files(self, remote_path: str = ".") -> List[str]:
"""列出目录文件"""
try:
return self.sftp.listdir(remote_path)
except Exception as e:
print(f"列出文件失败: {e}")
return []
# 使用示例
if __name__ == "__main__":
# 创建SFTP管理器
sftp_mgr = SFTPManager(
host="192.168.1.100",
port=22,
username="user",
key_file="~/.ssh/id_rsa" # 可选,默认使用此路径
)
# 连接
if sftp_mgr.connect():
print("连接成功!")
# 执行操作
files = sftp_mgr.list_files("/remote/path")
print(f"文件列表: {files}")
# 上传文件
# sftp_mgr.upload_file("local.txt", "/remote/path/remote.txt")
# 下载文件
# sftp_mgr.download_file("/remote/path/file.txt", "local_file.txt")
# 断开连接
sftp_mgr.disconnect()
使用fabric库(更高级的封装)
from fabric import Connection
def fabric_sftp_example():
"""使用fabric库进行免密SFTP"""
# 方法1:使用默认密钥
c = Connection(
host="192.168.1.100",
user="username",
connect_kwargs={
"key_filename": "~/.ssh/id_rsa" # 指定密钥文件
}
)
# 方法2:使用ssh配置文件
# c = Connection("username@192.168.1.100")
# 上传文件
c.put("local_file.txt", "/remote/path/")
# 下载文件
c.get("/remote/path/remote_file.txt", "local/")
# 执行远程命令
result = c.run("ls -la")
print(result.stdout)
c.close()
安全注意事项
-
密钥权限:确保SSH密钥文件的权限正确
chmod 600 ~/.ssh/id_rsa chmod 644 ~/.ssh/id_rsa.pub chmod 700 ~/.ssh
-
使用SSH Agent(避免密钥密码反复输入):
import paramiko import os
使用SSH Agent
agent = paramiko.Agent() agent_keys = agent.get_keys()
ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
使用Agent中的密钥
ssh.connect( hostname="192.168.1.100", username="user", look_for_keys=True # 自动查找SSH Agent中的密钥 )
## 常见问题排查
1. **检查服务器端配置**:确保服务器的SSH配置允许密钥认证
```bash
# 在远程服务器上检查
sudo grep "PubkeyAuthentication" /etc/ssh/sshd_config
# 应该显示: PubkeyAuthentication yes
- 调试连接:
import paramiko import logging
开启调试日志
logging.basicConfig(level=logging.DEBUG) paramiko.util.log_to_file('paramiko.log')
3. **测试连接**:
```bash
ssh -v username@remote_host
选择哪种方法取决于你的具体需求,对于简单的脚本,直接用Paramiko就足够了;如果需要更复杂的运维操作,可以考虑使用Fabric。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播