diff --git a/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/Menu/index.md b/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/Menu/index.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/figures/image-20230828094539717.png b/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/figures/image-20230828094539717.png new file mode 100644 index 0000000000000000000000000000000000000000..db620cb37b44ba6cc3c30035ce65a2ef5a18efea Binary files /dev/null and b/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/figures/image-20230828094539717.png differ diff --git a/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/figures/image-20230828094723153.png b/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/figures/image-20230828094723153.png new file mode 100644 index 0000000000000000000000000000000000000000..fe85725a5748b7405bf0c4ac104158449098403e Binary files /dev/null and b/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/figures/image-20230828094723153.png differ diff --git a/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/figures/image-20230828135001624.png b/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/figures/image-20230828135001624.png new file mode 100644 index 0000000000000000000000000000000000000000..2b17e0dd49ad6ec34028fc233738581d0fa6e209 Binary files /dev/null and b/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/figures/image-20230828135001624.png differ diff --git a/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/figures/image-20230828140355863.png b/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/figures/image-20230828140355863.png new file mode 100644 index 0000000000000000000000000000000000000000..de9dbabc6e6f8a157a18e23ee8fbeb68ec2630e1 Binary files /dev/null and b/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/figures/image-20230828140355863.png differ diff --git a/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/figures/image-20230828140709441.png b/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/figures/image-20230828140709441.png new file mode 100644 index 0000000000000000000000000000000000000000..9dd87d5c65190428efd9bf81ee18e8809d6cc6d9 Binary files /dev/null and b/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/figures/image-20230828140709441.png differ diff --git a/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/media/media/image1.png b/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/media/media/image1.png new file mode 100644 index 0000000000000000000000000000000000000000..feff5b7bae51f432b5a8a05828295ace5b2f616d Binary files /dev/null and b/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/media/media/image1.png differ diff --git a/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/media/media/image2.png b/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/media/media/image2.png new file mode 100644 index 0000000000000000000000000000000000000000..c241e9356595daf58732a25a2bb31cd0a75bd027 Binary files /dev/null and b/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/media/media/image2.png differ diff --git a/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/media/media/image3.png b/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/media/media/image3.png new file mode 100644 index 0000000000000000000000000000000000000000..f00123d7b8553d8b7c374c7a0becd4269a663084 Binary files /dev/null and b/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/media/media/image3.png differ diff --git a/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/media/media/image4.png b/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/media/media/image4.png new file mode 100644 index 0000000000000000000000000000000000000000..9a047ff75fb1144c7df513345acef97357aa82b7 Binary files /dev/null and b/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/media/media/image4.png differ diff --git a/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/overview.md b/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..76fde7cef6cf6c41594275e75ab437392c0b4d23 --- /dev/null +++ b/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/overview.md @@ -0,0 +1 @@ +本文档是介绍基于 Rust 语言重构的 shell 及 Linux 命令,可在 openEuler 系统上使用,与 Linux 原生命令兼容。 diff --git a/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/utshell_guide.md b/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/utshell_guide.md new file mode 100644 index 0000000000000000000000000000000000000000..65a02a46f73e2e9358d9079ce45716894bf3ba66 --- /dev/null +++ b/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/utshell_guide.md @@ -0,0 +1,273 @@ +# utshell 用户手册 + +## 介绍 + +utshell 是一个与 bash 兼容的 shell。它实现了基本的内建命令执行和启动外部命令。同时也实现了任务、管道和信号处理等功能。 + +## 安装和卸载 + +### 安装 + +utshell 使用 rpm 命令进行安装,我们假设使用的是欧拉的 2309 系统: + +进入命令行界面执行: + +![截图.png](./media/media/image1.png) + +根据提示输入\"y\",即可安装成功。 + +![截图.png](./media/media/image2.png) + +### 卸载 + +在命令行执行`rpm -e utshell`即可卸载 utshell。 + +```shell + +rpm -e utshell + +``` + +![截图.png](./media/media/image3.png) + +## 使用 + +### 一般命令 + +在 utshell 环境下,直接键入命令名即可执行对应的命令。 + +utshell 支持如下内建命令: + +![截图.png](./media/media/image4.png) + +### 变量定义和使用 + +#### 变量定义 + +变量定义直接用\"=\",中间不能有空格。 + +```shell + +var=4 + +``` + +#### 变量使用 + +```shell + +echo \${var} + +``` + +### 数组的定义和使用 + +#### 数组的定义 + +```shell + +distros=(ubuntu fedora suse \"arch linux\") + +``` + +#### 数组的使用 + +```shell + +echo \${distros\[2\]} + +``` + +### 函数定义和使用 + +#### 函数的定义 + +```shell + +func() { echo \$1; } + +``` + +#### 函数的调用 + +```shell + +func 1 + +``` + +#### 给函数传递参数 + +调用函数时,在函数名后面直接以空格分割参数: + +func firstParam secondParam + +在函数体中使用\$1,\$2\...\...其中\$1 表示第一个参数,\$2 表示第二个参数,大于 9 的需要用大括号括起来。 + +```shell + +func() { + +echo \$1 \${10} \#需要传递 10 个参数 + +} + +\#调用 + +func 1 2 3 4 5 6 7 8 9 0 + +``` + +### 逻辑判断 + +#### if 语句 + +语法为: + +```shell + +if condition; then + +do-if-true; + +elif second-condition; then + +do-else-if-true + +elif third-condition; then + +do-else-if-third-true + +else + +do-else-false + +fi + +``` + +其中 condition 可以是命令,如: + +```shell + +if \[ \"\$s\" = \"string\" \]; then + +echo \"string is equivalent to \\\$s\" + +else + +echo \"string is not equivalent to \\\$s\" + +fi + +``` + +也可以是测试条件操作符: + +下面简单介绍些条件操作符: + +```shell + + -f 检查文件是否存在并且它是一个普通文件。 + + -d 检查提供的参数是否是目录。 + + -h 检查提供的参数是否是符号链接。 + + -s 检查文件是否存在且不为空。 + + -r 检查文件是否可读。 + + -w 检查文件是否可写。 + + -x 检查文件是否可执行。 + +``` + +如果用于数字比较,可以用如下测试条件操作符: + +```shell + + -lt 小于 + + -gt 大于 + + -ge 大于等于 + + -le 小于等于 + + -ne 不等于 + +``` + +如果用于字符串比较,可以用如下测试条件操作符: + +```shell + + == 两个字符串相同 + + = 两个字符串相同(同==) + + != 两个字符串不同 + + -z 空字符串,返回 true + + -n 长度不是 0,则返回 true + +``` + +### 循环 + +#### for 循环 + +```shell + +for number in 1 2 3 4 5 + +do + +echo \$number + +done + +使用列表: + +for number in {1..500..2} + +do + +echo \$number + +done + +``` + +其中{1..500..2}表示起始数字为 1,结束数字为 500(包括),步长为 2。 + +#### until 循环 + +```shell + +until \[condition\]; do + +commands + +done + +``` + +当条件为真时,执行循环; + +#### while 循环 + +```shell + +while \[ condition \]; do + +commands + +done + +``` + +当条件为真时,执行循环。 diff --git "a/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/utsudo-\347\224\250\346\210\267\346\214\207\345\215\227.md" "b/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/utsudo-\347\224\250\346\210\267\346\214\207\345\215\227.md" new file mode 100644 index 0000000000000000000000000000000000000000..3a50f647dc9ec77d50ad29dc89da39ff0957f7e5 --- /dev/null +++ "b/docs/zh/docs/1newStruct/Server/Administration/CompaCommand/utsudo-\347\224\250\346\210\267\346\214\207\345\215\227.md" @@ -0,0 +1,84 @@ +# utsudo 使用指南 + +本文档主要介绍`utsudo`工具的安装和简单使用,帮助用户快速上手。`utsudo`从参数功能到插件使用都是完全兼容`sudo`,大大降低了用户的学习成本,欢迎大家使用。 + +本文档主要适用于`utsudo`的开发人员、测试人员、以及普通用户。 + +## utsudo 介绍 + +utsudo 诞生于 2022 年 6 月份,是一个目前正在进行的使用 Rust 语言重构 Sudo 的项目。utsudo 旨在提供一个更加高效、安全、灵活的提权工具,涉及的模块主要有:通用工具库、整体框架和插件功能等。 + +## utsudo 安装 + +在`0.0.1`版本中,`utsudo`与`sudo`还存在部分文件冲突。需要先使用`yum`命令,把`utsudo`的二进制`rpm`包下载到本地,再使用`rpm`命令进行安装 ,以允许与`sudo`的文件冲突。 + +首先使用`yumdownloader utsudo`命令下载`utsudo`二进制包到本地。 + +然后使用`sudo rpm -Uvh utsudo-0.0.1-0.01.x86_64.rpm --replacefiles`命令安装`utsudo`,执行过程如下所示。 + +![image-20230828094539717](./figures/image-20230828094539717.png) + +安装完成后,使用`rpm -qa | grep utsudo`命令查看`utsudo`是否正常安装,如下图所示。 + +![image-20230828094723153](./figures/image-20230828094723153.png) + +由上图可知,`utsudo`已正常安装,安装的版本是`0.0.1-0.01`。 + +`utsudo`后续还会有版本更新,大家以自己安装的版本为准。 + +## utsudo使用 + +下面给大家介绍一下`utsudo`的简单使用。 + +`utsudo`参数较多,下面简单列出部分参数,详细内容可使用`utsudo -h`列出。 + +```shell + +-e, --edit 编辑文件而非执行命令 +-k, --reset-timestamp 无效的时间戳文件 +-l, --list 列出用户权限或检查某个特定命令;对于长格式,使用两次 + +``` + +### `-e` 参数 + +`-e`参数的功能:编辑文件。 + +`utsudo -e`相当于`sudoedit`命令,执行时会调用普通用户进行编辑,而位于调用用户可写目录中的文件是无法编辑的,除非该用户是`root`用户。 + +在当前用户没有可写权限的目录`e`中,存在一个当前用户没有可编辑权限的文件:`test.txt`。使用普通用户编辑`test.txt`文件,会提示没有权限。使用`utsudo -e`后,可以正常编辑。具体执行过程如下图所示。 + +![image-20230828135001624](./figures/image-20230828135001624.png) + +由上图可知,成功修改了`test.txt`文件的内容。(其中`utsudo -e is okay !!`,是我们在编辑器中自己添加的。) + +### `-k`参数 + +`-k`参数功能:使时间戳无效。 + +默认使用`utsudo`执行命令时,第一次是需要输入密码的,短时间内(默认是5分钟)再次执行`sudo`命令则不需要再次输入密码。使用`-k`参数可以强迫使用者在下一次执行`utsudo`时询问密码。 + +![image-20230828140355863](./figures/image-20230828140355863.png) + +`utsudo`输入密码后,默认`5`分钟之内不需要输入密码。 + +但是,由上图可知,`utsudo -k`使得`utsudo`的时间戳失效了。 + +### `-l`参数 + +`-l`参数功能:用于显示当前用户可以用`utsudo`执行哪些命令。 + +执行过程如下所示: + +![image-20230828140709441](./figures/image-20230828140709441.png) + +上图显示了`test`用户,可以运行如下命令: + +```shell + +(ALL) ALL + +``` +也就是所有命令,说明`/etc/sudoers`文件中,并没有对`test`用户做过多的限制。 + +`utsudo`的使用,就简单介绍这些,除了上面介绍到的,`utsudo`还有很多其他的功能和参数,此处就不一一列举了。欢迎大家讨论。 diff --git a/docs/zh/docs/1newStruct/Server/Administration/sysMaster/Menu/index.md b/docs/zh/docs/1newStruct/Server/Administration/sysMaster/Menu/index.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/docs/zh/docs/1newStruct/Server/Maintenance/A-Ops/Menu/index.md b/docs/zh/docs/1newStruct/Server/Maintenance/A-Ops/Menu/index.md new file mode 100644 index 0000000000000000000000000000000000000000..9db60b1cf6df692d3403c6325ae755b0bca0f14d --- /dev/null +++ b/docs/zh/docs/1newStruct/Server/Maintenance/A-Ops/Menu/index.md @@ -0,0 +1,12 @@ +--- +headless: true +--- +- [Aops用户指南]({{< relref "./docs/A-Ops/overview.md" >}}) + - [AOps部署指南]({{< relref "./docs/A-Ops/AOps部署指南.md" >}}) + - [AOps智能定位框架使用手册]({{< relref "./docs/A-Ops/AOps智能定位框架使用手册.md" >}}) + - [AOps漏洞管理模块使用手册]({{< relref "./docs/A-Ops/AOps漏洞管理模块使用手册.md" >}}) + - [热补丁dnf插件使用手册]({{< relref "./docs/A-Ops/dnf插件命令使用手册.md" >}}) + - [社区热补丁制作发布流程]({{< relref "./docs/A-Ops/社区热补丁制作发布流程.md" >}}) + - [gala-anteater使用手册]({{< relref "./docs/A-Ops/gala-anteater使用手册.md" >}}) + - [gala-gopher使用手册]({{< relref "./docs/A-Ops/gala-gopher使用手册.md" >}}) + - [gala-spider使用手册]({{< relref "./docs/A-Ops/gala-spider使用手册.md" >}}) \ No newline at end of file diff --git a/docs/zh/docs/1newStruct/Server/MemoryandStorage/overview.md b/docs/zh/docs/1newStruct/Server/MemoryandStorage/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..00e0746392712d842c638cab77e42eb5cd8585b5 --- /dev/null +++ b/docs/zh/docs/1newStruct/Server/MemoryandStorage/overview.md @@ -0,0 +1,151 @@ +# 管理内存 + +## 基本概念 + +**内存**是计算机的重要组成部件,用于暂时存放CPU中的运算数据,以及与硬件等外部存储器交换的数据。特别地,**非统一内存访问架构**(non-uniform memory access,简称NUMA)是一种为多处理器的电脑设计的内存架构,**内存访问时间取决于内存相对于处理器的位置**。在NUMA下,处理器访问本地内存的速度比非本地内存速度(内存位于另一个处理器,或者是处理器之间共享的内存)快。 + +## 查看内存 + +1. free:可用于**显示系统内存状态**。 + + 例如: + + ```shell + # 显示系统内存状态,以MB单位显示 + free -m + ``` + + 回显信息如下: + + ```shell + [root@openEuler ~]# free -m + total used free shared buff/cache available + Mem: 2633 436 324 23 2072 2196 + Swap: 4043 0 4043 + ``` + + 在命令的输出信息中,各字段所代表的含义如下: + + |标识|含义| + |--|--| + |total|总内存数。| + |used|已经使用的内存数。| + |free|空闲的内存数。| + |shared|多个进程共享的内存总数。| + |buff/cache|缓冲和缓存内存总数。| + |available|估计有多少内存可用于启动新应用程序,而不交换。| + +2. vmstat:可以**动态地监控系统内存**,查看系统内存的使用情况。 + + 例如: + + ```shell + # 监测系统内存,显示活跃和非活跃内存 + vmstat -a + ``` + + 回显信息如下: + + ```shell + [root@openEuler ~]# vmstat -a + procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- + r b swpd free inact active si so bi bo in cs us sy id wa st + 2 0 520 331980 1584728 470332 0 0 0 2 15 19 0 0 100 0 0 + ``` + + 在命令的输出信息中,与内存相关的memory字段所代表的含义如下: + + |字段|含义| + |--|--| + |memory|内存信息字段。-swpd:虚拟内存的使用情况,单位为 KB。-free:空闲的内存容量,单位为 KB。-inact:非活跃的内存容量,单位为 KB。-active:活跃的内存容量,单位为 KB。| + +3. sar:可用于**监控系统的内存使用情况**。 + + 例如: + + ```shell + # 系统内存在采样时间内的使用情况,每2秒统计一次,统计 3 次 + sar -r 2 3 + ``` + + 回显信息如下: + + ```shell + [root@openEuler ~]# sar -r 2 3 + + 04:02:09 PM kbmemfree kbavail kbmemused %memused kbbuffers kbcached kbcommit %commit kbactive kbinact kb + dirty + 04:02:11 PM 332180 2249308 189420 7.02 142172 1764312 787948 11.52 470404 1584924 + 36 + 04:02:13 PM 332148 2249276 189452 7.03 142172 1764312 787948 11.52 470404 1584924 + 36 + 04:02:15 PM 332148 2249276 189452 7.03 142172 1764312 787948 11.52 470404 1584924 + 36 + Average: 332159 2249287 189441 7.03 142172 1764312 787948 11.52 470404 1584924 + 36 + ``` + + 在命令的输出信息中,各字段所代表的含义如下: + + |字段|含义| + |--|--| + |kbmemfree|内存的未使用空间。| + |kbmemused|内存的已使用空间。| + |%memused|已使用空间的百分比。| + |kbbuffers|缓冲区的数据存取量。| + |kbcached|系统全域的数据存取量。| + +4. numactl:可用于**查看NUMA节点配置和状态**。 + + 例如: + + ```shell + # 查看当前的NUMA配置 + numactl -H + ``` + + 回显信息如下: + + ```shell + [root@openEuler ~]# numactl -H + available: 1 nodes (0) + node 0 cpus: 0 1 2 3 + node 0 size: 2633 MB + node 0 free: 322 MB + node distances: + node 0 + 0: 10 + ``` + + 服务器共划分为1个NUMA节点。每个节点包含4个CPU core,每个节点的内存大小约为6GB。 + 同时,该命令还给出了不同节点间的距离,距离越远,跨NUMA内存访问的延时越大。应用程序运行时应减少跨NUMA访问内存。 + + numastat:可用于**观察各个NUMA节点的状态** + + ```shell + # 观察NUMA节点的状态 + numastat + ``` + + ```shell + [root@openEuler ~]# numastat + node0 + numa_hit 5386186 + numa_miss 0 + numa_foreign 0 + interleave_hit 17483 + local_node 5386186 + other_node 0 + ``` + + numastat命令输出字段及其含义如下: + + |标识|含义| + |--|--| + |numa_hit|节点内CPU核访问本地内存的次数。| + |numa_miss|节点内核访问其他节点内存的次数。| + |numa_foreign|初始分配在本地,最后分配在其他节点的叶数量。每个numa_foreign对应numa_miss事件。| + |interleave_hit|interleave策略页成功分配到这个节点。| + |local_node|该节点的进程成功在这个节点上分配内存访问的大小。| + |other_node|该节点的进程在其他节点上分配的内存访问大小。| + \ No newline at end of file diff --git "a/docs/zh/docs/1newStruct/Server/Security/\345\206\205\346\240\270\345\256\214\346\225\264\346\200\247\345\272\246\351\207\217\357\274\210IMA\357\274\211.md" "b/docs/zh/docs/1newStruct/Server/Security/\345\206\205\346\240\270\345\256\214\346\225\264\346\200\247\345\272\246\351\207\217\357\274\210IMA\357\274\211.md" new file mode 100644 index 0000000000000000000000000000000000000000..98f1afc8b1de1afb58e4a87c3efb79629395dbdc --- /dev/null +++ "b/docs/zh/docs/1newStruct/Server/Security/\345\206\205\346\240\270\345\256\214\346\225\264\346\200\247\345\272\246\351\207\217\357\274\210IMA\357\274\211.md" @@ -0,0 +1,1140 @@ +# 内核完整性度量(IMA) + +## 概述 + +### IMA介绍 + +IMA,全称 Integrity Measurement Architecture(完整性度量架构),是内核中的一个子系统,能够基于自定义策略对通过`execve()`、`mmap()`和`open()`等系统调用访问的文件进行度量,度量结果可被用于**本地/远程证明**,或者和已有的参考值比较以**控制对文件的访问**。 + +IMA的运行模式主要包含以下两种: + +- 度量(measure):提供了对文件的完整性状态观测功能,访问受保护文件时,会往度量日志(位于内核内存中)增加度量记录。如果系统包含TPM芯片,还可以往TPM芯片PCR寄存器中扩展度量摘要值,以保证度量信息不被篡改。度量场景并不提供对文件访问的控制,它记录的文件信息可传递给上层应用软件,进一步用于远程证明。 +- 评估(appraise):提供了对文件的完整性校验功能,从根本上杜绝了未知的/被篡改的文件的访问。通过哈希、签名、HMAC等密码学技术对文件的内容进行完整性验证,如果验证失败,则不允许任何进程对该文件进行访问。该特性为系统提供了底层韧性设计,在系统被破坏时牺牲一部分功能(被篡改的部分文件),避免攻击造成的影响进一步升级。 + +可以看到,IMA度量模式相当于一个“只记录不干涉”的观察员,IMA评估模式相当于一位严格的保安人员,它的职责是拒绝对所有“人证不一”的文件访问。 + +### EVM介绍 + +EVM,全称 Extended Verification Module(扩展验证模块),是对IMA功能的扩展,在通过IMA实现对于文件内容的完整性保护的基础上,使用EVM可以更进一步地实现对于文件扩展属性(如UID、security.ima 、security.selinux等属性)的保护。 + +### IMA摘要列表介绍 + +IMA Digest Lists(IMA摘要列表)是openEuler对内核原生完整性保护机制的增强,旨在对原生的IMA/EVM机制的以下痛点进行优化: + +**TPM扩展导致文件访问性能下降:** + +IMA度量模式下,每次触发度量都需要访问TPM芯片,TPM属于低速芯片,通常采用几十MHz时钟频率的SPI协议与CPU通信,导致系统调用性能下降: + +![](./figures/ima_tpm.png) + +**非对称运算导致文件访问性能下降:** + +IMA评估模式下,需要使用签名机制保护不可变文件,每次触发文件校验都需要进行签名验证,而非对称运算相对复杂 ,同样导致系统调用性能下降: + +![](./figures/ima_sig_verify.png) + +**复杂的部署方式导致效率和安全性下降:** + +IMA评估模式下,需要通过fix模式进行部署,即系统首先需要进入fix模式进行IMA/EVM扩展属性标记,然后再切换为校验模式启动。同时在受保护的文件升级时,需要重启进入fix模式,完成文件和扩展属性更新。一方面降低了部署效率,另一方面需要在运行环境中访问密钥,降低了安全性: + +![](./figures/ima_priv_key.png) + +IMA摘要列表旨在通过一个哈希列表文件管理一系列文件的基准摘要值,即将若干文件(如一个软件包中的所有可执行文件)的基准摘要值汇总到单个文件中进行管理。基准摘要值可包含文件内容摘要(对应IMA模式)和文件扩展属性摘要(对应EVM模式),这个文件就是IMA摘要列表文件。 + +![](./figures/ima_digest_list_pkg.png) + +开启IMA摘要列表功能后,内核维护一个哈希白名单池,用于存放导入的IMA摘要列表文件中的摘要值,并通过securityfs对外提供IMA摘要列表文件的导入/删除/查询等接口。 + +在度量模式下,导入内核的摘要列表文件需要进行度量和TPM扩展才可添加至白名单池,后续如果度量的目标文件的摘要值和白名单池匹配,则不进行额外的度量日志记录以及TPM扩展;在评估模式下,导入内核的摘要列表文件需要通过签名验证才可添加至白名单池,后续将访问的目标文件的摘要值和白名单池中的摘要值进行匹配即可判断评估结果。 + +![](./figures/ima_digest_list_flow.png) + +相比Linux原生IMA/EVM机制,IMA摘要列表扩展从安全性、性能、易用性三个方面进行了改良,以实现更好的落地效果: + +- 安全性:IMA摘要列表可以随软件包一起发布,软件包安装时同步导入摘要列表,确保了基准值来自于软件发行商(如openEuler社区),避免在运行环境生成基准值的流程,实现了完整的信任链。 +- 性能:IMA摘要列表机制以摘要列表为单位进行度量/校验,降低TPM访问和非对称运算频率为1/n(n为平均单个摘要列表管理的文件哈希数量),可一定程度提升系统调用性能和系统启动性能。 +- 易用性:IMA摘要列表机制可以实现“开箱即用”,即完成系统安装后直接进入评估模式,且允许在评估模式下直接安装/升级软件包,而无需进入fix模式进行文件标记,从而实现快速部署和平滑升级。 + +需要注意的是,IMA摘要列表相比原生IMA/EVM,将度量/评估的基准值在内核内存中进行维护,也引入了一个假设,即内核内存不可被未授权篡改,这就使得IMA摘要列表也依赖于其他安全机制(如内核模块安全启动和内存动态度量等)以保护内核内存的完整性。 + +但无论社区原生IMA机制还是IMA摘要列表扩展,都只是系统安全链中的一环,无法孤立地保证系统的安全性,安全自始至终都是一个构建纵深防御的系统工程。 + +## 接口说明 + +### 内核启动参数说明 + +openEuler IMA/EVM机制提供的内核启动参数及说明如下: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
参数名称取值功能
ima_appraiseenforce-evmIMA评估强制校验模式(EVM开启)
log-evmIMA评估日志模式(EVM开启)
enforceIMA评估强制校验模式
logIMA评估日志模式
off关闭IMA评估
ima_appraise_digest_listdigest基于摘要列表进行IMA+EVM评估(比较文件内容和扩展属性)
digest-nometadata基于摘要列表进行IMA评估(只比较文件内容)
evmx509直接开启基于可移植签名的EVM(无论EVM证书是否加载)
complete启动后不允许通过securityfs接口修改EVM模式
allow_metadata_writes允许修改文件元数据,EVM不做拦截
ima_hashsha256/sha1/...声明IMA度量哈希算法
ima_templateima声明IMA度量模板(d|n)
ima-ng声明IMA度量模板(d-ng|n-ng),默认使用该模板
ima-sig声明IMA度量模板(d-ng|n-ng|sig)
ima_policyexec_tcb度量所有执行、映射方式访问的文件,以及加载的内核模块、固件、内核等文件
tcb在exec_tcb策略的基础上,额外度量以uid=0或euid=0身份访问的文件
secure_boot评估所有加载的内核模块、固件、内核等文件,并指定使用IMA签名模式
appraise_exec_tcb在secure_boot策略的基础上,额外评估所有执行、映射方式访问的文件
appraise_tcb评估访问的所有属主为0的文件
appraise_exec_immutable与appraise_exec_tcb策略配合使用,可执行文件的扩展属性不可变
ima_digest_list_pcr10在PCR 10中扩展基于摘要列表的IMA度量结果,禁用原生IMA度量
11在PCR 11中扩展基于摘要列表的IMA度量结果,禁用原生IMA度量
+11在PCR 11中扩展基于摘要列表的IMA度量结果,在PCR 10中扩展原生IMA度量结果
ima_digest_db_sizenn[M]设置内核摘要列表上限(0M~64M),不做配置的情况下默认为16MB(不做配置指的是不写该参数,但注意不能将值留空,如ima_digest_db_size=)
ima_capacity-1~2147483647设置内核度量日志条数上限,不做配置的情况下默认为100000条,配置-1表示无上限
initramtmpfs在initrd中支持tmpfs,以携带文件扩展属性
+ + +根据用户实际场景诉求,建议采取如下参数组合: + +**1) 原生IMA度量:** + +``` +# 原生IMA度量+自定义策略 +无需配置,默认开启 +# 原生IMA度量+TCB默认策略 +ima_policy="tcb" +``` + +**2) 基于摘要列表的IMA度量:** + +``` +# 摘要列表IMA度量+自定义策略 +ima_digest_list_pcr=11 ima_template=ima-ng initramtmpfs +# 摘要列表IMA度量+默认策略 +ima_digest_list_pcr=11 ima_template=ima-ng ima_policy="exec_tcb" initramtmpfs +``` + +**3) 基于摘要列表的IMA评估,只保护文件内容:** + +``` +# IMA评估+日志模式 +ima_appraise=log ima_appraise_digest_list=digest-nometadata ima_policy="appraise_exec_tcb" initramtmpfs +# IMA评估+强制校验模式 +ima_appraise=enforce ima_appraise_digest_list=digest-nometadata ima_policy="appraise_exec_tcb" initramtmpfs +``` + +**4) 基于摘要列表的IMA评估,保护文件内容和扩展属性:** + +``` +# IMA评估+日志模式 +ima_appraise=log-evm ima_appraise_digest_list=digest ima_policy="appraise_exec_tcb|appraise_exec_immutable" initramtmpfs evm=x509 evm=complete +# IMA评估+强制校验模式 +ima_appraise=enforce-evm ima_appraise_digest_list=digest ima_policy="appraise_exec_tcb|appraise_exec_immutable" initramtmpfs evm=x509 evm=complete +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 以上四种参数都可以单独配置使用,但只有基于摘要列表的度量和评估模式可以组合使用,即2)和3)搭配或2)和4)搭配。 + +### securityfs接口说明 + +openEuler IMA提供的securityfs接口位于`/sys/kernel/security`目录下,接口名及说明如下: + +| 路径 | 权限 | 说明 | +| :----------------------------- | :--- | :-------------------------------------- | +| ima/policy | 600 | IMA策略查询/导入接口 | +| ima/ascii_runtime_measurement | 440 | 查询IMA度量日志,以字符串形式输出 | +| ima/binary_runtime_measurement | 440 | 查询IMA度量日志,以二进制形式输出 | +| ima/runtime_measurement_count | 440 | 查询IMA度量日志条数 | +| ima/violations | 440 | 查询异常IMA度量日志数量 | +| ima/digests_count | 440 | 显示系统哈希表中的总摘要数量(IMA+EVM) | +| ima/digest_list_data | 200 | 摘要列表新增接口 | +| ima/digest_list_data_del | 200 | 摘要列表删除接口 | +| evm | 660 | 查询/设置EVM模式 | + +其中,`/sys/kernel/security/evm` 的接口的取值有以下三种: + +- 0:EVM 未初始化; +- 1:使用 HMAC(对称加密)方式校验扩展属性完整性; +- 2:使用公钥验签(非对称加密)方式校验扩展属性完整性; +- 6:关闭扩展属性完整性校验。 + +### 摘要列表管理工具说明 + +digest-list-tools软件包提供IMA摘要列表文件生成和管理的工具,主要包含如下几个命令行工具: + +#### gen_digest_lists工具 + +用户可通过调用gen_digest_lists命令行工具生成摘要列表。命令参数定义如下: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
参数名称取值功能
-d<path>指定生成摘要列表文件存放的位置,需为有效目录。
-fcompact指定生成摘要列表文件的格式,当前仅支持compact格式。
-i<option arg>:<option value>指定生成摘要列表的目标文件范围,具体参数定义如下。
I:<path>指定需要生成摘要列表的文件绝对路径,如指定目录,则会执行递归生成。
E:<path>指定需要排除的路径或目录。
F:<path>指定路径或目录,为该路径或目录下所有文件生成摘要列表(同时指定e:参数时,忽略e:选项的筛选效果)。
e:仅对可执行文件生成摘要列表。
l:policy从系统SELinux策略匹配文件安全上下文,而不是直接从文件扩展属性中读取安全上下文。
i:当生成metadata类型的摘要列表时,被计算的扩展属性信息包含文件的摘要值(必须指定)。
M:允许显式指定文件的扩展属性信息(需要结合rpmbuild命令使用)。
u:将“L:”参数所指定的列表文件名作为生成摘要列表的文件名(需要结合rpmbuild命令使用)。
L:<path>指定列表文件的路径,列表文件中包含需要生成摘要列表的信息数据(需要结合rpmbuild命令使用)。
-oadd指定生成摘要列表的操作,当前仅支持add操作,即将摘要列表添加到文件中。
-p-1指定将摘要列表写入文件中的位置,当前仅支持指定-1。
-tfile只针对文件内容生成摘要列表。
metadata针对对文件的内容和扩展属性分别生成摘要列表。
-TNA不添加该参数,则生成摘要列表文件,添加该参数则生成TLV摘要列表文件。
-A<path>指定相对根目录,将文件路径截去指定的前缀进行路径匹配和SELinux标签匹配。
-mimmutable指定生成摘要列表文件的modifiers属性,当前仅支持指定immutable。摘要列表在enforce/enforece-evm模式下,摘要列表只能以只读模式打开。
-hNA打印帮助信息。
+ +**参考使用示例:** + +- 场景1:为单个文件生成摘要列表/TLV摘要列表。 + + ``` + gen_digest_lists -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/usr/bin/ls -d ./ -i i: gen_digest_lists -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/usr/bin/ls -d ./ -i i: -T + ``` + +- 场景2: 为单个文件生成摘要列表/TLV摘要列表,并指定相对根目录。 + + ``` + gen_digest_lists -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/usr/bin/ls -A /usr/ -d ./ -i i: gen_digest_lists -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/usr/bin/ls -A /usr/ -d ./ -i i: -T + ``` + +- 场景3:为目录下的文件递归生成摘要列表/TLV摘要列表。 + + ``` + gen_digest_lists -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/usr/bin/ -d ./ -i i: + gen_digest_lists -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/usr/bin/ -d ./ -i i: -T + ``` + +- 场景4:为目录下的可执行文件递归生成摘要列表/TLV摘要列表。 + + ``` + gen_digest_lists -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/usr/bin/ -d ./ -i i: -i e:gen_digest_lists -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/usr/bin/ -d ./ -i i: -i e: -T + ``` + +- 场景5:为目录下的文件递归生成摘要列表/TLV摘要列表,排除部分子目录。 + + ``` + gen_digest_lists -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/usr/ -d ./ -i i: -i E:/usr/bin/gen_digest_lists -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/usr/ -d ./ -i i: -i E:/usr/bin/ -T + ``` + +- 场景6:rpmbuild回调脚本中,通过读取rpmbuild传入的列表文件生成摘要列表。 + + ``` + gen_digest_lists -i M: -t metadata -f compact -d $DIGEST_LIST_DIR -i l:policy \ + -i i: -o add -p -1 -m immutable -i L:$BIN_PKG_FILES -i u: \ + -A $RPM_BUILD_ROOT -i e: \ + -i E:/usr/src \ + -i E:/boot/efi \ + -i F:/lib \ + -i F:/usr/lib \ + -i F:/lib64 \ + -i F:/usr/lib64 \ + -i F:/lib/modules \ + -i F:/usr/lib/modules \ + -i F:/lib/firmware \ + -i F:/usr/lib/firmware + + gen_digest_lists -i M: -t metadata -f compact -d $DIGEST_LIST_DIR.tlv \ + -i l:policy -i i: -o add -p -1 -m immutable -i L:$BIN_PKG_FILES -i u: \ + -T -A $RPM_BUILD_ROOT -i e: \ + -i E:/usr/src \ + -i E:/boot/efi \ + -i F:/lib \ + -i F:/usr/lib \ + -i F:/lib64 \ + -i F:/usr/lib64 \ + -i F:/lib/modules \ + -i F:/usr/lib/modules \ + -i F:/lib/firmware \ + -i F:/usr/lib/firmware + ``` + +#### manage_digest_lists工具 + +manage_digest_lists命令行工具主要用于将二进制格式的TLV摘要列表文件解析转换为可读的文本形式。命令参数定义如下: + +| 参数名称 | 取值 | 功能 | +| -------- | ---------- | ----------------------------------------------------------- | +| -d | \ | 指定TLV摘要列表文件存放的目录。 | +| -f | \ | 指定TLV摘要列表文件名。 | +| -p | dump | 指定操作类型,当前仅支持dump,表示解析打印TLV摘要列表操作。 | +| -v | NA | 打印详细信息。 | +| -h | NA | 打印帮助信息。 | + +**参考使用示例:** + +查看TLV摘要列表信息: + +``` +manage_digest_lists -p dump -d /etc/ima/digest_lists.tlv/ +``` + +## 文件格式说明 + +### IMA策略文件语法说明 + +IMA策略文件为文本文件,一个文件中可包含若干条按照换行符`\n`分隔的规则语句,每条规则语句都必须以 action 关键字代表的**动作**开头,后接**筛选条件**: + +``` + <筛选条件1> [筛选条件2] [筛选条件3]... +``` + +action表示该条策略具体的动作,一条策略只能选一个 action,具体的action见后表(实际书写时**可忽略 action 字样**,例如直接书写 dont_measure,不需要写成 action=dont_measure): + +筛选条件支持如下几种类型: + +- func:表示被度量或评估的文件类型,常和 mask 匹配使用,一条策略只能选一个 func。 + + - FILE_CHECK 只能同 MAY_EXEC、MAY_WRITE、MAY_READ 匹配使用。 + - MODULE_CHECK、MMAP_CHECK、BPRM_CHECK 只能同 MAY_EXEC 匹配使用。 + - 匹配关系以外的组合不会产生效果。 + +- mask:表示文件在做什么操作时将被度量或评估,一条策略只能选一个 mask。 + +- fsmagic:表示文件系统类型的十六进制魔数,定义在 `/usr/include/linux/magic.h` 文件中(默认情况下度量所有文件系统,除非使用 dont_measure/dont_appraise 标记不度量某文件系统)。 + +- fsuuid:表示系统设备 uuid 的 16 位的十六进制字符串。 + +- objtype:表示文件安全类型,一条策略只能选一个文件类型,objtype 相比 func 而言,划分的粒度更细,比如 obj_type=nova_log_t 表示SELinux类型为 nova_log_t 的文件。 + +- uid:表示哪个用户(用用户 id 表示)对文件进行操作,一条策略只能选一个 uid。 + +- fowner:表示文件的属主(用用户 id 表示)是谁,一条策略只能选一个 fowner。 + +关键字的具体取值及说明如下: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
关键字说明
actionmeasure开启IMA度量
dont_measure禁用IMA度量
appraise开启IMA评估
dont_appraise禁用IMA评估
audit开启审计
funcFILE_CHECK将要被打开的文件
MODULE_CHECK将要被装载的内核模块文件
MMAP_CHECK将要被映射到进程内存空间的动态库文件
BRPM_CHECK将要被执行的文件(不含通过 /bin/hash 等程序打开的脚本文件)
POLICY_CHECK将要被导入的IMA策略文件
FIRMWARE_CHECK将要被加载到内存中的固件
DIGEST_LIST_CHECK将要被加载到内核中的摘要列表文件
KEXEC_KERNEL_CHECK将要切换的 kexec 内核
maskMAY_EXEC执行文件
MAY_WRITE写文件
MAY_READ读文件
MAY_APPEND扩展文件属性
fsmagicfsmagic=xxx表示文件系统类型的十六进制魔数
fsuuidfsuuid=xxx表示系统设备 uuid 的 16 位的十六进制字符串
fownerfowner=xxx文件属主的用户 id
uiduid=xxx操作文件的用户 id
obj_typeobj_type=xxx_t表示文件的类型(基于 SELinux 标签)
pcrpcr=选择 TPM 中用于扩展度量值的 PCR(默认为 10)
appraise_typeimasig基于签名进行IMA评估
meta_immutable基于签名进行文件扩展属性的评估(支持摘要列表)
+ +## 使用说明 + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 原生IMA/EVM为Linux开源特性,本章节仅简单介绍基本使用方式,其他资料可参考开源WIKI: +> +> + +### 原生IMA使用说明 + +#### IMA度量模式 + +用户需要配置度量策略,开启IMA度量功能,具体步骤如下: + +**步骤1:** 用户可通过配置启动参数或手动配置的方式,指定度量策略。通过启动参数配置IMA策略的示例如下: + +``` +ima_policy="tcb" +``` + +手动配置IMA策略的示例如下: + +``` +echo "measure func=BPRM_CHECK" > /sys/kernel/security/ima/policy +``` + +**步骤2:** 重启系统,用户可实时检查度量日志获取当前的度量情况: + +``` +cat /sys/kernel/security/ima/ascii_runtime_measurements +``` + +#### IMA评估模式 + +用户需要首先进入fix模式,完成文件的IMA标记后,再开启log或enforce模式。具体步骤如下: + +**步骤1:** 配置启动参数,重启后进入fix模式: + +``` +ima_appraise=fix ima_policy=appraise_tcb +``` + +**步骤2:** 为所有需要评估的文件生成IMA扩展属性: + +对于不可变文件(如二进制程序文件)可以使用签名模式,将文件摘要值的签名写入IMA扩展属性中。举例如下(其中`/path/to/ima.key`指的是和IMA证书匹配的签名私钥): + +``` +find /usr/bin -fstype ext4 -type f -executable -uid 0 -exec evmctl -a sha256 ima_sign --key /path/to/ima.key '{}' \; +``` + +对于可变文件(如数据文件)可以使用哈希模式,将文件的摘要值写入IMA扩展属性中。IMA支持自动标记机制,即在fix模式下仅需触发文件访问,即可自动生成IMA扩展属性: + +``` +find / -fstype ext4 -type f -uid 0 -exec dd if='{}' of=/dev/null count=0 status=none \; +``` + +可通过如下命令检查文件是否被成功标记了IMA扩展属性(security.ima): + +``` +getfattr -m - -d /sbin/init +``` + +**步骤3:** 配置启动参数,修改IMA评估为log或enforce模式后,重启系统: + +``` +ima_appraise=enforce ima_policy=appraise_tcb +``` + +### IMA摘要列表使用说明 + +#### 前置条件 + +IMA摘要列表特性使用前,用户需安装`ima-evm-utils`和`digest-list-tools`软件包: + +``` +yum install ima-evm-utils digest-list-tools +``` + +#### 机制介绍 + +##### 摘要列表文件 + +在安装openEuler发布的RPM包后,默认会在`/etc/ima`目录下生成摘要列表文件。根据文件名的不同,存在如下几种文件: + +**/etc/ima/digest_lists/0-metadata_list-compact-** + +为IMA摘要列表文件,通过`gen_digest_lists`命令生成(生成方法详见[gen_digest_lists工具](#gen_digest_list工具)),该文件为二进制格式,包含header信息以及一连串SHA256哈希值,分别代表合法的文件内容摘要值和文件扩展属性摘要值。该文件被度量或评估后,最终被导入内核,并以该文件中的白名单摘要值为基准进行IMA摘要列表度量或评估。 + +**/etc/ima/digest_lists/0-metadata_list-rpm-** + +为RPM摘要列表文件,**实际为RPM包的头信息**。RPM包安装后,如果IMA摘要列表文件不包含签名,则会把RPM头信息写入该文件中,并将头信息的签名写入`security.ima`扩展属性中。这样通过签名可验证RPM头信息的真实性,由于RPM头信息又包含了摘要列表文件的摘要值,则可实现摘要列表的间接验证。 + +**/etc/ima/digest_lists/0-parser_list-compact-libexec** + +为IMA PARSER摘要列表文件,存放`/usr/libexec/rpm_parser`文件的摘要值。该文件用于实现RPM摘要列表->IMA摘要列表的信任链,内核IMA摘要列表机制会对该文件执行后产生的进程进行特殊校验,如果确定是`rpm_parser`程序,则会信任其导入的所有摘要列表而无需校验签名。 + +**/etc/ima/digest_lists.sig/0-metadata_list-compact-.sig** + +为IMA摘要列表的签名文件,若RPM包中包含此文件,则在RPM包安装阶段,会将该文件的内容写入对应的RPM摘要列表文件的`security.ima`扩展属性,从而在IMA摘要列表导入内核阶段进行签名验证。 + +**/etc/ima/digest_lists.tlv/0-metadata_list-compact_tlv-** + +为TLV摘要列表文件,通常在对目标文件生成IMA摘要列表文件时一并生成,存放目标文件的完整性信息(文件内容摘要值、文件扩展属性等)。该文件的功能是协助用户查询/恢复目标文件的完整性信息。 + +##### 摘要列表文件签名方式 + +在IMA摘要列表评估模式下,IMA摘要列表文件需要经过签名验证才可导入内核,并用于后续的文件白名单匹配。IMA摘要列表文件支持如下几种签名方式: + +**1) IMA扩展属性签名** + +即原生的IMA签名机制,将签名信息按照一定格式,存放在`security.ima`扩展属性中。可通过`evmctl`命令生成并添加: + +``` +evmctl ima_sign --key /path/to/ima.key -a sha256 +``` + +也可添加`-f`参数,将签名信息和头信息存入独立的文件中: + +``` +evmctl ima_sign -f --key /path/to/ima.key -a sha256 +``` + +在开启IMA摘要列表评估模式下,可直接将摘要列表文件路径写入内核接口,实现摘要列表的导入/删除。该过程会自动触发评估,基于`security.ima`扩展属性完成对摘要列表文件内容的签名验证: + +``` +# 导入IMA摘要列表文件 +echo > /sys/kernel/security/ima/digest_list_data +# 删除IMA摘要列表文件 +echo > /sys/kernel/security/ima/digest_list_data_del +``` + +**2) IMA摘要列表追加签名(openEuler 24.03 LTS版本默认)** + +openEuler 24.03 LTS版本开始支持IMA专用签名密钥,并采用CMS签名。由于签名信息包含证书链,可能由于长度超出限制而无法写入文件的`security.ima`扩展属性中,因此采用类似内核模块的追加签名的方式: + + + +其签名机制为: + +1) 将CMS签名信息追加到IMA摘要列表文件末尾; + +2) 填充结构体并添加到签名信息末尾,结构体定义如下: + +``` +struct module_signature { + u8 algo; /* Public-key crypto algorithm [0] */ + u8 hash; /* Digest algorithm [0] */ + u8 id_type; /* Key identifier type [PKEY_ID_PKCS7] */ + u8 signer_len; /* Length of signer's name [0] */ + u8 key_id_len; /* Length of key identifier [0] */ + u8 __pad[3]; + __be32 sig_len; /* Length of signature data */ +}; +``` + +3) 添加魔鬼字符串`"~Module signature appended~\n"` + +此步骤的参考脚本如下: + +``` +#!/bin/bash +DIGEST_FILE=$1 # IMA摘要列表文件路径 +SIG_FILE=$2 # IMA摘要列表签名信息保存路径 +OUT=$3 #完成签名信息添加后的摘要列表文件输出路径 + +cat $DIGEST_FILE $SIG_FILE > $OUT +echo -n -e "\x00\x00\x02\x00\x00\x00\x00\x00" >> $OUT +echo -n -e $(printf "%08x" "$(ls -l $SIG_FILE | awk '{print $5}')") | xxd -r -ps >> $OUT +echo -n "~Module signature appended~" >> $OUT +echo -n -e "\x0a" >> $OUT +``` + +**3) 复用RPM签名(openEuler 22.03 LTS版本默认)** + +openEuler 22.03 LTS版本支持复用RPM签名机制实现IMA摘要列表文件的签名。旨在解决版本无专用IMA签名密钥的问题。用户无需感知该签名流程,当RPM包中含有IMA摘要列表文件,而不包含IMA摘要列表的签名文件时,会自动使用该签名机制。其核心原理是通过RPM包的头信息实现对IMA摘要列表的验证。 + +对于openEuler发布的RPM包,每一个包文件可以包含两部分: + +- **RPM头信息:** 存放RPM包属性字段,如包名、文件摘要值列表等,通过RPM头签名保证其完整性; +- **RPM文件:** 实际安装至系统中的文件,也包括构建阶段生成的IMA摘要列表文件。 + + + +在RPM包安装阶段,如果RPM进程检测到包中的摘要列表文件不包含签名,则在`/etc/ima`目录下创建一个RPM摘要列表文件,将RPM头信息写入文件内容,将RPM头签名写入文件的`security.ima`扩展属性中。后续可通过RPM摘要列表间接实现IMA摘要列表的验证和导入。 + +##### IMA摘要列表导入 + +在开启IMA度量模式下,导入IMA摘要列表文件无需经过签名验证,可直接将路径写入内核接口,实现摘要列表的导入/删除: + +``` +# 导入IMA摘要列表文件 +echo > /sys/kernel/security/ima/digest_list_data +# 删除IMA摘要列表文件 +echo > /sys/kernel/security/ima/digest_list_data_del +``` + +在开启IMA评估模式下,导入摘要列表必须通过签名验证。根据签名方式不同,可分为两种导入方式。 + +**直接导入方式** + +对于已包含签名信息的IMA摘要列表文件(IMA扩展属性签名或IMA摘要列表追加签名),可直接将路径写入内核接口,实现摘要列表的导入/删除。该过程会自动触发评估,基于`security.ima`扩展属性完成对摘要列表文件内容的签名验证: + +``` +# 导入IMA摘要列表文件 +echo > /sys/kernel/security/ima/digest_list_data +# 删除IMA摘要列表文件 +echo > /sys/kernel/security/ima/digest_list_data_del +``` + +**调用`upload_digest_lists`导入方式** + +对于复用RPM签名的IMA摘要列表文件,需要调用`upload_digest_lists`命令实现导入。具体命令如下(注意指定的路径为对应的RPM摘要列表): + +``` +# 导入IMA摘要列表文件 +upload_digest_lists add +# 删除IMA摘要列表文件 +upload_digest_lists del +``` + +该流程相对复杂,需要满足以下前置条件: + +1) 系统已导入openEuler发布的`digest_list_tools`软件包中的摘要列表(包含IMA摘要列表和IMA PARSER摘要列表); + +2) 已配置对应用程序执行的IMA评估策略(BPRM_CHECK策略)。 + +#### 操作指导 + +##### RPM构建自动生成摘要列表 + +openEuler RPM工具链支持`%__brp_digest_list`宏定义,配置格式如下: + +``` +%__brp_digest_list /usr/lib/rpm/brp-digest-list %{buildroot} +``` + +当配置了该宏定义后,当用户调用`rpmbuild`命令进行软件包构建时,在RPM打包阶段会调用`/usr/lib/rpm/brp-digest-list`脚本进行摘要列表的生成和签名等流程。openEuler默认针对可执行程序、动态库、内核模块等关键文件生成摘要列表。用户也可以通过修改脚本,自行配置生成摘要列表的范围和指定签名密钥。如下示例使用用户自定义的签名密钥`/path/to/ima.key`进行摘要列表签名。 + +``` +...... (line 66) +DIGEST_LIST_TLV_PATH="$DIGEST_LIST_DIR.tlv/0-metadata_list-compact_tlv-$(basename $BIN_PKG_FILES)" +[ -f $DIGEST_LIST_TLV_PATH ] || exit 0 + +chmod 644 $DIGEST_LIST_TLV_PATH +echo $DIGEST_LIST_TLV_PATH + +evmctl ima_sign -f --key /path/to/ima.key -a sha256 $DIGEST_LIST_PATH &> /dev/null +chmod 400 $DIGEST_LIST_PATH.sig +mkdir -p $DIGEST_LIST_DIR.sig +mv $DIGEST_LIST_PATH.sig $DIGEST_LIST_DIR.sig +echo $DIGEST_LIST_DIR.sig/0-metadata_list-compact-$(basename $BIN_PKG_FILES).sig +``` + +##### IMA摘要列表度量 + +用户可通过如下功能开启IMA摘要列表度量: + +**步骤1:** 用户需要配置启动参数度量策略,开启IMA度量功能,具体步骤同**原生IMA度量**,不同的是需要单独配置度量所使用的TPM PCR寄存器,启动参数示例如下: + +``` +ima_policy=exec_tcb ima_digest_list_pcr=11 +``` + +**步骤2:** 用户导入IMA摘要列表,以`bash`软件包的摘要列表为例: + +``` +echo /etc/ima/digest_lists/0-metadata_list-compact-bash-5.1.8-6.oe2203sp1.x86_64 > /sys/kernel/security/ima/digest_list_data +``` + +可查询到IMA摘要列表的度量日志: + +``` +cat /sys/kernel/security/ima/ascii_runtime_measurements +``` + +导入IMA摘要列表后,如果后续度量的文件摘要值包含在IMA摘要列表中,则不会额外记录度量日志。 + +##### IMA摘要列表评估 + +###### 默认策略启动场景 + +用户可在启动参数中配置`ima_policy`参数指定IMA默认策略,则在内核启动阶段,IMA初始化完成后立即启用默认策略进行评估。用户可通过如下功能开启IMA摘要列表评估: + +**步骤1:** 执行`dracut`命令将摘要列表文件写入initrd: + +``` +dracut -f -e xattr +``` + +**步骤2:** 配置启动参数和IMA策略,典型的配置如下: + +``` +# 基于摘要列表的IMA评估log/enforce模式,只保护文件内容,配置默认策略为appraise_exec_tcb +ima_appraise=log ima_appraise_digest_list=digest-nometadata ima_policy="appraise_exec_tcb" initramtmpfs module.sig_enforce +ima_appraise=enforce ima_appraise_digest_list=digest-nometadata ima_policy="appraise_exec_tcb" initramtmpfs module.sig_enforce +# 基于摘要列表的IMA评估log/enforce模式,保护文件内容和扩展属性,配置默认策略为appraise_exec_tcb+appraise_exec_immutable +ima_appraise=log-evm ima_appraise_digest_list=digest ima_policy="appraise_exec_tcb|appraise_exec_immutable" initramtmpfs evm=x509 evm=complete module.sig_enforce +ima_appraise=enforce-evm ima_appraise_digest_list=digest ima_policy="appraise_exec_tcb|appraise_exec_immutable" initramtmpfs evm=x509 evm=complete module.sig_enforce +``` + +重启系统即可开启IMA摘要列表评估功能,启动过程中自动完成IMA策略生效和IMA摘要列表文件导入。 + +###### 无默认策略启动场景 + +用户可在启动参数中不配置`ima_policy`参数,代表系统启动阶段无默认策略,IMA评估机制等待用户导入策略后生效启用。 + +**步骤1:** 配置启动参数,典型的配置如下: + +``` +# 基于摘要列表的IMA评估log/enforce模式,只保护文件内容,无默认策略 +ima_appraise=log ima_appraise_digest_list=digest-nometadata initramtmpfs +ima_appraise=enforce ima_appraise_digest_list=digest-nometadata initramtmpfs +# 基于摘要列表的IMA评估log/enforce模式,保护文件内容和扩展属性,无默认策略 +ima_appraise=log-evm ima_appraise_digest_list=digest initramtmpfs evm=x509 evm=complete +ima_appraise=enforce-evm ima_appraise_digest_list=digest initramtmpfs evm=x509 evm=complete +``` + +重启系统,此时由于系统无策略,IMA评估并不生效。 + +**步骤2:** 导入IMA策略,将策略文件的全路径写入内核接口: + +``` +echo /path/to/policy > /sys/kernel/security/ima/policy +``` + +> ![](./public_sys-resources/icon-note.gif) **说明:** +> +> 策略中需要包含一些固定规则,用户可参考如下策略模板: +> +> openEuler 22.03 LTS版本的策略模板如下(复用RPM签名场景): +> +``` +# 不评估securityfs文件系统的访问行为 +dont_appraise fsmagic=0x73636673 +# 其他用户自定义的dont_appraise规则 +...... +# 评估导入的IMA摘要列表文件 +appraise func=DIGEST_LIST_CHECK appraise_type=imasig +# 评估/usr/libexec/rpm_parser进程打开的所有文件 +appraise parser appraise_type=imasig +# 评估执行的应用程序(触发对/usr/libexec/rpm_parser执行的评估,也可以新增其他限制条件,如SELinux标签等) +appraise func=BPRM_CHECK appraise_type=imasig +# 其他用户自定义的appraise规则 +...... +``` +> +> openEuler 24.03 LTS版本的策略模板如下(IMA扩展属性签名或追加签名场景): +> +``` +# 用户自定义的dont_appraise规则 +...... +# 评估导入的IMA摘要列表文件 +appraise func=DIGEST_LIST_CHECK appraise_type=imasig|modsig +# 其他用户自定义的appraise规则 +...... +``` + +**步骤3:** 导入IMA摘要列表文件,对于不同签名方式的摘要列表,需要使用不同的导入方式。 + +openEuler 22.03 LTS的摘要列表导入方式如下(复用RPM签名的IMA摘要列表): + +``` +# 导入digest_list_tools软件包的摘要列表 +echo /etc/ima/digest_lists/0-metadata_list-compact-digest-list-tools-0.3.95-13.x86_64 > /sys/kernel/security/ima/digest_list_data +echo /etc/ima/digest_lists/0-parser_list-compact-libexec > /sys/kernel/security/ima/digest_list_data +# 导入其他的RPM摘要列表 +upload_digest_lists add /etc/ima/digest_lists +# 检查导入的摘要列表条数 +cat /sys/kernel/security/ima/digests_count +``` + +openEuler 24.03 LTS的摘要列表导入方式如下(追加签名的IMA摘要列表): + +``` +find /etc/ima/digest_lists -name "0-metadata_list-compact-*" -exec echo {} > /sys/kernel/security/ima/digest_list_data \; +``` + +##### 软件升级场景 + +开启IMA摘要列表功能后,对于覆盖在IMA保护范围内的文件,在升级更新场景需要同步更新摘要列表。对于openEuler发布的RPM包,在包安装、升级、卸载的同时,将自动完成RPM包中的摘要列表的添加、更新和删除,不需要用户手动操作。对于用户维护的非RPM格式的软件包,则需要手动完成摘要列表的导入。 + +##### 用户证书导入 + +用户可以通过导入自定义证书,从而针对非openEuler发布的软件进行度量或评估。openEuler IMA评估模式支持从如下两种密钥环中获取证书进行签名校验: + +- builtin_trusted_keys密钥环:内核编译时预置的根证书; +- ima密钥环:通过initrd中的/etc/keys/x509_ima.der导入,需要为builtin_trusted_keys密钥环中任意一本证书的子证书。 + +**将根证书导入builtin_trusted_keys密钥环的步骤如下:** + +**步骤1:** 生成根证书,以openssl命令为例: + +``` +echo 'subjectKeyIdentifier=hash' > root.cfg +openssl genrsa -out root.key 4096 +openssl req -new -sha256 -key root.key -out root.csr -subj "/C=AA/ST=BB/O=CC/OU=DD/CN=openeuler test ca" +openssl x509 -req -days 3650 -extfile root.cfg -signkey root.key -in root.csr -out root.crt +openssl x509 -in root.crt -out root.der -outform DER +``` + +**步骤2:** 获取openEuler kernel源码,以最新的OLK-5.10分支为例: + +``` +git clone https://gitee.com/openeuler/kernel.git -b OLK-5.10 +``` + +**步骤3:** 进入源码目录,并将根证书拷贝至目录下: + +``` +cd kernel +cp /path/to/root.der . +``` + +修改config文件的CONFIG_SYSTEM_TRUSTED_KEYS选项: + +``` +CONFIG_SYSTEM_TRUSTED_KEYS="./root.crt" +``` + +**步骤4:** 编译安装内核(步骤略,注意需要为内核模块生成摘要列表)。 + +**步骤5:** 重启后检查证书导入成功: + +``` +keyctl show %:.builtin_trusted_keys +``` + +**将子证书导入ima密钥环的步骤如下,注意需要提前将根证书导入builtin_trusted_keys密钥环:** + +**步骤1:** 基于根证书生成子证书,以openssl命令为例: + +``` +echo 'subjectKeyIdentifier=hash' > ima.cfg +echo 'authorityKeyIdentifier=keyid,issuer' >> ima.cfg +echo 'keyUsage=digitalSignature' >> ima.cfg +openssl genrsa -out ima.key 4096 +openssl req -new -sha256 -key ima.key -out ima.csr -subj "/C=AA/ST=BB/O=CC/OU=DD/CN=openeuler test ima" +openssl x509 -req -sha256 -CAcreateserial -CA root.crt -CAkey root.key -extfile ima.cfg -in ima.csr -out ima.crt +openssl x509 -outform DER -in ima.crt -out x509_ima.der +``` + +**步骤2:** 将IMA证书拷贝到/etc/keys目录下: + +``` +mkdir -p /etc/keys/ +cp x509_ima.der /etc/keys/ +``` + +**步骤3:** 打包initrd,将IMA证书和摘要列表置入initrd镜像中: + +``` +echo 'install_items+=" /etc/keys/x509_ima.der "' >> /etc/dracut.conf +dracut -f -e xattr +``` + +**步骤4:** 重启后检查证书导入成功: + +``` +keyctl show %:.ima +``` + +#### 典型使用场景 + +根据运行模式的不同,IMA摘要列表可应用于可信度量场景和用户态安全启动场景。 + +##### 可信度量场景 + +可信度量场景主要基于IMA摘要列表度量模式,由内核+硬件可信根(如TPM)共同完成对关键文件的度量,再结合远程证明工具链完成对当前系统的文件可信状态的证明: + +![](./figures/ima_trusted_measurement.png) + +**运行阶段** + +- 软件包部署时同步导入摘要列表,IMA对摘要列表进行度量并记录度量日志(同步扩展TPM); + +- 应用程序执行时触发IMA度量,若文件摘要值匹配白名单则忽略,否则记录度量日志(同步扩展TPM) 。 + +**证明阶段(业界通用流程)** + +- 远程证明服务器下发证明请求,客户端回传IMA度量日志以及经过签名的TPM PCR值; + +- 远程证明服务器依次校验PCR(校验签名)、度量日志(PCR回放)、文件度量信息(比对本地基准值)的正确性,上报结果至安全中心; + +- 安全管理中心采取对应操作,如事件通知、节点隔离等。 + +##### 用户态安全启动场景 + +用户态安全启动场景主要基于IMA摘要列表评估模式,与安全启动类似,旨在对执行的应用程序或访问的关键文件执行完整性校验,如果校验失败,则拒绝访问: + +![](./figures/ima_secure_boot.png) + +**运行阶段** + +- 应用部署时导入摘要列表,内核验签通过后,加载摘要值到内核哈希表中作为白名单; +- 应用程序执行时触发IMA校验,计算文件hash值,若与基线值一致,则允许访问,否则记录日志或拒绝访问 。 + +## 附录 + +### 内核编译选项说明 + +原生IMA/EVM提供的编译选项及说明如下: + +| 编译选项 | 功能 | +| :------------------------------- | :------------------------ | +| CONFIG_INTEGRITY | IMA/EVM 总编译开关 | +| CONFIG_INTEGRITY_SIGNATURE | 使能IMA签名校验 | +| CONFIG_INTEGRITY_ASYMMETRIC_KEYS | 使能IMA非对称签名校验 | +| CONFIG_INTEGRITY_TRUSTED_KEYRING | 使能 IMA/EVM 密钥环 | +| CONFIG_INTEGRITY_AUDIT | 编译 IMA audit 审计模块 | +| CONFIG_IMA | IMA 总编译开关 | +| CONFIG_IMA_WRITE_POLICY | 允许在运行阶段更新IMA策略 | +| CONFIG_IMA_MEASURE_PCR_IDX | 允许指定IMA度量 PCR 序号 | +| CONFIG_IMA_LSM_RULES | 允许配置 LSM 规则 | +| CONFIG_IMA_APPRAISE | IMA 评估总编译开关 | +| IMA_APPRAISE_BOOTPARAM | 启用IMA评估启动参数 | +| CONFIG_EVM | EVM 总编译开关 | + +openEuler IMA摘要列表特性提供的编译选项及说明如下(openEuler内核编译默认开启): + +| 编译选项 | 功能 | +| :----------------- | :---------------------- | +| CONFIG_DIGEST_LIST | 开启IMA摘要列表特性开关 | + +### IMA摘要列表根证书说明 + +openEuler 22.03版本使用RPM密钥对IMA摘要列表进行签名,为保证IMA功能开箱可用,openEuler内核编译时默认将RPM根证书(PGP证书)导入内核。当前包含旧版本使用的OBS证书和openEuler 22.03 LTS SP1版本切换的openEuler证书: + +```shell +# cat /proc/keys | grep PGP +1909b4ad I------ 1 perm 1f030000 0 0 asymmetri private OBS b25e7f66: PGP.rsa b25e7f66 [] +2f10cd36 I------ 1 perm 1f030000 0 0 asymmetri openeuler fb37bc6f: PGP.rsa fb37bc6f [] +``` + +由于当前内核不支持导入PGP子公钥,而切换后的openEuler证书采用子密钥签名,因此openEuler内核编译前对证书进行了预处理,抽取子公钥并导入内核,具体处理流程可见内核软件包代码仓内的process_pgp_certs.sh脚本文件: + +openEuler 24.03及之后的版本支持IMA专用证书,详见[证书签名](../CertSignature/签名证书介绍.md)文档相关章节。 + +如果用户不使用IMA摘要列表功能或使用其他密钥实现签名/验签,则可将相关代码移除,自行实现内核根证书配置。 diff --git "a/docs/zh/docs/1newStruct/Server/Security/\345\212\250\346\200\201\345\256\214\346\225\264\346\200\247\345\272\246\351\207\217\357\274\210DIM\357\274\211.md" "b/docs/zh/docs/1newStruct/Server/Security/\345\212\250\346\200\201\345\256\214\346\225\264\346\200\247\345\272\246\351\207\217\357\274\210DIM\357\274\211.md" new file mode 100644 index 0000000000000000000000000000000000000000..69fe61f71cbe09520a193652e91c91c28d4aeb01 --- /dev/null +++ "b/docs/zh/docs/1newStruct/Server/Security/\345\212\250\346\200\201\345\256\214\346\225\264\346\200\247\345\272\246\351\207\217\357\274\210DIM\357\274\211.md" @@ -0,0 +1,732 @@ +# 动态完整性度量(DIM) + +本章节为DIM(Dynamic Integrity Measurement)动态完整性度量的特性介绍以及使用说明。 + +## 背景 + +随着信息产业的不断发展,信息系统所面临的安全风险也日益增长。信息系统中可能运行大量软件,部分软件不可避免地存在漏洞,这些漏洞一旦被攻击者利用,可能会对系统业务造成严重的影响,如数据泄露、服务不可用等。 + +绝大部分的软件攻击,都会伴随着完整性破坏,如恶意进程运行、配置文件篡改、后门植入等。因此业界提出了完整性保护技术,指的是从系统启动开始,对关键数据进行度量和校验,从而保证系统运行达到预期效果。当前业界已广泛使用的完整性保护技术(如安全启动、文件完整性度量等)都无法对进程运行时的内存数据进行保护。如果攻击者利用一些手段修改了进程的代码指令,可能导致进程被劫持或被植入后门,具有攻击性强,隐蔽性高的特点。对于这种攻击手段,业界提出了动态完整性度量技术,即对进程的运行时内存中的关键数据进行度量和保护。 + +## 术语说明 + +静态基线:针对度量目标的二进制文件进行解析所生成的度量基准数据; + +动态基线:针对度量目标执行首次度量的结果; + +度量策略:指定度量目标的配置信息; + +度量日志:存储度量结果的列表,包含度量对象、度量结果等信息。 + +## 特性简介 + +DIM特性通过在程序运行时对内存中的关键数据(如代码段、数据段)进行度量,并将度量结果和基准值进行对比,确定内存数据是否被篡改,从而检测攻击行为,并采取应对措施。 + +### 功能范围 + +- 当前DIM特性支持在ARM64/X86架构系统中运行; +- 当前DIM特性支持对以下关键内存数据执行度量: + - 用户态进程的代码段:对应ELF文件中属性为PT_LOAD、权限为RX的段,对应进程加载后权限为RX的vma区域; + - 内核模块代码段:起始地址为内核模块对应struct module结构体中的core_layout.base,长度为core_layout.text_size; + - 内核代码段:对应\_stext符号至\_etext,跳过可能由于内核static key机制发生变化的地址。 +- 当前DIM特性支持对接以下硬件平台: + - 支持将度量结果扩展至TPM 2.0芯片的PCR寄存器,以实现远程证明服务对接。 + +### 技术限制 + +- 对于用户态进程,仅支持度量文件映射代码段,不支持度量匿名代码段; +- 不支持度量内核热补丁; +- 仅支持主动触发机制,如果两次触发过程中发生了篡改-恢复的行为,会导致无法识别攻击; +- 对于主动修改代码段的场景(如代码段重定位、自修改或热补丁),会被识别为攻击; +- 对于内核、内核模块的度量,以触发动态基线时的度量结果作为度量基准值,静态基线值仅作为一个固定标识; +- 度量目标必须在触发动态基线的时刻就已在内存中加载(如进程运行或内核模块加载),否则后续无法度量; +- 在需要使用TPM芯片的PCR寄存器验证度量日志的场景下,DIM模块不允许卸载,否则会导致度量日志清空,而无法和PCR寄存器匹配; +>![](./public_sys-resources/icon-note.gif) **说明:** +> +>特性启用后,会对系统性能存在一定影响,主要包括以下方面: +> - DIM特性自身加载以及基线数据、度量日志管理会对系统内存造成消耗,具体影响与保护策略配置相关; +> - DIM特性执行度量期间需要进行哈希运算,造成CPU消耗,具体影响与需要度量的数据大小有关; +> - DIM特性执行度量期间需要对部分资源执行上锁或获取信号量操作,可能导致其他并发进程等待。 + +### 规格约束 + +| 规格项 | 值 | +| ------------------------------------------------------------ | ---- | +| 文件大小上限(策略文件、静态基线文件、签名文件、证书文件) | 10MB | +| 同一个度量目标在一次动态基线后多次度量期间最多记录的篡改度量日志条数 | 10条 | +| /etc/dim/policy中度量策略最大可记录数|10000条| + +### 架构说明 + +DIM包含两个软件包dim_tools和dim,分别提供如下组件: + +| 软件包 | 组件 | 说明 | +| --------- | ---------------- | ------------------------------------------------------------ | +| dim_tools | dim_gen_baseline | 用户态组件,静态基线生成工具,用于生成动态度量所需要的基线数据,该基线数据在DIM特性运行时会被导入并作为度量基准值 | +| dim | dim_core | 内核模块,执行核心的动态度量逻辑,包括策略解析、静态基线解析、动态基线建立、度量执行、度量日志记录、TPM芯片扩展操作等,实现对内存关键数据的度量功能 | +| dim | dim_monitor | 内核模块,执行对dim_core的代码段和关键数据的度量保护,一定程度防止由于dim_core遭受攻击导致的DIM功能失效。 | + +整体架构如下图所示: + +![](./figures/dim_architecture.jpg) + +### 关键流程说明 + +dim_core和dim_monitor模块均提供了对内存数据的度量功能,包含两个核心流程: + +- 动态基线流程:dim_core模块读取并解析策略和静态基线文件,然后对目标进程执行代码段度量,度量结果在内存中以动态基线形式存放,最后将动态基线数据和静态基线数据进行对比,并将对比结果记录度量日志;dim_monitor模块对dim_core模块的代码段和关键数据进行度量,作为动态基线并记录度量日志; +- 动态度量流程:dim_core和dim_monitor模块对目标执行度量,并将度量结果与动态基线值进行对比,如果对比不一致,则将结果记录度量日志。 + +### 接口说明 + +#### 文件路径说明 + +| 路径 | 说明 | +| ------------------------------- | ------------------------------------------------------------ | +| /etc/dim/policy | 度量策略文件 | +| /etc/dim/policy.sig | 度量策略签名文件,用于存放策略文件的签名信息,在签名校验功能开启的情况下使用 | +| /etc/dim/digest_list/*.hash | 静态基线文件,用于存放度量的基准值信息 | +| /etc/dim/digest_list/*.hash.sig | 静态基线签名文件,用于存放静态基线文件的签名信息,在签名校验功能开启的情况下使用 | +| /etc/keys/x509_dim.der | 证书文件,用于校验策略文件和静态基线文件的签名信息,在签名校验功能开启的情况下使用 | +| /sys/kernel/security/dim | DIM文件系统目录,DIM内核模块加载后生成,目录下提供对DIM功能进行操作的内核接口 | + +#### 文件格式说明 + +1. 度量策略文件格式说明 + + 文本文件,以UNIX换行符进行分隔,每行代表一条度量策略,当前支持以下几种配置格式: + + 1. 用户态进程代码段度量配置: + + ``` + measure obj=BPRM_TEXT path=<度量目标进程可执行文件或动态库对应二进制文件的绝对路径> + ``` + + 2. 内核模块代码段度量配置: + + ``` + measure obj=MODULE_TEXT name=<内核模块名> + ``` + + 3. 内核度量配置: + + ``` + measure obj=KERNEL_TEXT + ``` + +**参考示例:** + +``` +# cat /etc/dim/policy +measure obj=BPRM_TEXT path=/usr/bin/bash +measure obj=BPRM_TEXT path=/usr/lib64/libc.so.6 +measure obj=MODULE_TEXT name=ext4 +measure obj=KERNEL_TEXT +``` + +2. 静态基线文件格式说明 + + 文本文件,以UNIX换行符进行分隔,每行代表一条静态基线,当前支持以下几种配置格式: + + 1. 用户态进程基线: + + ``` + dim USER sha256:6ae347be2d1ba03bf71d33c888a5c1b95262597fbc8d00ae484040408a605d2b <度量目标进程可执行文件或动态库对应二进制文件的绝对路径> + ``` + + 2. 内核模块基线: + + ``` + dim KERNEL sha256:a18bb578ff0b6043ec5c2b9b4f1c5fa6a70d05f8310a663ba40bb6e898007ac5 <内核release号>/<内核模块名> + ``` + + 3. 内核基线: + + ``` + dim KERNEL sha256:2ce2bc5d65e112ba691c6ab46d622fac1b7dbe45b77106631120dcc5441a3b9a <内核release号> + ``` + +**参考示例:** + +``` +dim USER sha256:6ae347be2d1ba03bf71d33c888a5c1b95262597fbc8d00ae484040408a605d2b /usr/bin/bash +dim USER sha256:bc937f83dee4018f56cc823f5dafd0dfedc7b9872aa4568dc6fbe404594dc4d0 /usr/lib64/libc.so.6 +dim KERNEL sha256:a18bb578ff0b6043ec5c2b9b4f1c5fa6a70d05f8310a663ba40bb6e898007ac5 6.4.0-1.0.1.4.oe2309.x86_64/dim_monitor +dim KERNEL sha256:2ce2bc5d65e112ba691c6ab46d622fac1b7dbe45b77106631120dcc5441a3b9a 6.4.0-1.0.1.4.oe2309.x86_64 +``` + +3. 度量日志格式说明 + + 文本内容,以UNIX换行符进行分隔,每行代表一条度量日志,格式为: + +``` + <度量日志哈希值> <度量算法>:<度量哈希值> <度量对象> <度量日志类型> +``` + +**参考示例:** + + 1. 对bash进程代码段执行度量,度量结果与静态基线一致: + + ``` + 12 0f384a6d24e121daf06532f808df624d5ffc061e20166976e89a7bb24158eb87 sha256:db032449f9e20ba37e0ec4a506d664f24f496bce95f2ed972419397951a3792e /usr/bin.bash [static baseline] + ``` + + 2. 对bash进程代码段执行度量,度量结果与静态基线不一致: + + ``` + 12 0f384a6d24e121daf06532f808df624d5ffc061e20166976e89a7bb24158eb87 sha256:db032449f9e20ba37e0ec4a506d664f24f496bce95f2ed972419397951a3792e /usr/bin.bash [tampered] + ``` + + 3. 对ext4内核模块代码段执行度量,未找到静态基线: + + ``` + 12 0f384a6d24e121daf06532f808df624d5ffc061e20166976e89a7bb24158eb87 sha256:db032449f9e20ba37e0ec4a506d664f24f496bce95f2ed972419397951a3792e ext4 [no static baseline] + ``` + + 4. dim_monitor对dim_core执行度量,记录基线时的度量结果: + + ``` + 12 660d594ba050c3ec9a7cdc8cf226c5213c1e6eec50ba3ff51ff76e4273b3335a sha256:bdab94a05cc9f3ad36d29ebbd14aba8f6fd87c22ae580670d18154b684de366c dim_core.text [dynamic baseline] + 12 28a3cefc364c46caffca71e7c88d42cf3735516dec32796e4883edcf1241a7ea sha256:0dfd9656d6ecdadc8ec054a66e9ff0c746d946d67d932cd1cdb69780ccad6fb2 dim_core.data [dynamic baseline] + ``` + +4. 证书/签名文件格式说明 + +为通用格式,详见[开启签名校验](#开启签名校验)章节。 + +#### 内核模块参数说明 + +1. dim_core模块参数 + +| 参数名 | 参数内容 | 取值范围 | 默认值 | +| -------------------- | ------------------------------------------------------------ | ------------------------ | ------ | +| measure_log_capacity | 度量日志最大条数,当dim_core记录的度量日志数量达到参数设置时,停止记录度量日志 | 100-UINT_MAX(64位系统) | 100000 | +| measure_schedule | 度量完一个进程/模块后调度的时间,单位毫秒,设置为0代表不调度 | 0-1000 | 0 | +| measure_interval | 自动度量周期,单位分钟,设置为0代表不设置自动度量 | 0-525600 | 0 | +| measure_hash | 度量哈希算法 | sha256, sm3 | sha256 | +| measure_pcr | 将度量结果扩展至TPM芯片的PCR寄存器,设置为0代表不扩展(注意需要与芯片实际的PCR编号保持一致) | 0-128 | 0 | +| signature | 是否启用策略文件和签名机制,设置为0代表不启用,设置为1代表启用 | 0, 1 | 0 | + +**使用示例**: + +``` +insmod /path/to/dim_core.ko measure_log_capacity=10000 measure_schedule=10 measure_pcr=12 +modprobe dim_core measure_log_capacity=10000 measure_schedule=10 measure_pcr=12 +``` + +2. dim_monitor模块参数 + +| 参数名 | 参数内容 | 取值范围 | 默认值 | +| -------------------- | ------------------------------------------------------------ | ------------------------ | ------ | +| measure_log_capacity | 度量日志最大条数,当dim_monitor记录的度量日志数量达到参数设置时,停止记录度量日志 | 100-UINT_MAX(64位系统) | 100000 | +| measure_hash | 度量哈希算法 | sha256, sm3 | sha256 | +| measure_pcr | 将度量结果扩展至TPM芯片的PCR寄存器,设置为0代表不扩展 | 0-128 | 0 | + +**使用示例**: + +``` +insmod /path/to/dim_monitor.ko measure_log_capacity=10000 measure_hash=sm3 +modprobe dim_monitor measure_log_capacity=10000 measure_hash=sm3 +``` + +#### 内核接口说明 + +1. dim_core模块接口 + +| 接口名 | 属性 | 功能 | 示例 | +| -------------------------- | ---- | ------------------------------------------------------------ | --------------------------------------------------------- | +| measure | 只写 | 写入字符串1触发动态度量,成功返回0,失败返回错误码 | echo 1 > /sys/kernel/security/dim/measure | +| baseline_init | 只写 | 写入字符串1触发动态基线,成功返回0,失败返回错误码 | echo 1 > /sys/kernel/security/dim/baseline_init | +| ascii_runtime_measurements | 只读 | 读取接口查询度量日志 | cat /sys/kernel/security/dim/ascii_runtime_measurements | +| runtime_status | 只读 | 读取接口返回状态类型信息,失败返回错误码 | cat /sys/kernel/security/dim/runtime_status | +| interval | 读写 | 写入数字字符串设置自动度量周期(范围同measure_interval参数);读取接口查询当前自动度量周期,失败返回错误码 | echo 10 > /sys/kernel/security/dim/interval
cat /sys/kernel/security/dim/interval | + +**dim_core状态类型信息说明:** + +状态信息以如下字段取值: + +- DIM_NO_BASELINE:表示dim_core已加载,但未进行任何操作; +- DIM_BASELINE_RUNNING:表示正在进行动态基线建立; +- DIM_MEASURE_RUNNING:表示正在进行动态度量度量; +- DIM_PROTECTED:表示已完成动态基线建立,处于受保护状态; +- DIM_ERROR:执行动态基线建立或动态度量时发生错误,需要用户解决错误后重新触发动态基线建立或动态度量。 + +2. dim_monitor模块接口 + +| 接口名 | 属性 | 说明 | 示例 | +| ---------------------------------- | ---- | ---------------------------------------------- | ------------------------------------------------------------ | +| monitor_run | 只写 | 写入字符串1触发度量,成功返回0,失败返回错误码 | echo 1 > /sys/kernel/security/dim/monitor_run | +| monitor_baseline | 只写 | 写入字符串1触发基线,成功返回0,失败返回错误码 | echo 1 > /sys/kernel/security/dim/monitor_baseline | +| monitor_ascii_runtime_measurements | 只读 | 读取接口查询度量日志 | cat /sys/kernel/security/dim/monitor_ascii_runtime_measurements | +| monitor_status | 只读 | 读取接口返回状态类型信息,失败返回错误码 | cat /sys/kernel/security/dim/monitor_status | + +**dim_monitor状态类型信息说明:** + +- ready:表示dim_monitior已加载,但未进行任何操作; +- running:表示正在进行动态基线建立或动态度量; +- error:执行动态基线建立或动态度量时发生错误,需要用户解决错误后重新触发动态基线建立或动态度量; +- protected:表示已完成动态基线建立,处于受保护状态。 + +#### 用户态工具接口说明 + +dim_gen_baseline命令行接口,详见: 。 + +## 如何使用 + +### 安装/卸载 + +**前置条件**: + +- OS版本:支持openEuler 23.09及以上版本; +- 内核版本:支持openEuler kernel 5.10/6.4版本。 + +安装dim_tools和dim软件包,以openEuler 23.09版本为例: + +``` +# yum install -y dim_tools dim +``` + +软件包安装完成后,DIM内核组件不会默认加载,可通过如下命令进行加载和卸载: + +``` +# modprobe dim_core 或 insmod /path/to/dim_core.ko +# modprobe dim_monitor 或 insmod /path/to/dim_monitor.ko +# rmmod dim_monitor +# rmmod dim_core +``` + +加载成功后,可以通过如下命令查询: + +``` +# lsmod | grep dim_core +dim_core 77824 1 dim_monitor +# lsmod | grep dim_monitor +dim_monitor 36864 0 +``` + +卸载前需要先卸载ko,再卸载rpm包 + +``` +# rmmod dim_monitor +# rmmod dim_core +# rpm -e dim +``` + +>![](./public_sys-resources/icon-note.gif) **说明:** +> +> dim_monitor必须后于dim_core加载,先于dim_core卸载; +> 也可使用源码编译安装,详见 。 + +### 度量用户态进程代码段 + +**前置条件**: + +- dim_core模块加载成功; + +- 用户需要准备一个常驻的度量目标用户态程序,本小节以程序路径/opt/dim/demo/dim_test_demo为例: + + ``` + # /opt/dim/demo/dim_test_demo & + ``` + +**步骤1**:为度量目标进程对应的二进制文件生成静态基线 + +``` +# mkdir -p /etc/dim/digest_list +# dim_gen_baseline /opt/dim/demo/dim_test_demo -o /etc/dim/digest_list/test.hash +``` + +**步骤2**:配置度量策略 + +``` +# echo "measure obj=BPRM_TEXT path=/opt/dim/demo/dim_test_demo" > /etc/dim/policy +``` + +**步骤3**:触发动态基线建立 + +``` +# echo 1 > /sys/kernel/security/dim/baseline_init +``` + +**步骤4**:查询度量日志 + +``` +# cat /sys/kernel/security/dim/ascii_runtime_measurements +0 e9a79e25f091e03a8b3972b1a0e4ae2ccaed1f5652857fe3b4dc947801a6913e sha256:02e28dff9997e1d81fb806ee5b784fd853eac8812059c4dba7c119c5e5076989 /opt/dim/demo/dim_test_demo [static baseline] +``` + +如上度量日志说明目标进程被成功度量,且度量结果与静态基线一致。 + +**步骤5**:触发动态度量 + +``` +# echo 1 > /sys/kernel/security/dim/measure +``` + +度量完成后可通过**步骤4**查询度量日志,如果度量结果和动态基线阶段的度量结果一致,则度量日志不会更新,否则会新增异常度量日志。如果攻击者尝试篡改目标程序(如采用修改代码重新编译的方式,过程略)并重新启动目标程序: + +``` +# pkill dim_test_demo +# /opt/dim/demo/dim_test_demo & +``` + +再次触发度量并查询度量日志,可以发现有标识为“tampered”的度量日志: + +``` +# echo 1 > /sys/kernel/security/dim/measure +# cat /sys/kernel/security/dim/ascii_runtime_measurements +0 e9a79e25f091e03a8b3972b1a0e4ae2ccaed1f5652857fe3b4dc947801a6913e sha256:02e28dff9997e1d81fb806ee5b784fd853eac8812059c4dba7c119c5e5076989 /opt/dim/demo/dim_test_demo [static baseline] +0 08a2f6f2922ad3d1cf376ae05cf0cc507c2f5a1c605adf445506bc84826531d6 sha256:855ec9a890ff22034f7e13b78c2089e28e8d217491665b39203b50ab47b111c8 /opt/dim/demo/dim_test_demo [tampered] +``` + +### 度量内核模块代码段 + +**前置条件**: + +- dim_core模块加载成功; + +- 用户需要准备一个度量目标内核模块,本小节假设内核模块路径为/opt/dim/demo/dim_test_module.ko,模块名为dim_test_module: + + ``` + # insmod /opt/dim/demo/dim_test_module.ko + ``` + +>![](./public_sys-resources/icon-note.gif) **说明:** +> +>需要保证内核模块的内核编译环境版本号和当前系统内核版本号一致,可以使用如下方法确认: +> +>``` +># modinfo dim_monitor.ko | grep vermagic | grep "$(uname -r)" +>vermagic: 6.4.0-1.0.1.4.oe2309.x86_64 SMP preempt mod_unload modversions +>``` + +即内核模块vermagic信息的第一个字段需要和当前内核版本号完全一致。 + +**步骤1**:为度量目标内核模块生成静态基线 + +``` +# mkdir -p /etc/dim/digest_list +# dim_gen_baseline /opt/dim/demo/dim_test_module.ko -o /etc/dim/digest_list/test.hash +``` + +**步骤2**:配置度量策略 + +``` +# echo "measure obj=MODULE_TEXT name=dim_test_module" > /etc/dim/policy +``` + +**步骤3**:触发动态基线建立 + +``` +# echo 1 > /sys/kernel/security/dim/baseline_init +``` + +**步骤4**:查询度量日志 + +``` +# cat /sys/kernel/security/dim/ascii_runtime_measurements +0 9603a9d5f87851c8eb7d2619f7abbe28cb8a91f9c83f5ea59f036794e23d1558 sha256:9da4bccc7ae1b709deab8f583b244822d52f3552c93f70534932ae21fac931c6 dim_test_module [static baseline] +``` + +如上度量日志说明dim_test_module模块被成功度量,并以当前的度量结果作为后续度量的基准值(此时度量日志中的哈希值不代表实际度量值)。 + +**步骤5**:触发动态度量 + +``` +echo 1 > /sys/kernel/security/dim/measure +``` + +度量完成后可通过**步骤4**查询度量日志,如果度量结果和动态基线阶段的度量结果一致,则度量日志不会更新,否则会新增异常度量日志。如果攻击者尝试篡改内核模块(如采用修改代码重新编译的方式,过程略)并重新加载: + +``` +rmmod dim_test_module +insmod /opt/dim/demo/dim_test_module.ko +``` + +再次触发度量并查询度量日志,可以发现有标识为“tampered”的度量日志: + +``` +# cat /sys/kernel/security/dim/ascii_runtime_measurements +0 9603a9d5f87851c8eb7d2619f7abbe28cb8a91f9c83f5ea59f036794e23d1558 sha256:9da4bccc7ae1b709deab8f583b244822d52f3552c93f70534932ae21fac931c6 dim_test_module [static baseline] +0 6205915fe63a7042788c919d4f0ff04cc5170647d7053a1fe67f6c0943cd1f40 sha256:4cb77370787323140cb572a789703be1a4168359716a01bf745aa05de68a14e3 dim_test_module [tampered] +``` + +### 度量内核代码段 + +**前置条件**: + +- dim_core模块加载成功。 + +**步骤1**:为内核生成静态基线 + +``` +# mkdir -p /etc/dim/digest_list +# dim_gen_baseline -k "$(uname -r)" -o /etc/dim/digest_list/test.hash /boot/vmlinuz-6.4.0-1.0.1.4.oe2309.x86_64 +``` + +>![](./public_sys-resources/icon-note.gif) **说明:** +> +>/boot/vmlinuz-6.4.0-1.0.1.4.oe2309.x86_64文件名不固定。 + +**步骤2**:配置DIM策略 + +``` +# echo "measure obj=KERNEL_TEXT" > /etc/dim/policy +``` + +**步骤3**:触发动态基线建立 + +``` +# echo 1 > /sys/kernel/security/dim/baseline_init +``` + +**步骤4**:查询度量日志 + +``` +# cat /sys/kernel/security/dim/ascii_runtime_measurements +0 ef82c39d767dece1f5c52b31d1e8c7d55541bae68a97542dda61b0c0c01af4d2 sha256:5f1586e95b102cd9b9f7df3585fe13a1306cbd464f2ebe47a51ad34128f5d0af 6.4.0-1.0.1.4.oe2309.x86_64 [static baseline] +``` + +如上度量日志说明内核被成功度量,并以当前的基线结果作为后续度量的基准值(此时度量日志中的哈希值不代表实际度量值)。 + +**步骤5**:触发动态度量 + +``` +# echo 1 > /sys/kernel/security/dim/measure +``` + +度量完成后可通过**步骤4**查询度量日志,如果度量结果和动态基线阶段的度量结果一致,则度量日志不会更新,否则会新增异常度量日志。 + +### 度量dim_core模块 + +**前置条件**: + +- dim_core和dim_monitor模块加载成功; +- 度量策略配置完成。 + +**步骤1**:触发dim_core动态基线 + +``` +# echo 1 > /sys/kernel/security/dim/baseline_init +``` + +**步骤2**:触发dim_monitor动态基线 + +``` +# echo 1 > /sys/kernel/security/dim/monitor_baseline +``` + +**步骤3**:查询dim_monitor度量日志 + +``` +# cat /sys/kernel/security/dim/monitor_ascii_runtime_measurements +0 c1b0d9909ddb00633fc6bbe7e457b46b57e165166b8422e81014bdd3e6862899 sha256:35494ed41109ebc9bf9bf7b1c190b7e890e2f7ce62ca1920397cd2c02a057796 dim_core.text [dynamic baseline] +0 9be7121cd2c215d454db2a8aead36b03d2ed94fad0fbaacfbca83d57a410674f sha256:f35d20aae19ada5e633d2fde6e93133c3b6ae9f494ef354ebe5b162398e4d7fa dim_core.data [dynamic baseline] +``` + +如上度量日志说明dim_core模块被成功度量,并以当前的基线结果作为后续度量的基准值。 +>![](./public_sys-resources/icon-note.gif) **说明:** +> +>若跳过动态基线创建,直接进行度量,日志中会显示tampered。 + +**步骤4**:触发dim_monitor动态度量 + +``` +# echo 1 > /sys/kernel/security/dim/monitor_run +``` + +如果度量结果和动态基线阶段的度量结果一致,则度量日志不会更新,否则会新增异常度量日志。尝试修改策略后重新执触发dim_core动态基线,此时由于度量目标发生变化,dim_core管理的基线数据也会发生变更,从而dim_monitor的度量结果也会发生变化: + +``` +# echo "measure obj=BPRM_TEXT path=/usr/bin/bash" > /etc/dim/policy +# echo 1 > /sys/kernel/security/dim/baseline_init +``` + +再次触发dim_monitor度量并查询度量日志,可以发现有标识为“tampered”的度量日志: + +``` +# echo 1 > /sys/kernel/security/dim/monitor_run +# cat /sys/kernel/security/dim/monitor_ascii_runtime_measurements +0 c1b0d9909ddb00633fc6bbe7e457b46b57e165166b8422e81014bdd3e6862899 sha256:35494ed41109ebc9bf9bf7b1c190b7e890e2f7ce62ca1920397cd2c02a057796 dim_core.text [dynamic baseline] +0 9be7121cd2c215d454db2a8aead36b03d2ed94fad0fbaacfbca83d57a410674f sha256:f35d20aae19ada5e633d2fde6e93133c3b6ae9f494ef354ebe5b162398e4d7fa dim_core.data [dynamic baseline] +0 6a60d78230954aba2e6ea6a6b20a7b803d7adb405acbb49b297c003366cfec0d sha256:449ba11b0bfc6146d4479edea2b691aa37c0c025a733e167fd97e77bbb4b9dab dim_core.data [tampered] +``` + +### 扩展TPM PCR寄存器 + +**前置条件**: + +- 系统已安装TPM 2.0芯片,执行如下命令返回不为空: + + ``` + # ls /dev/tpm* + /dev/tpm0 /dev/tpmrm0 + ``` + +- 系统已安装tpm2-tools软件包,执行如下命令返回不为空: + + ``` + # rpm -qa tpm2-tools + ``` + +- 度量策略和静态基线配置完成。 + +**步骤1**:加载dim_core和dim_monitor模块,并配置扩展度量结果的PCR寄存器编号,这里为dim_core度量结果指定PCR 12,为dim_monitor指定PCR 13 + +``` +# modprobe dim_core measure_pcr=12 +# modprobe dim_monitor measure_pcr=13 +``` + +**步骤2**:触发dim_core和dim_monitor基线 + +``` +# echo 1 > /sys/kernel/security/dim/baseline_init +# echo 1 > /sys/kernel/security/dim/monitor_baseline +``` + +**步骤3**:查看度量日志,每条日志都显示了对应的TPM PCR寄存器编号 + +``` +# cat /sys/kernel/security/dim/ascii_runtime_measurements +12 2649c414d1f9fcac1c8d0df8ae7b1c18b5ea10a162b957839bdb8f8415ec6146 sha256:83110ce600e744982d3676202576d8b94cea016a088f99617767ddbd66da1164 /usr/lib/systemd/systemd [static baseline] +# cat /sys/kernel/security/dim/monitor_ascii_runtime_measurements +13 72ee3061d5a80eb8547cd80c73a80c3a8dc3b3e9f7e5baa10f709350b3058063 sha256:5562ed25fcdf557efe8077e231399bcfbcf0160d726201ac8edf7a2ca7c55ad0 dim_core.text [dynamic baseline] +13 8ba44d557a9855c03bc243a8ba2d553347a52c1a322ea9cf8d3d1e0c8f0e2656 sha256:5279eadc235d80bf66ba652b5d0a2c7afd253ebaf1d03e6e24b87b7f7e94fa02 dim_core.data [dynamic baseline] +``` + +**步骤4**:检查TPM芯片的PCR寄存器,对应的寄存器均已被写入了扩展值 + +``` +# tpm2_pcrread sha256 | grep "12:" + 12: 0xF358AC6F815BB29D53356DA2B4578B4EE26EB9274E553689094208E444D5D9A2 +# tpm2_pcrread sha256 | grep "13:" + 13: 0xBFB9FF69493DEF9C50E52E38B332BDA8DE9C53E90FB96D14CD299E756205F8EA +``` + +### 开启签名校验 + +**前置条件**: + +- 用户准备公钥证书和签名私钥,签名算法需要为RSA,哈希算法为sha256,证书格式需要为DER。也可以采用如下方式生成: + + ``` + # openssl genrsa -out dim.key 4096 + # openssl req -new -sha256 -key dim.key -out dim.csr -subj "/C=AA/ST=BB/O=CC/OU=DD/CN=DIM Test" + # openssl x509 -req -days 3650 -signkey dim.key -in dim.csr -out dim.crt + # openssl x509 -in dim.crt -out dim.der -outform DER + ``` + +- 度量策略配置完成。 + +**步骤1**:将DER格式的证书放置在/etc/keys/x509_dim.der路径 + +``` +# mkdir -p /etc/keys +# cp dim.der /etc/keys/x509_dim.der +``` + +**步骤2**:对策略文件和静态基线文件进行签名,签名文件必须为原文件名直接添加.sig后缀 + +``` +# openssl dgst -sha256 -out /etc/dim/policy.sig -sign dim.key /etc/dim/policy +# openssl dgst -sha256 -out /etc/dim/digest_list/test.hash.sig -sign dim.key /etc/dim/digest_list/test.hash +``` + +**步骤3**:加载dim_core模块,开启签名校验功能 + +``` +modprobe dim_core signature=1 +``` + +此时,策略文件和静态基线文件均需要通过签名校验后才能加载。 +修改策略文件触发基线,会导致基线失败: + +``` +# echo "" >> /etc/dim/policy +# echo 1 > /sys/kernel/security/dim/baseline_init +-bash: echo: write error: Key was rejected by service +``` + +>![](./public_sys-resources/icon-note.gif) **说明:** +> +>如果某个静态基线文件签名校验失败,dim_core会跳过该文件的解析,而不会导致基线失败。 + +### 配置度量算法 + +**前置条件**: + +- 度量策略配置完成。 + +**步骤1**:加载dim_core和dim_monitor模块,并配置度量算法,这里以sm3算法为例 + +``` +# modprobe dim_core measure_hash=sm3 +# modprobe dim_monitor measure_hash=sm3 +``` + +**步骤2**:配置策略并为度量目标程序生成sm3算法的静态基线 + +``` +# echo "measure obj=BPRM_TEXT path=/opt/dim/demo/dim_test_demo" > /etc/dim/policy +# dim_gen_baseline -a sm3 /opt/dim/demo/dim_test_demo -o /etc/dim/digest_list/test.hash +``` + +**步骤3**:触发基线 + +``` +# echo 1 > /sys/kernel/security/dim/baseline_init +# echo 1 > /sys/kernel/security/dim/monitor_baseline +``` + +**步骤4**:查看度量日志,每条日志都显示了对应的哈希算法 + +``` +# cat /sys/kernel/security/dim/ascii_runtime_measurements +0 585a64feea8dd1ec415d4e67c33633b97abb9f88e6732c8a039064351d24eed6 sm3:ca84504c02bef360ec77f3280552c006ce387ebb09b49b316d1a0b7f43039142 /opt/dim/demo/dim_test_demo [static baseline] +# cat /sys/kernel/security/dim/monitor_ascii_runtime_measurements +0 e6a40553499d4cbf0501f32cabcad8d872416ca12855a389215b2509af76e60b sm3:47a1dae98182e9d7fa489671f20c3542e0e154d3ce941440cdd4a1e4eee8f39f dim_core.text [dynamic baseline] +0 2c862bb477b342e9ac7d4dd03b6e6705c19e0835efc15da38aafba110b41b3d1 sm3:a4d31d5f4d5f08458717b520941c2aefa0b72dc8640a33ee30c26a9dab74eae9 dim_core.data [dynamic baseline] +``` + +### 配置自动周期度量 + +**前置条件**: + +- 度量策略配置完成; + +**方式1**:加载dim_core模块,配置定时度量间隔,此处配置为1分钟 + +``` +modprobe dim_core measure_interval=1 +``` + +在模块加载完成后,自动触发动态基线流程,后续每隔1分钟触发一次动态度量。 + +>![](./public_sys-resources/icon-note.gif) **说明:** +> +>此时不能配置dim_core度量自身代码段的度量策略,否则会产生误报。 +>同时需要提前配置/etc/dim/policy,否则指定measure_interval=1加载模块会失败 + +**方式2**:加载dim_core模块后,也可通过内核模块接口配置定时度量间隔,此处配置为1分钟 + +``` +modprobe dim_core +echo 1 > /sys/kernel/security/dim/interval +``` + +此时不会立刻触发度量,1分钟后会触发动态基线或动态度量,后续每隔1分钟触发一次动态度量。 + +### 配置度量调度时间 + +**前置条件**: + +- 度量策略配置完成; + +加载dim_core模块,配置定时度量调度时间,此处配置为10毫秒: + +``` +modprobe dim_core measure_schedule=10 +``` + +触发动态基线或动态度量时,dim_core每度量一个进程,就会调度让出CPU 10毫秒时间。 \ No newline at end of file diff --git "a/docs/zh/docs/1newStruct/Server/Security/\345\217\257\344\277\241\345\271\263\345\217\260\346\216\247\345\210\266\346\250\241\345\235\227\357\274\210TPCM\357\274\211.md" "b/docs/zh/docs/1newStruct/Server/Security/\345\217\257\344\277\241\345\271\263\345\217\260\346\216\247\345\210\266\346\250\241\345\235\227\357\274\210TPCM\357\274\211.md" new file mode 100644 index 0000000000000000000000000000000000000000..2cbe00d46cf37245dd331e4bc19c1a2518fc37bb --- /dev/null +++ "b/docs/zh/docs/1newStruct/Server/Security/\345\217\257\344\277\241\345\271\263\345\217\260\346\216\247\345\210\266\346\250\241\345\235\227\357\274\210TPCM\357\274\211.md" @@ -0,0 +1,39 @@ +# 可信平台控制模块(TPCM) + +## 背景 + +可信计算在近40年的研究过程中,经历了不断的发展和完善,已经成为信息安全的一个重要分支。中国的可信计算技术近年发展迅猛,在可信计算2.0的基础上解决了可信体系与现有体系的融合问题、可信管理问题以及可信开发的简化问题,形成了基于主动免疫体系的可信计算技术--可信计算3.0。相对于可信计算2.0被动调用的外挂式体系结构,可信计算3.0提出了以自主密码为基础、控制芯片为支柱、双融主板为平台、可信软件为核心、可信连接为纽带、策略管控成体系、安全可信保应用的全新的可信体系框架,在网络层面解决可信问题。 + +可信平台控制模块(Trusted Platform Control Module,TPCM)是一种可集成在可信计算平台中,用于建立和保障信任源点的基础核心模块。它作为中国可信计算3.0中的创新点之一和主动免疫机制的核心,实现了对整个平台的主动可控。 + +TPCM可信计算3.0架构为双体系架构,分为防护部件和计算部件,以可信密码模块为基础,通过可信平台控制模块对防护部件和计算部件及组件的固件进行可信度量,可信软件基(Trusted Software Base,TSB)对系统软件及应用软件进行可信度量,同时TPCM管理平台实现对可信度量的验证及可信策略同步和管理。 + + + +## 功能描述 + +如下图所示,整体系统方案由防护部件、计算部件和可信管理中心三部分组成。 + +![](./figures/TPCM.png) + +- 可信管理中心:对可信计算节点的防护策略和基准值进行制定、下发、维护、存储等操作的集中管理平台,可信管理中心由第三方厂商提供。 +- 防护部件:独立于计算部件执行,为可信计算平台提供具有主动度量和主动控制特征的可信计算防护功能,实现运算的同时进行安全防护。防护部件包括可信平台控制模块、可信软件基,以及可信密码模块(Trusted Cryptography Module,TCM)。TPCM是可信计算节点中实现可信防护功能的关键部件,可以采用多种技术途径实现,如板卡、芯片、IP核等,其内部包含中央处理器、存储器等硬件,固件,以及操作系统与可信功能组件等软件,支撑其作为一个独立于计算部件的防护部件组件,并行于计算部件按内置防护策略工作,对计算部件的硬件、固件及软件等需防护的资源进行可信监控,是可信计算节点中的可信根。 + +- 计算部件:主要包括硬件、操作系统和应用层软件。其中操作系统分为引导阶段和运行阶段,在引导阶段openEuler的shim和grub2支持可信度量能力,可实现对shim、grub2以及操作系统内核、initramfs等启动文件的可信度量防护;在运行阶段,openEuler操作系统支持部署可信验证要素代理(由第三方厂商可信华泰提供),它负责将数据发送给TPCM模块,用以实现运行阶段的可信度量防护。 + +其中,TPCM作为可信计算节点中实现可信防护功能的关键部件,需要与TSB、TCM、可信管理中心和可信计算节点的计算部件交互,交互方式如下: + +1. TPCM的硬件、固件与软件为TSB提供运行环境,设置的可信功能组件为TSB按策略库解释要求实现度量、控制、支撑与决策等功能提供支持。 +2. TPCM通过访问TCM获取可信密码功能,完成对防护对象可信验证、度量和保密存储等计算任务,并提供TCM服务部件以支持对TCM的访问。 +3. TPCM通过管理接口连接可信管理中心,实现防护策略管理、可信报告处理等功能。 +4. TPCM通过内置的控制器和I/O端口,经由总线与计算部件的控制器交互,实现对计算部件的主动监控。 +5. 计算部件操作系统中内置的防护代理获取预设的防护对象有关代码和数据提供给TPCM,TPCM将监控信息转发给TSB,由TSB依据策略库进行分析处理。 + +## 约束限制 + +适配服务器:TaiShan 200(型号2280)VF
+适配BMC插卡型号:BC83SMMC + +## 应用场景 + +通过TPCM特性构成一个完整的信任链,保障系统启动以后进入一个可信的计算环境。 \ No newline at end of file diff --git "a/docs/zh/docs/1newStruct/Server/Security/\345\217\257\344\277\241\350\256\241\347\256\227.md" "b/docs/zh/docs/1newStruct/Server/Security/\345\217\257\344\277\241\350\256\241\347\256\227.md" new file mode 100644 index 0000000000000000000000000000000000000000..73d88b12b203a3b58c18f11138f15112e446681d --- /dev/null +++ "b/docs/zh/docs/1newStruct/Server/Security/\345\217\257\344\277\241\350\256\241\347\256\227.md" @@ -0,0 +1,25 @@ +# 可信计算 + +## 可信计算基础 + +不同国际组织对可信(Trusted)做了不同的定义。 + +1. 可信计算组织(TCG)的定义: + + 一个实体是可信的,它的行为总是以预期的方式达到预期的目标。 + +2. 国际标准化组织与国际电子技术委员会定义(1999): + + 参与计算的组件、操作或过程在任意的条件下是可预测的,并能够抵御病毒和一定程度的物理干扰。 + +3. IEEE Computer Society Technical Committee on Dependable Computing 定义: + + 所谓可信,是指计算机系统所提供的服务是可被论证其是可信赖的,可信赖主要是指系统的可靠性和可用性。 + +简而言之,可信就是系统按照预定的设计和策略运行,不做其他事情。 + +一个可信计算系统由信任根、可信硬件平台、可信操作系统和可信应用组成,它的基本思想是首先创建一个安全信任根(TCB),然后建立从硬件平台、操作系统到应用的信任链,在这条信任链上从根开始,前一级认证后一级,实现信任的逐级扩展,从而实现一个安全可信的计算环境。 + +![](./figures/trusted_chain.png) + +相比于传统安全机制的“头痛医头,脚痛医脚”,发现一个病毒消灭一个病毒,可信计算采用的是白名单机制,即只允许经过认证的内核、内核模块、应用程序等在系统上运行,如果发现程序已发生更改(或本来就是一个未知的程序),就拒绝其执行。 diff --git "a/docs/zh/docs/1newStruct/Server/Security/\345\217\257\344\277\241\350\256\241\347\256\227\345\270\270\350\247\201\351\227\256\351\242\230\344\270\216\350\247\243\345\206\263\346\226\271\346\263\225.md" "b/docs/zh/docs/1newStruct/Server/Security/\345\217\257\344\277\241\350\256\241\347\256\227\345\270\270\350\247\201\351\227\256\351\242\230\344\270\216\350\247\243\345\206\263\346\226\271\346\263\225.md" new file mode 100644 index 0000000000000000000000000000000000000000..3ea692d5617db348608021dfec4a4287b0139788 --- /dev/null +++ "b/docs/zh/docs/1newStruct/Server/Security/\345\217\257\344\277\241\350\256\241\347\256\227\345\270\270\350\247\201\351\227\256\351\242\230\344\270\216\350\247\243\345\206\263\346\226\271\346\263\225.md" @@ -0,0 +1,254 @@ +# 常见问题与解决方法 + +## **问题1:开启IMA评估enforce模式并配置默认策略后,系统启动失败** + +### 原因分析 + +IMA默认策略可能包含对应用程序执行、内核模块加载等关键文件访问流程的校验,如果关键文件访问失败,可能导致系统无法启动。通常原因有: + +1) IMA校验证书未导入内核,导致摘要列表无法被正确校验; +2) 摘要列表文件未正确签名,导致摘要列表校验失败; +3) 摘要列表文件未导入initrd中,导致启动过程无法导入摘要列表; +4) 摘要列表文件和应用程序不匹配,导致应用程序匹配已导入的摘要列表失败。 + +### 解决方法 + +用户需要通过log模式进入系统进行问题定位和修复。重启系统,进入grub界面修改启动参数,采用log模式启动: + +``` +ima_appraise=log +``` + +系统启动后,可参考如下流程进行问题排查: + +**步骤1:** 检查keyring中的IMA证书: + +``` +keyctl show %:.builtin_trusted_keys +``` + +对于openEuler LTS版本,至少应存在以下几本内核证书(其他未列出版本可根据发布时间前推参考): + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
版本证书
openEuler 22.03 LTSprivate OBS b25e7f66
openEuler 22.03 LTS SP1/2/3private OBS b25e7f66
openeuler <openeuler@compass-ci.com> b675600b
openEuler 22.03 LTS SP4private OBS b25e7f66
openeuler <openeuler@compass-ci.com> b675600b
openeuler <openeuler@compass-ci.com> fb37bc6f
openEuler 24.03openEuler kernel ICA 1: 90bb67eb4b57eb62bf6f867e4f56bd4e19e7d041
+ +如果用户导入了其他内核根证书,也同样需要通过`keyctl`命令查询确认证书是否被成功导入。openEuler默认不使用IMA密钥环,如果用户存在使用的情况,则需要通过如下命令查询IMA密钥环中是否存在用户证书: + +``` +keyctl show %:.ima +``` + +如果排查结果为证书未正确导入,则用户需要根据*用户证书导入场景*章节进行流程排查。 + +**步骤2:** 检查摘要列表携带签名信息: + +用户可通过如下命令查询当前系统中的摘要列表文件: + +``` +ls /etc/ima/digest_lists | grep '_list-compact-' +``` + +对于每个摘要列表文件,需要检查存在**以下三种之一**的签名信息: + +1) 检查该摘要列表文件存在对应的**RPM摘要列表文件**,且**RPM摘要列表文件**的ima扩展属性中包含签名值。以bash软件包的摘要列表为例,摘要列表文件路径为: + +``` +/etc/ima/digest_lists/0-metadata_list-compact-bash-5.1.8-6.oe2203sp1.x86_64 +``` + +RPM摘要列表路径为: + +``` +/etc/ima/digest_lists/0-metadata_list-rpm-bash-5.1.8-6.oe2203sp1.x86_64 +``` + +检查RPM摘要列表签名,即文件的`security.ima`扩展属性不为空: + +``` +getfattr -n security.ima /etc/ima/digest_lists/0-metadata_list-rpm-bash-5.1.8-6.oe2203sp1.x86_64 +``` + +2) 检查摘要列表文件的`security.ima`扩展属性不为空: + +``` +getfattr -n security.ima /etc/ima/digest_lists/0-metadata_list-compact-bash-5.1.8-6.oe2203sp1.x86_64 +``` + +3) 检查摘要列表文件的末尾包含了签名信息,可通过检查文件内容末尾是否包含`~Module signature appended~`魔鬼字符串进行判断(仅openEuler 24.03 LTS及之后版本支持的签名方式): + +``` +tail -c 28 /etc/ima/digest_lists/0-metadata_list-compact-kernel-6.6.0-28.0.0.34.oe2403.x86_64 +``` + +如果排查结果为摘要列表未包含签名信息,则用户需要根据*摘要列表签名机制说明*章节进行流程排查。 + +**步骤3:** 检查摘要列表的签名信息正确: + +在确保摘要列表已携带签名信息的情况下,用户还需要确保摘要列表采用正确的私钥签名,即签名私钥和内核中的证书匹配。除用户自行进行私钥检查外,还可通过dmesg日志或audit日志(默认路径为`/var/log/audit/audit.log`)判断是否有签名校验失败的情况发生。典型的日志输出如下: + +``` +type=INTEGRITY_DATA msg=audit(1722578008.756:154): pid=3358 uid=0 auid=0 ses=1 subj=unconfined_u:unconfined_r:haikang_t:s0-s0:c0.c1023 op=appraise_data cause=invalid-signature comm="bash" name="/root/0-metadata_list-compact-bash-5.1.8-6.oe2203sp1.x86_64" dev="dm-0" ino=785161 res=0 errno=0UID="root" AUID="root" +``` + +如果检查结果为签名信息错误,则用户需要根据*摘要列表签名机制说明*章节进行流程排查。 + +**步骤4:** 检查initrd中是否导入摘要列表文件: + +用户需要通过如下命令查询当前initrd中是否存在摘要列表文件: + +``` +lsinitrd | grep 'etc/ima/digest_lists' +``` + +如果未查询到摘要列表文件,则用户需要重新制作initrd,并再次检查摘要列表导入成功: + +``` +dracut -f -e xattr +``` + +**步骤5:** 检查IMA摘要列表和应用程序是否匹配: + +参考[问题2章节](#问题2开启IMA评估enforce模式后部分文件执行失败)。 + +## **问题2:开启IMA评估enforce模式后,部分文件执行失败** + +### 原因分析 + +开启IMA评估enforce模式后,对于配置IMA策略的文件访问,如果文件的内容或扩展属性设置有误(和导入的摘要列表不匹配),则可能会导致文件访问被拒绝。通常原因有: + +1) 摘要列表未成功导入(可参考FAQ1); + +2) 文件内容或属性被篡改。 + +### 解决方法 + + 对于出现文件执行失败的场景,首先需要确定摘要列表文件已经成功导入内核,用户可以检查摘要列表数量判断导入情况: + +``` +cat /sys/kernel/security/ima/digests_count +``` + +然后用户可通过audit日志(默认路径为`/var/log/audit/audit.log`)判断具体哪个文件校验失败以及原因。典型的日志输出如下: + +``` +type=INTEGRITY_DATA msg=audit(1722811960.997:2967): pid=7613 uid=0 auid=0 ses=1 subj=unconfined_u:unconfined_r:haikang_t:s0-s0:c0.c1023 op=appraise_data cause=IMA-signature-required comm="bash" name="/root/test" dev="dm-0" ino=814424 res=0 errno=0UID="root" AUID="root" +``` + +在确定校验失败的文件后,可对比TLV摘要列表确定文件被篡改的原因。对于未开启扩展属性校验的场景,仅对比文件SHA256哈希值和TLV摘要列表中的`IMA digest`项即可,对于开启扩展属性校验的场景,则还需要对比文件当前的属性和TLV摘要列表中显示扩展属性的区别。 + +在确定问题原因后,可通过还原文件的内容及属性,或对当前文件再次生成摘要列表,签名并导入内核的方式解决问题。 + +## **问题3:开启IMA评估模式后,跨openEuler 22.03 LTS SP版本安装软件包时出现报错信息** + +### 原因分析 + +开启IMA评估模式后,当安装不同版本的openEuler 22.03 LTS的软件包时,会自动触发IMA摘要列表的导入。其中包含对摘要列表的签名验证流程,即使用内核中的证书验证摘要列表的签名。由于openEuler在演进过程中,签名证书发生变化,因此部分跨版本安装场景存在后向兼容问题(无前向兼容问题,即新版本的内核可正常校验旧版本的IMA摘要列表文件)。 + +### 解决方法 + +建议用户确认当前内核中包含以下几本签名证书: + +``` +# keyctl show %:.builtin_trusted_keys +Keyring + 566488577 ---lswrv 0 0 keyring: .builtin_trusted_keys + 383580336 ---lswrv 0 0 \_ asymmetric: openeuler b675600b + 453794670 ---lswrv 0 0 \_ asymmetric: private OBS b25e7f66 + 938520011 ---lswrv 0 0 \_ asymmetric: openeuler fb37bc6f +``` + +如缺少证书,建议将内核升级至最新版本。 + +``` +yum update kernel +``` + +openEuler 24.03 LTS及之后版本已具备IMA专用证书,且支持证书链校验,证书生命周期可覆盖整个LTS版本。 + +## **问题4:开启IMA摘要列表评估模式后,IMA摘要列表文件签名正确,但是导入失败** + +### 原因分析 + +IMA摘要列表导入存在检查机制,如果某次导入过程中,摘要列表的签名校验失败,则会关闭摘要列表导入功能,从而导致后续即使正确签名的摘要列表文件也无法被导入。用户可检查dmesg日志中是否存在如下打印确认是否为该原因导致: + +``` +# dmesg +ima: 0-metadata_list-compact-bash-5.1.8-6.oe2203sp1.x86_64 not appraised, disabling digest lists lookup for appraisal +``` + +如上述日志,则说明在开启IMA摘要列表评估模式的情况下,已经导入了一个签名错误的摘要列表文件,从而导致功能关闭。 + +### 解决方法 + +用户需要重启系统,并修复错误的摘要列表签名信息。 + +## **问题5:openEuler 24.03 LTS及之后版本导入用户自定义的IMA证书失败** + +Linux 6.6内核新增了对导入证书的字段校验限制,对于导入IMA密钥环的证书,需要满足如下约束(遵循X.509标准格式): + +- 为数字签名证书,即设置`keyUsage=digitalSignature`字段; +- 非CA证书,即不可设置`basicConstraints=CA:TRUE`字段; +- 非中间证书,即不可设置`keyUsage=keyCertSign`字段。 + +## **问题6:开启IMA评估模式后kdump服务启动失败** + +开启IMA评估enforce模式后,如果IMA策略中配置了如下KEXEC_KERNEL_CHECK规则,可能导致kdump服务启动失败。 + +```shell +appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig +``` + +原因是在该场景下,所有通过KEXEC加载的文件都需要经过完整性校验,因此内核限制kdump加载内核映像文件时必须使用kexec_file_load系统调用。可通过修改/etc/sysconfig/kdump配置文件的KDUMP_FILE_LOAD开启kexec_file_load系统调用。 + +```shell +KDUMP_FILE_LOAD="on" +``` + +同时,kexec_file_load系统调用自身也会执行文件的签名校验,因此要求被加载的内核映像文件必须包含正确的安全启动签名,而且当前内核中必须包含对应的验签证书。 + +## **问题7:RAS安装后无法启动** + +### 原因分析 + +因为在当前RAS的设计逻辑中,程序启动后需要从当前目录查找一份名为 `ecdsakey.pub` 的文件进行读取并作为之后访问该程序的身份验证码,若当前目录没有该文件,则RAS启动会报错。 + +### 解决方法 + +解决方法一:运行 `ras -T` 生成测试用token后会生成 `ecdsakey.pub` 。 + +解决方法二:自行部署oauth2认证服务后,将对应JWT token生成方对应的验证公钥保存为 `ecdsakey.pub` 。 + +## **问题8:RAS启动后,通过restapi无法访问** + +因为RAS默认以https模式启动,开发者需要向RAS提供合法的证书才能正常访问,而http模式下启动的RAS则不需要提供证书。 diff --git "a/docs/zh/docs/1newStruct/Server/Security/\350\277\234\347\250\213\350\257\201\346\230\216\357\274\210\351\262\262\351\271\217\345\256\211\345\205\250\345\272\223\357\274\211.md" "b/docs/zh/docs/1newStruct/Server/Security/\350\277\234\347\250\213\350\257\201\346\230\216\357\274\210\351\262\262\351\271\217\345\256\211\345\205\250\345\272\223\357\274\211.md" new file mode 100644 index 0000000000000000000000000000000000000000..1bf89f24a84b0b8d0eb8eaa4cc8c27a080da083e --- /dev/null +++ "b/docs/zh/docs/1newStruct/Server/Security/\350\277\234\347\250\213\350\257\201\346\230\216\357\274\210\351\262\262\351\271\217\345\256\211\345\205\250\345\272\223\357\274\211.md" @@ -0,0 +1,400 @@ +# 远程证明(鲲鹏安全库) + +## 介绍 + +本项目开发运行在鲲鹏处理器上的基础安全软件组件,前期主要聚焦在远程证明等可信计算相关领域,使能社区安全开发者。 + +## 软件架构 + +在未使能TEE的平台上,本项目可提供平台远程证明特性,其软件架构如下图所示: + +![img](./figures/RA-arch-1.png) + +在已使能TEE的平台上,本项目可提供TEE远程证明特性,其软件架构如下图所示: + +![img](./figures/RA-arch-2.png) + +## 安装配置 + +1. 使用yum安装程序的rpm包,命令如下: + + ```shell + # yum install kunpengsecl-ras kunpengsecl-rac kunpengsecl-rahub kunpengsecl-qcaserver kunpengsecl-attester kunpengsecl-tas kunpengsecl-devel + ``` + +2. 准备数据库环境:进入 `/usr/share/attestation/ras` 目录,执行 `prepare-database-env.sh` 脚本进行自动化的数据库环境配置。 + +3. 程序运行时依赖的配置文件有三个路径,分别为:当前路径 `./config.yaml` ,家路径 `${HOME}/.config/attestation/ras(rac)(rahub)(qcaserver)(attester)(tas)/config.yaml` ,以及系统路径 `/etc/attestation/ras(rac)(rahub)(qcaserver)(attester)(tas)/config.yaml` 。 + +4. (可选)如果需要创建家目录配置文件,可在安装好rpm包后,执行位于 `/usr/share/attestation/ras(rac)(rahub)(qcaserver)(attester)(tas)` 下的脚本 `prepare-ras(rac)(hub)(qca)(attester)(tas)conf-env.sh` 从而完成家目录配置文件的部署。 + +## 相关参数 + +### RAS启动参数 + +命令行输入 `ras` 即可启动RAS程序。请注意,在当前目录下需要提供**ECDSA**公钥并命名为 `ecdsakey.pub` 。相关参数如下: + +```shell + -H --https http/https模式开关,默认为https(true),false=http + -h --hport https模式下RAS监听的restful api端口 + -p, --port string RAS监听的client api端口 + -r, --rest string http模式下RAS监听的restful api端口 + -T, --token 生成一个测试用的验证码并退出 + -v, --verbose 打印更详细的RAS运行时日志信息 + -V, --version 打印RAS版本并退出 +``` + +### RAC启动参数 + +命令行输入 `sudo raagent` 即可启动RAC程序,请注意,物理TPM模块的开启需要sudo权限。相关参数如下: + +```shell + -s, --server string 指定待连接的RAS服务端口 + -t, --test 以测试模式启动 + -v, --verbose 打印更详细的RAC运行时日志信息 + -V, --version 打印RAC版本并退出 + -i, --imalog 指定ima文件路径 + -b, --bioslog 指定bios文件路径 + -T, --tatest 以TA测试模式启动 +``` + +**注意:** +>1.若要使用TEE远程证明特性,需要以非TA测试模式启动RAC,并将待证明TA的uuid、是否使用TCB、mem_hash和img_hash按序放入RAC执行路径下的**talist**文件内。同时预装由TEE团队提供的**libqca.so**库和**libteec.so**库。**talist**文件格式如下: +> +>```text +>e08f7eca-e875-440e-9ab0-5f381136c600 false ccd5160c6461e19214c0d8787281a1e3c4048850352abe45ce86e12dd3df9fde 46d5019b0a7ffbb87ad71ea629ebd6f568140c95d7b452011acfa2f9daf61c7a +>``` +> +>2.若不使用TEE远程证明特性,则需要将 `${DESTDIR}/usr/share/attestation/qcaserver` 目录下的libqca.so库和libteec.so库复制到 `/usr/lib` 或 `/usr/lib64` 目录,并以TA测试模式启动RAC。 + +### QCA启动参数 + +命令行输入 `${DESTDIR}/usr/bin/qcaserver` 即可启动QCA程序,请注意,这里必须要使用qcaserver的完整路径以正常启动QTA,同时需要使QTA中的CA路径参数与该路径保持相同。相关参数如下: + +```shell + -C, --scenario int 设置程序的应用场景,默认为no_as场景(0),1=as_no_daa场景,2=as_with_daa场景 + -S, --server string 指定开放的服务器地址/端口 +``` + +### ATTESTER启动参数 + +命令行输入 `attester` 即可启动ATTESTER程序。相关参数如下: + +```shell + -B, --basevalue string 设置基准值文件读取路径 + -M, --mspolicy int 设置度量策略,默认为-1,需要手动指定。1=仅比对img-hash值,2=仅比对hash值,3=同时比对img-hash和hash两个值 + -S, --server string 指定待连接的服务器地址 + -U, --uuid int 指定待验证的可信应用 + -V, --version 打印程序版本并退出 + -T, --test 读取固定的nonce值以匹配目前硬编码的可信报告 +``` + +### TAS启动参数 + +命令行输入 `tas` 即可启动TAS程序。相关参数如下: + +```shell + -T, --token 生成一个测试用的验证码并退出 +``` + +**注意:** +>1.若要启用TAS服务,需要先为TAS配置好私钥。可以按如下命令修改家目录下的配置文件: +> +>```shell +># cd ${HOME}/.config/attestation/tas +># vim config.yaml +> # 如下DAA_GRP_KEY_SK_X和DAA_GRP_KEY_SK_Y的值仅用于测试,正常使用前请务必更新其内容以保证安全。 +>tasconfig: +> port: 127.0.0.1:40008 +> rest: 127.0.0.1:40009 +> akskeycertfile: ./ascert.crt +> aksprivkeyfile: ./aspriv.key +> huaweiitcafile: ./Huawei IT Product CA.pem +> DAA_GRP_KEY_SK_X: 65a9bf91ac8832379ff04dd2c6def16d48a56be244f6e19274e97881a776543c65a9bf91ac8832379ff04dd2c6def16d48a56be244f6e19274e97881a776543c +> DAA_GRP_KEY_SK_Y: 126f74258bb0ceca2ae7522c51825f980549ec1ef24f81d189d17e38f1773b56126f74258bb0ceca2ae7522c51825f980549ec1ef24f81d189d17e38f1773b56 +>``` +> +>之后再输入`tas`启动TAS程序。 +> +>2.在有TAS环境中,为提高QCA配置证书的效率,并非每一次启动都需要访问TAS以生成相应证书,而是通过证书的本地化存储,即读取QCA侧 `config.yaml` 中配置的证书路径,通过 `func hasAKCert(s int) bool` 函数检查是否已有TAS签发的证书保存于本地,若成功读取证书,则无需访问TAS,若读取证书失败,则需要访问TAS,并将TAS返回的证书保存于本地。 + +## 接口定义 + +### RAS接口 + +为了便于管理员对目标服务器、RAS以及目标服务器上部署的TEE中的用户 TA 进行管理,本程序设计了以下接口可供调用: + +| 接口 | 方法 | +| --------------------------------- | --------------------------- | +| / | GET | +| /{id} | GET、POST、DELETE | +| /{from}/{to} | GET | +| /{id}/reports | GET | +| /{id}/reports/{reportid} | GET、DELETE | +| /{id}/basevalues | GET | +| /{id}/newbasevalue | POST | +| /{id}/basevalues/{basevalueid} | GET、POST、DELETE | +| /{id}/ta/{tauuid}/status | GET | +| /{id}/ta/{tauuid}/tabasevalues | GET | +| /{id}/ta/{tauuid}/tabasevalues/{tabasevalueid} | GET、POST、DELETE | +| /{id}/ta/{tauuid}/newtabasevalue | POST | +| /{id}/ta/{tauuid}/tareports | GET | +| /{id}/ta/{tauuid}/tareports/{tareportid} | GET、POST、DELETE | +| /{id}/basevalues/{basevalueid} | GET、DELETE | +| /version | GET | +| /config | GET、POST | +| /{id}/container/status | GET | +| /{id}/device/status | GET | + +上述接口的具体用法分别介绍如下。 + +若需要查询所有服务器的信息,可以使用`"/"`接口。 + +```shell +# curl -X GET -H "Content-Type: application/json" http://localhost:40002/ +``` + +*** +若需要查询目标服务器的详细信息,可以使用`"/{id}"`接口的`GET`方法,其中{id}是RAS为目标服务器分配的唯一标识号。 + +```shell +# curl -X GET -H "Content-Type: application/json" http://localhost:40002/1 +``` + +*** +若需要修改目标服务器的信息,可以使用`"/{id}"`接口的`POST`方法,其中$AUTHTOKEN是事先使用`ras -T`自动生成的身份验证码。 + +```go +type clientInfo struct { + Registered *bool `json:"registered"` // 目标服务器注册状态 + IsAutoUpdate *bool `json:"isautoupdate"`// 目标服务器基准值更新策略 +} +``` + +```shell +# curl -X POST -H "Authorization: $AUTHTOKEN" -H "Content-Type: application/json" http://localhost:40002/1 -d '{"registered":false, "isautoupdate":false}' +``` + +*** +若需要删除目标服务器,可以使用`"/{id}"`接口的`DELETE`方法。 +**注意:** +>使用该方法并非删除目标服务器的所有信息,而是把目标服务器的注册状态置为`false`! + +```shell +# curl -X DELETE -H "Authorization: $AUTHTOKEN" -H "Content-Type: application/json" http://localhost:40002/1 +``` + +*** +若需要查询指定范围内的所有服务器信息,可以使用`"/{from}/{to}"`接口的`GET`方法。 + +```shell +# curl -X GET -H "Content-Type: application/json" http://localhost:40002/1/9 +``` + +*** +若需要查询目标服务器的所有可信报告,可以使用`"/{id}/reports"`接口的`GET`方法。 + +```shell +# curl -X GET -H "Content-Type: application/json" http://localhost:40002/1/reports +``` + +*** +若需要查询目标服务器指定可信报告的详细信息,可以使用`"/{id}/reports/{reportid}"`接口的`GET`方法,其中{reportid}是RAS为目标服务器指定可信报告分配的唯一标识号。 + +```shell +# curl -X GET -H "Content-Type: application/json" http://localhost:40002/1/reports/1 +``` + +*** +若需要删除目标服务器指定可信报告,可以使用`"/{id}/reports/{reportid}"`接口的`DELETE`方法。 +**注意:** +>使用该方法将删除指定可信报告的所有信息,将无法再通过接口对该报告进行查询! + +```shell +# curl -X DELETE -H "Authorization: $AUTHTOKEN" -H "Content-Type: application/json" http://localhost:40002/1/reports/1 +``` + +*** +若需要查询目标服务器的所有基准值,可以使用`"/{id}/basevalues"`接口的`GET`方法。 + +```shell +# curl -X GET -H "Content-Type: application/json" http://localhost:40002/1/basevalues +``` + +*** +若需要给目标服务器新增一条基准值信息,可以使用`"/{id}/newbasevalue"`接口的`POST`方法。 + +```go +type baseValueJson struct { + BaseType string `json:"basetype"` // 基准值类型 + Uuid string `json:"uuid"` // 容器或设备的标识号 + Name string `json:"name"` // 基准值名称 + Enabled bool `json:"enabled"` // 基准值是否可用 + Pcr string `json:"pcr"` // PCR值 + Bios string `json:"bios"` // BIOS值 + Ima string `json:"ima"` // IMA值 + IsNewGroup bool `json:"isnewgroup"` // 是否为一组新的基准值 +} +``` + +```shell +# curl -X POST -H "Authorization: $AUTHTOKEN" -H "Content-Type: application/json" http://localhost:40002/1/newbasevalue -d '{"name":"test", "basetype":"host", "enabled":true, "pcr":"testpcr", "bios":"testbios", "ima":"testima", "isnewgroup":true}' +``` + +*** +若需要查询目标服务器指定基准值的详细信息,可以使用`"/{id}/basevalues/{basevalueid}"`接口的`GET`方法,其中{basevalueid}是RAS为目标服务器指定基准值分配的唯一标识号。 + +```shell +# curl -X GET -H "Content-Type: application/json" http://localhost:40002/1/basevalues/1 +``` + +*** +若需要修改目标服务器指定基准值的可用状态,可以使用`"/{id}/basevalues/{basevalueid}"`接口的`POST`方法。 + +```shell +# curl -X POST -H "Content-type: application/json" -H "Authorization: $AUTHTOKEN" http://localhost:40002/1/basevalues/1 -d '{"enabled":true}' +``` + +*** +若需要删除目标服务器指定基准值,可以使用`"/{id}/basevalues/{basevalueid}"`接口的`DELETE`方法。 +**注意:** +>使用该方法将删除指定基准值的所有信息,将无法再通过接口对该基准值进行查询! + +```shell +# curl -X DELETE -H "Authorization: $AUTHTOKEN" -H "Content-Type: application/json" http://localhost:40002/1/basevalues/1 +``` + +*** +若需要查询目标服务器上特定用户 TA 的可信状态,可以使用`"/{id}/ta/{tauuid}/status"`接口的GET方法。其中{id}是RAS为目标服务器分配的唯一标识号,{tauuid}是特定用户 TA 的身份标识号。 + +```shell +# curl -X GET -H "Content-type: application/json" -H "Authorization: $AUTHTOKEN" http://localhost:40002/1/ta/test/status +``` + +*** +若需要查询目标服务器上特定用户 TA 的所有基准值信息,可以使用`"/{id}/ta/{tauuid}/tabasevalues"`接口的GET方法。 + +```shell +# curl -X GET -H "Content-type: application/json" http://localhost:40002/1/ta/test/tabasevalues +``` + +*** +若需要查询目标服务器上特定用户 TA 的指定基准值的详细信息,可以使用`"/{id}/ta/{tauuid}/tabasevalues/{tabasevalueid}"`接口的GET方法。其中{tabasevalueid}是RAS为目标服务器上特定用户 TA 的指定基准值分配的唯一标识号。 + +```shell +# curl -X GET -H "Content-type: application/json" http://localhost:40002/1/ta/test/tabasevalues/1 +``` + +*** +若需要修改目标服务器上特定用户 TA 的指定基准值的可用状态,可以使用`"/{id}/ta/{tauuid}/tabasevalues/{tabasevalueid}"`接口的`POST`方法。 + +```shell +# curl -X POST -H "Content-type: application/json" -H "Authorization: $AUTHTOKEN" http://localhost:40002/1/ta/test/tabasevalues/1 --data '{"enabled":true}' +``` + +*** +若需要删除目标服务器上特定用户 TA 的指定基准值,可以使用`"/{id}/ta/{tauuid}/tabasevalues/{tabasevalueid}"`接口的`DELETE`方法。 +**注意:** +>使用该方法将删除指定基准值的所有信息,将无法再通过接口对该基准值进行查询! + +```shell +# curl -X DELETE -H "Content-type: application/json" -H "Authorization: $AUTHTOKEN" -k http://localhost:40002/1/ta/test/tabasevalues/1 +``` + +*** +若需要给目标服务器上特定用户 TA 新增一条基准值信息,可以使用`"/{id}/ta/{tauuid}/newtabasevalue"`接口的`POST`方法。 + +```go +type tabaseValueJson struct { + Uuid string `json:"uuid"` // 用户 TA 的标识号 + Name string `json:"name"` // 基准值名称 + Enabled bool `json:"enabled"` // 基准值是否可用 + Valueinfo string `json:"valueinfo"` // 镜像哈希值和内存哈希值 +} +``` + +```shell +# curl -X POST -H "Content-Type: application/json" -H "Authorization: $AUTHTOKEN" -k http://localhost:40002/1/ta/test/newtabasevalue -d '{"uuid":"test", "name":"testname", "enabled":true, "valueinfo":"test info"}' +``` + +*** +若需要查询目标服务器上特定用户 TA 的所有可信报告,可以使用`"/{id}/ta/{tauuid}/tareports"`接口的`GET`方法。 + +```shell +# curl -X GET -H "Content-type: application/json" http://localhost:40002/1/ta/test/tareports +``` + +*** +若需要查询目标服务器上特定用户 TA 的指定可信报告的详细信息,可以使用`"/{id}/ta/{tauuid}/tareports/{tareportid}"`接口的`GET`方法,其中{tareportid}是RAS为目标服务器上特定用户 TA 的指定可信报告分配的唯一标识号。 + +```shell +# curl -X GET -H "Content-type: application/json" http://localhost:40002/1/ta/test/tareports/2 +``` + +*** +若需要删除目标服务器上特定用户 TA 的指定可信报告,可以使用`"/{id}/ta/{tauuid}/tareports/{tareportid}"`接口的`DELETE`方法。 +**注意:** +>使用该方法将删除指定可信报告的所有信息,将无法再通过接口对该报告进行查询! + +```shell +# curl -X DELETE -H "Content-type: application/json" http://localhost:40002/1/ta/test/tareports/2 +``` + +*** +若需要获取本程序的版本信息,可以使用`"/version"`接口的`GET`方法。 + +```shell +# curl -X GET -H "Content-Type: application/json" http://localhost:40002/version +``` + +*** +若需要查询目标服务器/RAS/数据库的配置信息,可以使用`"/config"`接口的`GET`方法。 + +```shell +# curl -X GET -H "Content-Type: application/json" http://localhost:40002/config +``` + +*** +若需要修改目标服务器/RAS/数据库的配置信息,可以使用`"/config"`接口的`POST`方法。 + +```go +type cfgRecord struct { + // 目标服务器配置 + HBDuration string `json:"hbduration" form:"hbduration"` + TrustDuration string `json:"trustduration" form:"trustduration"` + DigestAlgorithm string `json:"digestalgorithm" form:"digestalgorithm"` + // RAS配置 + MgrStrategy string `json:"mgrstrategy" form:"mgrstrategy"` + ExtractRules string `json:"extractrules" form:"extractrules"` + IsAllupdate *bool `json:"isallupdate" form:"isallupdate"` + LogTestMode *bool `json:"logtestmode" form:"logtestmode"` +} +``` + +```shell +# curl -X POST -H "Authorization: $AUTHTOKEN" -H "Content-Type: application/json" http://localhost:40002/config -d '{"hbduration":"5s","trustduration":"20s","DigestAlgorithm":"sha256"}' +``` + +### TAS接口 + +为了便于管理员对TAS服务的远程控制,本程序设计了以下接口可供调用: + +| 接口 | 方法 | +| --------------------| ------------------| +| /config | GET、POST | + +若需要查询TAS的配置信息,可使用`"/config"`接口的`GET`方法: + +```shell +# curl -X GET -H "Content-Type: application/json" http://localhost:40009/config +``` + +*** +若需要修改TAS的配置信息,可使用`"/config"`接口的`POST`方法: + +```shell +curl -X POST -H "Content-Type: application/json" -H "Authorization: $AUTHTOKEN" http://localhost:40009/config -d '{"basevalue":"testvalue"}' +``` + +**注意:** +>TAS的配置信息读取与修改目前仅支持基准值