为rsync包装器脚本限制SSH访问的方案咨询
我来给你几个贴合你场景的解决方案,毕竟既要灵活访问多目录、又要锁死SSH权限确实是个头疼的问题:
用智能的SSH_ORIGINAL_COMMAND验证脚本替代静态匹配
别局限于只允许固定的rsync命令,而是写一个脚本解析SSH_ORIGINAL_COMMAND里的rsync参数,做动态安全校验:- 先预定义一批允许访问的目录列表,解析rsync命令里的源/目标路径,只允许路径落在这些目录范围内(比如只允许
/var/backups/、/home/data/这类可信目录) - 过滤掉危险的rsync参数,比如
--rsh、--exec、--shell这些能绕开限制执行其他命令的选项,只保留--archive、--compress、--delete这类同步相关的安全参数 - 对ln命令也做类似的路径校验,只允许在可信目录内创建软链
给你一个简化版的脚本示例:
#!/bin/bash # 预定义允许访问的目录 ALLOWED_DIRS=("/var/backups" "/home/data" "/opt/apps") # 处理rsync命令 if [[ "$SSH_ORIGINAL_COMMAND" =~ ^rsync\s+(.*)$ ]]; then RSYNC_ARGS="${BASH_REMATCH[1]}" # 遍历所有参数,检查路径和危险选项 for arg in $RSYNC_ARGS; do # 校验绝对路径是否在允许范围内 if [[ "$arg" =~ ^/ ]]; then ALLOWED=0 for dir in "${ALLOWED_DIRS[@]}"; do if [[ "$arg" == "$dir"* ]]; then ALLOWED=1 break fi done if [ $ALLOWED -eq 0 ]; then echo "错误:路径 $arg 不被允许" >&2 exit 1 fi fi # 禁止危险参数 if [[ "$arg" == --rsh* || "$arg" == --exec* || "$arg" == --shell* ]]; then echo "错误:危险参数 $arg 不被允许" >&2 exit 1 fi done # 校验通过,执行rsync exec rsync $RSYNC_ARGS # 处理ln命令 elif [[ "$SSH_ORIGINAL_COMMAND" =~ ^ln\s+(.*)$ ]]; then LN_ARGS="${BASH_REMATCH[1]}" # 这里可以添加ln的路径校验逻辑,比如只允许在允许的目录内操作 exec ln $LN_ARGS else echo "错误:仅允许执行rsync和ln命令" >&2 exit 1 fi最后把这个脚本配置到
authorized_keys里,比如:command="/usr/local/bin/validate_rsync.sh",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa AAAAB3NzaC1yc2E...这样你的本地脚本生成的各种rsync参数,只要符合安全规则就能正常执行,同时又锁死了权限范围。
- 先预定义一批允许访问的目录列表,解析rsync命令里的源/目标路径,只允许路径落在这些目录范围内(比如只允许
借助sudo做精细化权限控制
如果你不想写复杂的验证脚本,可以用sudo来限制用户只能执行指定参数的rsync和ln命令。比如在sudoers文件里添加类似规则:backupuser ALL=(ALL) NOPASSWD: /usr/bin/rsync --archive --compress --delete * /var/backups/*, /usr/bin/rsync --archive --compress --delete /var/backups/* *, /usr/bin/ln -s /var/backups/* /opt/links/*这里用通配符适配不同的子目录,同时固定核心参数。不过这个方案需要你调整本地脚本的rsync参数,尽量和sudo允许的格式对齐,灵活性不如第一个方案,但配置起来更简单。
切换到rsync守护进程模式
如果你能接受改变同步方式,可以放弃SSH隧道,改用rsync daemon模式。在服务器上配置rsyncd.conf,给每个需要访问的目录定义一个模块,设置好只读/读写权限、允许的IP、访问密码等。客户端直接用rsync://server/module的地址同步,不用SSH,权限控制完全由rsync daemon的配置来管理,安全性也很高。这个方案的好处是不用折腾SSH权限,缺点是需要额外配置和启动rsync服务,和你现在用SSH的同步流程有差异,需要评估是否适配你的场景。
总的来说,第一个智能验证脚本的方案最贴合你的需求——既能兼容本地脚本生成的各种rsync参数,又能严格锁死访问范围,是平衡灵活性和安全性的最优解。
备注:内容来源于stack exchange,提问作者janeden

