在 EC2 上对 SELinux 故障进行紧急恢复以及排查的思路及方法
概述
SELinux,全称 Security-Enhanced Linux,是一个为系统提供强制访问控制机制的安全模块,安装并启用 SELinux 模块的操作系统会为每个进程和系统资源打上一个特殊的安全标记,称为 SELinux 上下文,并根据 SELinux 上下文信息以允许或拒绝访问行为。
亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里有技术文档、开发案例、技术专栏、培训视频、活动与竞赛等。帮助中国开发者对接世界最前沿技术,观点,和项目,并将中国优秀开发者或技术推荐给全球云社区。如果你还没有关注/收藏,看到这里请一定不要匆匆划过,点这里让它成为你的技术宝库!
根据国家网络安全等级保护基本要求,第三级系统在安全计算环境层面“应对重要主体和客体设置安全标记,并控制主体对有安全标记信息资源的访问”,因此需要通过国家等保三级测评的系统均需要在系统内开启 SELinux。
注:亚马逊官方系统镜像 Amazon Linux 2022 已默认开启了 Enforcing 策略的 SELinux。
随着 SELinux 的应用越来越广泛,由 SELinux 配置不当导致的系统故障也随之增多,严重情况下可能导致系统启动失败,本文先从如何紧急恢复 SELinux 故障的 EC2 主机入手,然后围绕 SELinux常见三大问题根源之一的“标签故障”,介绍在 AWS 上进行故障排查的方法及思路。
EC2 紧急恢复的两种方法
EC2 串行控制台访问
如果故障主机满足串行控制台访问前置条件,并且启用了串行控制台访问,则可以直接使用 EC2 串行控制台访问进行紧急恢复以及故障排查,串行控制台不要求您的 EC2 实例具有任何联网功能。使用串行控制台,您可以向实例输入命令,就像键盘和显示器直接连接到实例的串行端口一样。串行控制台会话在实例重启和停止期间持续。在重新启动期间,您可以从一开始就查看所有启动消息。串行控制台默认未启用,需要明确授权以后方可使用,具体方法如下:
1、授予账户可执行串行控制台的权限,建议的 IAM 策略如下:
配置此策略后,账户将可以在连接 EC2 实例时,看到“EC2 串行控制台访问”的选项,初始默认为“禁止”,需要点击“管理”,设置为“允许”,完毕,账号即可对 EC2 进行串行控制台访问.
2、在串行控制台登陆 EC2 服务器前,我们还需要为 EC2 建立允许在串行控制台使用密码登陆的用户及口令。使用默认的 SSH 方式远程登录 EC2 服务器,登录以后使用 passwd 设定密码,下面使用 root 为例:
3、禁用 SELinux 以进行紧急恢复,对于因 SELinux 导致的系统故障,我们可以先禁用 SELinux 以进行紧急恢复及故障排查。串行控台登录服务器以后,直接修改 /etc/selinux/config 并将 SELINUX=disabled,然后重启服务器,即可生效。
救援实例
对于不支持串行控制台访问的服务器,或支持但前期未启用的,我们还可以使用救援实例对 SELinux 故障主机进行紧急恢复。具体操作如下:
在 Virtual Private Cloud (VPC)中启动新的Amazon EC2实例,且使用与受损实例相同的 Amazon 系统映像 (AMI)并与其位于同一可用区中。新实例将成为您的“救援”实例。或者,也可以使用您可以访问的现有实例,但前提是该实例使用与受损实例相同的 AMI,并且二者位于同一可用区中.
从受损实例中分离Amazon Elastic Block Store (Amazon EBS)根卷(/dev/xvda 或/dev/sda1)。记下设备名称,以确保稍后重新连接时它是相同的
将 EBS 卷作为辅助设备(/dev/sdf)附加到救援实例。
使用 SSH 连接到您的救援实例。
成为根用户,使用 lsblk 标识正确的设备名称,然后将其保存以在整个过程中使用:
注意:设备(/dev/xvdf1)可能会以不同的设备名称附加到救援实例。使用 lsblk 命令查看可用磁盘设备及其挂载点,以确定正确的设备名称。
6、选择要使用的适当临时挂载点,并确保它存在,请使用/mnt,除非该挂载点已在使用
7、从附加的卷挂载根文件系统:
注意:如果卷挂载失败,请检查 dmesg | tail。如果日志显示 UUID 冲突,请使用选项 -o nouuid。
8、修改 SELinux 配置文件
9、完成后,卸载辅助设备:
10、将辅助卷(/dev/sdf)与救援 EC2 实例分离,然后以/dev/xvda 或 /dev/sda1(根卷)的形式将其附加到原始实例。确保这与步骤 2 中看到的相同。/11、启动 EC2 实例,然后验证实例是否正常重启。
SELinux 日志分析
系统恢复以后,我们第一步是分析 SELinux 拦截日志,分析 SELinux 到底是拦截了哪些进程才导致的系统异常。默认情况下,SELinux 拦截日志均记录在/var/log/audit/audit.log 及/var/log/messages 文件中,对于 audit 和 message,我们均可以通过关键词“AVC”(Access Vector Cache,访问矢量缓存)筛选除 SELinux 拦截的日志,以下是当 Apache HTTP 服务器(在 httpd_t 域中运行)尝试访问 /var/www/html/file1 文件(标有 samba_share_t 类型)时发生的 AVC 拒绝日志(以及关联的系统调用)示例(具体日志格式含义,可参考 RedHat官方链接 ):
通过分析 SELinux 拦截日志,可识别出故障发生时 SELinux 拦截掉的进程及路径文件信息。
注:如果通过分析日志无法直观识别出被拦截的异常进程,由于 audit 及 message 都默认有归档功能,还可以将故障时间点的拦截日志与正常时间段拦截日志进行对比分析,识别出故障发生时被额外拦截的进程。
进程上下文标签重置
分析上下文标签有两种方式:一种是直接对拦截日志中主客体的上下文各个字段进行分析,包括分析 SELinux 用户、角色、类型、以及级别,这方面的分析需要管理员对 SELinux 有非常深刻的理解,要求较高。
作为一种简单但更实用的排查方法,对于仅仅启用默认 SELinux 策略的系统,我们可以使用 rhel-autorelabel 服务将系统进程上下文标签进行恢复重置,然后通过对比重置前后的文件标签属性,识别出进程上下文标签的异常。
对于文件标签属性,我们有两种方法进行对比,一种手动对比,我们可使用系统命令“ls -z file”查看并记录重置前后 file 的上下文标签值。这种对比方法适用于小量文件的对比;另一种是在系统安装 AIDE 文件完整性校验工具,将需要对比的文件加入 aide.conf 文件中,自动化进行对比。AIDE 使用方法参考如下:
启用 rhel-autorelabel 服务的操作命令如下:
故障原因验证
在通过标签重置,并对比分析识别到标签故障具体原因后,我们可以尝试系统命令 chcon 将异常进程的上下文标签修改为正确或错误的值,验证异常现象是否消失或复现,从而确定故障的根本原因。
总结
本文围绕“标签故障”这一 SELinux 常见故障根源,讨论了 SELinux 故障分析的思路和方法,但在实际环境中,系统故障的原因有多种,甚至 SELinux 故障仍有许多可能性,因此还需要查阅系统日志文件及官方文档进行详细分析。
本篇作者
王俊峰
亚马逊云科技专业服务团队安全顾问,负责云安全合规、云安全解决方案等的咨询设计及落地实施,致力于为客户上云提供安全最佳实践,并解决客户上云中碰到的安全需求。
评论