文件完整性保护
内核完整性度量架构(IMA)
IMA全称Integrity Measurement Architecture,是Linux内核提供的强制访问控制子系统,通过在文件访问系统调用添加检查hook,实现文件的完整性度量/校验。
前置条件
- 准备openEuler内核编译环境,可参考:https://gitee.com/openeuler/kernel/wikis/kernel;
- 内核模块签名支持商密算法在openEuler 5.10内核支持,建议选取最新5.10内核源码进行编译;
- 生成内核SM2根证书:
# 生成证书配置文件(配置文件其他字段可按需定义)
$ echo 'subjectKeyIdentifier=hash' > ca.cfg
# 生成SM2签名私钥
$ openssl ecparam -genkey -name SM2 -out ca.key
# 生成签名请求
$ openssl req -new -sm3 -key ca.key -out ca.csr
# 生成SM2证书
$ openssl x509 -req -days 3650 -extfile ca.cfg -signkey ca.key -in ca.csr -out ca.crt
- 生成IMA二级证书:
# 创建证书配置文件
echo 'subjectKeyIdentifier=hash' > ima.cfg
echo 'authorityKeyIdentifier=keyid,issuer' >> ima.cfg
# 生成私钥
openssl ecparam -genkey -name SM2 -out ima.key
# 生成签名请求
openssl req -new -sm3 -key ima.key -out ima.csr
# 基于一级证书生成二级证书
openssl x509 -req -sm3 -CAcreateserial -CA ca.crt -CAkey ca.key -extfile ima.cfg -in ima.csr -out ima.crt
# 转换为DER格式
openssl x509 -outform DER -in ima.crt -out x509_ima.der
- 将根证书放置到内核源码目录,并修改内核编译选项CONFIG_SYSTEM_TRUSTED_KEYS,将指定证书编译到内核TRUSTED密钥中:
$ cp /path/to/ca.crt .
$ make openeuler_defconfig
$ cat .config | grep CONFIG_SYSTEM_TRUSTED_KEYS
CONFIG_SYSTEM_TRUSTED_KEYS="ca.crt"
- 编译并安装内核:
$ make -j64
$ make modules_install
$ make install
如何使用
场景1:原生IMA
IMA度量模式
启动参数配置IMA策略和摘要算法,关闭IMA评估模式,重启系统:
ima_policy=tcb ima_hash=sm3 ima_appraise=off
检查度量日志,可以发现IMA对于所有目标保护文件都进行了度量,且摘要算法为SM3:
cat /sys/kernel/security/ima/ascii_runtime_measurements
10 601989730f01fb4688bba92d0ec94340cd90757f ima-sig sm3:0000000000000000000000000000000000000000000000000000000000000000 boot_aggregate
10 dc0a98316b03ab15edd2b8daae75a0d64bca7c56 ima-sig sm3:3c62ee3c13ee32d7a287e04c843c03ebb428a5bb3dd83561efffe9b08444be22 /usr/lib/systemd/systemd
10 1d0a5140e3924e2542963ad887a80def0aa8acac ima-sig sm3:4d3b83e143bd9d5288ef099eff4d01444947516d680165c6dd08cd5900768032 /usr/lib64/ld-linux-x86-64.so.2
......
IMA评估模式(hash)
启动参数配置IMA策略和摘要算法,开启IMA评估fix模式,重启系统:
ima_policy=appraise_tcb ima_hash=sm3 ima_appraise=fix
appraise_tcb代表对所有 root 属主的文件进行评估。
对所有需要评估的文件进行一次open操作,以自动标记ima扩展属性:
find / -fstype ext4 -type f -uid 0 -exec dd if='{}' of=/dev/null count=0 status=none \;
完成标记后,可以看到所有的文件都标记了SM3摘要算法的ima扩展属性:
getfattr -m - -d -e hex /bin/bash
getfattr: Removing leading '/' from absolute path names
# file: bin/bash
security.ima=0x0411a794922bb9f0a034257f6c7090a3e8429801a42d422c21f1473e83b7f7eac385
security.selinux=0x73797374656d5f753a6f626a6563745f723a7368656c6c5f657865635f743a733000
openssl dgst -sm3 /bin/bash
SM3(/bin/bash)= a794922bb9f0a034257f6c7090a3e8429801a42d422c21f1473e83b7f7eac385
开启enforce模式后重启,系统可正常运行:
ima_policy=appraise_tcb ima_hash=sm3 ima_appraise=enforce
IMA评估模式(签名)
前置条件:
- 内核预置商密根证书;
- 安装ima-evm-utils软件包,且大于或等于指定版本:
$ rpm -qa ima-evm-utils
ima-evm-utils-1.3.2-4.oe2209.x86_64
生成IMA二级证书:
# 创建证书配置文件
echo 'subjectKeyIdentifier=hash' > ima.cfg
echo 'authorityKeyIdentifier=keyid,issuer' >> ima.cfg
# 生成私钥
openssl ecparam -genkey -name SM2 -out ima.key
# 生成签名请求
openssl req -new -sm3 -key ima.key -out ima.csr
# 基于一级证书生成二级证书
openssl x509 -req -sm3 -CAcreateserial -CA ca.crt -CAkey ca.key -extfile ima.cfg -in ima.csr -out ima.crt
# 转换为DER格式
openssl x509 -outform DER -in ima.crt -out x509_ima.der
将IMA证书放置在/etc/keys目录下,执行dracut重新制作initrd:
mkdir -p /etc/keys
cp x509_ima.der /etc/keys
echo 'install_items+=" /etc/keys/x509_ima.der "' >> /etc/dracut.conf
dracut -f
对需要进行保护的文件执行签名操作,例如此处对/usr/bin目录下所有root用户的可执行文件进行签名:
find /usr/bin -fstype ext4 -type f -executable -uid 0 -exec evmctl -a sm3 ima_sign --key /path/to/ima.key '{}' \;
开启enforce模式后重启,系统可正常运行:
ima_policy=appraise_tcb ima_hash=sm3 ima_appraise=enforce
检查签名模式的保护效果:
# getfattr -m - -d /bin/echo
getfattr: Removing leading '/' from absolute path names
# file: bin/echo
security.ima=0sAwIRNJFkBQBIMEYCIQDLBg/bYlrkBqSaXNQMyK7rhiZj+qRiKdu+0fqW8lSmPQIhAJY2qSZJ0HgSu7kygydrS4MCC0KTK59nUkvISenZAUCo
security.selinux="system_u:object_r:bin_t:s0"
# echo 123 >> /bin/echo
-bash: /bin/echo: Permission denied
注意事项:
对于每一个在IMA防护范围内的文件,都需要选择使用hash模式和签名模式其中之一的方法标记完整性信息。一般情况下,对于可能发生变化的文件(例如数据文件、配置文件等)采用hash模式标记,对于不会发生变化的文件(例如可执行文件、动态链接库等)采用签名模式标记。
场景2:IMA摘要列表模式
生成SM3摘要列表
gen_digest_lists支持-a sm3参数,支持生成SM3摘要列表:
gen_digest_lists -a sm3 -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/usr/bin/bash -d <output_dir> -i i:
gen_digest_lists -a sm3 -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/usr/bin/bash -d <output_dir> -i i: -T
配置SM3摘要算法
整体步骤与开启IMA摘要列表特性相同,唯一区别在于将ima_hash启动参数配置为SM3。启动参数参考配置如下:
# log模式
ima_template=ima-sig ima_policy="exec_tcb|appraise_exec_tcb|appraise_exec_immutable" initramtmpfs ima_hash=sm3 ima_appraise=log evm=allow_metadata_writes evm=x509 ima_digest_list_pcr=11 ima_appraise_digest_list=digest
# enforce模式
ima_template=ima-sig ima_policy="exec_tcb|appraise_exec_tcb|appraise_exec_immutable" initramtmpfs ima_hash=sm3 ima_appraise=enforce-evm evm=allow_metadata_writes evm=x509 ima_digest_list_pcr=11 ima_appraise_digest_list=digest
其余步骤可参考 管理员指南->可信计算->摘要列表场景初次部署 章节。
配置完成后重启系统,通过查询度量日志可以看到,度量日志中的默认算法已变成SM3:
cat /sys/kernel/security/ima/ascii_runtime_measurements
......
11 9e32183b5b1da72c6ff4298a44026e3f9af510c9 ima-sig sm3:5a2d81cd135f41e73e0224b9a81c3d8608ccde8caeafd5113de959ceb7c84948 /usr/bin/upload_digest_lists
11 f3b9264761dbaeaf637d08b86cc3655e8f3380f7 ima-sig sm3:cc6faecee9976c12279dab1627a78ef36f6998c65779f3b846494ac5fe5493a1 /usr/libexec/rpm_parser
11 dc0a98316b03ab15edd2b8daae75a0d64bca7c56 ima-sig sm3:3c62ee3c13ee32d7a287e04c843c03ebb428a5bb3dd83561efffe9b08444be22 /usr/lib/systemd/systemd
......
配置SM2证书校验摘要列表
前置条件:
- 内核预置商密根证书;
- 安装digest-list-tools和ima-evm-utils软件包,且大于或等于指定版本:
$ rpm -qa ima-evm-utils
ima-evm-utils-1.3.2-4.oe2209.x86_64
$ rpm -qa digest-list-tools
digest-list-tools-0.3.95-10.oe2209.x86_64
执行步骤:
- 生成IMA/EVM二级证书(需要为内核预置的商密根证书的子证书):
# 创建证书配置文件
echo 'subjectKeyIdentifier=hash' > ima.cfg
echo 'authorityKeyIdentifier=keyid,issuer' >> ima.cfg
# 生成私钥
openssl ecparam -genkey -name SM2 -out ima.key
# 生成签名请求
openssl req -new -sm3 -key ima.key -out ima.csr
# 基于一级证书生成二级证书
openssl x509 -req -sm3 -CAcreateserial -CA ca.crt -CAkey ca.key -extfile ima.cfg -in ima.csr -out ima.crt
# 转换为DER格式
openssl x509 -outform DER -in ima.crt -out x509_ima.der
openssl x509 -outform DER -in ima.crt -out x509_evm.der
- 将IMA/EVM证书放置在/etc/keys目录下,执行dracut重新制作initrd:
mkdir -p /etc/keys
cp x509_ima.der /etc/keys
cp x509_evm.der /etc/keys
echo 'install_items+=" /etc/keys/x509_ima.der /etc/keys/x509_evm.der "' >> /etc/dracut.conf
dracut -f -e xattr
- 配置启动参数,开启IMA摘要列表功能,重启后可以检查证书被导入IMA/EVM密钥环:
cat /proc/keys
......
024dee5e I------ 1 perm 1f0f0000 0 0 keyring .evm: 1
......
3980807f I------ 1 perm 1f0f0000 0 0 keyring .ima: 1
......
- 将IMA摘要列表使用IMA/EVM证书对应的私钥进行签名,签名后可被正常导入内核:
# 使用evmctl对摘要列表进行签名
evmctl ima_sign --key /path/to/ima.key -a sm3 0-metadata_list-compact-tree-1.8.0-2.oe2209.x86_64
# 检查签名后的扩展属性
getfattr -m - -d 0-metadata_list-compact-tree-1.8.0-2.oe2209.x86_64
# file: 0-metadata_list-compact-tree-1.8.0-2.oe2209.x86_64
security.ima=0sAwIRNJFkBQBHMEUCIQCzdKVWdxw1hoVm9lgZB6sl+sxapptUFNjqHt5XZD87hgIgBMuZqBdrcNm7fXq/reQw7rzY/RN/UXPrIOxrVvpTouw=
security.selinux="unconfined_u:object_r:admin_home_t:s0"
# 将签名后的摘要列表文件导入内核
echo /root/tree/etc/ima/digest_lists/0-metadata_list-compact-tree-1.8.0-2.oe2209.x86_64 > /sys/kernel/security/ima/digest_list_data
# 检查度量日志,可以看到摘要列表的导入记录
cat /sys/kernel/security/ima/ascii_runtime_measurements
11 43b6981f84ba2725d05e91f19577cedb004adffb ima-sig sm3:b9430bbde2b7f30e935d91e29ab6778b6a825a2c3e5e7255895effb8747b7c1a /root/tree/etc/ima/digest_lists/0-metadata_list-compact-tree-1.8.0-2.oe2209.x86_64 0302113491640500473045022100b374a556771c35868566f6581907ab25facc5aa69b5414d8ea1ede57643f3b86022004cb99a8176b70d9bb7d7abfade430eebcd8fd137f5173eb20ec6b56fa53a2ec
注意:
- openEuler默认提供的摘要列表中使用的哈希算法为SHA256。当IMA摘要列表度量算法配置为SM3算法时,必须将/etc/ima/digest_lists目录下的摘要列表移除,然后重新生成并签名,否则会导致文件完整性校验错误。参考步骤如下:
# 重置磁盘SELinux标签(开启IMA扩展属性校验,并开启SELinux时执行)
fixfiles -F restore
# 为所有文件生成摘要列表(也可自行设置生成范围)
gen_digest_lists -a sm3 -t metadata -f compact -i l:policy -o add -p -1 -m immutable -i I:/ -d /etc/ima/digest_lists -i i:
# 修改生成的摘要列表文件名(可选)
mv /etc/ima/digest_lists/0-metadata_list-compact- /etc/ima/digest_lists/0-metadata_list-compact-everything-sm3
# 签名
evmctl ima_sign --key /path/to/ima.key -a sm3 /etc/ima/digest_lists/0-metadata_list-compact-everything-sm3
# 重新制作initrd
dracut -f -e xattr
- 对于openEuler发布的软件包,会默认提供IMA摘要列表文件。由于默认提供的摘要算法为sha256,因此当摘要算法切换为SM3时,会导致openEuler发布的摘要列表无法被导入,在软件包安装过程中可能出现提示信息:
Cannon parse /etc/ima/digest_lists/0-metadata_list-rpm-......
轻量入侵检测(AIDE)
AIDE是一款轻量级的入侵检测工具,主要通过检测文件的完整性,以及时发现针对系统的恶意入侵行为。AIDE数据库能够使用sha256、sha512等哈希算法,用密文形式建立每个文件的校验码或散列号。openEuler提供的AIDE在开源软件的基础上新增了对SM3算法的支持。
前置条件
AIDE大于或等于0.17.4-1版本:
$ rpm -qa aide
aide-0.17.4-1.oe2209.x86_64
如何使用
修改/etc/aide.conf配置文件,添加SM3算法支持:
......
FIPSR = p+i+n+u+g+s+m+c+acl+selinux+xattrs+sha256+sm3
......
DATAONLY = p+n+u+g+s+acl+selinux+xattrs+sha256+sm3
......
- 初始化数据库,并保存数据库作为基准。
初始化数据库:
$ aide -c /etc/aide.conf -i
示例输出如下:
AIDE initialized database at /var/lib/aide/aide.db.new.gz
Number of entries: 64249
---------------------------------------------------
The attributes of the (uncompressed) database(s):
---------------------------------------------------
/var/lib/aide/aide.db.new.gz
MD5 : a7y5ErdpBAezV2iGdaVleg==
SHA1 : u7W7jxomFtZn8rwMlkIRCN0r7iQ=
SHA256 : 88Kw5b2yJ9bejwO+NqT6lyAieno+K0+W
BPVBjXcUl08=
SHA512 : WyOIgRxk9SeSoktF6BYVV0tRL7nGNDKQ
A9QyxVCgzg+PwPMV7tzxmwOZI/dB64pP
vQ/D2jqJdf3NS2PHMI4yvg==
RMD160 : qTEPs2SIxPm3iEwsCnwvp9hR4s4=
TIGER : 0HgLucmhCcB56bxOMj+j1Kuja8UIsFRg
CRC32 : VKE1TA==
WHIRLPOOL : JSA35/NmkMOkUWEpcZJf3PR1UUz5WcLG
AmBKPkao3fzQUsLMTJizCV4CwAE0G/Yc
KX0mpW5vx+gk3njya8rAvA==
GOST : yKjiytOwRr3bJcFsxnJ310t1FY6YE3HB
YNT8XP93xpc=
STRIBOG256: 9bzS+5j4ZAoU/P7v3tkKOWn4ZfggcX28
9dLQVhaiJtQ=
STRIBOG512: 9LLXgqsRIRiXP2WOrOJt1qhx6psfbACd
un+GTVmu441quX4zaaPIIG9lzDMBAqMg
hZx5DlxsQj3YjMezSUsXLg==
SM3 : Vwii+uw3Ge5Hh3eo1KOombxn2jWgyYRX
ZdyCRZqWZ/E=
End timestamp: 2022-08-12 09:01:25 +0800 (run time: 2m 43s)
保存数据库作为基准:
$ mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz
场景1:检测被保护文件变化
$ aide -c /etc/aide.conf --check
---------------------------------------------------
Detailed information about changes:
---------------------------------------------------
File: /boot/config-5.10.0-106.3.0.57.oe2209.aarch64
Size : 182936 | 182938
Mtime : 2022-08-04 08:00:00 +0800 | 2022-08-12 09:05:34 +0800
Ctime : 2022-08-11 01:42:44 +0800 | 2022-08-12 09:05:34 +0800
SHA256 : ae0fOzf7U+e/evTZKpk6JQa00kvSkc5J | gOlhcUgnZWhcyJYMEPxCYccXwFr9lERX
vMTX5Ysh+1k= | KK3O/ytfR/g=
SHA512 : zAPIxIAM7YvJPjwl/PH23leBb/HiO0Rf | p+WxVOZ6DX323rHDRF864w297yh7POk6
PlRME7yvpzFZk/5BrNe2ofQWR/0sFu1m | 11dOzahlKTWpAKaexC/u+4REiCzjl1rm
JsDSy8m57wzCpJA9iUFq1g== | eb/kd3Xgp1LoKwn49mtqxw==
SM3 : CW0GnITxNeGeYOCAm4xfu78Vqm+wLp/Z | GWq/3nXL16tMYyxyFD/HTZbvJi2h+ttg
cOmXmIKJT4Q= | 6d8XmSHu26A=
场景2:更新数据库
执行以下命令进行数据库更新,更新后数据库文件为 /var/lib/aide/aide.db.new.gz:
$ aide -c /etc/aide.conf --update
---------------------------------------------------
Detailed information about changes:
---------------------------------------------------
File: /boot/config-5.10.0-106.3.0.57.oe2209.aarch64
Size : 182936 | 182938
Mtime : 2022-08-04 08:00:00 +0800 | 2022-08-12 09:05:34 +0800
Ctime : 2022-08-11 01:42:44 +0800 | 2022-08-12 09:05:34 +0800
SHA256 : ae0fOzf7U+e/evTZKpk6JQa00kvSkc5J | gOlhcUgnZWhcyJYMEPxCYccXwFr9lERX
vMTX5Ysh+1k= | KK3O/ytfR/g=
SHA512 : zAPIxIAM7YvJPjwl/PH23leBb/HiO0Rf | p+WxVOZ6DX323rHDRF864w297yh7POk6
PlRME7yvpzFZk/5BrNe2ofQWR/0sFu1m | 11dOzahlKTWpAKaexC/u+4REiCzjl1rm
JsDSy8m57wzCpJA9iUFq1g== | eb/kd3Xgp1LoKwn49mtqxw==
SM3 : CW0GnITxNeGeYOCAm4xfu78Vqm+wLp/Z | GWq/3nXL16tMYyxyFD/HTZbvJi2h+ttg
cOmXmIKJT4Q= | 6d8XmSHu26A=
场景3:比较数据库
在/etc/aide.conf中配置两个数据库:
# The location of the database to be read.
database_in=file:@@{DBDIR}/aide.db.gz
database_new=file:@@{DBDIR}/aide.db.new.gz
执行以下命令进行数据库比较:
$ aide -c /etc/aide.conf --compare
---------------------------------------------------
Detailed information about changes:
---------------------------------------------------
File: /boot/config-5.10.0-106.3.0.57.oe2209.aarch64
Size : 182936 | 182938
Mtime : 2022-08-04 08:00:00 +0800 | 2022-08-12 09:05:34 +0800
Ctime : 2022-08-11 01:42:44 +0800 | 2022-08-12 09:05:34 +0800
SHA256 : ae0fOzf7U+e/evTZKpk6JQa00kvSkc5J | gOlhcUgnZWhcyJYMEPxCYccXwFr9lERX
vMTX5Ysh+1k= | KK3O/ytfR/g=
SHA512 : zAPIxIAM7YvJPjwl/PH23leBb/HiO0Rf | p+WxVOZ6DX323rHDRF864w297yh7POk6
PlRME7yvpzFZk/5BrNe2ofQWR/0sFu1m | 11dOzahlKTWpAKaexC/u+4REiCzjl1rm
JsDSy8m57wzCpJA9iUFq1g== | eb/kd3Xgp1LoKwn49mtqxw==
SM3 : CW0GnITxNeGeYOCAm4xfu78Vqm+wLp/Z | GWq/3nXL16tMYyxyFD/HTZbvJi2h+ttg
cOmXmIKJT4Q= | 6d8XmSHu26A=
---------------------------------------------------
The attributes of the (uncompressed) database(s):
---------------------------------------------------
/var/lib/aide/aide.db.gz
MD5 : a7y5ErdpBAezV2iGdaVleg==
SHA1 : u7W7jxomFtZn8rwMlkIRCN0r7iQ=
SHA256 : 88Kw5b2yJ9bejwO+NqT6lyAieno+K0+W
BPVBjXcUl08=
SHA512 : WyOIgRxk9SeSoktF6BYVV0tRL7nGNDKQ
A9QyxVCgzg+PwPMV7tzxmwOZI/dB64pP
vQ/D2jqJdf3NS2PHMI4yvg==
RMD160 : qTEPs2SIxPm3iEwsCnwvp9hR4s4=
TIGER : 0HgLucmhCcB56bxOMj+j1Kuja8UIsFRg
CRC32 : VKE1TA==
WHIRLPOOL : JSA35/NmkMOkUWEpcZJf3PR1UUz5WcLG
AmBKPkao3fzQUsLMTJizCV4CwAE0G/Yc
KX0mpW5vx+gk3njya8rAvA==
GOST : yKjiytOwRr3bJcFsxnJ310t1FY6YE3HB
YNT8XP93xpc=
STRIBOG256: 9bzS+5j4ZAoU/P7v3tkKOWn4ZfggcX28
9dLQVhaiJtQ=
STRIBOG512: 9LLXgqsRIRiXP2WOrOJt1qhx6psfbACd
un+GTVmu441quX4zaaPIIG9lzDMBAqMg
hZx5DlxsQj3YjMezSUsXLg==
SM3 : Vwii+uw3Ge5Hh3eo1KOombxn2jWgyYRX
ZdyCRZqWZ/E=
/var/lib/aide/aide.db.new.gz
MD5 : sKt4dVDKY/8A9EY/X4Ue2A==
SHA1 : hagLXMv7G+KbEKh861kjjFSYpRw=
SHA256 : HTHF7k5U294ECjCLneoZ3o8bH6PYgY5u
AzoIyCacZp4=
SHA512 : 5gWi7K/ztWMl7H+PK1doV/tWDHmaE2m/
ndRXGR7b5J3v82Jv2HeJPoOt5A4Z/9FH
5H+uCLYaHwRleyalyy5Wew==
RMD160 : uMM1HtAbfz+G3Y9Z+rVR4qjdqcQ=
TIGER : OTHdXNQOxnHnOl6C9M3czSC42+SeZAZA
CRC32 : T9G1Tw==
WHIRLPOOL : FRMnQ2wHgylsTmpKE8RwdUvkzXucHwu1
W9ZkUrxoXeci2g7jIgoMmpoeDPhH73qz
nZ7fKj1lStSpiUGD5KPeWA==
GOST : haeO5dhT+t34C1GJf+2dc3q1GMN71FqB
kqoiODo+j2o=
STRIBOG256: lgZUZhhd9JfMOXgNzYptapqagwgmvdM+
7uWzJsmOxoY=
STRIBOG512: PA6jksprS37xQzHm1ZIvLR9ROa+FxoiF
/xbAe0pSi4lMXXzABrPKkjyK0WtjxFvx
07Poj2iDwNNcUJWekbaEXA==
SM3 : R5/HXng5MNvrjoCh8/JzrWle1IO8ggsR
P5i2ePX5BpY=