Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

Linux系统安全加固指南

 点击上方“分布式实验室”关注公众号

回复“1”抽取纸质技术书


本指南旨在说明如何尽可能地加强Linux的安全性和隐私性,并且不限于任何特定的指南。

免责声明:如果您不确定自己在做什么,请不要尝试在本文中使用任何内容。

本指南仅关注安全性和隐私性,而不关注性能,可用性或其他内容。

列出的所有命令都将需要root特权。以“$”符号开头的单词表示一个变量,不同终端之间可能会有所不同。


  1 
选择正确的Linux发行版


选择一个好的Linux发行版有很多因素。

  • 避免分发冻结程序包,因为它们在安全更新中通常很落后。

  • 不使用与Systemd机制的发行版。Systemd包含许多不必要的攻击面;它尝试做的事情远远超出了必要,并且超出了初始化系统应做的事情。

  • 使用musl作为默认的C库。Musl专注于最小化,这会导致很小的攻击面,而其他C库(例如glibc)过于复杂,容易产生漏洞。例如,与musl中的极少数漏洞相比,glibc中的一百多个漏洞已被公开披露。尽管仅靠披露的CVE本身通常是不准确的统计信息,但有时这种情况有时可以用来表示过分的问题。Musl还具有不错的漏洞利用缓解措施,尤其是其新的强化内存分配器。

  • 最好默认情况下使用LibreSSL而不是OpenSSL的发行版。OpenSSL包含大量完全不必要的攻击面,并且遵循不良的安全做法。例如,它仍然保持OS / 2和VMS支持这些已有数十年历史的古老操作系统。这些令人讨厌的安全做法导致了可怕的Heartbleed漏洞。LibreSSL是OpenBSD团队的OpenSSL分支,它采用了出色的编程实践并消除了很多攻击面。在LibreSSL成立的第一年内,它缓解了许多漏洞,其中包括一些高严重性的漏洞。

用作强化操作系统基础的最佳发行版是Gentoo Linux,因为它可以让您精确地配置系统,以达到理想的效果,这将非常有用,尤其是参考我们在后面的章节中使用更安全的编译标志。

但是,由于Gentoo的巨大可用性缺陷,它对于许多人来说可能并不顺手。在这种情况下,Void Linux的Musl构建是一个很好的折衷方案。


  2 
内核


内核是操作系统的核心,不幸的是很容易受到攻击。正如Brad Spengler曾经说过的那样,可以将其视为系统上最大,最易受攻击的setuid根二进制文件。因此,对内核进行尽可能多的强化非常重要。

Stable vs LTS内核

Linux内核以两种主要形式发布:稳定和长期支持(LTS)。稳定版本是较新的版本,而LTS发行版本是较老的稳定版本,长期以来一直受支持。选择上述任何一个发行版本都有许多后果。

Linux内核未使用CVE标识安全漏洞。这意味着大多数安全漏洞的修复程序不能向后移植到LTS内核。但是稳定版本包含到目前为止进行的所有安全修复。

但是,有了这些修复程序,稳定的内核将包含更多新功能,因此大大增加了内核的攻击面,并引入了大量新错误。相反,LTS内核的受攻击面较小,因为这些功能没有被不断添加。

此外,稳定的内核还包括更新的强化功能,以减轻LTS内核没有的某些利用。此类功能的一些示例是Lockdown LSM和STACKLEAK GCC插件。

总而言之,在选择稳定或LTS内核时需要权衡取舍。LTS内核具有较少的强化功能,并且并非当时所有的公共错误修复都已向后移植,但是通常它的攻击面更少,并且引入未知错误的可能性也较小。

稳定的内核具有更多的强化功能,并且包括所有已知的错误修复,但它也具有更多的攻击面以及引入更多未知错误的机会更大。最后,最好使用较新的LTS分支(如4.19内核)。

Sysctl

Sysctl是允许用户配置某些内核设置并启用各种安全功能或禁用危险功能以减少攻击面的工具。要临时更改设置,您可以执行:

      

sysctl -w $tunable = $value

要永久更改sysctls,您可以将要更改的sysctls添加到/etc/sysctl.conf或/etc/sysctl.d中的相应文件,具体取决于您的Linux发行版。

以下是您应更改的建议sysctl设置。

Kernel self-protection:

      

kernel.kptr_restrict=2

内核指针指向内核内存中的特定位置。这些在利用内核方面可能非常有用,但是默认情况下不会隐藏内核指针,例如,通过读取/proc/kallsyms的内容即可轻松发现它们。此设置旨在减轻内核指针泄漏。另外,您可以设置kernel.kptr_restrict = 1以仅从没有CAP_SYSLOG功能的进程中隐藏内核指针。

      

kernel.dmesg_restrict=1

dmesg是内核日志,它公开了大量有用的内核调试信息,但这通常会泄漏敏感信息,例如内核指针。更改上述sysctl设置会将内核日志限制为CAP_SYSLOG功能。

      

kernel.printk=3 3 3 3

尽管dmesg_restrict的值,启动过程中内核日志仍将显示在控制台中。能够在引导过程中记录屏幕的恶意软件可能会滥用此恶意软件以获得更高的特权。此选项可防止这些信息泄漏。必须将其与下面描述的某些引导参数结合使用才能完全有效。

      

kernel.unprivileged_bpf_disabled=1
net.core.bpf_jit_harden=2

eBPF暴露了很大的攻击面,因此需加以限制。这些系统将eBPF限制为CAP_BPF功能(在5.8之前的内核版本上为CAP_SYS_ADMIN),并启用JIT强化技术,例如常量绑定。

      

dev.tty.ldisc_autoload=0

这将加载TTY行规则限制为CAP_SYS_MODULE功能,以防止非特权的攻击者使用TIOCSETD ioctl加载易受攻击的线路规则,而该TIOCSETD ioctl之前已在许多漏洞利用中被滥用。

      

vm.unprivileged_userfaultfd=0

serfaultfd() 系统调用经常被滥用以利用“事后使用(use-after-free)”缺陷。因此,该sysctl用于将此syscall限制为CAP_SYS_PTRACE功能。

      

kernel.kexec_load_disabled=1

kexec是一个系统调用,用于在运行时引导另一个内核。可以滥用此功能来加载恶意内核并在内核模式下获得任意代码执行能力,因此该sysctl设置将被禁用。

      

kernel.sysrq=4

SysRq密钥向非特权用户公开了许多潜在的危险调试功能。与通常的假设相反,SysRq不仅是物理攻击的问题,而且还可以远程触发。该sysctl的值使其可以使用户只能使用SAK密钥,这对于安全地访问root是必不可少的。或者,您可以简单地将值设置为0以完全禁用SysRq。

      

kernel.unprivileged_userns_clone=0

用户名称空间是内核中的一项功能,旨在改善沙箱并使非特权用户易于访问它,但是,此功能公开了重要的内核攻击面,以进行特权升级,因此该sysctl将用户名称空间的使用限制为CAP_SYS_ADMIN功能。对于无特权的沙箱,建议使用具有很少攻击面的setuid二进制文件,以最大程度地减少特权升级的可能性。沙箱章节部分将进一步讨论此主题。

请注意,尽管该sysctl仅在某些Linux发行版中存在,因为它需要内核补丁。如果您的内核不包含此补丁,则可以通过设置user.max_user_namespaces = 0来完全禁用用户名称空间(包括root用户)。

      

kernel.unprivileged_userns_clone=0

用能事件会增加大量内核攻击面,并导致大量漏洞。此sysctl设置将性能事件的所有使用限制为CAP_PERFMON功能(5.8之前的内核版本为CAP_SYS_ADMIN)。

请注意,此sysctl设置需要在某些发行版中具备相关的内核补丁。否则,此设置等效于kernel.perf_event_paranoid = 2,它仅限制此功能的子集。

网络:

      

net.ipv4.tcp_syncookies=1

这有助于防止SYN泛洪攻击,这种攻击是拒绝服务攻击的一种形式,在这种攻击中,攻击者发送大量虚假的SYN请求,以尝试消耗足够的资源以使系统对合法流量不响应。

      

net.ipv4.tcp_rfc1337=1

这通过丢弃处于时间等待状态的套接字的RST数据包来防止time-wait状态。

      

net.ipv4.conf.all.rp_filter=1
net.ipv4.conf.default.rp_filter=1

这些启用了源验证,以验证从计算机所有网络接口接收到的数据包。

      

net.ipv4.conf.all.accept_redirects=0
net.ipv4.conf.default.accept_redirects=0
net.ipv4.conf.all.secure_redirects=0
net.ipv4.conf.default.secure_redirects=0
net.ipv6.conf.all.accept_redirects=0
net.ipv6.conf.default.accept_redirects=0
net.ipv4.conf.all.send_redirects=0
net.ipv4.conf.default.send_redirects=0

这些设置禁用了ICMP重定向,以防止中间人攻击并最大程度地减少信息泄露。

      

net.ipv4.icmp_echo_ignore_all=1

此设置使您的系统忽略所有ICMP请求,以避免Smurf攻击,使设备更难以在网络上枚举,并防止通过ICMP时间戳识别时钟指纹。

      

net.ipv4.conf.all.accept_source_route=0
net.ipv4.conf.default.accept_source_route=0
net.ipv6.conf.all.accept_source_route=0
net.ipv6.conf.default.accept_source_route=0

源路由是一种允许用户重定向网络流量的机制。由于这可用于执行中间人攻击,在中间人攻击中,出于恶意目的将流量重定向,因此上述设置将会禁用此功能。

      

net.ipv6.conf.all.accept_ra=0
net.ipv6.conf.default.accept_ra=0

恶意的IPv6路由广告可能会导致中间人攻击,因此应将其禁用。

      

net.ipv4.tcp_sack=0
net.ipv4.tcp_dsack=0
net.ipv4.tcp_fack=0

禁用TCP SACK。ACK通常被利用,并且在许多情况下是不必要的,因此如果您不需要它,则应将其禁用。

用户空间:

      

kernel.yama.ptrace_scope=2

ptrace是一个系统调用,它允许程序调试、修改和检查另一个正在运行的进程,从而使攻击者可以轻易修改其他正在运行的程序的内存。设置将ptrace的使用限制为仅具有CAP_SYS_PTRACE功能的进程。或者,将sysctl设置为3以完全禁用ptrace。

      

vm.mmap_rnd_bits=32
vm.mmap_rnd_compat_bits=16

ASLR是一种常见的漏洞利用缓解措施,它可以使进程的关键部分在内存中的位置随机化。这可能会使各种各样的漏洞利用更困难,因为它们首先需要信息泄漏。上述设置增加了用于mmap ASLR的熵的位数,从而提高了其有效性。

这些sysctls的值必须根据CPU体系结构进行设置。以上值与x86兼容,但其他体系结构可能有所不同。

      

fs.protected_symlinks=1
fs.protected_hardlinks=1

仅当在可全局写入的粘性目录之外,当符号链接和关注者的所有者匹配或目录所有者与符号链接的所有者匹配时,才允许遵循符号链接。这还可以防止没有对源文件的读/写访问权限的用户创建硬链接。这两者都阻止了许多常见的TOCTOU漏洞(time-of-check-to-time-of-use)。

fs.protected_fifos=2      
fs.protected_regular=2

这些阻止了在可能由攻击者控制的环境(例如,全局可写目录)中创建文件,从而使数据欺骗攻击更加困难。

引导参数

引导参数在引导时使用引导加载程序(bootloader)将设置传递给内核。类似于sysctl,可以使用某些设置来提高安全性。引导加载程序通常在引导参数设置方式上有所不同。下面列出了一些示例,但是您应该研究特定bootloader的修改参数的必要步骤。

如果使用GRUB作为引导程序,请编辑/etc /default/grub并将参数添加到GRUB_CMDLINE_LINUX_DEFAULT=line。

如果使用Syslinux,请编辑/boot/syslinux/syslinux.cfg并将它们添加到APPEND行中。

如果使用systemd-boot,请编辑您的加载程序条目,并将其附加到linux行的末尾。

建议使用以下设置以提高安全性。

Kernel self-protection:

      

slab_nomerge

这将禁用slab合并,这将通过防止覆盖合并的缓存中的对象并使其更难以影响slab缓存的布局,从而大大增加了堆利用的难度。

      

slub_debug=FZ

这些启用健全性检查(F)和重新分区(Z)。健全性检查会添加各种检查,以防止某些slab操作中的损坏。重新分区会在slab周围添加额外的区域,以检测slab何时被覆盖超过其实际大小,从而有助于检测溢出。

      

init_on_alloc=1 init_on_free=1

这样可以在分配和空闲时间期间将内存清零,这可以帮助减轻使用后使用的漏洞并清除内存中的敏感信息。如果您的内核版本低于5.3,则这些选项不存在。而是在上述slub_debug选项后面附加“ P”,以获得slub_debug=FZP并添加page_poison=1。由于它们实际上是一种调试功能,刚好具有一些安全性,因此它们在释放时提供的内存擦除形式较弱。

      

page_alloc.shuffle=1

此选项使页分配器空闲列表随机化,从而通过降低页分配的可预测性来提高安全性,同时这也提高了性能。

      

pti=on

这将启用内核页表隔离,从而减轻崩溃并防止某些KASLR绕过。

      

vsyscall=none

这将禁用vsyscall,因为它们已过时且已被vDSO取代。 vsyscall也在内存中的固定地址上,使其成为ROP攻击的潜在目标。

      

debugfs=off

这将禁用debugfs,它会公开许多有关内核的敏感信息。

      

oops=panic

有时某些内核漏洞利用会导致所谓的“oops”。此参数将引发内核对此类事件panic,从而防止这些攻击。但是,有时错误的驱动程序会导致无害的操作,这会导致系统崩溃,这意味着此引导参数只能在某些硬件上使用。

      

module.sig_enforce=1

这仅允许加载已使用有效密钥签名的内核模块,使加载恶意内核模块更加困难。

这可以防止加载所有树外内核模块(包括DKMS模块),除非您已对其进行签名,这意味着诸如VirtualBox或Nvidia驱动程序之类的模块可能不可用,但根据您的设置可能并不重要。

      

lockdown=confidentiality

内核锁定LSM可以消除用户空间代码滥用以升级为内核特权并提取敏感信息的许多方法。为了在用户空间和内核之间实现清晰的安全边界,此LSM是必需的。上面的选项在confidentiality模式(最严格的选项)中启用此功能。这意味着module.sig_enforce=1。

      

mce=0

这将导致内核对ECC内存中无法利用的错误panic,而这些错误可能会被利用。对于没有ECC内存的系统,这是不必要的。

      

quiet loglevel=0

这些参数可防止引导期间信息泄漏,并且必须与上面的kernel.printk sysctl结合使用。

CPU缓解:

最好启用适用于您的CPU的所有CPU缓解措施,以确保您不受已知漏洞的影响。这是启用所有内置缓解措施的列表:

      

spectre_v2=on spec_store_bypass_disable=on tsx=off tsx_async_abort=full,nosmt mds=full,nosmt l1tf=full,force nosmt=force kvm.nx_huge_pages=force

您必须研究系统受其影响的CPU漏洞,并相应地选择上述缓解措施。请记住,您将需要安装微代码更新,以完全免受这些漏洞的影响。但所有这些操作都可能导致性能显着下降。

结果:

如果遵循了以上所有建议(不包括特定的CPU缓解措施),则将具有:

      

slab_nomerge slub_debug=FZ init_on_alloc=1 init_on_free=1 page_alloc.shuffle=1 pti=on vsyscall=none debugfs=off oops=panic module.sig_enforce=1 lockdown=confidentiality mce=0 quiet loglevel=0

如果将GRUB用作引导加载程序,则可能需要重新生成GRUB配置文件才能应用这些文件。

hidepid

proc是一个伪文件系统,其中包含有关系统上当前正在运行的所有进程的信息。默认情况下,所有用户都可以访问此程序,这可能使攻击者可以窥探其他进程。

要只允许用户看到自己的进程,而不能看到其他用户的进程,则必须使用hidepid=2,gid=proc挂载选项来挂载/proc。gid=proc将proc组从此功能中排除,因此您可以将特定的用户或进程列入白名单。添加这些选项的一种方法是编辑/etc/fstab并添加:

      

proc /proc proc nosuid,nodev,noexec,hidepid=2,gid=proc 0 0

systemd-logind仍然需要查看其他用户的进程,因此,要使用户会话在systemd系统上正常工作,必须创建/etc/systemd/system/systemd-logind.service.d/hidepid.conf并添加:

      

[Service]
SupplementaryGroups=proc


减少内核攻击面

最好禁用不是绝对必要的任何功能,以最大程度地减少潜在的内核攻击面。这些功能不必一定很危险,它们可以只是被删除以减少攻击面的良性代码。切勿禁用您不了解的随机事物。以下是一些可能有用的示例,具体取决于您的设置。

引导参数:

引导参数通常可以用来减少攻击面,这样的例子之一是:

      

ipv6.disable=1

这将禁用整个IPv6堆栈,如果您尚未迁移到该堆栈,则可能不需要该堆栈。如果正在使用的IPv6,请不要使用此引导参数。

将内核模块列入黑名单:

内核允许非特权的用户通过模块自动加载来间接导致某些模块被加载。这使攻击者可以自动加载易受攻击的模块,然后加以利用。一个这样的示例是CVE-2017-6074,其中攻击者可以通过启动DCCP连接来触发DCCP内核模块的加载,然后利用该内核模块中的漏洞。

可以通过将文件插入/etc/modprobe.d并将指定的内核模块列入黑名单的方法,将特定的内核模块列入黑名单。

Install参数告诉modprobe运行特定命令,而不是像往常一样加载模块。/bin/false是仅返回1的命令,该命令实际上不会执行任何操作。两者都告诉内核运行/bin/false 而不是加载模块,这将防止攻击者利用该模块。以下是最有可能不需要的内核模块:

      

install dccp /bin/false
install sctp /bin/false
install rds /bin/false
install tipc /bin/false
install n-hdlc /bin/false
install ax25 /bin/false
install netrom /bin/false
install x25 /bin/false
install rose /bin/false
install decnet /bin/false
install econet /bin/false
install af_802154 /bin/false
install ipx /bin/false
install appletalk /bin/false
install psnap /bin/false
install p8023 /bin/false
install p8022 /bin/false
install can /bin/false
install atm /bin/false

特别是模糊的网络协议会增加大量的远程攻击面。此黑名单:

      

DCCP — Datagram Congestion Control Protocol

SCTP — Stream Control Transmission Protocol

RDS — Reliable Datagram Sockets

TIPC — Transparent Inter-process Communication

HDLC — High-Level Data Link Control

AX25 — Amateur X.25

NetRom

X25

ROSE

DECnet

Econet

af_802154 — IEEE 802.15.4

IPX — Internetwork Packet Exchange

AppleTalk

PSNAP — Subnetwork Access Protocol

p8023 — Novell raw IEEE 802.3

p8022 — IEEE 802.2

CAN — Controller Area Network

ATM

      

install cramfs /bin/false
install freevxfs /bin/false
install jffs2 /bin/false
install hfs /bin/false
install hfsplus /bin/false
install squashfs /bin/false
install udf /bin/false

将各种稀有文件系统列入黑名单。

      

install cifs /bin/true
install nfs /bin/true
install nfsv3 /bin/true
install nfsv4 /bin/true
install gfs2 /bin/true

如果不使用网络文件系统,也可以将其列入黑名单。

      

install vivid /bin/false

vivid driver驱动程序仅用于测试目的,并且是特权提升漏洞的原因,因此应禁用它。

      

install bluetooth /bin/false
install btusb /bin/false

禁用具有安全问题历史记录的蓝牙。

      

install uvcvideo /bin/false

这会禁用网络摄像头,以防止其被用来监视您。

您也可以将麦克风模块列入黑名单,但这在系统之间可能会有所不同。要查找模块的名称,请在/proc/asound/modules中查找并将其列入黑名单。例如,一个这样的模块是snd_hda_intel。

请注意,尽管有时麦克风的内核模块与扬声器的模块相同。这意味着像这样禁用麦克风也可能会无意中禁用任何扬声器,虽然扬声器也有可能变成麦克风,所以这不一定是消极的结果。

最好从物理上删除这些设备,或者至少在BIOS/UEFI中禁用它们。禁用内核模块并不总是那么有效。

rfkill:

可以通过rfkill将无线设备列入黑名单,以进一步减少远程攻击面。要将所有无线设备列入黑名单,请执行:

      

rfkill block all

WiFi可以通过以下方式解锁:

      

rfkill unblock wifi

在使用systemd的系统上,rfkill在所有会话中均保持不变,但是,在使用其他init系统的系统上,您可能必须创建一个init脚本以在引导时执行这些命令。

其他内核指针泄漏

前面的部分已经防止了一些内核指针泄漏,但是还有更多泄漏。

在文件系统上,/boot中存在内核映像和System.map文件。/usr/src和/{,usr/} lib/modules目录中还有其他敏感的内核信息。您应该限制这些目录的文件权限,以使它们只能由root用户读取。您还应该删除System.map文件,因为除高级调试外,它们都不需要。

此外,某些日志记录守护程序(例如systemd的journalctl)包括内核日志,可用于绕过上述dmesg_restrict保护。从adm组中删除用户通常足以撤销对以下日志的访问:

      

gpasswd -d $user adm

限制对sysfs的访问

sysfs是伪文件系统,可提供大量的内核和硬件信息。它通常安装在/sys上。sysfs导致大量信息泄漏,尤其是内核指针泄漏。Whonix的security-misc软件包包括hide-hardware-info脚本,该脚本限制访问此目录以及/proc中的一些脚本,以试图隐藏潜在的硬件标识符并防止内核指针泄漏。

该脚本是可配置的,并允许基于组将特定的应用程序列入白名单。建议应用此方法,并使其在启动时使用init脚本执行。或者这样做成systemd服务[1]。

为了使基本功能在使用systemd的系统上运行,必须将一些系统服务列入白名单。这可以通过创建/etc/systemd/system/[email protected]/sysfs.conf并添加以下内容来完成:

      

[Service]
SupplementaryGroups=sysfs

但是,这不能解决所有问题。许多应用程序可能仍会中断,您需要将它们正确列入白名单。

Linux强化

某些发行版(例如Arch Linux)包括强化的内核程序包。它包含许多强化补丁程序和更注重安全性的内核配置。如果可能的话,建议安装它。

Grsecurity

Grsecurity是一组内核修补程序,可以大大提高内核安全性。这些补丁曾经可以免费获得,但是现在需要购买了。如果可用,则强烈建议您获取它。Grsecurity提供了最新的内核和用户空间保护。

内核运行时防护

Linux Kernel Runtime Guard(LKRG)是一个内核模块,可确保运行时内核的完整性并检测漏洞。它可以杀死整个类别的内核漏洞。但这并不是一个完美的缓解方法,因为LKRG在设计上可以绕开。它仅适用于现成的恶意软件。但是,尽管可能性不大,但LKRG本身可能会像其他任何内核模块一样公开新的漏洞。

自编译内核

建议编译您自己的内核,同时启用尽可能少的内核模块和尽可能多的安全性功能,以将内核的受攻击面保持在绝对最低限度。

另外,应用内核强化补丁,例如如上所述的linux-hardened或grsecurity。

发行版编译的内核还具有公共内核指针/符号,这对于漏洞利用非常有用。编译自己的内核将为您提供独特的内核符号,连同kptr_restrict,dmesg_restrict和其他针对内核指针泄漏的强化措施,将使攻击者更加难以创建依赖于内核指针知识的漏洞利用程序。

您就可以从Whonix的强化内核[2]中汲取灵感或使用它。


  3 
强制访问措施


强制访问控制(MAC)系统对程序可以访问的内容进行细粒度的控制。这意味着您的浏览器将无权访问您的整个主目录或类似目录。

最常用的MAC措施是SELinux和AppArmor。SELinux比AppArmor更安全,因为它的粒度更细。例如,它是基于inode而不是基于路径的,允许强制执行明显更严格的限制,可以过滤内核ioctl等。不幸的是,这是以难以使用和难以学习为代价的,因此某些人可能会首选AppArmor。

要在内核中启用AppArmor,必须设置以下引导参数:

      

apparmor=1 security=apparmor

要启用SELinux,请设置以下参数:

      

selinux=1 security=selinux

请记住,仅启用MAC措施本身并不能神奇地提高安全性。您必须制定严格的政策才能充分利用它。例如,要创建AppArmor配置文件,请执行:

      

aa-genprof $path_to_program

打开程序,然后像往常一样开始使用它。AppArmor将检测需要访问哪些文件,并将它们添加到配置文件中(如果您选择的话)。但是,仅凭这一点不足以提供高质量的配置文件。请参阅AppArmor文档[3]以获取更多详细信息。

如果您想更进一步,则可以通过实施initramfs勾子来设置一个完整的系统MAC策略,该策略限制每个单个用户空间进程,该挂钩对init系统强制实施MAC策略。这就是Android使用SELinux的方式,以及Whonix未来将如何使用AppArmor的方式。对于加强实施最小特权原则的强大安全模型是必要的。


  4 
沙箱


应用沙箱

沙箱可让您在隔离的环境中运行程序,该环境对系统的其余部分具有有限的访问权限或完全没有访问权限。您可以使用它们来保护应用程序安全或运行不受信任的程序。

建议与AppArmor或SELinux一起在单独的用户帐户中使用Bubblewrap到沙箱程序。您也可以考虑改用gVisor,它的优点是为每个来宾提供了自己的内核。

这些方法中的任何一个都可以用来创建一个功能强大的沙箱,并且暴露的攻击面最小。如果您不想自己创建沙箱,请在完成后考虑使用Whonix的sandbox-app-launcher。您不应该使用Firejail[4]。

诸如Docker和LXC之类的容器解决方案经常被误导为沙盒形式。它们太宽松了,无法广泛支持各种应用程序,因此不能认为它们是强大的应用程序沙箱。

常见沙箱逃逸

  • PulseAudio:PulseAudio是一种常见的声音服务器,但在编写时并未考虑隔离或沙盒的问题,这使其成为重复出现的沙盒逃逸漏洞。为了防止这种情况,建议您从沙箱中阻止对PulseAudio的访问,或者从系统中完全卸载它。

  • D-Bus:D-Bus是台式机Linux上最流行的进程间通信形式,但它也是沙箱逃逸的另一种常见途径,因为它允许与服务自由交互。这些漏洞的一个例子就是Firejail。您应该从沙箱中阻止对D-Bus的访问,或者通过MAC以细粒度的规则进行调解。

  • GUI隔离:任何Xorg窗口都可以访问另一个窗口。这允许琐碎的键盘记录或屏幕截图程序,甚至可以记录诸如root密码之类的内容。您可以使用嵌套的X11服务器(例如Xpra或Xephyr和bubblewrap)将Xorg窗口沙箱化。默认情况下,Wayland将窗口彼此隔离,这将是一个比Xorg更好的选择,尽管Wayland可能不如Xorg普遍可用,因为它在开发中较早。

  • ptrace:如前所述,ptrace是一个系统调用,可能会被滥用破坏在沙箱外部运行的进程。为避免这种情况,您可以通过sysctl启用内核YAMA ptrace限制,也可以在seccomp过滤器中将ptrace syscall列入黑名单。

  • TIOCSTI:TIOCSTI是一个ioctl,它允许注入终端命令,并为攻击者提供了一种简单的机制,可以在同一用户会话内的其他进程之间横向移动。可以通过将seccomp过滤器中的ioctl列入黑名单或使用bubblewrap的--new-session参数来缓解这种攻击。

  • Systemd沙箱:虽然不建议使用systemd,但有些系统可能无法切换。这些人至少可以使用沙盒服务,因此他们只能访问所需的内容。

这是一个沙箱化systemd服务的示例:

      

[Service]
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
ProtectSystem=strict
ProtectHome=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
ProtectKernelLogs=true
ProtectHostname=true
ProtectClock=true
ProtectProc=invisible
ProcSubset=pid
PrivateTmp=true
PrivateUsers=yes
PrivateDevices=true
MemoryDenyWriteExecute=true
NoNewPrivileges=true
LockPersonality=true
RestrictRealtime=true
RestrictSUIDSGID=true
RestrictAddressFamilies=AF_INET
RestrictNamespaces=yes
SystemCallFilter=write read openat close brk fstat lseek mmap mprotect munmap rt_sigaction rt_sigprocmask ioctl nanosleep select access execve getuid arch_prctl set_tid_address set_robust_list prlimit64 pread64 getrandom
SystemCallArchitectures=native
UMask=0077
IPAddressDeny=any
AppArmorProfile=/etc/apparmor.d/usr.bin.example

所有选项的说明:

      

CapabilityBoundingSet=— Specifies the capabilitiesthe process is given.

ProtectHome=true— Makes all home directories inaccessible.

ProtectKernelTunables=true— Mounts kernel tunables such as those modified throughsysctlas read-only.

ProtectKernelModules=true— Denies module loading and unloading.

ProtectControlGroups=true— Mounts all control group hierarchies as read-only.

ProtectKernelLogs=true— Prevents accessing the kernel logs.

ProtectHostname=true— Prevents changes to the system hostname.

ProtectClock— Prevents changes to the system clock.

ProtectProc=invisible— Hides all outside processes.

ProcSubset=pid— Permits access to only the pid subset of/proc.

PrivateTmp=true— Mounts an empty tmpfs over/tmpand/var/tmp, therefore hiding their previous contents.

PrivateUsers=true— Sets up an empty user namespace to hide other user accounts on the system.

PrivateDevices=true— Creates a new/devmount with minimal devices present.

MemoryDenyWriteExecute=true— Enforces a memory W^X policy.

NoNewPrivileges=true— Prevents escalating privileges.

LockPersonality=true— Locks down thepersonality()syscall to prevent switching execution domains.

RestrictRealtime=true— Prevents attempts to enable realtime scheduling.

RestrictSUIDSGID=true— Prevents executing setuid or setgid binaries.

RestrictAddressFamilies=AF_INET— Restricts the usable socket address families to IPv4 only (AF_INET).

RestrictNamespaces=true— Prevents creating any new namespaces.

SystemCallFilter=...— Restricts the allowed syscalls to the absolute minimum. If you aren't willing to maintain your own custom seccomp filter, then systemd provides many [predefined system call sets](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#System Call Filtering) that you can use.@system-servicewill be suitable for many use cases.

SystemCallArchitectures=native— Prevents executing syscalls from other CPU architectures.

UMask=0077— Sets the umaskto a more restrictive value.

IPAddressDeny=any— Blocks all incoming and outgoing traffic to/from any IP address. SetIPAddressAllow=to configure a whitelist. Alternatively, setup a network namespace withPrivateNetwork=true.

AppArmorProfile=...— Runs the process under the specified AppArmor profile.

您不能仅将此示例配置复制到您的配置中,每种服务的要求各不相同,并且必须针对每种服务微调沙箱。要了解有关您可以设置的所有选项的更多信息,请阅读systemd.exec手册页[5]。

如果您使用的系统不是systemd而是init,那么可以使用bubblewrap轻松复制所有这些选项。

gVisor

普通沙箱固有地与主机共享同一内核。您信任我们已经评估为不安全的内核,可以正确限制这些程序。由于主机内核的整个攻击面已完全暴露,因此沙盒中的内核利用程序可以绕过任何限制。已经进行了一些努力来限制使用seccomp的攻击面,但不足以完全解决此问题。

GVisor是解决此问题的方法。它为每个应用程序提供了自己的内核,该内



This post first appeared on IT瘾 | IT社区推荐资讯, please read the originial post: here

Share the post

Linux系统安全加固指南

×

Subscribe to It瘾 | It社区推荐资讯

Get updates delivered right to your inbox!

Thank you for your subscription

×