나는 최근 FreeBSD에서 이 문제에 직면했지만 ZFS가 이 문제를 해결하는 데 도움을 주신 것에 감사드립니다. 그러나 CentOS에서 ext4를 사용하여 이 문제를 다시 만났고 이를 우회할 수 있는 쉬운 방법(또는 우회할 수 있는 방법)이 있는지 궁금했습니다. 내가 원하는 것은 사용자 무능력 umask
, 잘못된 FTP 클라이언트 업로드 결정 등에 관계없이 특정 그룹의 모든 사용자에게 파일에 대한 읽기/쓰기 액세스가 보장되는 디렉토리입니다. 나는 이것이 가능하다고 생각하지 않지만 틀리고 싶습니다. 이것이 불가능해 보이는 이유는 ext4 ACL이 파일 권한을 재정의할 수 없고 오직 교차만 할 수 있기 때문입니다. 예를 들어:
# mkdir bar
# chmod 700 bar
# getfacl bar
# file: bar
# owner: root
# group: mygroup
# flags: -s-
user::rwx
group::rwx #effective:---
group:mygroup:rwx #effective:---
mask::---
other::---
default:user::rwx
default:group::rwx
default:group:mygroup:rwx
default:mask::rwx
default:other::---
기본 ACL을 볼 수 있습니다.그리고rwx
마스크는 두 가지 모두 에 대해 지정되지만 mygroup
파일 권한이 이보다 우선 ---
하므로 이는 사용자의 FTP 클라이언트(예를 들어)가 파일을 640으로 업로드하는 경우 그룹의 다른 사람들이 이를 방해할 수 없음을 의미합니다. 해결책이 있나요?
답변1
ACL에서 부여한 권한예추가적이지만 재귀적일 것으로 예상했나요? (그들은 그렇지 않다)
ACL을 사용하면 원하는 것을 거의 얻을 수 있습니다. 먼저 위와 같이 ACL을 설정해야 합니다.재귀적으로트리의 모든 파일과 디렉터리. default:group:mygroup:rwx
디렉터리에 대한 설정을 포함해야 합니다 . 이제 모든 새 디렉터리에는 해당 디렉터리 내의 새 파일과 마찬가지로 이러한 설정이 자동으로 적용됩니다.
두 개는 여전히 실패했습니다.
- 누군가가 트리 외부에서 파일이나 디렉터리를 이동할 때. inode가 이미 존재하므로 기본값이 설정되지 않습니다.
- 누군가 ACL 인식 프로그램을 사용하여 아카이브에서 파일을 추출하면 프로그램이 기본값을 재정의합니다.
주기적으로 실행되도록 크론 작업을 작성하는 것 외에는 이 두 가지 문제를 처리할 수 있는 방법이 없습니다 chgrp -R mygroup DIRECTORY; chmod g+rwx -R DIRECTORY
. 이는 공유 디렉터리의 파일 수에 따라 실용적일 수도 있고 그렇지 않을 수도 있습니다.
이것은 파일 트리에서 ACL을 수정하는 데 사용하는 스크립트를 약간 수정한 버전입니다. 특정 읽기-쓰기 및 읽기 전용 그룹 목록이 있는 트리의 모든 항목에 대해 ACL을 완전히 재정의합니다.
#! /usr/bin/env perl
use strict;
use warnings;
use String::ShellQuote;
use Cwd 'abs_path';
# Usage: fix-permissions.pl DIRECTORY RW_GROUP1,RW_GROUP2... RO_GROUP1,RO_GROUP2...
my $dir= $ARGV[0];
my @rw_groups= split ',', $ARGV[1] if $ARGV[1];
my @ro_groups= split ',', $ARGV[2] if $ARGV[2];
-d $dir or die "No such directory'$dir'\n";
$dir= abs_path($dir);
$dir =~ m|/[^/]+/| or die "Cowardly refusing to run on a top-level directory: $dir\n";
# Give all files rw-r----- and all directories rwxr-x---
# then give each rw_group read/write access, then each ro_group
# read-only access to the whole tree
my $dir_perm= join(',',
'u::rwx',
'g::r-x',
'o::---',
'd:u::rwx',
'd:g::r-x',
'd:o::---',
( map { "g:$_:rwx" } @rw_groups ),
( map { "d:g:$_:rwx" } @rw_groups ),
( map { "g:$_:r-x" } @ro_groups ),
( map { "d:g:$_:r-x" } @ro_groups )
);
my $file_perm= join(',',
'u::rwx',
'g::r-x',
'o::---',
( map { "g:$_:rw-" } @rw_groups ),
( map { "g:$_:r--" } @ro_groups )
);
for (
"find ".shell_quote($dir)." -type d -print0 | xargs -0 -r setfacl --set ".shell_quote($dir_perm),
"find ".shell_quote($dir)." ! -type d -print0 | xargs -0 -r setfacl --set ".shell_quote($file_perm)
) {
0 == system($_) or die "command failed: $_\n";
}