如何为 rsync 创建只读用户?

如何为 rsync 创建只读用户?

我有 A 和 B Linux 服务器。我有许多用户的主目录位于 中/home

我想在 B 中运行 rsync 来/home从 A 同步。我需要考虑以下几点:

  • 我想使用 SSH 密钥验证进行 rsync。
  • 我想使用非 sudo 用户进行 rsync。
  • 用户主目录中的某些文件具有 400 权限。因此普通用户无法访问它。
  • 我不希望B能够在A中拥有写权限。

实现这一目标的最佳方法是什么?

答案1

这很棘手,而且据我所知,可能没有简单的方法可以做到这一点,同时保留 Linux 文件结构中的 400 权限。

我可能会尝试使用某种覆盖/联合金融服务,创建一个备份用户并授予该用户对 UnionFS 版本的文件系统的完全访问权限,但将 UnionFS 以只读方式挂载到该用户 - 或者如果失败,则将底层文件系统以只读方式挂载,然后丢弃在文件系统上进行的任何写入,从而允许用户使用覆盖的文件系统。

我在 Ubuntu 中对此进行了原型设计,如下所示(只进行了非常轻微的测试 - 可能需要进行调整)-

以 root 身份:

apt install unionfs-fuse
mkdir /path/to/overlayfs
unionfs -o allow_other,ro,uid=1001 /path/to/mount /path/to/overlayfs

1001与备份帐户关联的用户 ID 在哪里。ro当然表示将文件系统挂载为只读,并allow_other允许我们覆盖默认权限。

要使用 fstab 挂载它,语法很奇怪,行看起来像

unionfs#/path/to/mount=ro      /path/to/overlayfs  fuse    allow_other,ro,uid=1001        0       0

(参考:https://grangerx.wordpress.com/2010/12/31/using-fuse-unionfs-with-centos-5-5-i686/

答案2

您可以使用“强制命令”来限制通过 SSH 连接的用户可以执行的操作。这样,您就可以安全地通过 SSH 授予超级用户访问权限。您可以sshd_config使用ForceCommand选项,可能放在一个Match块中。或者您可以将其直接放入 中authorized_keys,这样您就可以创建专用的 SSH 密钥。它可能看起来像这样:

command="/var/lib/backup-operator/.ssh/allowed-commands.sh",no-port-forwarding,no-X11-forwarding,no-pty ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDcnXDtzZygrdwpxwsTe+nr7hwF6quQNkwhoROBKPagv user@client

我的脚本是这样的:

#!/bin/sh

case "$SSH_ORIGINAL_COMMAND" in
    "rsync --server --sender -vlogDtpre.iLsfxCIvu . /tank/backup/mysql/")
        exec rsync --server --sender -vlogDtpre.iLsfxCIvu . /tank/backup/mysql/
        ;;
    *)
        echo "Access denied."
        echo "$SSH_ORIGINAL_COMMAND" > /var/lib/backup-operator/last-failed-command
        exit 1
        ;;
esac

它很脆弱:新rsync版本有时需要使用不同的开关更改允许的命令。

我可以轻松添加另一个块来备份不同的目录。我还可以偷偷带入sudo(必须进行适当设置)来提升该rsync过程。


如果您想正确同步或备份主文件夹,则不得更改其 UID、GID 或权限。无论如何,获取所有文件的唯一方法是(或有相应的能力,但我从来没有用过它们)。

答案3

使用以下方式挂载文件系统,以便 rsync 只读systemd 运行。 看systemd.exec(5)了解详情。不过,此解决方案需要能够绑定挂载文件系统的特权用户。

#!/bin/sh

# Run rsync from SSH with read-only filesystems

# Execute this script from your authorized_keys file:
# command="/usr/local/sbin/rsnapshot-rsync",no-pty,no-port-forwarding,no-X11-forwarding...

case "$SSH_ORIGINAL_COMMAND" in
rsync\ *)
 systemd-run -qGP -p PrivateDevices=true -p ProtectSystem=strict $SSH_ORIGINAL_COMMAND
 ;;
*)
 echo "Access denied" 1>&2
 exit 1
 ;;
esac

或者,通过运行 rsync 来删除权限--uid <USER> $SSH_ORIGINAL_COMMAND

我简化了上述示例。我将创建一个专用用户,例如“rsnapshot”,然后使用 sudo 执行 systemd-run 或创建文件/etc/polkit-1/rules.d/50-rsnapshot.rules如果有 polkit 可用。

polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.systemd1.manage-units" &&
        subject.user == "rsnapshot") {
        return polkit.Result.YES;
    }
});

相关内容