我在所有服务器上使用密钥对进行 SSH 身份验证。出于安全原因,我们在所有 Linux 服务器上禁用通过 SSH 进行密码登录。
在每台服务器上,我都有一个根级别的文件夹,在该文件夹中,我有一组脚本,我倾向于在所有服务器上运行这些脚本来进行例行维护。
我有一个单独的 Linux 管理工作站,我用它通过 SSH 连接到我的每个服务器,并且在该管理站上我有该脚本文件夹的副本。
我想要做的是在我的管理站上只保留该文件夹的一个副本,然后使用脚本通过 SCP 进入我的每台服务器,然后将该文件夹复制过来。我有一个文本文件中的所有服务器列表,该文件与我的复制脚本放在一起。
到目前为止,我已经编写了复制脚本来处理解析“服务器”文件并循环遍历每个条目和 SCP 到每个服务器以复制文件夹。
我的问题是每次我都被要求输入私钥的密钥短语,我想知道是否有办法打开密钥一次,然后将其用于所有连接。这样只需要一次询问我密钥短语,而不是针对它要连接的每个服务器询问一次。
我意识到我可以使用像 Syncthing 或其他复制系统之类的东西来自动执行此复制,甚至可能是 rsync,但我想避免在所有服务器上运行这样的软件,只是为了复制这个文件夹,并且我对设置 rsync 所涉及的内容知之甚少,并且我想避免在所有服务器上放置特定的配置以允许 rsync 工作。
我拥有的基本/粗略的脚本如下,它可以起作用,但我只需要继续输入密码。
复制文件
hosts=$(<servers_file)
for host in $hosts; do
echo "Connecting to host $host";
scp -r /data/scripts root@$host:/data
done
服务器文件
10.1.1.10
10.1.1.11
etc
我以为我找到了一个使用 SSH 套接字的好解决方案,但它只允许我在需要连接到多个主机时在同一远程主机上运行多个命令。https://serverfault.com/questions/389404/use-scp-to-copy-a-file-to-different-servers将会起作用,但只有当我们使用 SSH 密码时,我们才会这样做。
如果有人能给我指明正确的方向,我将不胜感激。
答案1
我有一个类似的用例,我希望通过 ssh 完全自动化命令,其中有一个可以自动化的交互。我已经使用 python 实现了自动化,并使用期望回答问题(可能是密码)
def localexpect(alog, config, host):
TMPLOG = "/tmp/pexpect.log"
mcs = config["mcs"]
cmd = f'''
ssh-keygen -R {host}.local ;\
ssh-copy-id -i rsa/id_rsa.pub {mcs["user"]}@{host}.local ;\
echo "publickeyinstalled" ;\
echo "alldone"
'''
alog.info(cmd)
with open(TMPLOG, "w") as log:
ch = pexpect.spawn(f"/bin/bash -c \"{cmd}\"", encoding='utf-8', logfile=log)
while True:
i = ch.expect(["Are you sure", "password:", "publickeyinstalled"])
if i == 0:
alog.info("ECDSA check")
ch.send("yes\r")
elif i == 1:
alog.info("Password required")
ch.send(f"{mcs['pwd']}\r")
elif i == 2:
alog.info("public key installed")
break
ch.expect("alldone")
i = ch.expect([pexpect.EOF], timeout=5)
ch.close()
alog.info("expect done - EOF")