我已经阅读了几篇如何使用 Rsync 和公钥身份验证自动备份文件的文章。它们都非常相似。我刚刚完成了所有设置,一切正常,但是...我刚刚发现一篇文章说它不安全。我做了以下事情:
/var/sites/.ssh
文件authorized_keys
)。该目录归"user12"
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
Run Code Online (Sandbox Code Playgroud)我运行 rsync 命令:
rsync -avzp --del -e "ssh -p 2211" user12@ORIGINAL.SERVERS.IP:/var/sites/photos/ /var/sites/sync/photos
Run Code Online (Sandbox Code Playgroud)
我收到错误消息:文件权限问题/root/validate_rsync
。我将文件/root/validate_rsync
移至/var/sites/validate_rsync
并将其更改为 user12:user12
现在同步工作。但是我发现一篇文章说它不安全:
1- 执行 rsync 命令的用户 ID 不应拥有或写入 validate_rsync 命令本身。否则,rsync 可用于用另一个不验证的脚本覆盖验证脚本,甚至执行任意命令。
2- 同样,授权密钥文件不应由 rsync 用户拥有或可写,否则 rsync 可用于覆盖该文件,其中一个删除了运行 validate-rsync 的要求,或者一个运行其他命令反而。
我能做什么?如果validate_rsync
由 root 拥有,则同步不会开始,因为user12
无法访问root
的文件。如果authorized-keys
文件将由另一个用户拥有,我将无法使用 username 登录user12
。
我的问题:
我应该将 validate_rsync 和授权密钥文件放在哪里,在哪个目录中?他们应该拥有哪些权限和所有权?
有什么方法可以告诉validate_rsync
文件只允许同步 2 个文件夹:/var/sites/photos/
,/var/sites/photos2/
这些安全担忧是正确的。因此,要回答您的第一个问题:要使其按您喜欢的方式工作,您应该将 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
Run Code Online (Sandbox Code Playgroud)
我认为这个解决方案比修改授权密钥更好。
另外,在您的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
Run Code Online (Sandbox Code Playgroud)
要回答第二个问题,当您记录 SSH_ORIGINAL_COMMAND 时,您可以使用要考虑的目录运行测试,然后检查您获得的 SSH_ORIGINAL_COMMAND。然后您可以validate_rsync
验证该命令。