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集合:

  1. Effective:内核进行线程capabilities检查时实际使用到的集合

  2. Inheritable:当程序对应的可执行文件设置了inheritable bit位时,调用execve执行该程序会继承调用者的Inheritable集合,并将其加入到permitted集合。但在非root用户下执行execve时,通常不会保留inheritable 集合,可以考虑使用ambient 集合,当一个程序drop掉一个capabilities时,只能通过execve执行SUID置位的程序或者程序的文件带有该capabilities的方式来获得该capabilities

  3. permitted:effective集合和inheritable集合的超集,限制了它们的范围,因此如果一个capabilities不存在permitted中,是不可以通过cap_set_proc来获取的。当一个线程从permitted集合中丢弃一个capabilities时,只能通过获取程序可执行文件的capabilities或execve一个set-user-ID-root(以root用户权限运行的)程序来获得

  4. ambient :是在内核4.3之后引入的,用于补充Inheritable使用上的缺陷,ambien集合可以使用函数prctl修改。当程序由于SUID(SGID)bit位而转变UID(GID),或执行带有文件capabilities的程序时会导致该集合被清空

  5. 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 查看:

img

  • 通过工具查看,例如getpcaps PID

img

查看文件的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
#include <tunables/global>  
2
/home/361way/apparmor-helper/demoexe {     
3
   #include <abstractions/base>
4
}

注意,该文件默认使用enforcement模式,要修改模式,只需将配置文件改为:

1
#include <tunables/global>  
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

img

更改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
#include <tunables/global>
2
/usr/bin/kopete {  //需要限制的应用程序的名称
3
#include <abstractions/X>
4
#include <abstractions/audio>
5
#include <abstractions/base>
6
#include <abstractions/kde>
7
#include <abstractions/nameservice>
8
#include <abstractions/user-tmp>
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的状况:

img

可以运行如下命令,修改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/

https://blog.csdn.net/ggf123456789/article/details/36686929?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

http://www.linuxdiyf.com/linux/2148.html