Linux权限
在Linux 系统中,一般习惯使用ROOT和非ROOT来表示用户(进程)的权限。ROOT 用户是指系统中 UID 为0的用户,具备最高权限。非 ROOT 用户指UID≠0的用户,通常就是我们所说的普通用户。Linux中UID又分做RUID、EUID、SUID。
RUID是真实UID, 用于在系统中标识一个用户是谁,当用户使用用户名和密码成功登录后,Linux系统唯一确定了他的RUID。
EUID表示进程运行时的有效ID,并不需要与RUID相同,用于系统决定用户对资源的访问权限。一般所说的特权进程就是EUID为0的进程。
SUID用于二进制文件对外开放权限,让程序在执行过程中拥有文件拥有者的权限 。
capabilities
什么是capabilities
Capabilities机制,是在Linux内核2.2之后引入的。它将root用户的权限细分为不同的领域,可以分别启用或禁用。从而,在实际进行特权操作时,如果euid不是root,便会检查是否具有该特权操作所对应的capabilities,并以此为依据,决定是否可以执行特权操作。
线程capabilities包含以下5个capabilities集合:
Effective:内核进行线程capabilities检查时实际使用到的集合
Inheritable:当程序对应的可执行文件设置了inheritable bit位时,调用execve执行该程序会继承调用者的Inheritable集合,并将其加入到permitted集合。但在非root用户下执行execve时,通常不会保留inheritable 集合,可以考虑使用ambient 集合,当一个程序drop掉一个capabilities时,只能通过execve执行SUID置位的程序或者程序的文件带有该capabilities的方式来获得该capabilities
permitted:effective集合和inheritable集合的超集,限制了它们的范围,因此如果一个capabilities不存在permitted中,是不可以通过cap_set_proc来获取的。当一个线程从permitted集合中丢弃一个capabilities时,只能通过获取程序可执行文件的capabilities或execve一个set-user-ID-root(以root用户权限运行的)程序来获得
ambient :是在内核4.3之后引入的,用于补充Inheritable使用上的缺陷,ambien集合可以使用函数prctl修改。当程序由于SUID(SGID)bit位而转变UID(GID),或执行带有文件capabilities的程序时会导致该集合被清空
Bounding:权限边界,Linux2.6.25引入,cap_bset。
P定义了进程能力集的上限;
E定义了实际生效的能力集,其他能力集都是为了最终影响能力集;
I 定义了可以exec方式继承的能力集(fork子进程继承父进程所有权限);P、E、I都在Linux2.6引入。
B在Linux2.6.25中引入,主要限制通过exec获得的能力,是I的超集。
- 进程运行时,不能向B添加新能力。
- 一旦能力被从B中删除,不能添加回来;
- 能力被从B中删除后,若已经在I中存在,不删除。
capabilities对应的特权操作
编号 | Capabilities list | 风险级别 | 建议 |
---|---|---|---|
1 | CAP_AUDIT_CONTROL | 中 | 谨慎使用 |
2 | CAP_AUDIT_READ | 低 | 谨慎使用 |
3 | CAP_AUDIT_WRITE | 中 | 谨慎使用 |
4 | CAP_BLOCK_SUSPEND | 低 | 正常使用 |
5 | CAP_CHOWN | 高 | 禁止使用 |
6 | CAP_DAC_OVERRIDE | 高 | 禁止使用 |
7 | CAP_DAC_READ_SEARCH | 高 | 禁止使用 |
8 | CAP_FOWNER | 高 | 禁止使用 |
9 | CAP_FSETID | 中 | 禁止使用 |
10 | CAP_IPC_LOCK | 低/无 | 正常使用 |
11 | CAP_IPC_OWNER | 中 | 禁止使用 |
12 | CAP_KILL | 中 | 禁止使用 |
13 | CAP_LEASE | 中/低 | 禁止使用 |
14 | CAP_LINUX_IMMUTABLE | 高 | 禁止使用 |
15 | CAP_MAC_ADMIN | 中/高 | 禁止使用 |
16 | CAP_MAC_OVERRIDE | 中/高 | 禁止使用 |
17 | CAP_MKNOD | 高 | 禁止使用 |
18 | CAP_NET_ADMIN | 中/高 | 谨慎使用 |
19 | CAP_NET_BIND_SERVICE | 低 | 谨慎使用 |
20 | CAP_NET_BROADCAST | 低/无 | 禁止使用 |
21 | CAP_NET_RAW | 中/低 | 谨慎使用 |
22 | CAP_SETGID | 高 | 禁止使用 |
23 | CAP_SETFCAP | 高 | 禁止使用 |
24 | CAP_SETPCAP | 高 | 禁止使用 |
25 | CAP_SETUID | 高 | 禁止使用 |
26 | CAP_SYS_ADMIN | 高 | 禁止使用 |
27 | CAP_SYS_BOOT | 中/低 | 禁止使用 |
28 | CAP_SYS_CHROOT | 高 | 谨慎使用 |
29 | CAP_SYS_MODULE | 高 | 禁止使用 |
30 | CAP_SYS_NICE | 低/无 | 正常使用 |
31 | CAP_SYS_PACCT | 低 | 正常使用 |
32 | CAP_SYS_PTRACE | 高 | 谨慎使用 |
33 | CAP_SYS_RAWIO | 高 | 禁止使用 |
34 | CAP_SYS_RESOURCE | 中/低 | 正常使用 |
35 | CAP_SYS_TIME | 低 | 谨慎使用 |
36 | CAP_SYS_TTY_CONFIG | 低 | 正常使用 |
37 | CAP_SYSLOG | 低 | 正常使用 |
38 | CAP_WAKE_ALARM | 低 | 正常使用 |
查看进程capabilities
- 通过/proc/PID/status 查看:
- 通过工具查看,例如getpcaps PID
查看文件的getcap
1 | $ getcap /bin/ping |
2 | /bin/ping = cap_net_raw+ep |
1 | $ getfattr -d -m "^security\\." /bin/ping |
2 | \# file: bin/ping |
3 | security.capability=0sAQAAAgAgAAAAAAAAAAAAAAAAAAA= |
AppArmor
AppArmor简介
AppArmor(Application Armor)是Linux内核的一个安全模块,AppArmor允许系统管理员将每个程序与一个安全配置文件关联,从而限制程序的功能。简单的说,AppArmor是与SELinux类似的一个访问控制系统,通过它你可以指定程序可以读、写或运行哪些文件,是否可以打开网络端口等。作为对传统Unix的自主访问控制模块的补充,AppArmor提供了强制访问控制机制,它已经被整合到2.6版本的Linux内核中。
Apparmor有两种工作模式:enforcement、complain/learning
Enforcement – 在这种模式下,配置文件里列出的限制条件都会得到执行,并且对于违反这些限制条件的程序会进行日志记录。
Complain – 在这种模式下,配置文件里的限制条件不会得到执行,Apparmor只是对程序的行为进行记录。例如程序可以写一个在配置文件里注明只读的文件,但Apparmor不会对程序的行为进行限制,只是进行记录。
那既然complain不能限制程序,为什么还需要这种模式呢,因为——如果某个程序的行为不符合其配置文件的限制,可以将其行为记录到系统日志,并且可以根据程序的行为,将日志转换成配置文件。当然我们可以随时对配置文件进行修改,选择自己需要的模式。
Apparmor可以对程序进行多方面的限制,这里我只介绍部分常用到的
(1)文件系统的访问控制
Apparmor可以对某一个文件,或者某一个目录下的文件进行访问控制,包括以下几种访问模式:
1 | r = read |
2 | w = write |
3 | l = link |
4 | k = lock |
5 | a = append |
6 | ix = inherit = Inherit the parent's profile. |
7 | px = requires a separate profile exists for the application, with environment scrubbing. |
8 | Px = requires a separate profile exists for the application, without environment scrubbing. |
9 | ux and Ux = Allow execution of an application unconfined, with and without environmental scrubbing. (use with caution if at all). |
10 | m = allow executable mapping. |
在配置文件中的写法,如
1 | 如 /tmp r, (表示可对/tmp目录下的文件进行读取) |
注意一点,没在配置文件中列出的文件,程序是不能访问的,这有点像白名单。
(2)资源限制
Apparmor可以提供类似系统调用setrlimit一样的方式来限制程序可以使用的资源。要限制资源,可在配置文件中这样写:
1 | set rlimit [resource] <= [value], |
其resource代表某一种资源,value代表某一个值,要对程序可以使用的虚拟内存做限制时,可以这样写:
1 | set rlimit as<=1M, (可以使用的虚拟内存最大为1M) |
注意:Apparmor可以对程序要使用多种资源进行限制(fsize,data,stack,core,rss,as,memlock,msgqueue等),但暂不支持对程序可以使用CPU时间进行限制。
(3)访问网络
Apparmor可以程序是否可以访问网络进行限制,在配置文件里的语法是:
1 | network [ [domain] [type] [protocol] ] |
了解网络编程的应该知道domain、type和protocol是什么。要让程序可以进行所有的网络操作,只需在配置文件中写:
1 | network, |
要允许程序使用在IPv4下使用TCP协议,可以这样写:
1 | network inet tcp, |
(4)capability条目
在linux的手册页里面有一个capablities列表,apparmor可以限制程序是否可以进行列表里的操作,如:capability setgid,(允许程序进行setgid操作)
1 | Capability statements are simply the word capability followed by the name of the POSIX.1e capability as defined in the capabilities(7) man page. |
配置文件的编写
前面提到,编写完配置文件后,要把文件放到/etc/apparmor.d这个目录下,其实有更方便的方法,直接在命令行里面用:
1 | sudo genprof [filename] |
就可以为指定的程序创建一个配置文件,并把它放到该目录。如:
1 | sudo genprof '/home/361way/apparmor-helper/demoexe |
建立的配置文件内容如下
1 |
|
2 | /home/361way/apparmor-helper/demoexe { |
3 | |
4 | } |
注意,该文件默认使用enforcement模式,要修改模式,只需将配置文件改为:
1 |
|
2 | /home/361way/apparmor-helper/demoexe flags=(complain){ |
3 | #include <abstractions/base> |
4 | } |
flags=(complain)前面的部分是文件的路径,作用是为这个配置文件绑定某个程序。那接下来就可以在配置文件中添加相应的内容,在大括号中加上:
1 | /home/361way/apparmor-helper/data rw, |
2 | set rlimit stack<=1M, |
然后再执行命令:
1 | sudo /etc/init.d/apparmor reload |
就可以重新加载配置文件,使配置文件生效。
apparmor的用法相关
查询当前Apparmor的状态
1 | sudo apparmor_status |
更改profile文件的状态
如果想把某个profile置为enforce状态,执行如下命令:
1 | sudo enforce <application_name> |
如果想把某个profile置为complain状态,执行如下命令:
1 | sudo complain <application_name> |
在修改了某个profile的状态后,执行如下命令使之生效:
1 | sudo /etc/init.d/apparmor restart |
profile文件的构建与管理
ubuntu发行版预定义了一些profile,可以通过如下命令安装ubuntu下的些预定义的profile文件:
1 | sudo apt-get install apparmor-profiles |
通过工具来管理profile,比较著名是:apparmor-utils,通过如下命令进行安装:
1 | sudo apt-get install apparmor-utils |
此工具最常用的两个命令为:aa-genprof和aa-logprof,前者用来生成profile文件,后者用来查询处于apparmor的日志记录,如:
1 | sudo aa-genprof slapd //生成openldap程序的profile文件 |
profile编写
1 |
|
2 | /usr/bin/kopete { //需要限制的应用程序的名称 |
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | //限制其在对家目录下几个文件的读写权限 |
10 | deny @{HOME}/.bash* rw, |
11 | deny @{HOME}/.cshrc rw, |
12 | deny @{HOME}/.profile rw, |
13 | deny @{HOME}/.ssh/* rw, |
14 | deny @{HOME}/.zshrc rw, |
15 |
|
16 | //对以下文件具有读、写、或可执行的权限 |
17 | /etc/X11/cursors/oxy-white.theme r, |
18 | /etc/default/apport r, |
19 | /etc/kde4/* r, |
20 | /etc/kde4rc r, |
21 | /etc/kderc r, |
22 | /etc/security/* r, |
23 | /etc/ssl/certs/* r, |
24 | owner /home/*/ r, |
25 | /opt/firefox/firefox.sh Px, |
26 | /usr/bin/convert rix, |
27 | /usr/bin/kde4 rix, |
28 | /usr/bin/kopete r, |
29 | /usr/bin/kopete_latexconvert.sh rix, |
30 | /usr/bin/launchpad-integration ix, |
31 | /usr/bin/xdg-open mrix, |
32 | /usr/lib/firefox*/firefox.sh Px, |
33 | /usr/lib/kde4/**.so mr, |
34 | /usr/lib/kde4/libexec/drkonqi ix, |
35 | /usr/share/emoticons/ r, |
36 | /usr/share/emoticons/** r, |
37 | /usr/share/enchant/** r, |
38 | /usr/share/kde4/** r, |
39 | /usr/share/kubuntu-default-settings/** r, |
40 | /usr/share/locale-langpack/** r, |
41 | /usr/share/myspell/** r, |
42 | owner @{HOME}/.config/** rwk, |
43 | owner @{HOME}/.kde/** rwlk, |
44 | owner @{HOME}/.local/share/mime/** r, |
45 | owner @{HOME}/.thumbnails/** rw, |
46 | owner @{HOME}/Downloads/ rw, |
47 | owner @{HOME}/Downloads/** rw, |
48 | } |
如果想更详细的学习,参见具体的讲解profile语法格式的文档,如:http://ubuntuforums.org/showthread.php?t=1008906
SElinux
什么是SELinux
SELinux(Secure Enhanced Linux):安全增强的Linux 是一个Linux安全策略机制,允许管理员更加灵活的定义安全策略。
SELinux是一个内核级的安全机制,从2.6内核之后,集成到Linux内核中。
SELinux定义了两个基本概念:
- 域:对进程进行限制;
- 上下文:对文件进行限制;
SELinux模式
SELinux 拥有三个基本的操作模式,当中 Enforcing 是缺省的模式。此外,它还有一个 targeted 或 mls 的修饰语。这管制 SELinux 规则的应用有多广泛,当中 targeted 是较宽松的级别。
- Enforcing: 这个缺省模式会在系统上启用并实施 SELinux 的安全性政策,拒绝访问及记录行动
- Permissive: 在 Permissive 模式下,SELinux 会被启用但不会实施安全性政策,而只会发出警告及记录行动。Permissive 模式在排除 SELinux 的问题时很有用
- Disabled: SELinux 已被停用
从上面不难看出,两者在强制模式上作用一样,而SELinux的宽松模式(Permissive)对应着apparmor的complain模式。
SELinux模式可以通过修改配置文件:/etc/sysconfig/selinux
进行修改。
命令getenforce可以查看当前SELinux工作模式。
命令setenforce可以修改当前SELinux工作模式。
SELinux的模式查看与修改
可以通过sestatus命令查看SELinux的状况:
可以运行如下命令,修改SELinux的运行状态:
1 | setenforce [ Enforcing | Permissive | 1 | 0 ] |
查看程序或文件的SELinux信息
常见的属于 coreutils 的工具如 ps、ls 等等,可以通过增加 Z 选项
的方式获知 SELinux 方面的信息。如:
1 | [root@PEK1000250612 ygy]# ps auxZ | grep lldpad |
2 | unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 root 48754 0.0 0.0 111636 1016 pts/0 S+ 20:10 0:00 grep lldpad |
3 | [root@PEK1000250612 ygy]# ls -Z /usr/lib/gcc/x86_64-redhat-linux/4.4.7/libgomp.so |
4 | lrwxrwxrwx. root root system_u:object_r:lib_t:s0 /usr/lib/gcc/x86_64-redhat-linux/4.4.7/libgomp.so -> ../../../../lib64/libgomp.so.1.0.0 |
配置示例
需求:让 Apache 可以访问位于非默认目录下的网站文件/data/test
1、先用semanage fcontext -l | grep '/var/www'
获知默认 /var/www
目录的 SELinux 上下文:
1 | /var/www(/.*)? all files system_u:object_r:httpd_sys_content_t:s0 |
从中可以看到 Apache 只能访问包含 httpd_sys_content_t
标签的文件。假设希望 Apache 使用 /data/test 作为网站文件目录,那么就需要给这个目录下的文件增加 httpd_sys_content_t 标签,分两步实现:
- /data/test 这个目录下的文件添加默认标签类型
1 | semanage fcontext -a -t httpd_sys_content_t '/data/test(/.*)?' |
- 用新的标签类型标注已有文件
1 | restorecon -Rv /data/test |
之后 Apache 就可以使用该目录下的文件构建网站了。
其中 restorecon 在 SELinux 管理中很常见,起到恢复文件默认标签的作用。比如当从用户主目录下将某个文件复制到 Apache 网站目录下时,Apache 默认是无法访问,因为用户主目录的下的文件标签是 user_home_t。此时就需要 restorecon 将其恢复为可被 Apache 访问的 httpd_sys_content_t 类型:
1 | restorecon -v /data/test/foo.com/html/file.html |
2 | restorecon reset /data/test/foo.com/html/file.html context unconfined_u:object_r:user_home_t:s0->system_u:object_r:httpd_sys_co |
总结
SELinux比Apparmor更安全,更灵活,同时配置起来也更复杂。SELinux与Apparmor最大的区别在于:Apparmor使用文件名(路径名)最为安全标签,而SELinux使用文件的inode作为安全标签,这就意味着,Apparmor机制可以通过修改文件名而被绕过,另外,在文件系统中,只有inode才具有唯一性。
初学者建议选择Apparmor而不是SELinux是因为 Apparmor比SELinux更简单,SElinux复杂的语法配置可能令大部分人望而生却。
参考:
http://www.361way.com/apparmor-selinux/3648.html
https://docs.docker.com/engine/security/apparmor/
http://www.linuxdiyf.com/linux/2148.html