当某些用户修改文件时,有什么方法可以更改文件所有者?

当某些用户修改文件时,有什么方法可以更改文件所有者?

例如,user1 创建文件。该文件的所有者是 user1。如果 user2 修改该文件的内容并保存它。之后,文件的所有者更改为 user2。是否可以?如果可能的话怎么办?

(Ubuntu 20.04)

答案1

有什么办法吗...

我的想法是使用现有的 Linux 审计子系统,与 2.6 天及更早版本的内核相比,现代 Linux 中的审计子系统已经相当不错了,并且可以/etc/audit/audit.rules自定义文件。

你会使用手表特征为手表指定要编辑的文件和文件夹。然后,它将显示为一个条目/var/log/audit/audit.log,并且可以根据审核过滤键根据-k审计监视规则的选项指定,您将了解发生的具体时间和人员。

到目前为止,这将是一种可靠的了解方式。现在的技巧是audit.log每当条目发生时就排队,然后chown对所述文件/文件夹执行 a,我的第一个想法是编写自己的 C 程序,最有可能以 root 身份运行,以便能够首先读取audit.log和执行然后执行chown命令。然后,在给定的文件/文件夹编辑后,您需要多久以及多久发生一次……一个 cron 作业以 root 身份运行这样的 C 程序,audit.log每 1、5 或 15 分钟读取一次?我不知道是否有办法让linux审计执行一些基于事件捕获的命令(这似乎是理想的方式)。

关于audit.rules的快速参考:https://www.cyberciti.biz/tips/linux-audit-files-to-see-who-made-changes-to-a-file.html

/etc/audit/audit.d/rulesrhel 7 中的一个核心示例:

## First rule - delete all
-D

## Increase the buffers to survive stress events.
## Make this bigger for busy systems
# -b 8192

# set from 8k to 1mb
-b 1048576


# 2 is shutdown, 1 is runlevel 1
#

-f 2


-a always,exit -F arch=b32 -S execve -C uid!=euid -F euid=0 -k setuid
-a always,exit -F arch=b64 -S execve -C uid!=euid -F euid=0 -k setuid
-a always,exit -F arch=b32 -S execve -C gid!=egid -F egid=0 -k setgid
-a always,exit -F arch=b64 -S execve -C gid!=egid -F egid=0 -k setgid

-a always,exit -F arch=b32 -S chown -F auid>=1000 -F auid!=unset -k perm_mod
-a always,exit -F arch=b64 -S chown -F auid>=1000 -F auid!=unset -k perm_mod

-a always,exit -F arch=b32 -S chmod -F auid>=1000 -F auid!=unset -k perm_mod
-a always,exit -F arch=b64 -S chmod -F auid>=1000 -F auid!=unset -k perm_mod


-a always,exit -F arch=b32 -S setxattr -F auid>=1000 -F auid!=unset -k perm_mod
-a always,exit -F arch=b64 -S setxattr -F auid>=1000 -F auid!=unset -k perm_mod

-a always,exit -F arch=b32 -S open -F exit=-EPERM -F auid>=1000 -F auid!=unset -k access
-a always,exit -F arch=b32 -S open -F exit=-EACCES -F auid>=1000 -F auid!=unset -k access
-a always,exit -F arch=b64 -S open -F exit=-EPERM -F auid>=1000 -F auid!=unset -k access
-a always,exit -F arch=b64 -S open -F exit=-EACCES -F auid>=1000 -F auid!=unset -k access

-a always,exit -F path=/usr/sbin/semanage -F auid>=1000 -F auid!=unset -k privileged-priv_change
-a always,exit -F path=/usr/sbin/setsebool -F auid>=1000 -F auid!=unset -k privileged-priv_change
-a always,exit -F path=/usr/bin/chcon -F auid>=1000 -F auid!=unset -k privileged-priv_change
-a always,exit -F path=/usr/sbin/setfiles -F auid>=1000 -F auid!=unset -k privileged-priv_change

-w /var/run/faillock -p wa -k logins
-w /var/log/lastlog -p wa -k logins

-a always,exit -F path=/usr/bin/passwd -F auid>=1000 -F auid!=unset -k privileged-passwd
-a always,exit -F path=/usr/sbin/unix_chkpwd -F auid>=1000 -F auid!=unset -k privileged-passwd
-a always,exit -F path=/usr/bin/gpasswd -F auid>=1000 -F auid!=unset -k privileged-passwd
-a always,exit -F path=/usr/bin/chage -F auid>=1000 -F auid!=unset -k privileged-passwd
-a always,exit -F path=/usr/sbin/userhelper -F auid>=1000 -F auid!=unset -k privileged-passwd
-a always,exit -F path=/usr/bin/su -F auid>=1000 -F auid!=unset -k privileged-priv_change 
-a always,exit -F path=/usr/bin/sudo -F auid>=1000 -F auid!=unset -k privileged-priv_change 

-w /etc/sudoers -p wa -k privileged-actions
-w /etc/sudoers.d/ -p wa -k privileged-actions

-a always,exit -F path=/usr/bin/newgrp -F auid>=1000 -F auid!=unset -k privileged-priv_change
-a always,exit -F path=/usr/bin/chsh -F auid>=1000 -F auid!=unset -k privileged-priv_change

-a always,exit -F arch=b32 -S mount -F auid>=1000 -F auid!=unset -k privileged-mount
-a always,exit -F arch=b64 -S mount -F auid>=1000 -F auid!=unset -k privileged-mount
-a always,exit -F path=/usr/bin/mount -F auid>=1000 -F auid!=unset -k privileged-mount

-a always,exit -F path=/usr/bin/umount -F auid>=1000 -F auid!=unset -k privileged-mount
-a always,exit -F path=/usr/sbin/postdrop -F auid>=1000 -F auid!=unset -k privileged-postfix
-a always,exit -F path=/usr/sbin/postqueue -F auid>=1000 -F auid!=unset -k privileged-postfix
-a always,exit -F path=/usr/libexec/openssh/ssh-keysign -F auid>=1000 -F auid!=unset -k privileged-ssh
-a always,exit -F path=/usr/bin/crontab -F auid>=1000 -F auid!=unset -k privileged-cron
-a always,exit -F path=/usr/sbin/pam_timestamp_check -F auid>=1000 -F auid!=unset -k privileged-pam
-a always,exit -F arch=b32 -S create_module -k module-change
-a always,exit -F arch=b64 -S create_module -k module-change
-a always,exit -F arch=b32 -S init_module -k module-change
-a always,exit -F arch=b64 -S init_module -k module-change


-a always,exit -F arch=b32 -S delete_module -k module-change
-a always,exit -F arch=b64 -S delete_module -k module-change

-w /usr/bin/kmod -p x -F auid!=unset -k module-change
-w /etc/passwd -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/gshadow -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/security/opasswd -p wa -k identity

-a always,exit -F arch=b32 -S unlink -F auid>=1000 -F auid!=unset -k delete
-a always,exit -F arch=b64 -S unlink -F auid>=1000 -F auid!=unset -k delete

-a always,exit -F arch=b32 -S unlink,unlinkat,rename,renameat,rmdir -F auid>=1000 -F auid!=unset -k delete
-a always,exit -F arch=b64 -S unlink,unlinkat,rename,renameat,rmdir -F auid>=1000 -F auid!=unset -k delete

-a always,exit -F arch=b32 -S init_module,finit_module -k modulechange
-a always,exit -F arch=b64 -S init_module,finit_module -k modulechange

-a always,exit -F arch=b32 -S creat,open,openat,open_by_handle_at,truncate,ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=unset -k access
-a always,exit -F arch=b32 -S creat,open,openat,open_by_handle_at,truncate,ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=unset -k access
-a always,exit -F arch=b64 -S creat,open,openat,open_by_handle_at,truncate,ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=unset -k access
-a always,exit -F arch=b64 -S creat,open,openat,open_by_handle_at,truncate,ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=unset -k access

-a always,exit -F arch=b32 -S setxattr,fsetxattr,lsetxattr,removexattr,fremovexattr,lremovexattr -F auid>=1000 -F auid!=unset -k perm_mod
-a always,exit -F arch=b64 -S setxattr,fsetxattr,lsetxattr,removexattr,fremovexattr,lremovexattr -F auid>=1000 -F auid!=unset -k perm_mod

-a always,exit -F arch=b32 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=unset -k perm_mod
-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=unset -k perm_mod

-a always,exit -F arch=b32 -S chown,fchown,fchownat,lchown -F auid>=1000 -F auid!=unset -k perm_mod
-a always,exit -F arch=b64 -S chown,fchown,fchownat,lchown -F auid>=1000 -F auid!=unset -k perm_mod

答案2

好吧,从技术上讲这是可能的:用于fanotify监视您感兴趣的文件或目录,处理观察到的事件,读取每个写入事件的 pid 字段,找出该 PID 背后的用户,更改文件的所有权。但是,这需要您编写自己的程序(可能是用 C 语言)。它也会严重影响写入文件的性能。

它也感觉与 Unixoid 系统上文件的典型用法不一致。我建议寻找一种不同的方式来实现你想要实现的目标。

答案3

如果您想为文件设置某些所有者,无论谁创建或修改文件,您可能想要探索目录的“粘性位”(也称为“setuid”和“setgid”位)。

否则,您可以将所有权更改包含在编辑文件方法的调用中,类似于“sudoedit”的操作。这种方法并不是万能的,但很容易实现:

让我们假设您的用户将使用一些“编辑”来编辑相关文件。您将“edit”二进制文件移动到另一个名称(例如:“edit-bin”),然后创建一个脚本“edit”,如下所示:

#! /bin/sh

local chUser=$(get_user)
local fTmp="${1}.$$"

/path/to/edit-bin "$1"
if ! diff "$1" "$fTmp" ; then
     mv "$fTmp" "${1}"
     chown "${chUser} ${1}
fi

exit 0

该脚本只是一个准系统示例,很容易实现保留备份副本和我在这里遗漏的其他安全措施。在生产脚本中,我还会使退出代码有意义。另请注意,您需要在 root 下运行脚本,这意味着您要么需要“edit-bin”来防止 shell 转义(因此没有即“vi”),要么需要在 root 下运行“edit-bin”真正的 UID,而不是 root。

相关内容