일부 사용자가 파일을 수정하면 파일 소유자를 변경할 수 있는 방법이 있습니까?

일부 사용자가 파일을 수정하면 파일 소유자를 변경할 수 있는 방법이 있습니까?

예를 들어 user1이 파일을 생성합니다. 이 파일의 소유자는 user1입니다. user2가 파일의 내용을 수정하고 저장하는 경우. 그 후 파일 소유자는 user2로 변경됩니다. 가능합니까? 가능하다면 어떨까요?

(우분투 20.04)

답변1

해결 방법이 무엇입니까...

내 생각은 기존 Linux 감사 하위 시스템을 사용하는 것입니다. 이는 2.6일 및 이전 커널에 비해 최신 Linux에서 이미 꽤 훌륭하고 /etc/audit/audit.rules파일로 사용자 정의할 수 있습니다.

당신은 사용할 것이다보다특징보다편집할 파일과 폴더를 지정합니다. 그러면 항목으로 표시되며 /var/log/audit/audit.log다음에 따라 변경될 수 있습니다.감사 필터 키-k감사 모니터링 규칙의 옵션 사양을 기반으로 언제, 누구에 의해 발생했는지 정확하게 알 수 있습니다.

이것은 지금까지 알 수 있는 믿을 수 있는 방법이 될 것입니다. 이제 비결은 audit.log항목이 발생할 때마다 대기열에 넣은 다음 실행을 chown수행하고 명령을 실행하는 것입니다. 그런 다음 주어진 파일/폴더가 편집된 후 얼마나 자주 발생해야 합니까? 이와 같은 C 프로그램을 루트로 실행하여 1, 5 또는 15분마다 읽는 cron 작업이 필요합니까? Linux 감사를 수행하는 방법이 있는지 모르겠습니다.audit.logchownaudit.log구현하다이벤트 캡처를 기반으로 한 일부 명령(이것이 이상적인 방법인 것 같습니다).

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

이 스크립트는 기본적인 예일 뿐이며 여기서 놓쳤던 백업 복사본 보관 및 기타 보안 조치를 쉽게 구현할 수 있습니다. 프로덕션 스크립트에서는 종료 코드를 의미 있게 만들 수도 있습니다. 또한 루트에서 스크립트를 실행해야 합니다. 즉, 쉘 이스케이프를 방지하기 위해 "edit-bin"이 필요하거나(예: "vi" 없음) 실제 UID를 위해 루트에서 "edit-bin"을 실행해야 함을 의미합니다. , 루트가 아닙니다.

관련 정보