即使是 root,目标处的 rsync 权限也存在错误,可能是由于粘滞位造成的?

即使是 root,目标处的 rsync 权限也存在错误,可能是由于粘滞位造成的?

我用rsync它来将本地文件备份到 USB 磁盘。多年来,它一直运行良好,但现在rsync却报告文件系统权限错误,尽管在 rw 文件系统上以 root 身份运行。这是我运行的命令和部分日志输出:

$ sudo rsync --verbose --archive --delete --partial --inplace /var/ /mnt/backup/var
[...]
log/postgresql/postgresql-12-main.log
log/postgresql/postgresql-12-main.log.1
log/postgresql/postgresql-12-main.log.10.gz
log/postgresql/postgresql-12-main.log.2.gz
log/postgresql/postgresql-12-main.log.3.gz
log/postgresql/postgresql-12-main.log.4.gz
log/postgresql/postgresql-12-main.log.5.gz
log/postgresql/postgresql-12-main.log.6.gz
log/postgresql/postgresql-12-main.log.7.gz
log/postgresql/postgresql-12-main.log.8.gz
log/postgresql/postgresql-12-main.log.9.gz
spool/anacron/cron.daily
tmp/
tmp/systemd-private-3bbae922a969453097f3c87f9cfcc52d-fwupd.service-iiu3gi/
tmp/systemd-private-3bbae922a969453097f3c87f9cfcc52d-fwupd.service-iiu3gi/tmp/
rsync: open "/mnt/backup/var/log/postgresql/postgresql-12-main.log" failed: Permission denied (13)
rsync: open "/mnt/backup/var/log/postgresql/postgresql-12-main.log.1" failed: Permission denied (13)
rsync: open "/mnt/backup/var/log/postgresql/postgresql-12-main.log.10.gz" failed: Permission denied (13)
rsync: open "/mnt/backup/var/log/postgresql/postgresql-12-main.log.2.gz" failed: Permission denied (13)
rsync: open "/mnt/backup/var/log/postgresql/postgresql-12-main.log.3.gz" failed: Permission denied (13)
rsync: open "/mnt/backup/var/log/postgresql/postgresql-12-main.log.4.gz" failed: Permission denied (13)
rsync: open "/mnt/backup/var/log/postgresql/postgresql-12-main.log.5.gz" failed: Permission denied (13)
rsync: open "/mnt/backup/var/log/postgresql/postgresql-12-main.log.6.gz" failed: Permission denied (13)
rsync: open "/mnt/backup/var/log/postgresql/postgresql-12-main.log.7.gz" failed: Permission denied (13)
rsync: open "/mnt/backup/var/log/postgresql/postgresql-12-main.log.8.gz" failed: Permission denied (13)
rsync: open "/mnt/backup/var/log/postgresql/postgresql-12-main.log.9.gz" failed: Permission denied (13)

sent 568,313,680 bytes  received 11,776 bytes  32,475,740.34 bytes/sec
total size is 9,562,808,631  speedup is 16.83
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1207) [sender=3.1.3]

如上所述,我以 root 身份运行此程序,并且目标文件系统已挂载 rw。请查看以下mount输出:

/dev/mapper/ubuntu--vg-root on / type ext4 (rw,relatime,errors=remount-ro)
/dev/mapper/backup-backup on /mnt/backup type ext4 (rw,nosuid,nodev,noexec,relatime,user)

请注意,rsync只有文件权限投诉目的地目录。此外,我只会观察到这些错误,如果某些文件已被已更改在源目录中。如果目标目录中缺少文件,rsync则复制它们。如果文件自上次运行以来没有更改,则rsync成功检测到并忽略它们进行复制。在这两种情况下,它都不会发出错误或警告。

上述rsync命令处理的其他文件我没有遇到太多问题。这些文件看起来都很好。

但我注意到的一件事是,失败文件的父目录已设置其粘性标志:

$ sudo ls -la /mnt/backup/var/log/postgresql/
total 48
drwxrwxr-t  2 root     postgres 4096 Mar  6 00:00 .
drwxrwxr-x 17 root     syslog   4096 Mar  6 00:00 ..
-rw-r-----  1 postgres adm         0 Mar  6 00:00 postgresql-12-main.log
-rw-r-----  1 postgres adm      1873 Mar  6 00:00 postgresql-12-main.log.1
-rw-r-----  1 postgres adm       437 Dec 12 09:37 postgresql-12-main.log.10.gz
-rw-r-----  1 postgres adm       701 Feb 27 00:00 postgresql-12-main.log.2.gz
-rw-r-----  1 postgres adm       436 Feb 20 00:00 postgresql-12-main.log.3.gz
-rw-r-----  1 postgres adm       435 Feb 13 00:00 postgresql-12-main.log.4.gz
-rw-r-----  1 postgres adm       535 Feb  6 00:00 postgresql-12-main.log.5.gz
-rw-r-----  1 postgres adm       720 Jan 30 00:00 postgresql-12-main.log.6.gz
-rw-r-----  1 postgres adm       453 Jan 23 00:00 postgresql-12-main.log.7.gz
-rw-r-----  1 postgres adm       453 Jan 13 10:49 postgresql-12-main.log.8.gz
-rw-r-----  1 postgres adm       441 Jan  5 22:00 postgresql-12-main.log.9.gz

但是我放入的其他目录也是如此rsync,并且这些目录不会导致任何错误。不用说,只要我以 root 身份执行此操作,我就可以使用其他 CLI 工具来操作上述文件,而不会遇到任何麻烦。

我感觉我一定忽略了一些非常明显的东西。有人能告诉我这里发生了什么吗?也许可以提出一些可以解决这个问题的 rsync 标志或挂载选项?

最后,以下是一些版本信息:

rsync  version 3.1.3  protocol version 31
Ubuntu 20.04.4 LTS

更新: 输出sysctl fs

$ sudo sysctl fs | grep fs.protect
fs.protected_fifos = 1
fs.protected_hardlinks = 1
fs.protected_regular = 2
fs.protected_symlinks = 1

答案1

除了其通常的含义之外,“sticky”标志还使 Linux 应用额外的保护,以预防过去的许多安全问题,这些问题是由于特权服务对共享/tmp目录的疏忽而导致的(例如,跟踪用户植入的符号链接并被诱骗覆盖 /etc 中的文件)。

  • 如果fs.protected_regularsysctl 非零,则仅有的允许文件所有者打开现有文件进行“创建 + 写入”(O_CREAT),除非这些文件与目​​录本身属于同一个 uid。

    如果fs.protected_regular设置为 2,这也适用于仅为 g+w 的目录,而不仅仅是 o+w。

  • (类似地,如果fs.protected_symlinkssysctl 非零,则粘性目录中的符号链接只能由链接所有者。例如,如果用户 A 将 /etc/passwd 符号链接到 /tmp/passwd,则只有用户 A 可以尝试打开 /tmp/passwd 符号链接;其他所有人(包括 root)均不允许。)

答案2

我发现我的问题也可以通过--inplace从命令中删除该选项来解决rsync。这将导致rsync创建一个新文件并删除旧文件。

这将比在用户1686回答(见那里的注释)。如果没有--inplacersync则永远不会真正打开现有文件进行写入,因此fs.protected_regular=2不会造成任何麻烦。

不确定这是否适用于所有具有粘性位的目录及其文件权限组合。但到目前为止对我来说是有效的。

话虽如此,我还是选择了用户 1886 的答案,因此我将其保留为接受的答案。

答案3

也许类似

查找 /mnt/backup/var type d perm /1000 print0 > sticky_dirs
xargs -0 --arg-file=sticky_dirs chmod -t
你的 同步 在此处命令
xargs -0 --arg-file=sticky_dirs chmod +t

关闭所有粘性位,然后恢复它们。

相关内容