Linux 系统是开放的, 其上安全机制、工具很多,不同的场景其安全目标和选择的工具都不相同。以下从个人角度仿ATT&CK列出一些常见的安全机制和技术。
Linux 系统分层
逻辑上总体可以分为三层:硬件层、内核层、应用层。每层都有攻击面和相应的安全技术。各层的安全技术相互配合形成体系化的防御。
红色表示攻击面,绿色表示安全机制
硬件
硬件是计算的基础,也是安全的基石。硬件大致由主板、各种总线、CPU、内存、硬盘、外设组成。按照这几个组件分析下攻击面和安全技术。
主板
主板是其他硬件组件物理上的base。物理安全不能忽视,历史上发生过黑客直接替换存储设备的案例,特定频率的电磁波也能使某些硬件故障。
主板上有CMOS,CMOS中代码和配置是个攻击面。其上的配置决定机器的功能和安全功能。如,是否启用Secure Boot,SGX等安全配置。管理BIOS要设置管理密码,开机使用要设置使用密码。
BMC(Baseboard Management Controller),一般存在服务器上,监控机器、控制机器启动、CMOS更新等,可以看作是单独一个系统。要加强保护,如弱口令等。
硬盘
硬盘这个就挑硬盘的使用和自加密磁盘说说。
自加密磁盘(SED),一般是固态硬盘。存储的内容是加密的,主控负责加密和解密,其作用防止数据物理泄漏。开机使用时,要输入正确的密码才能使用。
CPU
CPU安全分为两个方面:1. CPU自身的安全,如 meltdown\ spectre等缺陷。2. CPU提供的安全特性。
仅在软件层面上做安全有其不足,如保护功能有限、性能不足等。现代CPU上也提供一些安全机制和功能。以12代intel CPU为例说明(ARM上也有类似的安全特性,按照发展来看,笔者比较看好ARM的CCA安全体系)。
TXT(可信执行技术) :是intel 实现可信计算平台在CPU中提供的技术。可信计算是一套安全理论,涉及到CPU、TPM、主板、内核、开发库、应用,还有一些intel未公开源码的微码。其使用也涉及到产品制造商、基础架构和运维、开发等。发展很多年了,但基本没有体系化使用,其中一些基础功能也比较陈旧,不符合现在的安全发展。TPM大家接触的较多。
说到TXT,可能会拿来与SGX比较。TXT是体系化的,平台化的,面向公司的基础架构,也有直接供运维和开发人员使用的TSS软件栈和TPM工具。SGX严格来说是可信计算中的隔离执行功能,其使用只依赖CPU特性+内核支持+SDK,对于开发人员来说,相对比较容易使用(但是也不容易使用。在12代CPU中已经废弃SGX功能)。
AES-NI: CPU上的AES加解密指令,提高AES的性能。这个一般的加解密库都使用了。
PCLMULQDQ: 无进位乘法指令,提高加解密性能。
SHA Extensions: sha1、sha256哈希算法的硬件加速指令。
Secure Key: CPU上的随机数产生指令。rdseed(产生随机数种子)、rdrand。 在内核中没有完全信任CPU的种子指令,只是作为熵源的一部分。
NX: 非执行位。标记某个页是禁止执行的,如果违反了,产生异常。
Boot Guard Technology: 启动保护技术,属于安全启动,其目的是保护启动过程的完整性(信任链的传递),防止未经验证的启动代码运行,例如BootKit。
SMEP & SMAP:阻止CPU在特权级别下执行用户模式的代码。RFLAGS寄存器中的AC标志清除时,阻止在特权级别下访问用户模式的内存。
UMIP: 一些指令只能在特权模式下执行。如SGDT、SIDT、SLDT、SMSW、STR。
MKTME: 多秘钥全内存加密,与AMD的SME对应。这个笔者比较关注,内存安全进了一大步。
CET: 控制流加强技术。两类: 1. 硬件影子栈,保护函数返回地址,如缓冲区溢出黑客利用。2. 新增ENDBRANCH(32位和64位)指令防御ROP/JOP/COP利用。gcc编译时函数第一条指令是ENDBRANCH,运行时,CPU根据该指令保存/检查相应的状态,判断是否恶意利用。
KeyLocker Technology:新增ENCODEKEY指令对key 进行wrap并返回一个handle,以后加解密使用这个handle即可。与使用TPM加解密原理相似。
Devil’s Gate Rock: BIOS保护技术。更新BIOS时,进行签名、权限检查等多项保护BIOS的技术集合。
MKTME、CET、Keylocker、Devil’s Gate Rock,这些技术只有在比较新的主板、CPU、内核中才能使用。
12代CPU废弃的安全技术:MPX和SGX。
外设
每一种外设都是一个攻击面。例如:WIFI、蓝牙、USB类的设备。
WIFI:各种移动设备,车载,路由器,家居设备。这些设备如果驱动或者应用有漏洞、访问接入控制策略不当,都能形成破坏和信息泄漏。如果拿个手机站在马路上,可以看到车上各种WIFI热点,如果有耐心走到车附近,很容易就能扫到行车记录仪上二维码中的密码。
蓝牙:这个危害同WIFI。例如蓝牙鼠标、键盘。如果联入系统的鼠标被偷走,盲点击就可以形成破坏。
USB设备:这个是对不联网系统破坏的重要通道。例如,U盘中的恶意文件。
这些外设,尽可能的减少,能物理割掉的割掉,不能割的封上,不能封的要禁止相应的驱动加载。使用的,要保持软件更新,实施合适的接入控制策略。
各种总线
USB总线、火线、PCI等总线。
PCI总线可以传输、更改SED的口令,火线可以直接读取物理内存,USB比较通用,较容易接入各种恶意物理设备。
安全物理设备
HSM、TPM都是用于安全目的芯片。TPM是可信计算中的组件,大多数计算机中都有,相对比较容易使用。openssl也有利用TPM的功能。
Ukey: 使用系统时用外部设备进行认证。例如,CentOS登录时,或者网银登录、玩游戏时都有相应的身份认证设备。
内核
内核大致由以下五部分组成:基础组件(进程调度与管理、内存管理、进程间通信,一般裁减时都会保留)、文件系统和块IO系统、网络子系统、各种基础库、驱动和固件。还有安全子系统。重点说一说内核中的安全机制和技术。
自主访问控制 & ACL
客体的拥有者决定其他用户的权限。例如:ACL中配置的策略。Linux系统的 用户/组/其他+ACL 组成基础的访问控制。ROOT作为管理身份,执行基础访问控制外的功能。
SETUID/SETGID/ NO_NEW_PRIV
这个是基础访问控制外的特例。如passwd、mount、各种沙箱程序,尽量减少这类程序就是了。说一说NO_NEW_PRIV,setuid/setgid和capabilites都是合法提权,在执行一些程序时,为了防止这些提权方法被滥用,可以使用prctl设置NO_NEW_PRIV。
capabilities
ROOT权限太大,要对ROOT进行分权。kernel v5.15中分成了41种具体的权限,如CAP_CHOWN、CAP_ADMIN、CAP_BPF等。在需要特权的可执行程序上设置特定的特权,在执行时就不需要ROOT账户了,如SOCKET_RAW,bpf操作。应用层开发库libcap2比以前易用很多,但应用的不是很多。
MAC
强制访问控制,相对自主访问控制而言。简单来说制定统一的规则,赋予主体与客体相应的标记,根据规则判断动作是否允许。访问控制模型有BRAC(基于角色的访问控制,这个用的多)、BLP、BIBA。BLP主要关注机密性,其控制规则“上不可读,下不可写”。BIBA主要关注完整性,其控制规则“上不可写,下不可读”。
内核中的Selinux实现多级访问控制,综合了几个访问控制模型,是CentOS和Andriod上默认的强制访问控制机制。
Apparmor: 是Ubuntu上基于路径的MAC实现,其配置比Selinux容易理解。但Apparmor仅针对配置的程序进行访问控制。
Smack: 简单的访问控制。Smack在Tizen OS(一种用在TV、Iot的操作系统)使用,其主要特点是实现了CIPSO协议。
Tomoyo: 日本人搞的强制访问控制实现。Smack和Tomoyo相对较少使用。
LSM
Linux 安全模型是一套框架,实质是分布在内核代码中多个地方的钩子,本身没有实现安全控制功能(现在的capabilites和IMA也在LSM框架中插入了hook)。在kernel V5.15中共有239个hook点。上面的Selinux、Apparmor就是实现不同hook点从而实现不同的访问控制实现。
关于LSM是否可以同时使用多个访问控制实现,历史上有过反复,开始可以,后来不可以,现在又可以了。
YAMA: 用于控制ptrace、prctl使用的机制。例如是否允许调试、注入so库,都可以通过设置yama实现,比较简单实用。现在也是通过LSM实现的。
IMA: 完整性度量基础设施,“计算”系统运行过程中文件、文件属性、进程的完整性。对系统运行过程中所有进程(还有内核)计算出一个hash值存于TPM中的17号寄存器中,当向对方证明时使用。IMA很占用内存,基本没有使用的。
LANDLOCK: 创建一个功能受限的环境,多用于沙箱。根据现在的代码来看,实现的比较粗糙。但配合cgroup、namespace也许能实现功能不错的沙箱。
lockdown: Linux系统安全增强功能。在CentOS早期版本中叫runlevel,Ubuntu上早期是通过应用层脚本实现。例如,是否允许加载ko,是否允许访问/dev/mem等等,这些原来允许使用但很危险的操作,可以通过lockdown限制。锁住系统,提高系统安全级别,比原来更安全了。安全级别只能提高,不能降级,如果想降级,要重启系统。一般用于IoT设备。
LoadPin: 确保进入内核地址空间的代码来自同一个文件系统,该文件系统可以设置ro属性。防止黑客引入ko攻击系统。
内核自保护技术: 内核作为一个软件,其本身也是攻击目标。例如:
1. 减少攻击面。以前导出的函数不再导出,以前老的系统调用被废弃,增加seccomp机制过滤系统调用。一些关键信息不再向用户空间导出,或者需要特权才能查看,如/proc/kallsym中符号的地址。内核空间数据复制到用户空间时,先初始化为0;系统调用返回时,清除栈;释放堆内存时,清除堆等等。
2. 执行代码的内存不能同时具有执行和写权限。
3. 一些数据设置为只读属性。
4. 内核模块、固件、UEFI代码验证签名。
5. 加强地址随机化。栈缓冲区保护。运行时检查计数器、整数是否溢出等。借鉴了pax项目的一些内存安全保护技术。
6. 使用安全编译选项编译内核。
Cgroup & namespace: namespace是资源隔离技术,v5.15对8类资源进行隔离(pid、net、uts、user、cgroup、ipc、mnt、time)。Cgroup 是资源控制技术,例如cpu使用量,内存使用量等。它们是实现容器的基础技术。其他资源控制技术如getrlimit、sched_setaffinity。
文件系统安全: 文件系统加密机制ecryptfs、dm-crypt、perfile加密。文件系统mount时只读、文件使用量限制quota、文件属性sticky位等。
SECRETMEM: 新版本内核中增加的隐私内存机制。在一个进程中申请的secret mem,在其他进程中不能使用ptrace访问。
网络安全方面:
1. Netfilter: 在这个基础上可以设置防火墙规则。
2. Netlabel: 在ip数据包的选项中增加数据包标记,实现数据包的访问控制
3. IPsec & wireguard进行安全通信。
4. KTLS:在TLS协议中,数据包加解密在内核进行,提高TLS的性能。
5. AF_PACKET & BPF 高效的抓包。XDP可实现抗D。
6. 负载均衡;重新实现TCP握手机制,增强抗SYN flood攻击等
内核HOOK机制:ftrace & kprobe & livepatch & bpf 。利用它们可以实现自己的安全功能,观测内核、进程事件。热补丁修复内核漏洞。
内核审计机制:Audit、kmsg、acct、cn_proc、fanotify等。
以上大致是进入内核主线的安全技术,还有一些没有进入主线如 grsec、tpe、lkrg、dpdk等等。一些发行版本,如Ubuntu也会有选择的引入其中一些安全技术。
应用层
场景不同,选择的工具也不同。下面就根据加固一个OS的基本原则说一下常用工具。
简单(KISS原则)
设计简单、使用简单……
减少攻击面
定制基线时,操作系统尽可能小,包含尽量少的软件包。例如gcc、tcpdump、nc等不常用的软件在生产系统上不要安装。不用的内核ko禁止加载或者从生产系统上删除。
一些可以裁减内核的系统,保持内核功能精简。使用busybox代替coreutils包中的基础工具,使用定制过的bash等等。
最小权限原则
最少的账户、账户最小的权限。/etc/passwd中不用的账户要删除,是否允许登录要控制等。使用sudo 控制账户执行的命令。如果允许网络登录,使用pam中的插件控制。sshd配置要尽可能严格,如禁止使用root登录。
设置不同类型的账户,如管理账户、审计账户。每类账户其权限刚好够用。
保持更新
软件保持更新,可以修复软件漏洞。策略更新,适用新的变化。如一些密码要周期性更新。
事件审计
重要事件要记录和监控。如登录事件、服务重启事件、配置更新事件。Linux上有各种日志记录功能,一般都在/var/log下。很多安全工具都会读取该目录下的文件。
进行基础的加固和监控
适当的分区及权限设置,适当的防火墙规则,适当的加解密措施,防止口令破解措施、2FA登录认证等等。
看待Linux系统安全有不同的角度,以上根据系统分层列出Linux安全机制和技术,是静态的。如果从事件活动角度,就可以把这些安全技术有机组合起来,形成防御功能。安全架构师,类似厨子,知道每项技术的优缺点,不迷信某个具体的技术,能根据具体场景,设计合适的安全架构,组合利用(或者开发)各种技术做出符合需求的佳肴。