可信计算
可信计算基础
可信计算
不同国际组织对可信(Trusted)做了不同的定义。
可信计算组织(TCG)的定义:
一个实体是可信的,它的行为总是以预期的方式达到预期的目标。
国际标准化组织与国际电子技术委员会定义(1999):
参与计算的组件、操作或过程在任意的条件下是可预测的,并能够抵御病毒和一定程度的物理干扰。
IEEE Computer Society Technical Committee on Dependable Computing 定义:
所谓可信,是指计算机系统所提供的服务是可被论证其是可信赖的,可信赖主要是指系统的可靠性和可用性。
简而言之,可信就是系统按照预定的设计和策略运行,不做其他事情。
一个可信计算系统由信任根、可信硬件平台、可信操作系统和可信应用组成,它的基本思想是首先创建一个安全信任根(TCB),然后建立从硬件平台、操作系统到应用的信任链,在这条信任链上从根开始,前一级认证后一级,实现信任的逐级扩展,从而实现一个安全可信的计算环境。
相比于传统安全机制的“头痛医头,脚痛医脚”,发现一个病毒消灭一个病毒,可信计算采用的是白名单机制,即只允许经过认证的内核、内核模块、应用程序等在系统上运行,如果发现程序已发生更改(或本来就是一个未知的程序),就拒绝其执行。
内核完整性度量(IMA)
概述
IMA
IMA,全称 Integrity Measurement Architecture(完整性度量架构),是内核中的一个子系统,能够基于自定义策略对通过 execve()、mmap() 和 open() 系统调用访问的文件进行度量,度量结果可被用于本地/远程证明,或者和已有的参考值比较以控制对文件的访问。
根据 IMA wiki 的定义,内核完整性子系统的功能可以被分为三部分:
- 度量(measure):检测对文件的意外或恶意修改,无论远程还是本地。
- 评估(appraise):度量文件并与一个存储在扩展属性中的参考值作比较,控制本地文件完整性。
- 审计(audit):将度量结果写到系统日志中,用于审计。
可以看到,相比于 IMA 度量作为一个“只记录不干涉”的观察员,IMA 评估更像是一位严格的保安人员,它的职责是拒绝对所有“人证不一”的程序的访问。
EVM
EVM,全称 Extended Verification Module(扩展验证模块),它的作用就是将系统当中某个文件的安全扩展属性,包括 security.ima 、security.selinux 等合起来计算一个哈希值,然后使用 TPM 中存的密钥或其他可信环境中的密钥对其进行签名,签名之后的值存在 security.evm 中,这个签名后的值是不能被篡改的,如果被篡改,再次访问的时候就会验签失败。
总而言之,EVM 的作用就是通过对安全扩展属性计算摘要和签名并将其存储在 security.evm 中,提供对安全扩展属性的离线保护。
IMA Digest Lists
IMA Digest Lists(IMA 摘要列表扩展)是 openEuler 对内核原生完整性保护机制的增强,它取代了原生 IMA 机制为文件完整性提供保护。
“摘要列表”(digest lists)是一种特殊格式的二进制数据文件,它与 rpm 包一一对应,记录了 rpm 包中受保护文件(即可执行文件和动态库文件)的哈希值。
当正确配置启动参数后,内核将维护一个哈希表(对用户空间不可见),并通过 securityfs 对外提供更新哈希表的接口(digest_list_data 和 digest_list_data_del)。摘要列表在构建阶段经过私钥签名,通过接口上传到内核时,需经过内核中的公钥验证。
在开启 IMA 评估的情况下,每当访问一个可执行文件或动态库文件,就会调用内核中的钩子,计算文件内容和扩展属性的哈希值,并在内核哈希表中进行搜索,如果匹配就允许文件的执行,否则就拒绝访问。
相比内核社区原生 IMA 机制,openEuler 内核提供的 IMA 摘要列表扩展从安全性、性能、易用性三个方面进行了改良,助力完整性保护机制在生产环境下落地:
具备完整的信任链,安全性好
原生 IMA 机制要求在现网环境下预先生成并标记文件扩展属性,访问文件时将文件扩展属性作为参考值,信任链不完整。
IMA 摘要列表扩展将文件参考摘要值保存在内核空间中,构建阶段通过摘要列表的形式携带在发布的 rpm 包中,安装 rpm 包的同时导入摘要列表并执行验签,确保了参考值来自于软件发行商,实现了完整的信任链。
惊艳的性能
由于 TPM 芯片是一种低速芯片,因此 PCR 扩展操作成为了 IMA 度量场景的性能瓶颈。摘要列表扩展在确保安全性的前提下,减少了不必要的 PCR 扩展操作,相比原生 IMA 性能提升高达 65%。
IMA 评估场景下,摘要列表扩展将签名验证统一移动到启动阶段进行,避免每次访问文件时都执行验签,相比原生 IMA 评估场景提升运行阶段文件访问的性能约 20%。
快速部署,平滑升级
原生 IMA 机制在初次部署或每次更新软件包时,都需要切换到 fix 模式手动标记文件扩展属性后再重启进入 enforce 模式,才能正常访问安装的程序。
摘要列表扩展可实现安装完成后开箱即用,且允许直接在 enforce 模式下安装或升级 rpm 包,无需重启和手动标记即可使用,实现了用户感知最小化,适合现网环境下的快速部署和平滑升级。
需要注意的是,IMA 摘要列表扩展将原生 IMA 的验签过程提前到启动阶段进行,也引入了一个假设,即内核空间的内存无法被篡改,这就使得 IMA 也依赖于其他安全机制(内核模块安全启动和内存动态度量)以保护内核内存的完整性。
但无论社区原生 IMA 机制还是 IMA 摘要列表扩展,都只是可信计算信任链中的一环,无法孤立地保证系统的安全性,安全自始至终都是一个构建纵深防御的系统工程。
约束限制
- 当前 IMA 评估模式仅支持保护系统中的不可变文件(包括可执行文件和动态库文件)。
- IMA 提供的是应用层的完整性度量,它的安全性依赖于之前环节的可信。
- 当前阶段 IMA 不支持第三方应用摘要列表的导入。
- 启动日志中可能存在
Unable to open file: /etc/keys/x509_ima.der
字样,该报错来自于开源社区,不影响 IMA 摘要列表特性的使用。 - ARM 版本中 IMA 开启日志模式可能存在一些 audit 报错信息,这是由于 modprobe 在摘要列表未导入时加载内核模块所致,不影响正常功能。
使用场景
IMA measurement
IMA 度量的目的是检测对系统文件的意外或恶意修改,度量结果可被用于本地证明或远程证明。
如果系统中存在 TPM 芯片,度量结果将被扩展到 TPM 芯片的指定 PCR 寄存器中,由于 PCR 扩展的单向性以及 TPM 芯片的硬件安全性,用户无法修改已被扩展的度量结果,这就确保了度量结果的真实性。
IMA 度量的文件范围和触发条件可以由用户通过 IMA 策略自行配置。
默认情况下 IMA 不启用,但系统会前往 /etc/ima/
路径下寻找 ima-policy 策略文件,如果找到,就会按照策略在启动时度量系统中的文件。如果不想手动编写策略文件,也可以在启动参数中配置 ima_policy=tcb
使用默认策略(更多策略参数请参考附录“IMA启动参数”章节)。
系统当前加载的 IMA 策略可以在 /sys/kernel/security/ima/policy
文件中查看,IMA 度量日志则位于/sys/kernel/security/ima/ascii_runtime_measurements
文件中,如下所示:
# head /sys/kernel/security/ima/ascii_runtime_measurements
10 ddee6004dc3bd4ee300406cd93181c5a2187b59b ima-ng sha1:9797edf8d0eed36b1cf92547816051c8af4e45ee boot_aggregate
10 180ecafba6fadbece09b057bcd0d55d39f1a8a52 ima-ng sha1:db82919bf7d1849ae9aba01e28e9be012823cf3a /init
10 ac792e08a7cf8de7656003125c7276968d84ea65 ima-ng sha1:f778e2082b08d21bbc59898f4775a75e8f2af4db /bin/bash
10 0a0d9258c151356204aea2498bbca4be34d6bb05 ima-ng sha1:b0ab2e7ebd22c4d17d975de0d881f52dc14359a7 /lib64/ld-2.27.so
10 0d6b1d90350778d58f1302d00e59493e11bc0011 ima-ng sha1:ce8204c948b9fe3ae67b94625ad620420c1dc838 /etc/ld.so.cache
10 d69ac2c1d60d28b2da07c7f0cbd49e31e9cca277 ima-ng sha1:8526466068709356630490ff5196c95a186092b8 /lib64/libreadline.so.7.0
10 ef3212c12d1fbb94de9534b0bbd9f0c8ea50a77b ima-ng sha1:f80ba92b8a6e390a80a7a3deef8eae921fc8ca4e /lib64/libc-2.27.so
10 f805861177a99c61eabebe21003b3c831ccf288b ima-ng sha1:261a3cd5863de3f2421662ba5b455df09d941168 /lib64/libncurses.so.6.1
10 52f680881893b28e6f0ce2b132d723a885333500 ima-ng sha1:b953a3fa385e64dfe9927de94c33318d3de56260 /lib64/libnss_files-2.27.so
10 4da8ce3c51a7814d4e38be55a2a990a5ceec8b27 ima-ng sha1:99a9c095c7928ecca8c3a4bc44b06246fc5f49de /etc/passwd
每一条记录从左到右分别是:
- PCR:用于扩展度量结果的 PCR 寄存器,默认是 10,只在系统装了 TPM 芯片的情况下有意义。
- 模板哈希值:最终被用于扩展的哈希值,组合了文件内容哈希和文件路径的长度和值。
- 模板:扩展度量值的模板,如 ima-ng。
- 文件内容哈希值:被度量的文件内容的哈希值。
- 文件路径:被度量的文件路径。
IMA appraisal
IMA 评估的目的是通过与标准参考值的比较,控制对本地文件的访问。
IMA 首先使用安全扩展属性 security.ima 和 security.evm 存储文件完整性度量的参考值:
- security.ima:存储文件内容的哈希值;
- security.evm:存储文件扩展属性的哈希值签名。
访问受保护文件时,将会触发内核中的钩子,依次验证文件扩展属性和内容的完整性:
- 使用内核 keyring 中的公钥对文件 security.evm 扩展属性中的签名值验签,与当前文件扩展属性的哈希值比较,如果匹配就证明文件的扩展属性是完整的(包括 security.ima)。
- 在文件扩展属性完整的前提下,将文件 security.ima 扩展属性的内容与当前文件内容的摘要值比较,如果匹配就允许对文件的访问。
同样,IMA 评估的文件范围和触发条件也可以由用户通过 IMA 策略自行配置。
IMA Digest Lists
IMA 摘要列表扩展当前提供对以下三种启动参数组合的支持:
IMA measurement 度量模式:
ima_policy=exec_tcb ima_digest_list_pcr=11
IMA appraisal 日志模式 + IMA measurement 度量模式:
ima_template=ima-sig ima_policy="exec_tcb|appraise_exec_tcb|appraise_exec_immutable" initramtmpfs ima_hash=sha256 ima_appraise=log evm=allow_metadata_writes evm=x509 ima_digest_list_pcr=11 ima_appraise_digest_list=digest
IMA appraisal 强制模式 + IMA measurement 度量模式:
ima_template=ima-sig ima_policy="exec_tcb|appraise_exec_tcb|appraise_exec_immutable" initramtmpfs ima_hash=sha256 ima_appraise=enforce-evm evm=allow_metadata_writes evm=x509 ima_digest_list_pcr=11 ima_appraise_digest_list=digest
操作指导
原生 IMA 场景初次部署
第一次启动时,需要在启动参数中配置:
ima_appraise=fix ima_policy=appraise_tcb
fix
模式会允许系统在没有参考值的情况下启动,appraise_tcb
对应了一种 IMA 策略,具体可参考附录中的“IMA 启动参数”章节。
接下来,你需要访问所有需要被校验的文件,从而为它们添加 IMA 扩展属性:
# time find / -fstype ext4 -type f -uid 0 -exec dd if='{}' of=/dev/null count=0 status=none \;
该过程会花费一定时间,请耐心等待。命令执行完成后,你可以从受保护文件的扩展属性中看到参考值已被标记:
# getfattr -m - -d /sbin/init
# file: sbin/init
security.ima=0sAXr7Qmun5mkGDS286oZxCpdGEuKT
security.selinux="system_u:object_r:init_exec_t"
最后,配置以下启动参数并重新启动系统:
ima_appraise=enforce ima_policy=appraise_tcb
摘要列表场景初次部署
配置内核参数进入 log 模式。
编辑
/boot/efi/EFI/openEuler/grub.cfg
文件,加入以下参数:ima_template=ima-sig ima_policy="exec_tcb|appraise_exec_tcb|appraise_exec_immutable" initramtmpfs ima_hash=sha256 ima_appraise=log evm=allow_metadata_writes evm=x509 ima_digest_list_pcr=11 ima_appraise_digest_list=digest
使用
reboot
重启系统进入 log 模式,该模式下已开启完整性校验,但不会因校验失败而无法启动。安装依赖包。
使用 yum 安装 digest-list-tools 和 ima-evm-utils,确认不低于以下版本:
# yum install digest-list-tools ima-evm-utils # rpm -qa | grep digest-list-tools digest-list-tools-0.3.93-1.oe1.x86_64 # rpm -qa | grep ima-evm-utils ima-evm-utils-1.2.1-9.oe1.x86_64
执行
dracut
重新生成 initrd:# dracut -f -e xattr
编辑
/boot/efi/EFI/openEuler/grub.cfg
文件,将 ima_appraise=log 改为 ima_appraise=enforce-evm:ima_template=ima-sig ima_policy="exec_tcb|appraise_exec_tcb|appraise_exec_immutable" initramtmpfs ima_hash=sha256 ima_appraise=enforce-evm evm=allow_metadata_writes evm=x509 ima_digest_list_pcr=11 ima_appraise_digest_list=digest
使用 reboot 重启即可完成初次部署。
在 OBS 上进行摘要列表构建
OBS 全称 Open Build Service,是一种编译系统,最早在 openSUSE 用于软件包的构建,能够支持多架构的分布式编译。
进行摘要列表构建之前,首先确保您的工程包含以下 rpm 包,且来自 openEuler:
- digest-list-tools
- pesign-obs-integration
- selinux-policy
- rpm
- openEuler-rpm-config
在交付件工程中增加 Project Config:
Preinstall: pesign-obs-integration digest-list-tools selinux-policy-targeted
Macros:
%__brp_digest_list /usr/lib/rpm/openEuler/brp-digest-list %{buildroot}
:Macros
- 在 Preinstall 中新增 digest-list-tools 用于生成摘要列表,pesign-obs-integration 用于生成摘要列表的签名,新增 selinux-policy-targeted 用于确保生成摘要列表时构建环境内 SELinux 标签正确。
- 在 Macros 中定义宏 %__brp_digest_list,rpm 将在构建阶段通过这个宏执行命令为编译完成的二进制文件生成摘要列表。这个宏可以作为一个开关控制工程中的摘要列表是否生成。
配置完成后,OBS 会自动执行全量构建,正常情况下构建完成后,软件包中会新增以下两个文件:
- /etc/ima/digest_lists/0-metadata_list-compact-[包名]-[版本号]
- /etc/ima/digest_lists.tlv/0-metadata_list-compact_tlv-[包名]-[版本号]
在 Koji 上进行摘要列表构建
Koji 是 Fedora 社区的编译系统,openEuler 社区将在后续支持,敬请期待。
FAQ
为什么进入 enforce 模式后系统无法启动或启动后命令无法执行/服务不正常?
enforce 模式下 IMA 会对文件访问做控制,如果访问文件的内容或扩展属性不完整,就会被拒绝访问,当影响启动的关键命令无法执行时,就会造成系统无法启动。
请确认是否存在以下问题:
摘要列表是否被加入到 initrd 中?
初次部署时是否执行了 dracut 命令将摘要列表加入内核?如果摘要列表没有加入 initrd,启动阶段就无法导入摘要列表,从而导致启动失败。
是否使用官方提供的 rpm 包?
如果使用的是非 openEuler 官方提供的 rpm 包,rpm 包可能没有携带摘要列表,或者对摘要列表签名的私钥与内核中的验签公钥不匹配,从而导致摘要列表没有被导入内核。
如果原因还不明确,可以进入 log 模式启动,从错误日志中寻找原因:
# dmesg | grep appraise
为什么 enforce 模式下没有对系统文件做访问控制?
系统没有按照预期对文件执行访问控制,首先查看启动参数中的 IMA 策略是否已被正确配置:
# cat /proc/cmdline ...ima_policy=exec_tcb|appraise_exec_tcb|appraise_exec_immutable...
其次查看当前内核中 IMA 策略是否已生效:
# cat /sys/kernel/security/ima/policy
如果 policy 文件是空的,证明策略没有设置成功,系统也就不会进行访问控制。
初次部署完成后,安装/升级/卸载软件包后还需要手动执行 dracut 生成 initrd 吗?
不需要。rpm 包提供的 digest_list.so 插件能够在 rpm 包粒度提供摘要列表的自动更新,可以实现用户对摘要列表的无感知。
附录
IMA securityfs 接口说明
原生 IMA 提供的 securityfs 接口如下:
注:以下接口路径都位于
/sys/kernel/security/
目录下。
路径 | 权限 | 说明 |
---|---|---|
ima/policy | 600 | IMA 策略接口 |
ima/ascii_runtime_measurement | 440 | ascii 码形式表示的 IMA 度量结果 |
ima/binary_runtime_measurement | 440 | 二进制形式表示的 IMA 度量结果 |
ima/runtime_measurement_count | 440 | 度量结果数量统计 |
ima/violations | 440 | IMA 度量结果冲突数 |
evm | 660 | EVM 模式,即校验文件扩展属性完整性的方式 |
其中,/sys/kernel/security/evm
的取值有以下三种:
- 0:EVM 未初始化;
- 1:使用 HMAC(对称加密)方式校验扩展属性完整性;
- 2:使用公钥验签(非对称加密)方式校验扩展属性完整性;
- 6:关闭扩展属性完整性校验(openEuler 使用此方式)。
IMA 摘要列表扩展额外提供的 securityfs 接口如下:
路径 | 权限 | 说明 |
---|---|---|
ima/digests_count | 440 | 显示系统哈希表中的总摘要数量(IMA+EVM) |
ima/digest_list_data | 200 | 摘要列表新增接口 |
ima/digest_list_data_del | 200 | 摘要列表删除接口 |
IMA 策略语法
每条 IMA 策略语句都必须以 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 表示 nova log 类型的文件。
uid:表示哪个用户(用用户 id 表示)对文件进行操作,一条策略只能选一个 uid。
fowner:表示文件的属主(用用户 id 表示)是谁,一条策略只能选一个 fowner。
关键字的具体取值及说明如下:
关键字 | 值 | 说明 |
---|---|---|
action | measure | 开启 IMA 度量 |
dont_measure | 禁用 IMA 度量 | |
appraise | 开启 IMA 评估 | |
dont_appraise | 禁用 IMA 评估 | |
audit | 开启审计 | |
func | FILE_CHECK | 将要被打开的文件 |
MODULE_CHECK | 将要被装载的内核模块文件 | |
MMAP_CHECK | 将要被映射到进程内存空间的动态库文件 | |
BRPM_CHECK | 将要被执行的文件(不含通过 /bin/hash 等程序打开的脚本文件) | |
POLICY_CHECK | 将要被作为补充 IMA 策略装载的文件 | |
FIRMWARE_CHECK | 将要被加载到内存中的固件 | |
DIGEST_LIST_CHECK | 将要被加载到内核中的摘要列表文件 | |
KEXEC_KERNEL_CHECK | 将要切换的 kexec 内核 | |
mask | MAY_EXEC | 执行文件 |
MAY_WRITE | 写文件。不建议使用,受限于 echo、vim 等开源机制(修改本质是新建临时文件再重命名),并不是每次修改都会触发 MAY_WRITE 的 IMA 度量。 | |
MAY_READ | 读文件 | |
MAY_APPEND | 扩展文件属性 | |
fsmagic | fsmagic=xxx | 表示文件系统类型的十六进制魔数 |
fsuuid | fsuuid=xxx | 表示系统设备 uuid 的 16 位的十六进制字符串 |
fowner | fowner=xxx | 文件属主的用户 id |
uid | uid=xxx | 操作文件的用户 id |
obj_type | obj_type=xxx_t | 表示文件的类型(基于 SELinux 标签) |
pcr | pcr=<num> | 选择 TPM 中用于扩展度量值的 PCR(默认为 10) |
appraise_type | imasig | 基于签名进行 IMA 评估 |
meta_immutable | 基于签名进行文件扩展属性的评估(支持摘要列表) |
注:PATH_CHECK 等同于 FILE_CHECK,FILE_MMAP 等同于 MMAP_CHECK,不在本表提及。
IMA 原生启动参数
原生 IMA 的内核启动参数列表如下:
参数名称 | 取值 | 功能 |
---|---|---|
ima_appraise | off | 关闭 IMA 评估模式,在访问文件时不进行完整性校验,也不为文件生成新的参考值。 |
enforce | 开启 IMA 评估强制模式,在访问文件时进行完整性校验,即计算文件摘要值并与参考值比对,如果比对失败就拒绝对文件的访问。IMA 会为新文件生成新的参考值。 | |
fix | 开启 IMA 修复模式,在该模式下允许更新受保护文件的参考值。 | |
log | 开启 IMA 评估日志模式,在访问文件时进行完整性校验,但即使校验失败也允许执行命令,只进行日志记录。 | |
ima_policy | tcb | 度量所有文件执行、动态库映射、内核模块导入以及设备驱动加载,此外,root 用户读文件的行为也会被度量。 |
appraise_tcb | 对所有 root 属主的文件进行评估。 | |
secure_boot | 对所有内核模块导入、硬件驱动加载、kexec 内核切换以及 IMA 策略进行评估,前提是这些文件都具有 IMA 签名, | |
ima_tcb | 无 | 等价于 ima_policy=tcb |
ima_appraise_tcb | 无 | 等价于 ima_policy=appraise_tcb |
ima_hash | sha1/md5/... | IMA 摘要算法,默认为 sha1 |
ima_template | ima | IMA 度量扩展模板 |
ima-ng | IMA 度量扩展模板 | |
ima-sig | IMA 度量扩展模板 | |
integrity_audit | 0 | 基础完整性审计信息(默认) |
1 | 额外完整性审计信息 |
注:ima_policy 参数可以同时指定多个值,例如 ima_policy=tcb|appraise_tcb,启动后系统的 IMA 策略就是这两种参数对应的策略的总和。
启动参数 ima_policy=tcb
对应的 IMA 策略为:
# PROC_SUPER_MAGIC = 0x9fa0
dont_measure fsmagic=0x9fa0
# SYSFS_MAGIC = 0x62656572
dont_measure fsmagic=0x62656572
# DEBUGFS_MAGIC = 0x64626720
dont_measure fsmagic=0x64626720
# TMPFS_MAGIC = 0x01021994
dont_measure fsmagic=0x1021994
# DEVPTS_SUPER_MAGIC=0x1cd1
dont_measure fsmagic=0x1cd1
# BINFMTFS_MAGIC=0x42494e4d
dont_measure fsmagic=0x42494e4d
# SECURITYFS_MAGIC=0x73636673
dont_measure fsmagic=0x73636673
# SELINUX_MAGIC=0xf97cff8c
dont_measure fsmagic=0xf97cff8c
# SMACK_MAGIC=0x43415d53
dont_measure fsmagic=0x43415d53
# CGROUP_SUPER_MAGIC=0x27e0eb
dont_measure fsmagic=0x27e0eb
# CGROUP2_SUPER_MAGIC=0x63677270
dont_measure fsmagic=0x63677270
# NSFS_MAGIC=0x6e736673
dont_measure fsmagic=0x6e736673
measure func=MMAP_CHECK mask=MAY_EXEC
measure func=BPRM_CHECK mask=MAY_EXEC
measure func=FILE_CHECK mask=MAY_READ uid=0
measure func=MODULE_CHECK
measure func=FIRMWARE_CHECK
启动参数 ima_policy=tcb_appraise
对应的 IMA 策略为:
# PROC_SUPER_MAGIC = 0x9fa0
dont_appraise fsmagic=0x9fa0
# SYSFS_MAGIC = 0x62656572
dont_appraise fsmagic=0x62656572
# DEBUGFS_MAGIC = 0x64626720
dont_appraise fsmagic=0x64626720
# TMPFS_MAGIC = 0x01021994
dont_appraise fsmagic=0x1021994
# RAMFS_MAGIC
dont_appraise fsmagic=0x858458f6
# DEVPTS_SUPER_MAGIC=0x1cd1
dont_appraise fsmagic=0x1cd1
# BINFMTFS_MAGIC=0x42494e4d
dont_appraise fsmagic=0x42494e4d
# SECURITYFS_MAGIC=0x73636673
dont_appraise fsmagic=0x73636673
# SELINUX_MAGIC=0xf97cff8c
dont_appraise fsmagic=0xf97cff8c
# SMACK_MAGIC=0x43415d53
dont_appraise fsmagic=0x43415d53
# NSFS_MAGIC=0x6e736673
dont_appraise fsmagic=0x6e736673
# CGROUP_SUPER_MAGIC=0x27e0eb
dont_appraise fsmagic=0x27e0eb
# CGROUP2_SUPER_MAGIC=0x63677270
dont_appraise fsmagic=0x63677270
appraise fowner=0
启动参数 ima_policy=secure_boot
对应的 IMA 策略为:
appraise func=MODULE_CHECK appraise_type=imasig
appraise func=FIRMWARE_CHECK appraise_type=imasig
appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig
appraise func=POLICY_CHECK appraise_type=imasig
IMA 摘要列表启动参数
IMA 摘要列表特性额外引入的内核启动参数如下:
参数名称 | 取值 | 功能 |
---|---|---|
integrity | 0 | IMA 特性总开关关闭(默认) |
1 | IMA 特性总开关打开 | |
ima_appraise | off | 关闭 IMA 评估模式 |
enforce-evm | IMA 评估强制模式,在访问文件时进行完整性校验并进行访问控制 | |
ima_appraise_digest_list | digest | 当 EVM 被禁用时,使用摘要列表进行 IMA appraise,摘要列表同时保护文件内容和扩展属性 |
digest-nometadata | 在EVM摘要值不存在的情况下,仅基于IMA摘要值进行完整性校验(不保护文件扩展属性) | |
evm | fix | 允许任何对扩展属性的修改(即使修改会导致扩展属性完整性校验失败) |
ignore | 只有在扩展属性不存在或不正确的情况下才允许修改 | |
ima_policy | exec_tcb | IMA 度量策略,详见下文策略说明。 |
appraise_exec_tcb | IMA 评估策略,详见下文策略说明。 | |
appraise_exec_immutable | IMA 评估策略,详见下文策略说明。 | |
ima_digest_list_pcr | 11 | 使用 PCR 11 替代 PCR 10,仅使用摘要列表进行度量 |
+11 | 依然保留 PCR 10 的度量,在有TPM芯片时也往TPM芯片写度量结果 | |
initramtmpfs | 无 | 添加对 tmpfs 的支持 |
启动参数 ima_policy=exec_tcb
对应的 IMA 策略为:
dont_measure fsmagic=0x9fa0
dont_measure fsmagic=0x62656572
dont_measure fsmagic=0x64626720
dont_measure fsmagic=0x1cd1
dont_measure fsmagic=0x42494e4d
dont_measure fsmagic=0x73636673
dont_measure fsmagic=0xf97cff8c
dont_measure fsmagic=0x43415d53
dont_measure fsmagic=0x27e0eb
dont_measure fsmagic=0x63677270
dont_measure fsmagic=0x6e736673
measure func=MMAP_CHECK mask=MAY_EXEC
measure func=BPRM_CHECK mask=MAY_EXEC
measure func=MODULE_CHECK
measure func=FIRMWARE_CHECK
measure func=POLICY_CHECK
measure func=DIGEST_LIST_CHECK
measure parser
启动参数 ima_policy=appraise_exec_tcb
对应的 IMA 策略为:
appraise func=MODULE_CHECK appraise_type=imasig
appraise func=FIRMWARE_CHECK appraise_type=imasig
appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig
appraise func=POLICY_CHECK appraise_type=imasig
appraise func=DIGEST_LIST_CHECK appraise_type=imasig
dont_appraise fsmagic=0x9fa0
dont_appraise fsmagic=0x62656572
dont_appraise fsmagic=0x64626720
dont_appraise fsmagic=0x858458f6
dont_appraise fsmagic=0x1cd1
dont_appraise fsmagic=0x42494e4d
dont_appraise fsmagic=0x73636673
dont_appraise fsmagic=0xf97cff8c
dont_appraise fsmagic=0x43415d53
dont_appraise fsmagic=0x6e736673
dont_appraise fsmagic=0x27e0eb
dont_appraise fsmagic=0x63677270
启动参数 ima_policy=appraise_exec_immutable
对应的 IMA 策略为:
appraise func=BPRM_CHECK appraise_type=imasig appraise_type=meta_immutable
appraise func=MMAP_CHECK
appraise parser appraise_type=imasig
IMA 内核编译选项详解
原生 IMA 提供的编译选项如下:
编译选项 | 功能 |
---|---|
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 总编译开关 |
IMA 摘要列表扩展额外提供的编译选项如下:
编译选项 | 功能 |
---|---|
CONFIG_DIGEST_LIST | 开启 IMA 摘要列表特性开关 |
IMA 性能参考数据
下图对比了不开启 IMA、开启原生 IMA、开启 IMA 摘要列表特性时的性能:
IMA 对kdump服务的影响
开启IMA enforce模式,在策略中配置kexec系统调用校验时,可能导致kdump启动失败。
appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig
kdump启动失败原因:由于开启IMA后,需要对文件执行完整性校验,因此限制kdump加载内核映像文件时需使用kexec_file_load系统调用。可通过修改/etc/sysconfig/kdump配置文件的KDUMP_FILE_LOAD开启kexec_file_load系统调用。
KDUMP_FILE_LOAD="on"
同时,kexec_file_load系统调用自身也会执行文件的签名校验,因此要求被加载的内核映像文件必须包含正确的安全启动签名,而且当前内核中必须包含对应的验签证书。
IMA 根证书配置
当前openEuler使用RPM密钥对IMA摘要列表进行签名,为保证IMA功能开箱可用,openEuler内核编译时默认将RPM根证书(PGP证书)导入内核。
# 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 <openeuler@compass-ci.com> fb37bc6f: PGP.rsa fb37bc6f []
由于当前内核不支持导入PGP子公钥,而切换后的openEuler证书采用子密钥签名,因此openEuler内核编译前对证书进行了预处理,抽取子公钥并导入内核,具体处理流程可见内核软件包代码仓内的process_pgp_certs.sh脚本文件:https://gitee.com/src-openeuler/kernel/blob/openEuler-{version}/process_pgp_certs.sh。
如果用户不使用IMA摘要列表功能或使用其他密钥实现签名/验签,则可将相关代码移除,自行实现内核根证书配置。
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寄存器匹配;
说明:
特性启用后,会对系统性能存在一定影响,主要包括以下方面:
- 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功能失效。 |
整体架构如下图所示:
关键流程说明
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功能进行操作的内核接口 |
文件格式说明
度量策略文件格式说明
文本文件,以UNIX换行符进行分隔,每行代表一条度量策略,当前支持以下几种配置格式:
- 用户态进程代码段度量配置:
measure obj=BPRM_TEXT path=<度量目标进程可执行文件或动态库对应二进制文件的绝对路径>
- 内核模块代码段度量配置:
measure obj=MODULE_TEXT name=<内核模块名>
- 内核度量配置:
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
静态基线文件格式说明
文本文件,以UNIX换行符进行分隔,每行代表一条静态基线,当前支持以下几种配置格式:
- 用户态进程基线:
dim USER sha256:6ae347be2d1ba03bf71d33c888a5c1b95262597fbc8d00ae484040408a605d2b <度量目标进程可执行文件或动态库对应二进制文件的绝对路径>
- 内核模块基线:
dim KERNEL sha256:a18bb578ff0b6043ec5c2b9b4f1c5fa6a70d05f8310a663ba40bb6e898007ac5 <内核release号>/<内核模块名>
- 内核基线:
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
度量日志格式说明
文本内容,以UNIX换行符进行分隔,每行代表一条度量日志,格式为:
<PCR寄存器编号> <度量日志哈希值> <度量算法>:<度量哈希值> <度量对象> <度量日志类型>
参考示例:
- 对bash进程代码段执行度量,度量结果与静态基线一致:
12 0f384a6d24e121daf06532f808df624d5ffc061e20166976e89a7bb24158eb87 sha256:db032449f9e20ba37e0ec4a506d664f24f496bce95f2ed972419397951a3792e /usr/bin.bash [static baseline]
- 对bash进程代码段执行度量,度量结果与静态基线不一致:
12 0f384a6d24e121daf06532f808df624d5ffc061e20166976e89a7bb24158eb87 sha256:db032449f9e20ba37e0ec4a506d664f24f496bce95f2ed972419397951a3792e /usr/bin.bash [tampered]
- 对ext4内核模块代码段执行度量,未找到静态基线:
12 0f384a6d24e121daf06532f808df624d5ffc061e20166976e89a7bb24158eb87 sha256:db032449f9e20ba37e0ec4a506d664f24f496bce95f2ed972419397951a3792e ext4 [no static baseline]
- dim_monitor对dim_core执行度量,记录基线时的度量结果:
12 660d594ba050c3ec9a7cdc8cf226c5213c1e6eec50ba3ff51ff76e4273b3335a sha256:bdab94a05cc9f3ad36d29ebbd14aba8f6fd87c22ae580670d18154b684de366c dim_core.text [dynamic baseline]
12 28a3cefc364c46caffca71e7c88d42cf3735516dec32796e4883edcf1241a7ea sha256:0dfd9656d6ecdadc8ec054a66e9ff0c746d946d67d932cd1cdb69780ccad6fb2 dim_core.data [dynamic baseline]
- 证书/签名文件格式说明
为通用格式,详见开启签名校验章节。
内核模块参数说明
- 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
- 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
内核接口说明
- 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:执行动态基线建立或动态度量时发生错误,需要用户解决错误后重新触发动态基线建立或动态度量。
- 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命令行接口,详见:https://gitee.com/openeuler/dim_tools/blob/master/doc/cmd.md 。
如何使用
安装/卸载
安装dim_tools和dim软件包
# 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
说明:
dim_monitor必须后于dim_core加载,先于dim_core卸载; 也可使用源码编译安装,详见https://gitee.com/openeuler/dim/blob/master/README.md 。
度量用户态进程代码段
前置条件:
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
说明:
需要保证内核模块的内核编译环境版本号和当前系统内核版本号一致,可以使用如下方法确认:
# 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
说明:
/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模块被成功度量,并以当前的基线结果作为后续度量的基准值。
说明:
若跳过动态基线创建,直接进行度量,日志中会显示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
说明:
如果某个静态基线文件签名校验失败,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分钟触发一次动态度量。
说明:
此时不能配置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毫秒时间。
远程证明(鲲鹏安全库)
介绍
本项目开发运行在鲲鹏处理器上的基础安全软件组件,前期主要聚焦在远程证明等可信计算相关领域,使能社区安全开发者。
软件架构
在未使能TEE的平台上,本项目可提供平台远程证明特性,其软件架构如下图所示:
在已使能TEE的平台上,本项目可提供TEE远程证明特性,其软件架构如下图所示:
安装配置
使用yum安装程序的rpm包,命令如下:
# yum install kunpengsecl-ras kunpengsecl-rac kunpengsecl-rahub kunpengsecl-qcaserver kunpengsecl-attester kunpengsecl-tas kunpengsecl-devel
准备数据库环境:进入
/usr/share/attestation/ras
目录,执行prepare-database-env.sh
脚本进行自动化的数据库环境配置。程序运行时依赖的配置文件有三个路径,分别为:当前路径
./config.yaml
,家路径${HOME}/.config/attestation/ras(rac)(rahub)(qcaserver)(attester)(tas)/config.yaml
,以及系统路径/etc/attestation/ras(rac)(rahub)(qcaserver)(attester)(tas)/config.yaml
。(可选)如果需要创建家目录配置文件,可在安装好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
。相关参数如下:
-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权限。相关参数如下:
-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文件格式如下:
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路径参数与该路径保持相同。相关参数如下:
-C, --scenario int 设置程序的应用场景,默认为no_as场景(0),1=as_no_daa场景,2=as_with_daa场景
-S, --server string 指定开放的服务器地址/端口
ATTESTER启动参数
命令行输入 attester
即可启动ATTESTER程序。相关参数如下:
-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程序。相关参数如下:
-T, --token 生成一个测试用的验证码并退出
注意:
1.若要启用TAS服务,需要先为TAS配置好私钥。可以按如下命令修改家目录下的配置文件:
# 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 |
上述接口的具体用法分别介绍如下。
若需要查询所有服务器的信息,可以使用"/"
接口。
# curl -X GET -H "Content-Type: application/json" http://localhost:40002/
若需要查询目标服务器的详细信息,可以使用"/{id}"
接口的GET
方法,其中{id}是RAS为目标服务器分配的唯一标识号。
# curl -X GET -H "Content-Type: application/json" http://localhost:40002/1
若需要修改目标服务器的信息,可以使用"/{id}"
接口的POST
方法,其中$AUTHTOKEN是事先使用ras -T
自动生成的身份验证码。
type clientInfo struct {
Registered *bool `json:"registered"` // 目标服务器注册状态
IsAutoUpdate *bool `json:"isautoupdate"`// 目标服务器基准值更新策略
}
# curl -X POST -H "Authorization: $AUTHTOKEN" -H "Content-Type: application/json" http://localhost:40002/1 -d '{"registered":false, "isautoupdate":false}'
若需要删除目标服务器,可以使用"/{id}"
接口的DELETE
方法。
注意:
使用该方法并非删除目标服务器的所有信息,而是把目标服务器的注册状态置为
false
!
# curl -X DELETE -H "Authorization: $AUTHTOKEN" -H "Content-Type: application/json" http://localhost:40002/1
若需要查询指定范围内的所有服务器信息,可以使用"/{from}/{to}"
接口的GET
方法。
# curl -X GET -H "Content-Type: application/json" http://localhost:40002/1/9
若需要查询目标服务器的所有可信报告,可以使用"/{id}/reports"
接口的GET
方法。
# curl -X GET -H "Content-Type: application/json" http://localhost:40002/1/reports
若需要查询目标服务器指定可信报告的详细信息,可以使用"/{id}/reports/{reportid}"
接口的GET
方法,其中{reportid}是RAS为目标服务器指定可信报告分配的唯一标识号。
# curl -X GET -H "Content-Type: application/json" http://localhost:40002/1/reports/1
若需要删除目标服务器指定可信报告,可以使用"/{id}/reports/{reportid}"
接口的DELETE
方法。
注意:
使用该方法将删除指定可信报告的所有信息,将无法再通过接口对该报告进行查询!
# curl -X DELETE -H "Authorization: $AUTHTOKEN" -H "Content-Type: application/json" http://localhost:40002/1/reports/1
若需要查询目标服务器的所有基准值,可以使用"/{id}/basevalues"
接口的GET
方法。
# curl -X GET -H "Content-Type: application/json" http://localhost:40002/1/basevalues
若需要给目标服务器新增一条基准值信息,可以使用"/{id}/newbasevalue"
接口的POST
方法。
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"` // 是否为一组新的基准值
}
# 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为目标服务器指定基准值分配的唯一标识号。
# curl -X GET -H "Content-Type: application/json" http://localhost:40002/1/basevalues/1
若需要修改目标服务器指定基准值的可用状态,可以使用"/{id}/basevalues/{basevalueid}"
接口的POST
方法。
# curl -X POST -H "Content-type: application/json" -H "Authorization: $AUTHTOKEN" http://localhost:40002/1/basevalues/1 -d '{"enabled":true}'
若需要删除目标服务器指定基准值,可以使用"/{id}/basevalues/{basevalueid}"
接口的DELETE
方法。
注意:
使用该方法将删除指定基准值的所有信息,将无法再通过接口对该基准值进行查询!
# 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 的身份标识号。
# curl -X GET -H "Content-type: application/json" -H "Authorization: $AUTHTOKEN" http://localhost:40002/1/ta/test/status
若需要查询目标服务器上特定用户 TA 的所有基准值信息,可以使用"/{id}/ta/{tauuid}/tabasevalues"
接口的GET方法。
# 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 的指定基准值分配的唯一标识号。
# curl -X GET -H "Content-type: application/json" http://localhost:40002/1/ta/test/tabasevalues/1
若需要修改目标服务器上特定用户 TA 的指定基准值的可用状态,可以使用"/{id}/ta/{tauuid}/tabasevalues/{tabasevalueid}"
接口的POST
方法。
# 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
方法。
注意:
使用该方法将删除指定基准值的所有信息,将无法再通过接口对该基准值进行查询!
# 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
方法。
type tabaseValueJson struct {
Uuid string `json:"uuid"` // 用户 TA 的标识号
Name string `json:"name"` // 基准值名称
Enabled bool `json:"enabled"` // 基准值是否可用
Valueinfo string `json:"valueinfo"` // 镜像哈希值和内存哈希值
}
# 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
方法。
# 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 的指定可信报告分配的唯一标识号。
# curl -X GET -H "Content-type: application/json" http://localhost:40002/1/ta/test/tareports/2
若需要删除目标服务器上特定用户 TA 的指定可信报告,可以使用"/{id}/ta/{tauuid}/tareports/{tareportid}"
接口的DELETE
方法。
注意:
使用该方法将删除指定可信报告的所有信息,将无法再通过接口对该报告进行查询!
# curl -X DELETE -H "Content-type: application/json" http://localhost:40002/1/ta/test/tareports/2
若需要获取本程序的版本信息,可以使用"/version"
接口的GET
方法。
# curl -X GET -H "Content-Type: application/json" http://localhost:40002/version
若需要查询目标服务器/RAS/数据库的配置信息,可以使用"/config"
接口的GET
方法。
# curl -X GET -H "Content-Type: application/json" http://localhost:40002/config
若需要修改目标服务器/RAS/数据库的配置信息,可以使用"/config"
接口的POST
方法。
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"`
}
# 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
方法:
# curl -X GET -H "Content-Type: application/json" http://localhost:40009/config
若需要修改TAS的配置信息,可使用"/config"
接口的POST
方法:
curl -X POST -H "Content-Type: application/json" -H "Authorization: $AUTHTOKEN" http://localhost:40009/config -d '{"basevalue":"testvalue"}'
注意:
TAS的配置信息读取与修改目前仅支持基准值
FAQ
RAS安装后,为什么无法启动?
因为在当前RAS的设计逻辑中,程序启动后需要从当前目录查找一份名为
ecdsakey.pub
的文件进行读取并作为之后访问该程序的身份验证码,若当前目录没有该文件,则RAS启动会报错。解决方法一:运行
ras -T
生成测试用token后会生成ecdsakey.pub
。 解决方法二:自行部署oauth2认证服务后,将对应JWT token生成方对应的验证公钥保存为ecdsakey.pub
。为什么RAS启动后,通过restapi无法访问?
因为RAS默认以https模式启动,您需要向RAS提供合法的证书才能正常访问,而http模式下启动的RAS则不需要提供证书。
可信平台控制模块(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管理平台实现对可信度量的验证及可信策略同步和管理。
功能描述
如下图所示,整体系统方案由防护部件、计算部件和可信管理中心三部分组成。
可信管理中心:对可信计算节点的防护策略和基准值进行制定、下发、维护、存储等操作的集中管理平台,可信管理中心由第三方厂商提供。
防护部件:独立于计算部件执行,为可信计算平台提供具有主动度量和主动控制特征的可信计算防护功能,实现运算的同时进行安全防护。防护部件包括可信平台控制模块、可信软件基,以及可信密码模块(Trusted Cryptography Module,TCM)。TPCM是可信计算节点中实现可信防护功能的关键部件,可以采用多种技术途径实现,如板卡、芯片、IP核等,其内部包含中央处理器、存储器等硬件,固件,以及操作系统与可信功能组件等软件,支撑其作为一个独立于计算部件的防护部件组件,并行于计算部件按内置防护策略工作,对计算部件的硬件、固件及软件等需防护的资源进行可信监控,是可信计算节点中的可信根。
计算部件:主要包括硬件、操作系统和应用层软件。其中操作系统分为引导阶段和运行阶段,在引导阶段openEuler的shim和grub2支持可信度量能力,可实现对shim、grub2以及操作系统内核、initramfs等启动文件的可信度量防护;在运行阶段,openEuler操作系统支持部署可信验证要素代理(由第三方厂商可信华泰提供),它负责将数据发送给TPCM模块,用以实现运行阶段的可信度量防护。
其中,TPCM作为可信计算节点中实现可信防护功能的关键部件,需要与TSB、TCM、可信管理中心和可信计算节点的计算部件交互,交互方式如下:
- TPCM的硬件、固件与软件为TSB提供运行环境,设置的可信功能组件为TSB按策略库解释要求实现度量、控制、支撑与决策等功能提供支持。
- TPCM通过访问TCM获取可信密码功能,完成对防护对象可信验证、度量和保密存储等计算任务,并提供TCM服务部件以支持对TCM的访问。
- TPCM通过管理接口连接可信管理中心,实现防护策略管理、可信报告处理等功能。
- TPCM通过内置的控制器和I/O端口,经由总线与计算部件的控制器交互,实现对计算部件的主动监控。
- 计算部件操作系统中内置的防护代理获取预设的防护对象有关代码和数据提供给TPCM,TPCM将监控信息转发给TSB,由TSB依据策略库进行分析处理。
约束限制
适配服务器:TaiShan 200(型号2280)VF
适配BMC插卡型号:BC83SMMC
应用场景
通过TPCM特性构成一个完整的信任链,保障系统启动以后进入一个可信的计算环境。