在计算机安全中,自主访问控制(英语: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 --help
setfacl 2.2.51 -- set file access control lists
Usage: 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_acl
echo '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_test
getfacl acl_test
# file: acl_test
# owner: root
# group: root
user::rw-
group::r--
other::r--
---
# file: acl_test <==== file name
# owner: root <==== owner
# group: root <==== user_group of owner user
user::rw- <==== user::,代表owner的权限
user:user1:rwx <==== user:user1:,代表用户user1的权限
group::r-- <==== group::,代表ower所属组的权限
mask::rwx <==== 此文件默认的有效权限
other::r-- <==== 其他人拥有的权限
su - user1 -c '/opt/acl_test'
hello
su - user13 -c '/opt/acl_test'
-bash: /opt/acl_test: Permission denied
删除指定权限,并不能恢复到未设置acl前,因为还有mask的权限在,使用setfacl -b删除得才彻底
# [d[efault]:] [u[ser]:]uid
setfacl -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_test
getfacl acl_test
group:user1:r-x
mask::r-x
su - 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_test
ll 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_test
other::r-x
设置有效权限掩码
# 有效权限掩码的含义是:给user、group赋权,必须小于等于mask的权限才有效,大于的部分无效;对owner无用。
# 对user、group赋权时,默认会赋予mask权限(等于user、group权限),所以,在user、group赋权前的mask权限会被覆盖。
# [d[efault]:] m[ask][:] [:perms]
chmod u+x acl_test
setfacl -m u:xiao:rx acl_test
setfacl -m m::r acl_test
ll 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_test
user:xiao:r-x
mask::r-x
user:xiao:r-x #effective:r--
mask::r--
/opt/acl_test
hello
su - 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_test
setfacl -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: root
user::rwx
group::r-x
other::r-x
user:user1:-wx
mask::rwx
su - user1 -c 'touch /opt/acl_test/test &&ls /opt/acl_test'
ls: cannot open directory /opt/acl_test: Permission denied
su - 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 denied
setfacl -b acl_test/
rm -rf acl_test/test
setfacl -m d:u:user1:wx acl_test
getfacl acl_test/
# file: acl_test/
# owner: root
# group: root
user::rwx
group::r-x
other::r-x
default:user::rwx
default:user:user1:-wx
default:group::r-x
default:mask::rwx
default:other::r-x
mkdir acl_test/dir1
getfacl acl_test/dir1/
# file: acl_test/dir1/
# owner: root
# group: root
user::rwx
user:user1:-wx
group::r-x
mask::rwx
other::r-x
default:user::rwx
default:user:user1:-wx
default:group::r-x
default:mask::rwx
default:other::r-x
su - 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 denied
su - user1 -c 'touch /opt/acl_test/dir1/test'