SSH 询问一次密码,重复使用密码直到超时结束

SSH 询问一次密码,重复使用密码直到超时结束

我该如何解决这个问题?我有一个 bash 脚本(在 Ubuntu Server 下),进行多次 SSH 连接,执行一些远程传输,例如 rsync。

我的问题是,我想避免多次输入密码。但我不想使用 SSH 公钥交换,因为如果有人有密钥,就能够连接远程计算机。

我想要以下内容:

  • 当我启动 bash 脚本时,SSH 应该询问密码
  • 重复使用密码,因此在超时之前不要再次询问密码
  • 超时结束后,再次询问密码。

类似地,sudo 的工作方式是使用 ssh。

知道如何解决这个问题吗?

编辑1:

我发现了一个新的 SSH 功能,名为 ssh multiplexing。也许利用这个功能我可以达到我想要的目标。

https://unix.stackexchange.com/questions/50508/reusing-ssh-session-for-repeated-rsync-commands

这有用吗?

答案1

这不是你想听到的,但这就是基于密钥的身份验证的目的。只要你在私钥上设置密码,它的安全性就不会低于密码身份验证。

您可以使用ssh-agent来避免每次都需要输入密码,并且该-t选项ssh-agent将为您提供所需的超时行为。

# start a shell under ssh-agent with a 5-minute timeout for keys loaded with ssh-add
ssh-agent -t 300 /bin/bash

# add your key(s) to the agent; ssh-add will prompt for passphrase, if one is set
ssh-add

# do some stuff
ssh remote.server cat /some/file
rsync file1 file2 [email protected]:/some/directory

# after 300 seconds, timeout reached, run ssh-add again to re-add your keys
ssh-add

您的脚本需要一些逻辑来确定何时发生超时。一种方法是运行和ssh,这将阻止交互式身份验证方法,因此如果密钥不再可用,将退出而不是提示输入密码。您可以使用退出代码来确定是否需要再次运行;在这种情况下应设置为。rsync-o BatchMode=yessshssh-add$?255

您仍然需要弄清楚如何将密码提供给ssh-add,因为它不提供以编程方式接受密码的方法。除非您的脚本会提示您手动输入密码,否则您可能需要使用 来完成expect这一部分,这意味着在某处对密码进行硬编码。

答案2

看来我找到了满足我需求的完美解决方案:

重复使用 ssh 会话来执行重复的 rsync 命令

#!/bin/bash

# Create ssh-mux (SSH multiplex) dir only if not exists
[[ ! -d dir ]] || mkdir ~/.ssh/ssh-mux

apache_site_path_source="/var/www/source_site"
apache_site_path_target="/var/www/target_site"

# Solution: Start SSH multiplexing session (works fine)
# https://unix.stackexchange.com/questions/50508/reusing-ssh-session-for-repeated-rsync-commands
sudo ssh -nNf -o ControlMaster=yes -o ControlPath="~/.ssh/ssh-mux/%L-%r@%h:%p" [email protected]

sudo rsync -av --progress -e 'ssh -l root -p 22 -o "ControlPath=~/.ssh/ssh-mux/%L-%r@%h:%p"' 192.168.0.1:${apache_site_path_source}/. ${apache_site_path_target}/;
printf "\n\n\n\n\n\n"
sudo rsync -av --progress -e 'ssh -l root -p 22 -o "ControlPath=~/.ssh/ssh-mux/%L-%r@%h:%p"' 192.168.0.1:${apache_site_path_source}/. ${apache_site_path_target}/;
printf "\n\n\n\n\n\n"
sudo rsync -av --progress -e 'ssh -l root -p 22 -o "ControlPath=~/.ssh/ssh-mux/%L-%r@%h:%p"' 192.168.0.1:${apache_site_path_source}/. ${apache_site_path_target}/;
printf "\n\n\n\n\n\n"

# Finish SSH multiplexing session
sudo ssh -O exit -o ControlPath="~/.ssh/ssh-mux/%L-%r@%h:%p" [email protected]

此解决方案仅询问一次密码,然后执行 rsync 3 次而无需再次询问密码。每次 rsync 都使用 SSH 多路复用重用 SSH 连接。

可以更改 SSH 配置并存储 SSH 多路复用设置,但使用此解决方案无需更改服务器配置,脚本按原样工作。

答案3

如果您使用密钥文件,则可以使用AddKeyToAgent选项(OpenSSH>=7.2)。

ssh(1):添加 AddKeysToAgent 客户端选项,可设置为“yes”、“no”、“ask”或“confirm”,默认为“no”。启用后,如果 ssh-agent 正在运行,则身份验证期间使用的私钥将添加到 ssh-agent(如果设置为“confirm”,则启用确认)。

因此你的脚本可能看起来像这样。

# make sure the ssh agent is running (may not be necessary on some systems)
eval "$(ssh-agent -s)"

# ssh commands.  only the first command needs AddKeysToAgent option
ssh -o AddKeysToAgent=yes user@host "echo hello"
ssh user@host "echo world"
...

答案4

我通常会告诉你尝试一下expect,但在这种情况下,我认为最好使用密码,它非常容易安装和使用,这里我发布一些使用案例

sshpass -p<pass> ssh <args> sshpass -pfoobar ssh -o StrictHostKeyChecking=no user@host command_to_run

玩得开心 :)

编辑1

按照脚本

#!/bin/bash
read -p "give me the password" pass
sshpass -p"$pass" ssh -o StrictHostKeyChecking=no user@host command_to_run

相关内容