安胜系统安全配置功能测试

启动并登录系统

安装完成 VMware Workstation 后可以直接打开 vmx 虚拟机文件,启动后使用用户名密码登录。VMware 虚拟机的网络默认配置为 NAT 模式。打开终端,使用 dhclient 连接网络。

可以看到获取到的 IP 地址为 192.168.245.128.

打开 系统设置 -> 安全级别,在弹出的窗口中勾选允许进入中的 SSH,确定后退出。

此时可以在宿主机使用 SSH 登录虚拟机,方便操作。

如遇乱码,可以在 /etc/profile 文件末尾加上 export LANG=zh_CN.UTF-8 设置字符编码为 UTF-8。

熟悉相关安全机制和常用的安全管理命令

标识与鉴别机制

安胜在普通 Linux 的基础上,将用户的安全信息保存 /etc/security/TCB/ia 下,文件 index、master 分别是库检索文件和用户配置安全库文件。用户的安全信息包括以下几项:

  • 用户名
  • 用户所拥有的安全级集合
  • 用户的审计掩码
  • 用户 id
  • 用户 shell
  • 用户主目录
  • 用户所属主组,辅组

修改 useradd、userdel、usermod 等命令,加入对用户安全档的管理操作。通过这些命令,在 /etc/security 目录下建立用户的安全文件档,它与 /etc/passwd 文件相对应,表明系统中每个用户的安全级范围,审计屏蔽码等。

管理员可对用户信息进行管理和修改(命令 ia_verify)。

修改用户登录进程,它不仅检查用户的登录名和口令、赋予用户唯一标识 uid、gid,还检查用户的安全级,赋予用户进程安全级。

用户标识与鉴别机制检查该安全级是否在安全文件档中定义的该用户安全级范围之内。若是,则认可,否则拒绝该次登录。若用户没有选择安全级,系统则从取出该用户的缺省安全级赋给用户。当标识与鉴别机制确认用户的登录名、口令和安全级都正确后,便允许用户登录。

用户标识和鉴别机制还具有可选的身份卡鉴别功能,对用户登录系统做进一步安全检查。仅当用户口令正确,并且用户身份卡正确时,用户才可以登录系统。

相关命令

useradd

  • 添加用户,赋予用户安全级,主目录安全级和审计事件集
  • 显示用户的缺省信息
  • 修改用户的缺省信息

命令格式:

1
2
useradd [-a event[,...]] [-h [+|-]level [...]] [-v def_level] [-w homedir_level] name
useradd -D [-v def_lvl] [-a event[,...]]

参数说明:

  • -h 添加用户安全级(一个或多个)
  • -v 设置用户缺省安全级(若未设,取系统缺省值)
  • -w 设置用户主目录安全级(若未设,取缺省安全级)
  • -a 设置用户审计事件集

语法说明:

  1. 若设 -h level1 -h level2 … -v def_level,此时 def_level 应属于所设安全级的集合。
  2. 若只设 -h,语法错误
  3. 若只设 -v,则用户安全集中只有所设的一个安全级,并且为缺省安全级
  4. -h-v 均不设定,此时分两种情况
    1. /etc/default/useradd 文件中 DEFLVL 项不为空,取其为用户缺省安全级,并将其设为用户唯一的安全级
    2. /etc/default/useradd 文件中 DEFLVL 项为空,系统显示出错信息
  5. 若未设定 -m(创建用户主目录),不允许设定 -w (设用户主目录安全级)
  6. 若设定 -w,所设目录安全级必须属于 -h 设定的安全集合,若未设定 -w,则目录安全级设为缺省安全级。
  7. -a 设置审计事件
    1. -a event1,event2…  设审计事件 event1,event2
    2. -a all 设审计所有事件
    3. -a none 所有事件均不审计
    4. 若不设 -a  将设为上述缺省文件中 AUDIT_MASK 所设的缺省值
  8. -D 配置默认值(实际上是修改上述默认配置文件)
    1. -D -v new_deflvl 修改系统缺省安全级为 new_deflvl
    2. -D -a new_auditevents 修改系统缺省审计掩码为 new_auditevents

usermod

  • 增加,删减,替换用户原有安全级集合
  • 修改用户缺省安全级
  • 增加,删减,替换用户原有审计事件集

命令格式:

1
2
usermod [-h [operator2]level [...]][-v def_level][-a [operater1]event[,...]] name
其中operater为 + -

语法说明:

  1. 增加用户安全级时,operater 为 +,只要安全级的表达正确,即使与用户原有安全级集合中某些项重复,系统会自动滤去多余项
  2. 删减用户安全级时,operater 为 -,只要安全级的表达正确,即使要删减的安全级在用户安全级集合中不存在,系统会自动忽略这些不合法的安全级
  3. 若将缺省安全级删除,又未指定新的缺省安全级,此时,缺省安全级将是用户安全级集合中的第一个安全级;
  4. 若指定的新缺省安全级在即将要删除的安全级集合内,将提示语法错误,拒绝执行;
  5. -a 修改审计事件
    1. -a +event1,event2,…  增加 event1,event2,… 入审计事件级;
    2. -a -event1,event2,… 对 event1,event2,… 不再审计;
    3. -a event1,event2,… 用 event1,event2,… 替换当前用户审计事件集;
    4. -a all 对所有的事件均审计;
    5. -a none 对所有事件均不审计。

userdel

userdel [-r] name:删除用户。缺省情况下,删除用户将不删除用户主目录,使用 -r 参数即可删除。

login

本地用户登录。登录时要求输入用户名,密码,本次登录安全级,系统将检查该用户是否存在,账号是否过期,是否被封,用户登录失败次数是否超过系统设置的最大上限,密码的正确性,输入安全级是否在该用户拥有的安全级范围内,是否在登录设备所允许的安全级范围内。若用户不输入安全级,将使用它的缺省安全级。这一切检查通过后,本次登录的安全级将设为该用户的缺省安全级,登录的安全级将设为该用户的缺省安全级,并置入用户进程,同时置入进程的还有用户的审计掩码。

执行后会询问以下信息用以登录:

1
2
3
sec-loginusername
Password:
User Level:[mac_level]

ia_userinfo

这是新增加的命令,用来查看与用户相关的标识鉴别信息。显示的信息实例如下:

1
2
3
4
5
6
7
uid     : 30019(test)
gid     : 100(users)
sgroups :
home    : /home/test
shell   : /bin/bash
level 1(default): USER_LOGIN
auditmask: fork,exec,login_ok
  • ia_userinfo username:列出用户 username 的标识鉴别库信息,包括 uid、组、辅助组、主目录、shell 以及安全级信息等。
  • ia_userinfo -a:列出所有用户的标识鉴别库信息。

ia_initfaillog

这是新增加的命令,用来在 /var/audit/ 目录下建立 faillogfile 文件,并且将当前用户的登录失败次数设初值为 0。

ia_verify

新增加的命令,用来校验系统用户文件与系统的标识鉴别库的一致性。校验的内容包括是否用户在标识鉴别库中有一条目,信息是否一致;以及系统用户文件的安全级别设定是否正确。

命令格式:

  • ia_verify -u [-y|-n] username:校验用户 username。
  • ia_verify -u [-y|-n]:校验所有用户
  • ia_verify -m [-y|-n]:校验系统用户信息文件的安全级,以保证非特权用户能正常地使用标识鉴别命令。
  • ia_verify -a [-y|-n]:校验所有用户,同时校验系统用户文件的安全级。

在执行中,如果发现不一致,程序会询问用户是否进行更改。如果设定了 -y 参数,表示对所有的询问均回答 yes;如果设定了 -n 参数,标识对所有的询问均回答 no。-y-n 不能同时设定。

lvladm

设置或显示安全级,在 MAC 中详细介绍。可以不加参数使用以查看所有现有安全级。

自主访问控制 (DAC) 机制

在普通 Linux 中,用户(客体的拥有者)不能够精确控制某个用户对此客体的访问权,如不能够指定同组的用户 A 能够对该客体具有读、写、执行权限,而同组的用户 B 不可以对该客体有任何权限。而在可信计算机系统中,必须做到这一点。

为此,安胜利用 ACL 机制来实现对客体访问的精确控制(粒度)。同时,仍保留 Linux 系统本身设计的访问控制权限,使 Linux 保护表示 (owner-group-other) 和 ACL 保护表示共存于系统之中,以实现自主存取控制,较 Linux 保护表示具有更细的控制粒度,达到可信计算机系统的要求。

安胜扩展了 ACL,让你允许或者拒绝对多重用户和组的访问允许。安胜中的 ACL 允许文件的拥有者可以区别谁可以谁不可以访问。有五个级别(五类用户)可以允许或者拒绝访问,分别用宏做以标记:

  • 客体拥有者(ACL_USER_OBJ)
  • 单个用户(ACL_USER)
  • 所属的组(ACL_GROUP_OBJ)
  • 其它组(ACL_GROUP)
  • 其它用户或组(ACL_OTHER_OBJ)
  • 屏蔽位(ACL_MASK_OBJ)

其中,ACL_USER、ACL_GROUP 为(除普通 Linux 自带的以外的)扩展项,ACL_MASK_OBJ 用于屏蔽 ACL_USER 和所有的组 (ACL_GROUP 和 ACL_GROUP_OBJ),限制 ACL_MASK_OBJ 限制扩展 ACL 的用户和组的可用允许。对用户的最独特的条目是将要判断访问。(说的什么东西,谁能来个中译中?)(根据下述的检查算法,ACL_MASK_OBJ 应该是能通过 ACL_USER、ACL_GROUP 与 ACL_GROUP_OBJ 取得的最大权限,若 ACL_MASK_OBJ 中没有给予相应权限,即使上述三个级别给了权限也没用。此处存疑,似乎前面说的和算法伪代码给的有冲突。)

安全策略

在安胜自主访问控制(DAC)的实现中,主体对客体的访问需遵循如下安全检查机制:

对 ACL 的检查优先权从高到低为:

  1. ACL_USER_OBJ
  2. ACL_OTHER_OBJ
  3. ACL_GROUP 和 ACL_OTHER_OBJ
  4. ACL_OTHER_OBJ

检查算法为:(以进程对文件的访问为例)

1
2
3
4
5
6
7
if 进程的 euid 和文件的属主相符
then 权限=ACL_USER_OBJ;
else if 进程的 euid 和 ACL_USER 项中的用户相符
then 权限=(相应项的 ACL_USER 权限)&(ACL_MASK_OBJ);
else if 进程符合 ACL_GROUP 或 ACL_OTHER_OBJ 项中的用户
then 权限=(相应项的 GROUP 权限)&(ACL_MASK_OBJ);
else 权限=ACL_OTHER_OBJ;

例如:

1
2
3
4
5
6
7
8
9
10
[root@t116 llp]# getfacl testfile
#file: testfile
#owner: testuser
#group: secgrp
user::rw-                        // ACL_USER_OBJ
user:lisa:rwx    #effective:r-x  // ACL_USER
group::rw-       #effective:r--  // ACL_GROUP_OBJ
group:bin:r-x                    // ACL_GROUP
mask::r-x                        // ACL_MASK_OBJ
other::r-x                       // ACL_OTHER_OBJ

当某项的权限与 mask 值冲突时,#后的内容列出该行主体的有效权限用户,如:lisa 对文件 testfile 的访问权限为:(rwx)&(r-x)=(r-x)。// 后的内容为注释。

进程对客体访问时,首先要根据以上方法判断其对客体的 DAC 访问权限,以决定是否能通过 DAC 检查。

DAC 的继承性

目录的 ACL

目录的 ACL 除了上述普通文件的六项外,附加了另外四项,分别为:

  • DEFAULT_ACL_USER
  • DEFAULT_ACL_GROUP
  • DEFAULT_ACL_MASK
  • DEFAULT_ACL_OTHER

新创建客体的默认 ACL

当在具有该四项扩展项的目录下生成文件和目录时,新生成客体的 ACL 项继承规则如下:

当生成子目录时,子目录继承父目录的所有 ACL 项;

当生成文件时,ACL_USER_OBJ 是通过请求创建的权限和系统属主屏蔽位相与获得 ACL_GROUP_OBJ 是通过请求创建的权限和系统同组屏蔽位相与获得。而其余项,当父目录存在 ACL_MASK_OBJ 时,则要与其相与,而不考虑 umask。当父目录不存在 ACL_MASK_OBJ,则考虑 umask。

目录的 ACL 可继承性保证了新创建的客体可拥有 ACL 项,方便系统管理。目录的缺省 ACL 不影响对目录的访问。

DAC 命令使用

setfacl

供拥有权限的用户在指定文件或目录的存取控制表 ACL 中设置系统中一用户或组的存取权限。

命令格式:

1
2
setfacl [-bkndRLPvh] [{-m|-x} acl_spec] [{-M|-X} acl_file] file ...
setfacl --restore=file

命令描述:该命令用于设置指定文件或目录的存取控制表 ACL。

  • 选项 --set-m-x 要求指定 ACL,并从文件或其它标准输入读取 ACL。各个要访问的 ACL 项由 , 分隔开。使用选项 --set-m 时,setfacl 也可接受 getfacl 的输出作为输入。
  • 选项 --set--set-file 用于重置文件或目录的 ACL,文件或目录原先的 ACL 被替换;
  • 选项 -m(--modify)-M(--modify-file) 用于修改文件或目录的 ACL;
  • 选项 -x(--remove)-X(--remove-file) 用于删除文件或目录的 ACL 项。
  • 选项 --restore=file 用于从 getfacl -R 产生的备份恢复 ACL,使用该选项整个目录树的访问权限都将被修改。

使用权限:文件所有者和其它对文件或目录拥有写权限的进程可以设置文件或目录的 ACL。

其它可选选项:

  • -b, --remove-all:删除文件或目录的 ACL 中除基本的 ACL 项:ACL_USER_OBJ、ACL_GROUP_OBJ、ACL_OTHER_OBJ 以外的所有项。
  • -k, --remove-default:删除目录的 ACL 中的所有 DEFAULT 项。
  • -n, --no-mask:加了这种选项后,ACL 设置操作不会自动重新生成有效的 ACL_MASK_OBJ。而只要未明确地指定新 ACL_MASK_OBJ 值,setfacl 命令默认通过对所有 ACL_USER 和 ACL_GROUP 进行与操作来计算新 ACL_MASK_OBJ 值。
  • --mask:重新生成有效的 ACL_MASK_OBJ,即便已明确地指定新 ACL_MASK_OBJ 值。
  • -d, --default:所有的设置操作都对 ACL 的 DEFAULT 项进行。命令输入中对普通 ACL 项的操作改为对 DEFAULT 项进行,而输入中的 DEFAULT 项被忽略。
  • --test:使用该选项 setfacl 命令不会真正修改文件活目录的 ACL,而只是把受影响的 ACL 列出。
  • -R, --recursive:对指定目录及其下的所有文件和目录沿目录树进行递归遍历式的 ACL 设置操作。该选项不能与--restore 合用。
  • -L, --logical:当对目录树作递归遍历时,将沿着逻辑路径,即会进入遇到的符号链接,而默认操作是跳过这些符号链接。该选项不能与 --restore 合用。
  • -P, --physical:沿物理路径设置文件或目录的 ACL,跳过所有的符号链接,包括参数中的符号链接。该选项不能与 --restore 合用。
  • --version:显示 setfacl 的版本号。
  • --help:显示帮助信息。
  • --:在命令行输入中表示已列出所有选项,输入中所有剩余参数都将被理解为文件或目录名,即使它们以 - 开始。
  • -:如果输入中的文件名参数只是一个 -setfacl 将从标准输入读取文件。

ACL 项:

  • [d[efault]:] [u[ser]:]uid [:perms]:设置一个命名用户的权限。如果参数 uid 为空,则为文件所有者的权限。
  • [d[efault]:] g[roup]:gid [:perms]:设置一个命名用户组的权限。如果参数 gid 为空,则为文件所有者组的权限。
  • [d[efault]:] m[ask][:] [:perms]:设置有效 mask 项。
  • [d[efault]:] o[ther][:] [:perms]:设置 ACL_OTHER 或 DEFAULT_ACL_OTHER 项。

示例:

  • 受予一个用户读文件权限:setfacl -m u:user:r file
  • 收回所有 ACL_USER、ACL_GROUP 的写权限:setfacl -m m::rx file
  • 从文件的 ACL 中删除一个组的 ACL 项:setfacl -x g:group file
  • 从一个文件复制 ACL 到另一个文件:getfacl file1 | setfacl -S- file2
  • 从目录的 ACL 复制权限到 ACL 中的默认项:getfacl -a dir | setfacl -d -M- dir
  • 从 getfacl -R 命令产生的备份恢复目录树的 ACL:getfacl -R dir > aclbak, setfacl -restore=aclbak

getfacl

读取文件或目录的存取控制表 ACL 的内容。

命令格式:

1
2
getfacl [-dRLPvh] file ...
getfacl [-dRLPvh] -

getfacl 能显示参数中每个文件或目录的所有者,用户组及存取控制表 ACL。当要显示多个文件或目录的 ACL 时,各 ACL 用空行隔开。getfacl 的输出可作为 setfacl 的输入。

使用权限:对文件或目录有搜索权限(也就是说对文件或目录的父目录有读权限)的进程可以使用该命令。

选项说明:

  • --access:显示 ACL。
  • -d, --default:显示 DEFAULT ACL 项。
  • --omit-header:不在 ACL 前显示文件名,所有者和所有者用户组,而默认将显示这 3 项。
  • --all-effective:显示所有项的有效权限,即使该项在 ACL 中定义的权限并不与 ACL_MASK_OBJECT 冲突(此时默认不显示)。
  • --no-effective:不显示 ACL 项的有效权限。
  • --skip-base:对 ACL 中只有 3 项基本的 ACL 项:ACL_USER_OBJ、ACL_GROUP_OBJ、ACL_OTHER_OBJ 的文件或目录将跳过不显示。
  • -R, --recursive:对指定目录及其下的所有文件和目录沿目录树进行递归遍历访问,并显示它们的 ACL。
  • -L, --logical:当对目录树作递归遍历时,将沿着逻辑路径,即会进入遇到的符号链接,而默认操作是跳过这些符号链接。
  • -P, --physical:沿物理路径访问文件或目录的 ACL,跳过所有的符号链接,包括参数中的符号链接。
  • --tabular:使用另一种列表显示风格。在这种风格中,普通 ACL 项和 DEFAULT ACL 项将并列显示;ACL 项与 ACL_MASK_OBJECT 冲突的权限将大写显示;ACL_USER_OBJ 项和 ACL_GROUP_OBJ 项的名字(user,group)也将大写显示。
  • --version:显示 getfacl 的版本号。
  • --help:显示帮助信息。
  • --:在命令行输入中表示已列出所有选项,输入中所有剩余参数都将被理解为文件或目录名,即使它们以“-”开始。
  • -:如果输入中的文件名参数只是一个“-”,getfacl 将从标准输入读取文件。

示例:命令:getfacl testdir

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# file: testdir/
# owner: lisa
# group: staff
user::rwx
user:joe:rwx            #effective:r-x
group::rwx              #effective:r-x
group:cool:r-x
mask:r-x
other:r-x
default:user::rwx
default:user:joe:rwx    #effective:r-x
default:group::r-x
default:mask:r-x
default:other:---

强制访问控制 (MAC) 机制

强制存取控制(MAC)机制是用于将系统中的信息分密级和类进行管理,保证每个用户只能够访问那些被标明能够由他访问的信息的一种访问约束机制。它对系统中的每个进程、每个文件、每个 IPC 客体赋予相应的安全标签(安全级)。当一进程访问一个客体时,根据进程的安全标识和访问方式,比较进程的安全标签和文件的安全标签,从而确定是否允许进程对文件的访问。

安全标签

定义

安胜安全操作系统中,每个主体和客体的安全标签包含两个清晰的部分:

  1. 级别(Hierarchy)
    • 级别部分反映出来的是一种等级关系。由于级别是唯一的,所以我们在实现时以数字从小到大依次递增表示。
  2. 范畴(Categories)
    • 范畴部分是无等级概念的元素组成的,表示一清晰的信息领域。其无等级是指不存在一范畴“大于”另一范畴,如不能说“红色”大于或小于“蓝色”。范畴是一集合,范畴之间的关系是包含、被包含、相等。它可以包含任何表示范畴的数字,在实现中我们以一数字的集合表示。

关系判断

两个安全标签 A 和 B 相互关系的定义:

  • A 支配 B:当且仅当 A 的级别(hierarchy)大于等于 B 的级别,A 的范畴包含 B 的范畴,即 B 的范畴是 A 的范畴的一个子集。
  • A 等于 B:当且仅当 A 的级别等于 B 的级别,A 的范畴中的任何一项也是 B 的范畴中的一项,反之亦然。也即 A 支配 B,B 支配 A。
  • A 与 B 无关:以上任何一条均不符合。

安全策略

文字描述

一进程(主体)要想访问客体,其安全标签必须具备:

  • 若想要对客体具有写访问权限,主体的安全级(级别 + 范畴)必须等于客体的安全级(主体的级别 = 客体的级别,主体的范畴 = 客体的范畴)。
  • 若想要对客体具有读权限,主体的安全级(级别 + 范畴)必须支配客体的安全级(主体的级别 >= 客体的级别,主体的范畴 >= 客体的范畴)。

如果进程(主体)不能够满足上面的任何一条要求,则不能够访问客体。

算法描述

以 CLASS(S)、CLASS(O) 表示主体与客体的安全级,强制性安全策略定义为:

1
2
3
4
(1) if CLASS(S)>=CLASS(O)
then Read(S,O) or Execute(S,O);
(2) if CLASS(S)=CLASS(O)
then Write(S,O) or Append(S,O);

安全级由级别和范畴两部分组成,分别以 S.l、S.c 表示主体的级别和范畴,O.l、O.c 表示客体的级别和范畴,授权规则可表示如下:

1
2
当(S.l>=O.l)且(S.c 包含 O.c)时,主体可以读(执行)客体;
当(S.l=O.l)且(S.c=O.c)时,主体可以写客体。 

管理和操作

安全级数据库

安全级数据库的创建、管理是由超级用户管理员来进行的。它可对数据库进行增删改操作。并可查询、浏览数据库。

系统第一次安装时,会为安全级数据库设置初始状态(命令 lvlinit),如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[root@t116 source]# lvladm
Levels:
1 SYS_PUBLIC:: system
2 SYS_ADMIN:: system: admin
3 SYS_RANGE_MAX:: range_max: ALL
4 USER_PUBLIC:: user
5 USER_LOGIN:: user: login
6 SYS_AUDIT:: system: audit
7 SYS_OPERATOR:: system: operator
8 SYS_RANGE_MIN:: range_min
9 SYS_WWW:: system: www
10 SYS_MYSQL:: system: mysql

Hierachies:
1: range_min
2: system
4: user
256: range_max

Categories:
1: admin
2: audit
3: login
4: operator
5: www
6: mysql

主体 MAC

安胜系统中,每个用户均有安全级范围和默认安全级。用户的安全级是在系统管理员创建用户(使用 useradd 命令)时设置,在用户安全文件档中为每个用户建立一项,表明用户的安全级范围,并说明用户的缺省安全级。

主体(进程)的安全级在登录后创建进程时确定,进程的安全级在其代表用户的安全级范围之内。用户登陆时(如:login ),在用户不进行选择的情况下,采用用户的默认安全级。

用户可以在登陆后查看进程的安全级(命令 lvl_gettsk)。超级管理员可以修改进程的安全级(命令 lvl_settsk),可以比较两个安全级之间的关系(命令 levelcmp)。

客体 MAC

用户创建的客体的安全级为创建该客体进程的安全级,且客体的安全级必须等于其父目录的安全级(超级用户进程创建的客体除外),另外,若其父目录是一个多级目录,普通进程创建的客体可以大于其父目录的安全级。关于多级目录后续进行详细的介绍。

超级管理员用户可设置客体的安全级(命令 setlevel)。任何用户可以查看其可以读访问的客体的安全级(命令 getlevel)。

多级目录(MLDs)

根据强制存取控制机制“写相等”的原则,在一目录下创建文件时,创建文件的进程(普通用户)的安全级必须与此目录的安全级相同,只有这样此进程才能够在该目录下产生文件,而一个目录的安全级是固定的,这就造成系统不允许不同安全级的进程在同一目录下创建不同安全级的文件,但是,有许多现存程序都需要一种在标准目录如 /tmp 下创建临时文件的能力,具有不同安全级的用户要运行这些程序就需要在这些标准目录下创建不同安全级的文件。如果这样用法,就会破坏 MAC 的限制或者要求这些程序都是可信的。但这两种选择都是不可接受的。

为了让不同安全级的进程能够在同一标准目录如 /tmp 下创建文件,我们在安胜中引入多级目录的概念,将这些标准目录设置成多级目录,在它的下面创建具有不同安全级的文件。

多级目录的结构

多级目录含有一些特殊的子目录,称为有效目录(Effective  Directory),或称隐藏目录(Hidden Directory)。有效目录是当某个进程第一次访问多级目录时由系统逐个创建的。有效目录的创建对用户来讲是自动的和透明的。有效目录名是与它相关的安全级标识(LID),安胜中目录 /tmp 即为一个多级目录。其示意下图所示:

进程的目录状态

与每个进程有关的是进程的目录状态,它决定了对多级目录的访问方式,这个状态可以是“实状态”(MLD_REAL)也可以是“虚状态”(MLD_VIRT)。继承于调用进程,内核根据进程的状态决定如何访问多级目录。在进程处于虚目录状态下,进程“看不见”隐藏目录;而在实目录状态下,进程则可以“看见”隐藏目录。

虚状态(virtual mode)

如果进程的多级目录状态为虚状态(对所有用户,虚状态为缺省状态),那么内核将把对多级目录的访问改变为对多级目录下有效目录的访问。这个有效目录的安全级与进程安全级相同。如果没有一个有效目录的安全级等于进程的安全级,那么内核将自动地创建一个具有进程安全级的有效目录。例如,进程 ProcessA 的安全级为 SYS_PUBLIC,其代表的 LevelId 为 1 ,在当它访问多级目录 /tmp 时,其所“看到”的 /tmp 目录其实是目录 /tmp/1,它在多级目录 /tmp 下创建文件 A 时,文件 A 的全路径为 /tmp/1/A,只不过对进程 ProcessA 来说,它“看不见”隐藏目录 1 ,故它“认为”是 /tmp/A

实状态(real mode)

当进程的多级目录状态为实方式时,对多级目录的访问与一般目录相同。

多级目录管理和操作

用户进程一般均处于虚目录模式下,超级用户可以查询和改变进程的目录状态(命令 mldmode)。

在安胜安全操作系统初始安装时,将自动创建系统所需的多级目录,以后将不再创建。系统初装后,/tmp,/var/tmp,/var/preserve,/var/mail,/var/spool/mqueue,/var/spool/at 和 /var/spool/cron 等目录为多级目录。

拥有特权的用户在实状态下也可以创建另外的多级目录(命令 mkmld),但如果不是所有用户都需要访问的特别目录,则不要随意创建一个多级目录。

系统管理员清理多级目录时,应处于实状态下进行,删除所有的有效目录及文件,最后将进程的多级目录状态改为虚状态。

删除多级目录时,需在实状态下将多级目录清空,然后删除多级目录自身。

应当注意以下几点:

  1. 应用程序只能在虚状态下运行。如果应用程序在实状态下访问一个多级目录,它可能不能创建文件,并有可能引起应用程序执行的混乱。
  2. 在多级目录中,应该只有有效目录。当在实状态下创建一个多级目录的子目录,但创建的目录将作为一个有效目录,在虚状态下,进程不能通过名字来访问这个目录。同样,在实状态下,也可以在多级目录中创建一个普通文件,但这是应该避免的,因为在虚状态下这个文件是不可访问的。
  3. 为了避免对自动创建的有效目录的命名操作,在实状态下,应该避免创建、移动、重命名操作多级目录下的文件和目录以及有效目录,否则,就有可能造成用户在某些安全级上不能访问多级目录。
  4. 在多级目录下再创建多级目录是没有什么用的,所以安胜安全操作系统不允许。

多级目录安全策略

在虚状态下,用户在访问多级目录时必须通过 DAC 检查,并且用户安全级必须支配多级目录的安全级。此外,有效目录的安全级和存取权限控制着对多级目录下文件的访问。在实状态下,正常的 MAC 和 DAC 限制着对多级目录的访问。有效目录继承多级目录的存取状态和 ACL。但是,有效目录不能具有缺省 ACL,即使多级目录已具有某个缺省 ACL。

设置多级目录的安全级和 DAC 权限,这样可使真正需要它的用户使用它。例如,/tmp 的安全级为 SYS_PUBLIC,DAC 权限为 0777。如果需要改变多级目录的安全级和有效目录的安全级,则必须在实状态下进行。但这可能使当前进程不能访问这个多级目录。

多级目录是 MAC 机制的一部分。如果关闭 MAC 机制或运行一个没有 MAC 机制的核心,则对多级目录和有效目录的访问将与普通目录一样。要访问有效目录下的文件,就需要敲全包括有效目录名在内的文件路径名。

有些程序依赖于多级目录下的文件,如果 MAC 机制不起作用,则需要将有效目录下的文件移到多级目录下,这样,这些程序才能找到这些文件,否则程序就不能进行。如果下次激活 MAC 机制或运行带有 MAC 机制的核心,那么则需要做相反操作。

MAC 中命令的使用

lvlinit

创建和初始化安全级数据库

lvladm

设置或显示安全级

命令格式:

1
2
3
4
5
lvladm -h HID:hierarchy[,HID:hierarchy]
lvladm -c CID:category[,CID:category]
lvladm -l LID::hierarchy[:category]
lvladm -a alias::hierarchy[:category]
lvladm [-p]

参数说明:

-a alias_name::level_name:将安全级别名 alias_name 赋给有效安全级全名 level_name; -h HID:hierarchy:添加一个级别,其 ID 为 HID,名称为 hierarchy; -c CID:category:添加一个范畴,其 ID 为 CID,名称为 category; -l LID::hierarchy[:category]:添加一个安全级,其 ID 为 LID,名称由 hierarchy[:category] 组成; -p:打印记录

lvlrm

删除安全级

命令格式:

1
2
3
4
5
lvldel -a alias[,alias...]
lvldel -h hierarchy[,hierarchy...]
lvldel -c category[,category...]
lvldel -l LID[,LID...]
lvldel -f hierarchy: category

setlevel

对文件赋以用户指定的安全级敏感性标签。

命令格式:setlevel lid_alias_name filename

参数说明:

  • filename 为要重新设置安全级的文件名,可使用统配符。
  • lid_alias_name 为将要设置的安全级别名

执行此命令的权限:此命令执行者必须同时具有 CAP_SETLEVEL 特权和 CAP_MAC_OVERWRITE 特权的管理员;同时,新设置的安全级必须支配(或相等)文件原有的安全级(安全级只升不降)。

getlevel

获取文件的安全级敏感性标签。

命令格式:getlevel filename

参数说明:filename 为将要获取其安全级的文件的名称,可使用统配符。

执行此命令的权限:此命令执行者必须对此文件具有读权限或者是具有 CAP_MAC_OVERREAD 特权的管理员。(事实上非管理员没有这个权限)

levelcmp

比较两个安全级之间的关系

命令格式:levelcmp lid_alias_name1 lid_alias_name2

参数说明:lid_alias_name1lid_alias_name2 为两个要进行比较的安全级,用别名表示。

mldmode

设置进程的实/虚模式

命令格式:mldmode [-q] [-r] [-v]

参数说明:

  • r 表示将当前进程的目录模式设置为实模式。
  • v 表示将当前进程的目录模式设置为虚模式。
  • q 查询当前进程的目录模式。MLD 模式共有两种:real,virtual,当为 real 模式时,进程将多级目录当做一般目录访问,当为 virtual 模式时,进程对多级目录的访问实际为对有效目录的访问。系统初始化为虚模式。

执行此命令的权限:普通用户不可以执行。

mkmld

创建多级目录

命令格式:mkmld [-m mode] [-p] [-l level] dir_name

3)参数说明:

  • -m mode:表示将要创建的多级目录的访问许可权,如:-m 777。
  • -l level:表示将要创建的多级目录的安全级。如:-l SYS_PUBLIC。
  • -p:表示在创建多级目录时,如其父目录不存在,则创建之。
  • dir_name:表示将要创建的多级目录名。

只有具有特权的用户才可以创建多级目录。且创建时需在实模式状态下。

执行此命令的权限:普通用户不允许执行此命令。

基于角色访问控制

这一部分实现基于角色的特权机制,通过管理员 root 授权、并规定必要的特权规则,授予普通用户执行某些管理员特权命令的权利,使特定的普通用户在安全机制下可以执行特定的管理员命令,达到更好的管理效果。

  1. 不同的用户由于承担不同的角色,而拥有不同的特权(主要指允许执行的命令集合不同)
  2. 由于root用户还受证书保护,所以通过认证和未通过认证的 root 用户特权不同。执行 initcert 设置根证书,root 用户再执行 user_auth 认证。
  3. 普通用户通过 user_auth 认证后拥有其角色所有特权,未通过认证的用户仅拥有普通用户权限。认证后使用 sudo <command> 执行特权操作。

注:要求修改 /etc/security/TCB/auth/.pub 为所有用户可读,修改 /bin/user_auth 命令权限为所有用户可执行。

系统安装和颁发证书

证书认证是角色管理的核心部分,证书必须妥善保存和使用。

安胜安装的最后一步将生成管理员初始化证书(参看《ERCIST 安胜 3.0 安装指南》),缺省存放于 /root,命名为 root.crt

如果系统管理员希望重新生成初始化证书,运行 /sbin/initcert 命令即可。

只有经过认证的 root 用户才能拥有所有的管理特权。其他用户的证书必须由拥有管理员证书并知道证书加密口令的授权用户来颁发,运行 /sbin/makecert 命令。

用户认证

要执行角色操作,必须先进行用户认证。用户提供证书文件存放路径和证书加密口令进行认证。

角色管理命令 roleadmin

1
2
3
4
5
6
7
roleadmin –a role:cmnd
          -d role[:cmnd]
          -m user:role 
          -u username 
          -l role      
          -i newr:oldr 
          -s

详细说明如下。

  • roleadmin -a role:cmnd:为角色 role 增加一条命令 cmnd。
  • roleadmin -d role[:cmnd]:删除角色 role 或者删除角色 role 的一条命令 cmnd。
  • roleadmin -m user:role:为用户 user 设置一个角色 role,其中 role 一定是已经存在的角色。
  • roleadmin -u user:删除用户 user 的角色。
  • roleadmin -l role:列出角色 role 的所有可执行命令。
  • roleadmin -i newr:oldr:创建一个新的角色 newr,并且继承原有角色 oldr 的命令。
  • roleadmin -s:列出系统中所有角色,及系统中已经拥有角色的用户。

该命令通过对角色配置文件的配置对角色进行管理。并通过 sudo 命令来执行相应的角色命令。

系统中共有四个缺省角色,分别是 AUDIT(审计操作)、SSO(安全操作)、SOP(系统操作)、NET(网络操作)管理员。他们分担普通系统中超级用户的功能。

角色操作命令 sudo

1
2
sudo -V | -h | -L | -l | -v | -k | -K | [-H] [-P] [-S] [-b] [-p prompt]
    [-u username/#uid] -s | <command>

sudo 命令基于由 roleadmin 产生的配置文件,对普通用户拥有的角色特权进行认证。如果通过,则可以授权执行指定命令 <command>

证书认证机制

证书认证机制是安胜安全的重要策略,通过该机制确保特权操作的安全性,使得只有通过认证的用户(包括 root 用户)才能最终具有特权操作的权限。

生成根证书命令 initcert

当旧的根证书快要过期或管理员希望重新生成根证书时,拥有根证书的管理员可以在认证(user_auth)之后,执行 initcert 命令来重新产生根证书。当新的根证书产生后,所有用户原有的证书都将失效。如有需要,必须执行 makecert 命令重新为用户生成证书。

initcert 执行界面的一个实例如下图:

生成普通用户证书命令 makecert

如果需要对普通用户进行认证,则必须由管理员为其生成用户证书,执行命令 makecert

makecert 的操作步骤如下图:

第 1 步:指定正常的存放位置和根证书存放位置、加密口令信息

第 2 步:选择用户并设定、确认加密口令

第 3 步:收集信息完毕,点击 Finish 生成用户证书

改变证书加密口令 chgpwdcert

用户证书的加密口令可以由用户通过执行 chgpwdcert 命令进行修改。如下图:

用户认证命令 user_auth

user_auth 的使用方法。

1
2
3
4
5
[root@t116 ~]# user_auth
CERTIFICATE PATH:/root/root.crt
PIN:************
authentication Success!
[root@t116 ~]#

可信路径机制

恶意用户可以制作一个欺骗性的登录界面,在终端上启动这个程序,然后离开。这个程序看起来和正常的登录界面别无二致,但是它读取合法的用户名密码,并把它们通过某种方式送至恶意用户。从而恶意用户就可以冒用合法用户登录系统,进而有可能获取管理员帐号,危害系统。

因此,要提供一种方法来确保用户见到的登录界面就是真正的登录界面,杜绝上述“特洛伊木马”攻击。

可信通路在此背景下产生,它预定义了一组键序列,当用户键入这组可信通路序列键后,控制权总是交给操作系统的可信计算基(TCB),即核心,从此用户进程对系统就失去了控制。安胜定义了(CTRL+PAUSE)键为可信通路键序列。

用户可以相信在键下(CTRL+PAUSE)键后所见到的登录界面为其同 TCB 间的通信提供了一个可信的通路,因为任何用户进程是不可能截获(CTRL+PAUSE)键的。安胜是真正的多任务操作系统,系统中的运行单元是进程,包括核心进程和用户进程。用户进程通过系统调用陷入核心进程,一旦陷入核心进程,用户进程便失去控制能力。

一旦有键盘出入,系统将陷入核心予以解释,并将结果送给等待键盘输入的用户进程。比如,(CTRL+PAUSE)键被点击,核心进程首先将其截获,解释后激活可信通路。即杀死当前终端的所有用户进程,重新激活登录界面。由此我们可以放心的输入合法的用户名密码,绝不可能有什么特洛伊木马了。即使在点击(CTRL+PAUSE)键之前真的是一个伪造的很好的特洛伊,那么点击后它也会被核心所杀死。(但是这和多任务操作系统有什么关系?不应该是和中断与特权级有关吗?)

审计机制

概论

一个安全系统的审计过程就是对系统中任一或所有有关安全活动的记录、检查及审查的过程。它是安全操作系统中的一个重要方面。审计数据中必须有足够细的粒度,以支持对一个特定个体已发生的动作或代表该个体发生的动作进行追踪。审计为系统进行事故原因的查询、定位、事故发生前的预测、报警以及事故发生之后的实时处理提供详细、可靠的依据和支持。

在安胜中,用户程序与操作系统的唯一接口是系统调用,也就是说当用户请求系统服务时,必须经过系统调用。因此,在此处(称作审计点)增加审计控制,就可以成功地审计系统调用,也就可以成功地审计了与安全有关的事件。

当发生可审计事件时,要在审计点调用审计函数并向审计进程发消息。由审计进程完成审计信息的缓冲、存贮、归档工作。虽然审计事件及审计点处理可能各不相同,但审计信息都要经过写缓冲区、写盘、再归档,这部分操作过程是相同的。因此,我们把它放在审计进程内完成,其余在审计点完成。整个审计机制的示意图如下图:

审计事件及审计事件标准

审计事件

待审计的用户活动按各自的性质不同,被视为不同的事件,事件是系统审计用户动作的最基本单位。常见的审计事件中有 openexec 这样的系统调用,它们跟系统的安全使用有关,所以要记录它们的执行情况,还有一些与系统安全关系密切的系统命令和特权命令(如 login, passwd, useradd 等),也需要详细的审计对其的调用。

为了配置管理的方便,系统根据审计事件自身的相关性,将它们划分成两大类:系统审计事件和应用程序审计事件。其中,系统审计事件中有一部分事件(open, chdir, mknod 等)含有对客体如文件、目录、设备等的操作,因此也要对这些被操作的客体进行审计。其它的系统审计事件不包含客体。系统审计事件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
access
acct-off
acct-sw
capset
chdir
chmod
chown
chroot
create
crtmodule
delmodule
exec
fchdir
fchmod
fcnown
fcntl
flock
fork
ftruncate
ioctl
ioperm
uselib
utime
sethostname
iopl
lchown
link
mkdir
mkmld
mknod
mount
open-rd
open-wr
pipe
reboot
rename
rmdir
setfsgid
setfsuid
setgid
setgroups
setpgid
setregid
setresgid
setresuid
setreuid
setrlimit
setsched
setsid
setuid
stime
symlink
syslog
truncate
umount
unlink
setpriority
settimeofday
socketcall

其中含有客体的系统审计事件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
access
acct-off
acct-on
acct-sw
chdir
chmod
chown
chroot
create
exec
fchdir
fchmod
fchown
fcntl
flock
ftruncate
ioctl
lchown
link
mkdir
mkmld
mknod
open-rd
open-wr
rename
rmdir
symlink
truncate
unlink
uselib
utime

另外,应用程序审计事件是对核外发生的事件的审计,是由当事的应用程序自主向内核申请审计动作的。应用层的审计事件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
grpadd
grpdel
grpmod
grppass
usradd
usrdel
usrmod
usrpass
login-autifail
login-badlvl
login-badmask
login-badname
login-ok
login-refused
adton
adtoff

其中的四个审计事件掩码 usraddgrpaddusrmodgrpmod 是固化在内核中的,是内核的缺省审计事件集。

审计事件标准

在实施审计之前,先要确立审计标准,即需要审计哪些事件。这个问题可以从两方面来看:

从主体(用户和代表用户的进程)角度上看,系统要记录用户进行的所有活动,每个用户有自己的待审计事件集,称为用户事件标准,一旦其行为落入用户事件集,系统就会将事件信息记录下来。

从客体(文件、消息、信号量、共享区等)角度上看,系统要有能力记录关于某一客体的所有存取活动。为了有更好的针对性,在我们的实现中是先定义关于该对象的哪些操作事件要求被审计,即包含客体对象的审计事件标准(access、acct-off、acct-on、 acct-sw、chdir、chmod、chown、chroot、create、exec、fchdir、fchmod、fchown、fcntl、flock、ftruncate、ioctl、lchown、link、mkdir、mkmld、mknod、open-rd、open-wr、rename、rmdir、symlink、truncate、unlink、uselib、utime),再确定一个待审计的客体的 MAC 安全级范围(由一些连续的范围和离散的点构成),只有属于该范围的客体的对象事件标准才被审计。

在用户事件标准中,每个用户都需审计的公共部分称为基本事件集,它由审计管理员设定。基本事件集和用户的事件集作并集运算,结果才是真实的用户事件标准。

另外,有些事件与系统安全性关系非常大,任何时候都不应免于审计。为此,安胜安全操作系统定义了一个固定的审计事件集——FIXMASKusraddgrpaddusrmodgrpmod),它是系统最基本的事件标准,在审计管理员设置或修改基本事件集时,固定事件集总是包含在系统基本事件集中。为了保障安全,固定审计事件通过硬编码固化在内核中,管理员不能改变它,除非修改内核程序。在我们的安全系统里,固定审计事件包括:添加删除用户帐号,分配 MAC 安全级等。

除了固定审计事件集,其它审计事件都是审计员可选的事件。通过 adtset 系统命令,审计员可以设置系统基本事件标准、用户事件标准及用户组事件标准。完整的审计事件标准如下图所示:

审计子系统工作过程描述

由于审计子系统涉及到操作系统的各个部分,为方便起见,下面从审计开启、审计文件配置、审计屏蔽字(这里的屏蔽字不是屏蔽某个事件的审计,而是开启某个事件的审计,用掩码来理解)设置、审计关闭、审计记录显示几方面对此子系统的工作过程进行描述。

首先,通过 adton 命令开启审计子系统,审计管理员可通过 adtconfig 命令设置审计子系统的配置文件、usermod 设置用户的审计屏蔽字、ia_userinfo 显示用户的审计屏蔽字。

审计开启后,审计管理员可通过 adtset 灵活地设置系统运行中的系统屏蔽字、用户屏蔽字。可通过 adtstat 观察审计状态。

最后,通过 adtoff 命令关闭审计子系统。

审计控制命令使用

adton

开启审计子系统。如果直接键入不带参数的 adton,则审计开启使用 /etc/default/audit.conf 配置文件中存放的系统参数,否则,用参数中的值代替配置文件中相应的值。

命令格式:

1
2
3
4
5
6
adton
[-f AUDIT_DISKFULL][-g AUDIT_PGM][-e AUDIT_LOGERR]
[-p AUDIT_PPATH][-P AUDIT_APATH][-n AUDIT_PNODE]
[-N AUDIT_ANODE][-m AUDIT_MAXSIZE][-b AUDIT_BSIZE]
[-c AUDIT_NBUFS][-G AUDIT_GMTSECOFF][-v AUDIT_VERSION]
[-h]

参数说明:

  • f:当磁盘满时,指定相应的处理:
    1. shutdown 关机
    2. disable 关闭审计子系统
    3. switch 切换到指定的程序,该选项必须与 -g 同时执行。
  • g:指定切换的程序,该选项必须与 -p switch 同时执行。
  • e:当审计出错时,指定相应的处理:
    1. shutdown 关机
    2. disable 关闭审计子系统。
  • p:指定审计日志文件的路径。
  • P:指定审计日志文件的切换路径。
  • n:指定审计日志文件名的后半部分。(不得超过 7 个字符)
  • N:指定切换时审计日志文件名的后半部分。(不得超过 7 个字符)
  • m:指定审计日志文件的大小。(0 为不限)
  • b:指定审计缓冲区的大小。
  • c:指定审计缓冲区的个数。
  • G:指定审计系统时间与格林威治的时差。
  • v:指定审计的版本。(不得超过 18 个字符)
  • h:该命令的帮助。

adtoff

adtoff:关闭审计。

adtconfig

管理审计配置文件,文件为 /etc/default/audit.conf

命令格式:

1
2
3
4
5
6
7
8
adtconfig  [-f AUDIT_DISKFULL]   [-g AUDIT_PGM]       [-e AUDIT_LOGERR]
[-p AUDIT_PPATH] [-P AUDIT_APATH] [-n AUDIT_PNODE]
[-N AUDIT_ANODE] [-m AUDIT_MAXSIZE] [-b AUDIT_BSIZE]
[-c AUDIT_NBUFS] [-G AUDIT_GMTSECOFF] [-v AUDIT_VERSION]
[-a AUDIT_SYSMASKS] [-A AUDIT_LVLMASKS]
[-t AUDIT_LVLTBL,...] [-r AUDIT_RLVL_MIN, AUDIT_RLVL_MAX]
[-d fgepPnNmbcGvaAtr]
[-h] [-H]

参数说明: -f –g –e –p –P –n –N –m –b –c –G –v –hadton 参数作用相同。 - a:配置系统屏蔽字,可用操作符 +-^。 - A:配置客体屏蔽字,可用操作符 +-^。 - t:配置离散安全级。(-t t1,t2,t3) - r:配置连续安全级。(-r t1,t2) - d:根据参数显示审计配置文件的内容。

adtset

审计运行时,管理系统及用户的审计屏蔽字。

命令格式:

1
2
3
4
5
adtset         [-d [-u user[,...]|-a]
adtset         [-s [operator]event[,...]][-o [operator]event[,...]]
[-r levelmin,levelmax] [-l level[,...]]
adtset         [-u user[,...]|-a][-e [operator]event[,...]]
adtset         [-h]

参数说明:

  • d:显示指定用户的屏蔽字。
  • u:指定用户。
  • a:指定所有用户。
  • s:设置系统审计屏蔽字。
  • o:设置系统客体审计屏蔽字。
  • e:设置指定用户的审计屏蔽字。
  • r:配置连续安全级(-r t1,t2)。
  • l:配置离散安全级(-l t1,t2,t3)。
  • h:该命令的帮助。

adtstat

显示审计状态。

命令格式:

1
2
3
4
5
6
adtstat
[-f AUDIT_DISKFULL] [-e AUDIT_LOGERR]
[-p AUDIT_PPATH] [-P AUDIT_APATH] [-n AUDIT_PNODE]
[-N AUDIT_ANODE] [-m AUDIT_MAXSIZE] [-b AUDIT_BSIZE]
[-c AUDIT_NBUFS] [-G AUDIT_GMTSECOFF] [-v AUDIT_VERSION]
[-h]

参数说明:参见 adton

审计记录查询工具

安胜 3.0 为用户提供了方便的审计记录查询工具,以方便在字符或图形终端上查询或者浏览审计记录。其英文版的命令为 adtview,中文版命令为 adtviewchs。下面两个图分别是英文版和中文版的命令主界面:

英文:

中文:

下面我们将以中文版为例介绍如何使用查询工具 adtview

浏览记录

用户可以顺序浏览审计记录,或者指定查询条件查询审计文件。在查询或浏览之前,用户需要指定审计文件,缺省的审计文件存放在 /var/audit 下,并且以 pnode 或者 anode 结尾。

选择文件之后,用户将看到匹配的审计记录列表,并附有此审计文件的版本信息以及记录摘要:

当选择指定的记录并按回车键,用户将看到此记录的详细描述:

用户还可以将审计查询结果作为文本文件输出,输出的文件已经作为格式化的文件方便用户查看。

通过进程属性查询

用户可以指定进程的 ID、名称、安全级、事件时间范围以及用户(组)ID 信息查询审计记录。查询条件是可以多选的,具体格式就是以空格(space)分隔。时间范围的格式为:(from-to) year:month:day:hour:minute:second-year:month:day:hour:minute:second

通过访问对象查询

用户可以指定事件访问的对象(文件)属性进行查询。

通过事件查询

用户可以指定不同的事件进行查询,事件被分为两类:系统调用事件和应用程序事件。

高级查询

高级查询也即复杂查询,前几种查询方式为用户提供了较小的特定的查询匹配集合。高级查询让用户可以选择复杂的查询条件。

设计测试案例展现安全机制的工作原理

查看 cat /etc/group 发现已有 group1 与 group2 用户组。

使用 useradd 创建如下几个用户,并用 passwd 设置密码:

用户名 用户组 安全级
user1 group1 SYS_PUBLIC | SYS_ADMIN | USER_PUBLIC
user2 group1 USER_PUBLIC
user3 group2 SYS_AUDIT | USER_PUBLIC
1
2
3
4
5
6
useradd -g group1 -h SYS_PUBLIC -h SYS_ADMIN -h USER_PUBLIC -v USER_PUBLIC -m user1
useradd -g group1 -v USER_PUBLIC -m user2
useradd -g group2 -h SYS_AUDIT -h USER_PUBLIC -v USER_PUBLIC -m user3
passwd user1
passwd user2
passwd user3

使用 id 命令查看各用户的相关 ID:

1
2
3
4
5
6
-bash-2.05b$ id user1
uid=500(user1) gid=501(group1) groups=501(group1)
-bash-2.05b$ id user2
uid=501(user2) gid=501(group1) groups=501(group1)
-bash-2.05b$ id user3
uid=502(user3) gid=502(group2) groups=502(group2)

自主访问控制 (DAC) 机制

使用 login 登录 user1 并创建文件进行测试:

1
2
3
4
5
6
7
8
9
10
11
[root@localhost root]# login
sec-login:user1
Password:
User Level:
Logging in at level USER_PUBLIC

-bash-2.05b$ echo "test user1" >> test1

-bash-2.05b$ ls -l
total 4
-rw------- 1 user1 group1 11 11-13 11:36 test1

此时登录 user2 测试访问此文件:

1
2
3
4
5
6
7
[root@localhost root]# login user2
Password:
User Level:
Logging in at level USER_PUBLIC

-bash-2.05b$ cat /home/user1/test1
cat: /home/user1/test1: 权限不够

返回 user1 将主目录与该文件设置为同组用户可访问:

1
2
-bash-2.05b$ chmod g+rx /home/user1
-bash-2.05b$ chmod g+r /home/user1/test1

此时由于属于同组用户,user2 可以访问:

1
2
-bash-2.05b$ cat /home/user1/test1
test user1

此时 user3 无法访问:

1
2
3
4
5
6
7
[root@localhost root]# login user3
Password:
User Level:
Logging in at level USER_PUBLIC

-bash-2.05b$ cat /home/user1/test1
cat: /home/user1/test1: 权限不够

使用 setfacl 取消 user2 的读取权限:

1
2
3
4
5
6
7
8
9
10
11
-bash-2.05b$ setfacl -m u:user2:- /home/user1/test1
-bash-2.05b$ getfacl /home/user1/test1
getfacl: Removing leading '/' from absolute path names
# file: home/user1/test1
# owner: user1
# group: group1
user::rw-
user:user2:---
group::r--
mask::r--
other::---

此时 user2 再次访问:

1
2
-bash-2.05b$ cat /home/user1/test1
cat: /home/user1/test1: 权限不够

使用 setfacl 添加 user3 的读写权限:

1
2
3
4
5
6
7
8
9
10
11
12
13
-bash-2.05b$ setfacl -m u:user3:rw /home/user1/test1
-bash-2.05b$ setfacl -m u:user3:rx /home/user1
-bash-2.05b$ getfacl /home/user1/test1
getfacl: Removing leading '/' from absolute path names
# file: home/user1/test1
# owner: user1
# group: group1
user::rw-
user:user2:---
user:user3:rw-
group::r--
mask::rw-
other::---

此时 user3 再次访问:

1
2
3
4
5
6
-bash-2.05b$ cat /home/user1/test1
test user1
-bash-2.05b$ echo "test user3 write" >> /home/user1/test1
-bash-2.05b$ cat /home/user1/test1
test user1
test user3 write

强制访问控制 (MAC) 机制

使用 lvladm 查看现有安全级、级别和范畴:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[root@localhost root]# lvladm
Levels:
LID ALIAS LEVEL NAME
1 SYS_PUBLIC system
2 SYS_SECURITY system:security
3 SYS_ADMIN system:admin,login,security
4 SYS_RANGE_MAX range_max:ALL
5 USER_PUBLIC user
6 USER_LOGIN user:login
7 SYS_AUDIT system:audit
8 SYS_LOGIN system:login
9 SYS_RANGE_MIN range_min

Hierachies:
HID NAME
1 range_min
2 system
4 user
256 range_max

Categories:
CID NAME
1 admin
2 audit
3 login
4 security
5 operator

测试 /home/user1/test1 文件的标签:

1
2
3
4
-bash-2.05b$ sudo /sbin/getlevel /home/user1/test1
begin execute
# file: /home/user1/test1
No mac level!

测试 SYS_PUBLIC 与 USER_PUBLIC 的关系:

1
2
3
-bash-2.05b$ sudo /sbin/levelcmp SYS_PUBLIC USER_PUBLIC
begin execute
"USER_PUBLIC" domain "SYS_PUBLIC"!

USER_PUBLIC 支配 SYS_PUBLIC。

使用 root 用户给 /home/user1/test1 文件打上 SYS_PUBLIC 标签:

1
[root@localhost root]# setlevel SYS_PUBLIC /home/user1/test1

查看文件的标签:

1
2
3
4
5
6
7
8
9
-bash-2.05b$ sudo /sbin/getlevel /home/user1/test1
begin execute
# file: /home/user1/test1
# level id
1
# alias name
SYS_PUBLIC
# full level name(hierarchy:class1,class2,...)
system

此时尝试使用 user1(登录标签为 USER_PUBLIC)读写该文件:

1
2
3
4
5
-bash-2.05b$ cat test1
test user1
test user3 write
-bash-2.05b$ echo "test user1 write" >> /home/user1/test1
-bash: /home/user1/test1: 权限不够

原因:USER_PUBLIC 标签支配 SYS_PUBLIC,读成功;不等于,写失败。

此时再次尝试使用 user3(登录标签为 USER_PUBLIC)写入该文件:

1
2
3
4
5
-bash-2.05b$ cat /home/user1/test1
test user1
test user3 write
-bash-2.05b$ echo "test user3 write 2" >> /home/user1/test1
-bash: /home/user1/test1: 权限不够

原因:USER_PUBLIC 标签支配 SYS_PUBLIC,读成功;不等于,写失败。

退出 user1,使用 SYS_PUBLIC 标签重新登录 user1 并再次测试读写:

1
2
3
4
5
6
7
8
9
10
11
12
[root@localhost root]# login user1
Password:
User Level: SYS_PUBLIC
Logging in at level SYS_PUBLIC
-bash-2.05b$ cat test1
test user1
test user3 write
-bash-2.05b$ echo "test user1 write" >> /home/user1/test1
-bash-2.05b$ cat test1
test user1
test user3 write
test user1 write

原因:主客体标签相同,读写成功。

使用 user3(登录标签为 USER_PUBLIC)创建文件 test3:

1
-bash-2.05b$ echo "test user3" >> test3

此时测试 user1(登录标签为 SYS_PUBLIC)对 /home/user3/test3 的读取:

1
2
-bash-2.05b$ cat /home/user3/test3
cat: /home/user3/test3: 权限不够

原因:SYS_PUBLIC 标签不支配 USER_PUBLIC,读失败。

多级目录测试

使用 root 用户在 /tmp 下创建一个多级目录:

1
2
[root@localhost root]# cd /tmp
[root@localhost tmp]# mkmld test

在 user1(登录标签为 SYS_PUBLIC)中创建 /tmp/test/testfile 并测试权限:

1
2
3
4
5
-bash-2.05b$ echo "user1 mld test" >> /tmp/test/testfile
-bash-2.05b$ cat /tmp/test/testfile
user1 mld test
-bash-2.05b$ ls /tmp/test/
testfile

在 user3(登录标签为 USER_PUBLIC)中检查 /tmp/test 目录:

1
2
-bash-2.05b$ ls /tmp/test
-bash-2.05b$

在 user3(登录标签为 USER_PUBLIC)中创建 /tmp/test/testfile 并测试权限:

1
2
3
4
5
-bash-2.05b$ echo "user3 mld test" >> /tmp/test/testfile
-bash-2.05b$ cat /tmp/test/testfile
user3 mld test
-bash-2.05b$ ls /tmp/test/
testfile

在 root 中切换为实模式并检查 /tmp 目录:

1
2
3
4
5
6
7
8
[root@localhost root]# mldmode -r
MLD_REAL!
[root@localhost root]# ls /tmp/test/
1 5
[root@localhost root]# cat /tmp/test/1/testfile
user1 mld test
[root@localhost root]# cat /tmp/test/5/testfile
user3 mld test

在 user3 中将文件权限设置为 777,退出 user1 并以 USER_PUBLIC 标签重新登陆,再次检查 /tmp/test/testfile 文件:

1
2
3
4
5
6
7
[root@localhost root]# login user1
Password:
User Level:
Logging in at level USER_PUBLIC

-bash-2.05b$ cat /tmp/test/testfile
user3 mld test

基于角色访问控制

在 root 用户下使用 user_auth 获取授权,证书路径为 /root/root.crt,PIN 码为 ansheng

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@localhost root]# user_auth
CERTIFICATE PATH:/root/root.crt
PIN:

Wrong Certificate or PIN, authentication failed!
[root@localhost root]# user_auth
CERTIFICATE PATH:/root/root.crt
PIN:

Certificate time limit error.
this because you used an overtime Certificate or you
have changed your system date.Anyway, you should create
a new certificate or get a new one from system administrator

证书已过期,使用 initcert 重新生成证书:

重新获取授权,并使用 makecert 为 user1、user2 创建证书,授予所有用户的 /etc/security/TCB/auth/.pub 读权限:

1
[root@localhost root]# chmod o+r,g+r /etc/security/TCB/auth/.pub

使用 roleadmin -s 查看所有角色以已有的用户角色分配,并使用 roleadmin -l 列出各个角色可执行的命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
[root@localhost root]# roleadmin -s

List all roles in the system:
AUDIT 3
SOP 2
NET 1
SSO 0

List user :: role in the system:
root :: ALL
user1 :: SSO
user3 :: AUDIT
user2 :: AUDIT

[root@localhost root]# roleadmin -l SSO

List SSO's commands:
/sbin/dellevel
/sbin/devadd
/sbin/devdel
/sbin/devmod
/sbin/devstat
/sbin/getlevel
/sbin/levelcmp
/sbin/lvl_settsk
/sbin/lvladm
/sbin/lvlrm
/sbin/netadd
/sbin/netconf
/sbin/netdel
/sbin/netmod
/sbin/setlevel
/sbin/runlevel
/sbin/sulogin
/usr/bin/at
/usr/bin/chfn
/usr/bin/du
/usr/bin/find
/usr/bin/passwd
/bin/chgrp
/bin/chmod
/bin/chown
/bin/cp
/bin/cpio
/bin/date
/bin/df
/bin/kill
/bin/ls
/bin/mkdir
/bin/mv
/bin/nice
/bin/ps
/bin/rm
/bin/su
/bin/vi
/usr/sbin/chpasswd
/usr/sbin/chroot
/usr/sbin/groupadd
/usr/sbin/groupdel
/usr/sbin/groupmod
/usr/sbin/grpck
/usr/sbin/grpconv
/usr/sbin/grpunconv
/usr/sbin/newusers
/usr/sbin/pwck
/usr/sbin/pwconv
/usr/sbin/pwunconv
/usr/sbin/setup
/usr/sbin/useradd
/usr/sbin/userdel
/usr/sbin/usermod
/usr/sbin/vigr
/usr/sbin/vipw
/usr/bin/crontab
/usr/bin/gpasswd
/usr/bin/ipcrm
/usr/bin/ipcs
/usr/bin/mkpasswd
/usr/bin/newgrp
Total 62 commnds.

[root@localhost root]# roleadmin -l AUDIT

List AUDIT's commands:
/sbin/adtconfig
/sbin/adtoff
/sbin/adton
/sbin/adtset
/sbin/adtstat
/bin/ls
/bin/ps
/usr/sbin/usermod
Total 8 commnds.

可以看到 AUDIT 角色不可执行如 /sbin/setlevel 之类的命令。

在 user1 下使用 sudo 运行 /sbin/setlevel 测试:

1
2
3
-bash-2.05b$ sudo /sbin/setlevel SYS_ADMIN test
begin execute
setlevel: test: Operation not permitted

有执行权限,无设置权限。

user1 使用 user_auth 获取授权并再次执行,使用 /sbin/getlevel 检查执行情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-bash-2.05b$ user_auth
CERTIFICATE PATH:/home/user1/user1.crt
PIN:
authentication Success!
-bash-2.05b$ sudo /sbin/setlevel SYS_ADMIN test
Password:
begin execute
-bash-2.05b$ sudo /sbin/getlevel test
begin execute
# file: test
# level id
3
# alias name
SYS_ADMIN
# full level name(hierarchy:class1,class2,...)
system:admin,login,security

执行成功,设置成功。

在 user2 下使用 sudo 运行 /sbin/setlevel 测试:

1
2
3
4
-bash-2.05b$ touch test
-bash-2.05b$ sudo /sbin/setlevel SYS_ADMIN test
Password:
Sorry, user user2 is not allowed to execute '/sbin/setlevel SYS_ADMIN test' as root on localhost.localdomain.

无执行权限。

user2 使用 user_auth 获取授权并再次执行,使用 /sbin/getlevel 检查执行情况:

1
2
3
4
5
6
7
-bash-2.05b$ user_auth
CERTIFICATE PATH:/home/user2/user2.crt
PIN:
authentication Success!
-bash-2.05b$ sudo /sbin/setlevel SYS_ADMIN test
Password:
Sorry, user user2 is not allowed to execute '/sbin/setlevel SYS_ADMIN test' as root on localhost.localdomain.

执行失败。

可信路径机制

在任意时刻按下 Ctrl + Pause 组合键,系统会杀死当前终端所有进程并启动系统的登陆程序,可以保证用户不会被钓鱼登陆程序所欺骗获取得到用户名密码。

审计机制

查看当前时间:

1
2
[root@localhost root]# date
一 11月 14 05:59:54 CST 2022

打开审计:

1
2
[root@localhost root]# adton
Seclinux: audit enabled.

查看审计状态:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@localhost root]# adtstat
AUDITSTATE =AUDITON
AUDIT_DISKFULL =SWITCH
AUDIT_PGM =cd /var/audit;/bin/rm -f *
AUDIT_FULLPERCENT =80
AUDIT_LOGERR =DISABLE
AUDIT_PPATH =/var/audit
AUDIT_APATH =/var/audit
AUDIT_PNODE =pnode
AUDIT_ANODE =anode
AUDIT_MAXSIZE =5000000
AUDIT_BSIZE =2048
AUDIT_NBUFS =4
AUDIT_GMTSECOFF =0
AUDIT_VERSION =Seclinux3.0
System Fixed Mask=0xffffffff|0xffffffff|0xffffffff|0xffffffff|0xffffffff|0xffffffff|0xffffffff|0xffffffff
Level Mask =0x0|0x0|0x0|0x0|0x0|0x0|0x0|0x0

使用 adtset -d -a 查看系统和所有用户的审计屏蔽字:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@localhost root]# adtset -d -a
System Audit Criteria: fork,openrd,openwr,create,link,unlink
exec,chdir,mknod,chmod,lchown,mount,umount
setuid,stime,utime,access,rename,mkdir
rmdir,pipe,setgid,acctoff,acctsw,accton
ioctl,fcntl,setpgid,chroot,setsid,setreuid
setregid,setfsuid,setfsgid,setresuid
setresgid,sethostname,setrlimit,settimeofday
setgroups,symlink,uselib,reboot,truncate
ftruncate,fchmod,fchown,setpriority
ioperm,socketcall,syslog,iopl,crtmodule
delmodule,fchdir,flock,setsched,chown
capset,aclfile,aclipc,mkmld,lvlfile
lvltask,setauid,login_badname,login_badlvl
login_badmask,login_ok,login_refused
login_authfail,usradd,grpadd,usrdel
grpdel,usrmod,grpmod,passwd,gpasswd
adton,adtoff
Object Audit Criteria: none
User Audit Criteria:
root(0): none
user2(501): fork,exec,login_ok
user1(500): fork,exec,login_ok
user3(502): fork,exec,login_ok

使用 adtview 查看最新的审计信息:

使用 adtconfig 减小缓冲区以便能及时在硬盘上记录每条审计记录,并重启审计:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@localhost root]# adtconfig -b 8
[root@localhost root]# adtconfig -c 1
[root@localhost root]# adtoff
SecLinux: audit disabled.
[root@localhost root]# adton
Seclinux: audit enabled.
[root@localhost root]# adtstat
AUDITSTATE =AUDITON
AUDIT_DISKFULL =SWITCH
AUDIT_PGM =cd /var/audit;/bin/rm -f *
AUDIT_FULLPERCENT =80
AUDIT_LOGERR =DISABLE
AUDIT_PPATH =/var/audit
AUDIT_APATH =/var/audit
AUDIT_PNODE =pnode
AUDIT_ANODE =anode
AUDIT_MAXSIZE =5000000
AUDIT_BSIZE =8
AUDIT_NBUFS =1
AUDIT_GMTSECOFF =0
AUDIT_VERSION =Seclinux3.0
System Fixed Mask=0xffffffff|0xffffffff|0xffffffff|0xffffffff|0xffffffff|0xffffffff|0xffffffff|0xffffffff
Level Mask =0x0|0x0|0x0|0x0|0x0|0x0|0x0|0x0

关闭所有系统审计字和所有用户的审计字,打开 user1 的 exec 审计字:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@localhost root]# adtset -s -fork,openrd,openwr,create,link,unlink,exec,chdir,mknod,chmod,lchown,mount,umount,setuid,stime,utime,access,rename,mkdir,rmdir,pipe,setgid,acctoff,acctsw,accton,ioctl,fcntl,setpgid,chroot,setsid,setreuid,setregid,setfsuid,setfsgid,setresuid,setresgid,sethostname,setrlimit,settimeofday,setgroups,symlink,uselib,reboot,truncate,ftruncate,fchmod,fchown,setpriority,ioperm,socketcall,syslog,iopl,crtmodule,delmodule,fchdir,flock,setsched,chown,capset,aclfile,aclipc,mkmld,lvlfile,lvltask,setauid,login_badname,login_badlvl,login_badmask,login_ok,login_refused,login_authfail,usradd,grpadd,usrdel,grpdel,usrmod,grpmod,passwd,gpasswd,adton,adtoff
[root@localhost root]# adtset -a -e -fork
[root@localhost root]# adtset -a -e -exec
[root@localhost root]# adtset -a -e -login_ok
[root@localhost root]# adtset -u user1 -e +exec

[root@localhost root]# adtset -d -a
System Audit Criteria: usradd,grpadd,usrmod,grpmod
Object Audit Criteria: none
User Audit Criteria:
root(0): none
user2(501): none
user1(500): exec
user3(502): none

在 user1 中运行程序:

1
2
3
4
5
6
-bash-2.05b$ date
一 11月 14 07:30:18 CST 2022
-bash-2.05b$ cat test1
test user1
test user3 write
test user1 write

重新查看审计日志:

可以看到在使用 adtset 设置完成后只有 user1 的两个 sys_execve 系统调用被记录:

尝试在 user2 执行程序:

1
2
3
4
5
6
7
8
9
10
-bash-2.05b$ date
一 11月 14 07:36:12 CST 2022
-bash-2.05b$ date
一 11月 14 07:36:16 CST 2022
-bash-2.05b$ date
一 11月 14 07:36:17 CST 2022
-bash-2.05b$ date
一 11月 14 07:36:17 CST 2022
-bash-2.05b$ date
一 11月 14 07:36:17 CST 2022

重新查看审计日志,没有任何相关记录,符合设置。