在计算机安全中,自主访问控制(英语:discretionary access control,缩写DAC)由《可信计算机系统评估准则》[1]所定义的访问控制中的一种类型。
Linux 内核的用户授权机制也叫访问控制机制,用户身份问题和文件管理方式就是受控于这种机制。Linux 系统中的用户主要分为 root(系统管理员)和普通用户两种,并将他/她们划分到不同的群组中。而这两种用户是否能够访问系统中的某个文件则与该文件的rwx 权限属性有关。如果某个程序想要访问这个文件,Linux 内核会根据该程序的拥有者的UID和所属群组的GID与该文件UID和GID的rwx权限属性进行对比来决定是否允许操作。 Linux 这种控制文件访问的机制有一个非常好听的名字:主动访问控制,英文的叫法是 Discretionary Access Control,简称 DAC。名字虽然好听,但缺陷不少:
root 拥有特权
SUID程序的权限升级
用户可以利用程序来更改文件的存取权限(777)
上述缺陷,容易引发内部员工的误操作,而导致服务瘫痪;并且这种概率远远高于被外部攻击导致的故障。为了修复弥补上面的缺陷,引入了ACL和Extended File Attributes,但是效果有限。所以,后面便出现了MAC,这个下一篇讲述。
# chattr - change file attributes on a Linux file system
Usage: chattr [-RVf] [-+=aAcCdDeijsStTu] [-v version] files...
# lsattr - list file attributes on a Linux second extended file system
Usage: lsattr [-RVadlv] [files...]
# chattr命令中的参数,并不是所有文件系统都支持的:
Not all flags are supported or utilized by all filesystems; refer to filesystem-specific man pages such as btrfs(5), ext4(5), and xfs(5) for more filesystem-specific details.
# 所以,这里只讲两个比较有用的参数chattr --help
-R 轮询
-V 显示详情
-f 禁止大多数错误输出
-v 版本信息+:增加属性
-:删除属性
=:只能是=后的属性a:append only 文件只能追加,不能对旧的内容进行删除,目录亦如此
i:immutable 文件或目录不能改动举例:
mkdir dir1
touch dir1/test
touch: cannot touch ‘dir1/test’: Permission denied
chattr -i dir1/
touch dir1/test &&ll dir1/
total 0
-rw-rw-r--+ 1 root root 0 Mar 20 21:14 test
在计算机安全性中,访问控制列表 (ACL) 是与系统资源(对象)关联的权限列表。ACL 指定向哪些用户或系统进程授予对对象的访问权限,以及允许对给定对象执行哪些操作。这里的ACL专指文件系统访问控制列表。故,只对用户授予文件对象的访问权限。
文件系统 ACL 是一种数据结构(通常是表),其中包含指定单个用户或组对特定系统对象(如程序、进程或文件)的权限的条目。这些条目访问控制条目(ACE)。
文件系统ACL是对DAC的一种补充,提供传统的ower、group、other的读、写、执行权限之外的详细权限设置。ACL 可以针对单一用户、单一文件或目录录来进行r、w、x的权限设置,对于需要特殊权限的使用状况非常有帮助。
目前ACL几乎已经默认加入了所有常见的 Linux文件系统的挂载参数中(ext2、ex3.ext4、xfs 等)。
# 查看内核是否加载ACL
# dmesg |grep -i '\bacl'[ 1.804912] systemd[1]: systemd 219 running in system mode. (+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 -SECCOMP +BLKID +ELFUTILS +KMOD +IDN)[ 3.368134] SGI XFS with ACLs, security attributes, no debug enabled
getfacl:获取某个文件/目录的 ACL 设置选项;
setfacl:设置某个目录/文件的 ACL 规范。
# setfacl --helpsetfacl 2.2.51 -- set file access control listsUsage: setfacl [-bkndRLP] { -m|-M|-x|-X ... } file ...-m, --modify=acl modify the current ACL(s) of file(s)-M, --modify-file=file read ACL entries to modify from file-x, --remove=acl remove entries from the ACL(s) of file(s)-X, --remove-file=file read ACL entries to remove from file-b, --remove-all remove all extended ACL entries-k, --remove-default remove the default ACL--set=acl set the ACL of file(s), replacing the current ACL--set-file=file read ACL entries to set from file--mask do recalculate the effective rights mask-n, --no-mask don't recalculate the effective rights mask-d, --default operations apply to the default ACL-R, --recursive recurse into subdirectories-L, --logical logical walk, follow symbolic links-P, --physical physical walk, do not follow symbolic links--restore=file restore ACLs (inverse of `getfacl -R')--test test mode (ACLs are not modified)-v, --version print version and exit-h, --help this help text
touch test_aclecho 'echo "hello"' >acl_test
设置用户访问权限
# [d[efault]:] [u[ser]:]uid [:perms]# For uid and gid you can specify either a name or a number.# 为acl_test文件,设置用户user1具有rwx权限setfacl -m u:user1:rwx acl_test # acl设置前后权限变化,除了会添加user的权限,还有添加mask权限ll test_acl -rw-r-----. 1 root root 13 Mar 20 18:38 acl_test-rw-rwxr--+ 1 root root 13 Mar 20 18:41 acl_testgetfacl acl_test # file: acl_test# owner: root# group: rootuser::rw-group::r--other::r-----# file: acl_test <==== file name# owner: root <==== owner# group: root <==== user_group of owner useruser::rw- <==== user::,代表owner的权限user:user1:rwx <==== user:user1:,代表用户user1的权限group::r-- <==== group::,代表ower所属组的权限mask::rwx <==== 此文件默认的有效权限other::r-- <==== 其他人拥有的权限su - user1 -c '/opt/acl_test'hellosu - user13 -c '/opt/acl_test'-bash: /opt/acl_test: Permission denied
删除指定权限,并不能恢复到未设置acl前,因为还有mask的权限在,使用setfacl -b删除得才彻底
# [d[efault]:] [u[ser]:]uidsetfacl -x u:user1 acl_test
设置组访问权限
# [d[efault]:] g[roup]:gid [:perms]setfacl -m g:user1:rx acl_test # acl设置前后权限变化ll test_acl -rw-r-----. 1 root root 13 Mar 20 18:38 acl_test-rw-r-xr--+ 1 root root 13 Mar 20 19:03 acl_testgetfacl acl_test group:user1:r-xmask::r-xsu - user1 -c '/opt/acl_test'hello
设置other权限,这个口子开得有点大,效果同chmod o+rx acl_test效果同,所以直接chmod即可,不建议用setfacl,并且这种使用setfacl -b都删不掉,得用chmod o-rx 才行
# [d[efault]:] o[ther][:] [:perms]setfacl -m o::rx acl_testll test_acl -rw-r-----. 1 root root 13 Mar 20 18:38 acl_test-rw-r--r-x. 1 root root 13 Mar 20 19:03 acl_testother::r-x
设置有效权限掩码
# 有效权限掩码的含义是:给user、group赋权,必须小于等于mask的权限才有效,大于的部分无效;对owner无用。
# 对user、group赋权时,默认会赋予mask权限(等于user、group权限),所以,在user、group赋权前的mask权限会被覆盖。
# [d[efault]:] m[ask][:] [:perms]chmod u+x acl_testsetfacl -m u:xiao:rx acl_test setfacl -m m::r acl_testll acl_test -rwxr--r--. 1 root root 13 Mar 20 19:03 acl_test-rwxr-xr--+ 1 root root 13 Mar 20 19:03 acl_test-rwxr--r--+ 1 root root 13 Mar 20 19:03 acl_testuser:xiao:r-xmask::r-xuser:xiao:r-x #effective:r--mask::r--/opt/acl_test hellosu - xiao -c '/opt/acl_test'-bash: /opt/acl_test: Permission denied
ACL的权限被子目录继承
# 默认是不继承父目录的ACL权限的
# 必须设置default权限才会被子目录及其文件继承,default权限赋予的目标必须是目录才可以:setfacl: acl_test: Only directories can have default ACLs
rm -rf acl_test mkdir acl_testsetfacl -m u:user1:wx acl_test <======= 虽然o:r-x权,但是只赋予u:user1:w是不行的ll -d acl_test/drwxr-xr-x. 2 root root 6 Mar 20 20:00 acl_test/drwxrwxr-x+ 2 root root 6 Mar 20 20:00 acl_test/getfacl acl_test/# file: acl_test/# owner: root# group: rootuser::rwxgroup::r-xother::r-xuser:user1:-wxmask::rwxsu - user1 -c 'touch /opt/acl_test/test &&ls /opt/acl_test'ls: cannot open directory /opt/acl_test: Permission deniedsu - user13 -c 'ls /opt/acl_test' -rw-rw-r--. 1 user1 user1 0 Mar 20 20:05 test # 可以看到文件并没有继承父目录的acl权限su - user13 -c 'touch /opt/acl_test/test2'touch: cannot touch ‘/opt/acl_test/test2’: Permission deniedsetfacl -b acl_test/rm -rf acl_test/test setfacl -m d:u:user1:wx acl_testgetfacl acl_test/# file: acl_test/# owner: root# group: rootuser::rwxgroup::r-xother::r-xdefault:user::rwxdefault:user:user1:-wxdefault:group::r-xdefault:mask::rwxdefault:other::r-xmkdir acl_test/dir1getfacl acl_test/dir1/# file: acl_test/dir1/# owner: root# group: rootuser::rwxuser:user1:-wxgroup::r-xmask::rwxother::r-xdefault:user::rwxdefault:user:user1:-wxdefault:group::r-xdefault:mask::rwxdefault:other::r-xsu - user1 -c 'touch /opt/acl_test/test' # d:u:user1:wx权限只设置到了默认权限中,对父目录无 # 效,只能单独执行一次:setfacl -m u:user1:rwx acl_test才可以touch: cannot touch ‘/opt/acl_test/test’: Permission deniedsu - user1 -c 'touch /opt/acl_test/dir1/test'