我正在编写一个 bash 脚本,该脚本将从 cron 调用,每天从远程服务器提取一次文件。我使用的是 SSH,因此我需要自动提供密码,因为它是在无人值守的情况下运行的。以下是我目前想到的办法:
1:通过创建DSA密钥对ssh-keygen
2:将公钥复制到远程服务器
3:配置ssh-agent
处理密钥密码
我的问题是:这一切都是必要的吗?这是最简单/最好的方法吗?这是一个非常简单的任务,所以我想在保持合理安全水平的同时,使配置尽可能简单。
附加信息:
-未运行 rsync 守护程序
-两台机器都是 Ubuntu Linux
答案1
如果不使用ssh
和,您所做的任何事情都会不安全sshd
。
规范的方法是使用scp
甚至更好的方法,rsync
以及没有密码的 ssh 密钥。
或者,创建一个仅用于复制的密钥,并在远程端编辑authorized_keys文件以仅包含您需要运行的命令和密钥,例如:
# remote_server:/home/copyuser/.ssh/authorized_keys:
command="[...]" ssh-rsa KEY_HERE user@host
还有scponly
可用的。如果您创建一个用户,将他们的 shell 设置/etc/passwd
为/usr/bin/scponly
,他们将不被允许登录,但可以按照正常权限复制文件进出。
答案2
虽然我认为你可以使用受密码保护的私钥,这通常不推荐用于打算通过 cron 运行的进程。我建议跳过密码,然后确保您使用的任何用户帐户在目标框上都只有非常有限的权限。通过跳过密码,您无需处理混乱的问题ssh-agent
。
答案3
以下是我的建议:
- 为该 cron 任务创建一组特定的 SSH 公钥/私钥。使用:ssh-keygen -t rsa -N '' -f id_cronjobname
- 保护生成的 id_cronjobname 文件,以便只有 cron 作业可以读取它。如果此文件被泄露,任何拥有该密钥文件的人都可能获得相同的权限。
- 限制远程端使用该密钥。例如,在远程 authorized_keys 中,您可能希望在密钥前加上以下示例。
- 还可以考虑使用“from”来限制 authorized_keys 文件中的 IP 地址。有关这些限制的更多信息,请参阅“man sshd”。
远程 authorized_keys 文件中的示例行:
no-pty,no-agent-forwarding,no-X11-forwarding,no-port-forwarding,command="rsync --server --sender -vlogDtprze.i --ignore-errors --numeric-ids --inplace . /path/on/destination/system" ssh-rsa SSH_KEY_STRING user@host"
您可以通过运行您计划使用的 rsync 命令来获取要输入的确切命令,然后同时在远程系统上执行“ps awwlx | grep rsync”。
注意:我遇到的一个常见问题是运行 cron 作业的用户没有远程主机的 SSH 密钥,因此它会尝试询问连接是否正常。请确保将远程系统的 SSH 主机密钥放在 /etc/ssh/ssh_known_hosts 中(连接后可能只需将其从您自己的 ~/.ssh/known_hosts 文件中复制出来)。或者,您可以执行“su - $USER_CRONJOB_RUNS_AS”,然后手动调用命令并确保其有效。此外,这对于测试作业很有用。
答案4
在步骤#1(生成密钥)中,当您被要求输入释义时,您应该立即按 Enter - 您将得到一个没有释义的密钥对,然后您可以跳过步骤#3(配置ssh-agent
)。
从安全角度来看,在此设置中,如果您的 ssh 客户端受到攻击,则 ssh 服务器(您从其提取数据的地方)也将对对手开放(如果您不是以 root 身份登录,则以非 root 身份访问)。这不是什么大问题,而且这是一种非常常见的做法。但请尝试定期对您的 Ubuntu 系统进行安全更新。
任何比这个设置更简单的装置的安全性都会很低。
描述的选项服务器忍者将为您提供更高的安全性(客户端和服务器之间更好的隔离),但这些设置的配置开销更大并且更难调试。
一旦您设置了无密码密钥对(将公钥复制到服务器上的 ~/.ssh/autorized_keys),rsync 将不需要任何额外的选项,就像 ssh 和 scp 一样。