如何通过Python Paramiko以其他用户身份执行SFTP操作
用服务账户登录后切换用户执行SFTP传输的解决方案
看起来你卡在用服务账户登录后,没法切换到目标用户做文件传输的问题上了。其实核心是要在登录服务账户后,通过sudo切换到目标用户再启动SFTP服务,而不是直接用Paramiko默认的SFTP通道——默认通道是跑在服务账户权限下的。
下面给你一步步的解决方法:
1. 先确保服务账户有sudo权限(关键)
首先得让你的serviceAccount能免密码切换到目标用户(比如叫targetUser)并执行sftp-server。编辑sudoers文件(记得用visudo,别直接编辑!):
sudo visudo
添加一行:
serviceAccount ALL=(targetUser) NOPASSWD: /usr/lib/openssh/sftp-server
这样服务账户就能不用输入密码,以targetUser身份启动SFTP服务了。
2. 修改Paramiko代码实现切换用户后的SFTP
你原来的代码只打开了会话但没正确启动SFTP服务,试试这个完整的示例:
import paramiko # 服务器信息 server_address = '<你的服务器地址>' server_port = <端口号,默认22> service_account = 'serviceAccount' service_password = '<服务账户密码>' target_user = '<目标用户名>' # 建立SSH传输连接 transport = paramiko.Transport((server_address, server_port)) transport.connect(username=service_account, password=service_password) # 打开会话,执行sudo切换用户并启动sftp-server channel = transport.open_session() # 设置终端类型,避免sudo报错 channel.get_pty() # 执行切换用户并启动sftp服务的命令 channel.exec_command(f'sudo -u {target_user} /usr/lib/openssh/sftp-server') # 检查命令执行状态,确保没有报错 if channel.recv_exit_status() != 0: print(f"启动SFTP服务失败: {channel.recv(1024).decode()}") transport.close() exit(1) # 创建SFTP客户端,基于这个切换用户后的通道 sftp = paramiko.SFTPClient.from_channel(channel) # 现在你可以用sftp对象执行文件操作了,权限是targetUser的! # 示例:上传本地文件到服务器目标用户的家目录 sftp.put('/本地文件路径', f'/home/{target_user}/目标文件名') # 示例:下载服务器文件到本地 sftp.get(f'/home/{target_user}/服务器文件名', '/本地保存路径') # 用完记得关闭连接 sftp.close() transport.close()
3. 可能遇到的坑
- 如果你的sudo配置需要输入密码,那上面的代码得处理密码输入:可以在
channel.exec_command后,用channel.send('<sudo密码>\n')来输入密码,但还是建议配置免密码sudo更安全方便。 - 确保
/usr/lib/openssh/sftp-server的路径是对的,不同Ubuntu版本可能路径不同,用which sftp-server确认一下。 - 检查服务器的
sshd_config里PermitRootLogin或者AllowUsers有没有限制服务账户登录,确保服务账户能正常SSH登录。
这样应该就能实现你想要的:用服务账户登录,然后以目标用户身份做文件传输了。
内容的提问来源于stack exchange,提问作者Parth Shah
相关产品推荐
相关产品推荐

