我想在 Python 脚本中使用 rsync。我使用模块调用它,并使用存储在远程机器上的文件subprocess
中的公钥进行身份验证。authorized_key
唯一的问题是,当我使用错误的远程用户名使用 rsync 时,系统会提示我输入密码,这显然会永远停止备份脚本。
rsync
如果无法验证,我可以强制退出并显示错误,而不是提示输入密码吗?
乌迪
答案1
假设您将 rsync 与 SSH 远程 shell 一起使用(而不是 - 例如 - 与 rsync 服务器一起使用),那么您可以让 rsync 以永远不会要求输入密码的方式运行 SSH。例如,可以使用此调用:
rsync -e 'ssh -o "NumberOfPasswordPrompts 0"' source user@target:/path
这将强制 rsync 使用 SSH,并且密码尝试次数为 0 次 - 如果无法使用其他身份验证方法(如公钥或 GSSAPI)获得访问权限,则将失败并出现错误。请注意,当发生这种情况时,rsync 不会喜欢您,并且会大声抱怨 STDERR 并以退出代码 255 中断。
答案2
下面是我用来保持安静的 ssh 命令行选项。
ssh -o stricthostkeychecking=no -o userknownhostsfile=/dev/null -o batchmode=yes -o passwordauthentication=no
如果您不维护 known_hosts 文件并且担心收到 MitM 警告,则仅需要 hostkey 内容。我没有像 James F 建议的那样指定身份验证类型,而是必须明确限制密码身份验证。不过,我使用它来访问数百台具有几个不同操作系统版本的主机,因此它可能只是不兼容。
答案3
回复:James 的建议(不给它 tty),对于子进程,尝试将 stdin=None 作为 Popen 的参数。
答案4
根据您启动 rsync 的方式,不给它 TTY 或 PTY 可能会有所帮助。
许多程序在决定提示用户输入之前会检查它们是否有控制 TTY。system() 和类似调用的默认行为是向子程序提供 tty,但您可以禁用此功能。
如果您控制两个系统,并且希望在解决此问题的同时摆脱密码验证以获得安全利益,那么也可能完全在远程端禁用密码验证。
如果您通过 SSH 执行 rsync,则可以将以下内容添加到相关主机的 ssh_config 文件中,或者通过 -o 命令行开关添加:
PreferredAuthentications publickey
在快速测试中(仅 ssh,而不是 rsync),当我的公钥不被接受时,SSH 会立即退出,而不会提示我输入密码。