
当使用 sudo 执行 SSH 命令时,系统默认加载 root 用户的 SSH 配置和密钥(位于 /root/.ssh/),而非当前用户的密钥,导致免密登录失败并提示输入密码。
当使用 sudo 执行 ssh 命令时,系统默认加载 root 用户的 ssh 配置和密钥(位于 `/root/.ssh/`),而非当前用户的密钥,导致免密登录失败并提示输入密码。
在 Linux Mint LMDE6 环境下,你的备份脚本(如 Backuso)需以 sudo 权限运行以读取 root 拥有的系统文件,但 sudo ssh 会切换到 root 用户上下文,从而忽略你个人账户(如 /home/youruser/.ssh/id_rsa)中已配置好的 SSH 密钥对——这是问题的根本原因。
? 验证问题根源
运行以下命令对比行为差异:
# 普通用户执行(成功免密) ssh user@nas 'ls /home/BackupGen10/BackupRemote/BackusoTEST/' # sudo 执行(失败,提示密码) sudo ssh user@nas 'ls /home/BackupGen10/BackupRemote/BackusoTEST/' # 加 -v 查看详细日志,确认密钥路径是否为 /root/.ssh/ sudo ssh -v user@nas 'echo ok' 2>&1 | grep "identity file"
日志中若显示 Trying private key: /root/.ssh/id_rsa,而该路径下无有效密钥或权限不正确,则验证成功。
✅ 正确解决方案:显式指定用户密钥路径
在 subprocess.run() 中,强制 SSH 使用你的私钥文件,而非默认查找 root 的密钥:
import subprocess
# ✅ 推荐:明确指定私钥路径(注意权限:私钥文件必须仅属主可读)
private_key_path = "/home/youruser/.ssh/id_rsa" # 替换为你的实际路径
command = f"sudo ssh -i '{private_key_path}' -o StrictHostKeyChecking=no user@nas 'ls \"/home/BackupGen10/BackupRemote/BackusoTEST/\"'"
proc = subprocess.run(
command,
text=True,
encoding="UTF-8",
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True
)⚠️ 关键注意事项:
- 文件权限必须严格:
chmod 600 /home/youruser/.ssh/id_rsa,否则 OpenSSH 会拒绝加载;- 避免 passphrase 密钥:若私钥设置了密码短语,
sudo ssh仍会阻塞等待输入——建议为自动化场景生成无密码密钥(ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_nopass -N "");- 主机密钥检查:添加
-o StrictHostKeyChecking=no可跳过首次连接确认(生产环境建议预先信任 NAS 主机指纹,更安全);- 不要复制密钥到 /root/.ssh/:虽可行,但违背最小权限原则,且易引发权限混乱与审计风险。
?️ 进阶加固建议(可选)
- 若需长期稳定运行,可考虑改用
sudo -u youruser ssh ...替代sudo ssh,保持用户环境一致性; - 在 NAS 端确保
sshd_config启用公钥认证:PubkeyAuthentication yes,并确认AuthorizedKeysFile指向正确的~/.ssh/authorized_keys; - 定期检查密钥强度:优先使用
ed25519(ssh-keygen -t ed25519),比传统 RSA 更高效安全。
通过显式指定 -i 参数,你绕过了 sudo 引起的用户上下文切换陷阱,既保留了备份所需的 root 权限,又复用了已配置的密钥信任链——这才是自动化 SSH 备份可靠运行的核心实践。

















