我读过几篇关于如何使用 Rsync 和公钥认证自动备份文件的文章。它们都非常相似。我刚刚完成了所有设置,一切正常,但是……我刚刚发现一篇文章说它不安全。我做了以下操作:
- 在备份服务器上我生成了公钥和私钥。
- 我将公钥复制到远程(原始)服务器目录:(
/var/sites/.ssh
文件authorized_keys
)。该目录归"user12"
- 我在authorized_keys文件中添加了以下内容:
from="BACKUP.SERVERS.IP.ADDRESS",command="/root/validate_rsync"
我创建了一个文件 /root/validate_rsync,其内容如下:
#!/bin/sh echo $SSH_ORIGINAL_COMMAND >> /var/log/synchronize-log.log case "$SSH_ORIGINAL_COMMAND" in *\&*) echo "Rejected" ;; *\;*) echo "Rejected" ;; *\(*) echo "Rejected" ;; *\{*) echo "Rejected" ;; *\<*) echo "Rejected" ;; *\>*) echo "Rejected" ;; *\`*) echo "Rejected" ;; *\|*) echo "Rejected" ;; rsync\ --server*) $SSH_ORIGINAL_COMMAND ;; *) echo "Rejected" ;; esac
我运行 rsync 命令:
rsync -avzp --del -e "ssh -p 2211" [email protected]:/var/sites/photos/ /var/sites/sync/photos
我收到错误消息:文件权限问题/root/validate_rsync
。我将文件移动/root/validate_rsync
到/var/sites/validate_rsync
并将所有者更改为 user12:user12
现在同步可以正常工作了。但是我发现一篇文章说它不安全:
1- 执行 rsync 命令的用户 ID 不应拥有或写入validate_rsync 命令本身。否则,rsync 可用于用另一个未验证的脚本覆盖验证脚本,甚至执行任意命令。
2- 类似地,authorized-keys 文件不应该由 rsync 用户拥有或可写入,否则 rsync 可用于覆盖该文件,使用一个消除运行 validator-rsync 的要求的文件,或使用一个运行其他命令的文件。
我该怎么办?如果validate_rsync
归 root 所有,则同步不会启动,因为user12
无法访问root
的文件。如果authorized-keys
文件归其他用户所有,我将无法使用用户名 登录user12
。
我的问题:
我应该将validate_rsync和authorized-keys文件放在哪里?在哪个目录中?它们应该具有什么权限和所有权?
有什么方法可以告诉文件
validate_rsync
仅允许同步 2 个文件夹:/var/sites/photos/
,/var/sites/photos2/
答案1
这些安全问题是正确的。因此,回答您的第一个问题:要使其按您希望的方式工作,您应该将validate_rsync放在user12
具有执行权限但没有写入权限的目录中。同一个validate_rsync
文件应该对用户具有读取和执行权限,但当然没有写入权限。这里的问题是/root
默认情况下只有root
用户可访问,您需要一个每个目录都具有执行权限的路径user12
。例如,您可以复制validate_rsync
到/usr/local/bin
并使其归所有root
。只要user12
可以执行和读取,就可以了。
您不需要保护您的authorized_keys
文件。最好user12
通过配置强制运行命令,输入sshd_config
以下内容:
Match user user12
ForceCommand /usr/local/bin/validate_rsync
我认为这个解决方案比修改authorized_keys更好。
另外,在您的validate_rsync
我会引用$SSH_ORIGINAL_COMMAND
(更安全),我会改变您的句子以使用;更容易,更紧凑,更强大case
来检查正则表达式命令的有效性:grep
echo "$SSH_ORIGINAL_COMMAND" >> /var/log/synchronize-log.log
if echo "$SSH_ORIGINAL_COMMAND" | grep -qE '[&;<>`|]'; then
echo Rejected
elif [[ "${SSH_ORIGINAL_COMMAND:0:14}" == "rsync --server" ]]; then
$SSH_ORIGINAL_COMMAND
else
echo Rejected
fi
回答你的第二个问题,当你记录 SSH_ORIGINAL_COMMAND 时,你可以对你想要考虑的目录运行测试,然后检查你得到的 SSH_ORIGINAL_COMMAND。然后你可以 make 来validate_rsync
验证该命令。
答案2
为了保护authorized_keys
文件,我遇到了这个解决方案:https://superuser.com/questions/852434/how-to-protect-authorized-keys-file
如果您不打算经常更改该文件,那么通常只需删除该文件的写访问权限即可。
chmod 400 ~/.ssh/authorized_keys
现在,当然,恶意脚本可以将写访问权限重新添加,因此您需要将文件及其父目录设置为不可变的:
sudo chattr +i ~/.ssh/authorized_keys
sudo chattr +i ~/.ssh