30 使程序免疫 #
要有效强化计算机系统,您需要将可调解特权的程序数量降至最低,然后尽可能保护程序的安全。利用 AppArmor,您只需为环境中曝露于攻击下的程序构建配置文件,这极大地减少了强化计算机所需执行的工作量。AppArmor 配置文件可强制策略以确保程序仅执行所限定操作。
AppArmor 提供的免疫技术可以保护应用程序,免于其固有的漏洞所带来的风险。安装 AppArmor、设置 AppArmor 配置文件并重引导计算机后,您的系统即变为免疫系统,因为它已开始强制执行 AppArmor 安全策略。使用 AppArmor 保护程序的过程称为免疫。
管理员自己只需关注那些容易受到攻击的应用程序,并为它们生成配置文件。这样,系统的强化就简化为构建和维护 AppArmor 配置文件集,以及监视 AppArmor 报告功能记录的任何策略违规或异常。
用户应该察觉不到 AppArmor 的运行。它在“后台”运行,无需任何用户交互操作。AppArmor 不会对性能造成明显的影响。如果应用程序的某些活动没有包含在 AppArmor 配置文件中或者被 AppArmor 阻止,管理员需要调整此应用程序的配置文件。
AppArmor 建立一个默认应用程序配置文件集以保护标准的 Linux 服务。要保护其他应用程序,请使用 AppArmor 工具为您要保护的应用程序创建配置文件。本章介绍使程序免疫的基本原理。如果您已做好构建和管理 AppArmor 配置文件的准备,请转到第 31 章 “配置文件组件和语法”、第 33 章 “使用 YaST 构建和管理配置文件”或第 34 章 “从命令行构建配置文件”。
AppArmor 会指定每个程序可以读取、写入和执行哪些文件,以及允许访问的网络类型,从而为网络服务提供优化的访问控制。这确保了每个程序只会执行它们应该执行的操作,而不会执行其他操作。AppArmor 会对程序进行检疫,以防止系统的其他部分被入侵的进程损坏。
AppArmor 是一套主机入侵防御或强制访问控制方案。以前,访问控制方案以用户为中心,因为它们是针对大型的分时共享系统而构建的。然而,现代网络服务器大多不允许用户登录,只是为用户提供各种网络服务(例如 Web、邮件、文件和打印服务器)。 AppArmor 对给予网络服务和其它程序的访问进行控制,以防御对其缺陷的攻击。
要更深入地全面了解 AppArmor 及其背后的总体概念,请参见第 28.2 节 “有关 AppArmor 配置文件构建的背景信息”。
30.1 AppArmor 框架简介 #
本节提供当您运行 AppArmor 时“幕后”(以及 YaST 界面之下)所发生的情况的基本知识。
AppArmor 配置文件是包含路径项和访问权限的纯文本文件。有关详细的参考配置文件,请参见第 31.1 节 “分解 AppArmor 配置文件”。AppArmor 例程会强制执行此文本文件中包含的指令来隔离进程或程序。
以下工具会参与 AppArmor 配置文件和策略的构建与强制执行:
aa-status
aa-status
可报告运行中 AppArmor 限制当前状态的各个方面。aa-unconfined
aa-unconfined
可检测系统上正在运行并会监听网络连接且不受 AppArmor 配置文件保护的任何应用程序。有关此工具的详细信息,请参见第 34.7.3.12 节 “aa-unconfined — 识别不受保护的进程”。aa-autodep
aa-autodep
可为投放到生产环境之前需要充实的配置文件创建基本框架。生成的配置文件将被装载并置于控诉模式,将报告 AppArmor 规则(尚)未涵盖的应用程序的任何行为。有关此工具的详细信息,请参见第 34.7.3.1 节 “aa-autodep — 创建大概的配置文件”。aa-genprof
aa-genprof
可生成基本配置文件,并请求您通过执行应用程序并生成需要由 AppArmor 策略处理的日志事件来优化此配置文件。系统会通过一系列问题引导您处理应用程序执行期间触发的日志事件。生成配置文件后,系统会装载此配置文件并将其置于强制模式。有关此工具的详细信息,请参见第 34.7.3.8 节 “aa-genprof — 生成配置文件”。aa-logprof
aa-logprof
会以交互方式扫描和检查处于控诉与强制模式的 AppArmor 配置文件所限制的应用程序生成的日志项。它可以帮助您在相关配置文件中生成新的项。有关此工具的详细信息,请参见第 34.7.3.9 节 “aa-logprof — 扫描系统日志”。aa-easyprof
aa-easyprof
提供了便于使用的界面来生成 AppArmor 配置文件。aa-easyprof
支持使用模板和策略组来快速构建应用程序的配置文件。请注意,尽管此工具有助于生成策略,但其实用程序依赖于所用模板、策略组和抽象的质量。aa-easyprof
在创建配置文件方面的限制比使用aa-genprof
和aa-logprof
创建配置文件要少一些。aa-complain
aa-complain
可将 AppArmor 配置文件从强制模式切换到控诉模式。系统会记录对配置文件中所设规则的违规,但不强制执行配置文件。有关此工具的详细信息,请参见第 34.7.3.2 节 “aa-complain — 进入控诉或学习模式”。aa-enforce
aa-enforce
可将 AppArmor 配置文件从控诉模式切换到强制模式。系统会记录且不允许对配置文件中所设规则的违规 — 将强制执行配置文件。有关此工具的详细信息,请参见第 34.7.3.6 节 “aa-enforce — 进入强制模式”。aa-disable
aa-disable
可禁用一个或多个 AppArmor 配置文件的强制模式。此命令将从内核中卸载配置文件,并防止在 AppArmor 启动时装载该配置文件。使用aa-enforce
和aa-complain
实用程序可更改此行为。aa-exec
aa-exec
可启动指定的 AppArmor 配置文件和/或名称空间所限制的程序。如果同时指定了配置文件和名称空间,命令将由新策略名称空间中的配置文件限制。如果仅指定了名称空间,将使用当前限制的配置文件名称。如果配置文件和名称空间均未指定,将使用标准的配置文件附件运行命令 — 如同不结合aa-exec
运行一样。aa-notify
aa-notify
是一个便利的实用程序,它可在桌面环境中显示 AppArmor 通知。您还可以对它进行配置,以显示指定的最近几天的通知摘要。有关更多信息,请参见第 34.7.3.13 节 “aa-notify”。
30.2 确定要使其免疫的程序 #
现在您已熟悉 AppArmor,请开始选择要为其构建配置文件的应用程序。需要构建配置文件的程序是那些调解权限的程序。以下程序可以访问使用此程序的用户所不能访问的资源,因此使用这些程序时可以授予用户权限:
cron
作业cron
定期运行的程序。此类程序会读取来自多个来源的输入,可以使用特权运行,有时甚至可以使用root
特权运行。例如,cron
可以每日运行/usr/sbin/logrotate
来轮换、压缩系统日志,甚至可以通过邮件发送系统日志。要了解如何查找此类程序,请参见第 30.3 节 “使cron
作业免疫”。- Web 应用程序
网页浏览器可以调用的程序,包括 CGI Perl 脚本、PHP 页面以及更复杂的 Web 应用程序。要了解如何查找此类程序,请参见第 30.4.1 节 “使 Web 应用程序免疫”。
- 网络代理
具有开放网络端口的程序(服务器端和客户端)。邮件客户端和网页浏览器等用户客户端会调解特权。这些程序在运行时具有书写用户主目录的权限,而且他们会处理来自恶意远程来源的输入,如恶意的网站和通过电子邮件发送的恶意代码。要了解如何查找此类程序,请参见第 30.4.2 节 “使网络代理免疫”。
相反,您不必为未非特权程序构建配置文件。例如,外壳脚本可以调用 cp
程序来复制文件。由于 cp
默认没有自身的配置文件或子配置文件,它将继承父外壳脚本的配置文件。因此,cp
可以复制父外壳脚本的配置文件能够读取和写入的任何文件。
30.3 使 cron
作业免疫 #
要查找由 cron
运行的程序,请检查您的本地 cron
配置。遗憾的是,cron
配置非常复杂,因此需要检查大量的文件。定期的 cron
作业是基于以下文件运行的:
/etc/crontab /etc/cron.d/* /etc/cron.daily/* /etc/cron.hourly/* /etc/cron.monthly/* /etc/cron.weekly/*
crontab
命令会列出/编辑当前用户的 crontab。要操作 root
的 cron
作业,请先转变为 root
用户,然后使用 crontab -e
编辑任务或使用 crontab -l
列出任务。
30.4 使网络应用程序免疫 #
使用 aa-unconfined
工具可以自动查找应构建配置文件的网络服务器守护程序。
aa-unconfined
工具使用 netstat -nlp
命令来检查计算机内部的开放端口、检测与这些端口相关联的程序,以及检查已装载的 AppArmor 配置文件集。然后,aa-unconfined
工具会报告这些程序以及与每个程序相关联的 AppArmor 配置文件,如果程序不受限制,则报告“none”。
如果您要创建新配置文件,必须重启动已构建配置文件的程序,使其受到 AppArmor 的有效限制。
下面是 aa-unconfined
输出示例:
37021 /usr/sbin/sshd2 confined by '/usr/sbin/sshd3 (enforce)' 4040 /usr/sbin/smbd confined by '/usr/sbin/smbd (enforce)' 4373 /usr/lib/postfix/master confined by '/usr/lib/postfix/master (enforce)' 4505 /usr/sbin/httpd2-prefork confined by '/usr/sbin/httpd2-prefork (enforce)' 646 /usr/lib/wicked/bin/wickedd-dhcp4 not confined 647 /usr/lib/wicked/bin/wickedd-dhcp6 not confined 5592 /usr/bin/ssh not confined 7146 /usr/sbin/cupsd confined by '/usr/sbin/cupsd (complain)'
aa-unconfined
需要 root
特权,且不应通过 AppArmor 配置文件限制的外壳运行。
aa-unconfined
不区分网络接口,因此会报告所有未受限的进程,甚至是可能正在监听内部 LAN 接口的进程。
用户网络客户应用程序的查找视用户的自选设置而定。aa-unconfined
工具会检测并报告客户端应用程序打开的网络端口,但仅限于执行 aa-unconfined
分析时正在运行的客户端应用程序。这是一个问题,因为网络服务一般不间断运行,而网络客户应用程序通常只在用户有兴趣时运行。
向用户网络客户端应用程序应用 AppArmor 配置文件的方式还取决于用户的偏好。因此,我们将用户网络客户端应用程序的配置文件构建作为留给用户的练习。
为了更主动地限制桌面应用程序,aa-unconfined
命令支持 --paranoid
选项,该选项会报告所有正在运行的进程,以及可能与各个进程相关联或不关联的对应 AppArmor 配置文件。这样用户就可以确定各个程序是否需要 AppArmor 配置文件。
如果您有新的或修改过的配置文件,可连同您使用的应用程序的行为用例,提交到 <apparmor@lists.ubuntu.com> 邮件列表。AppArmor 团队将审查该配置文件,并可能会将最终成果提交到 SUSE Linux Enterprise Server 中。我们无法保证包含每个配置文件,但会尽力包含尽可能多的配置文件。
30.4.1 使 Web 应用程序免疫 #
要查找 Web 应用程序,请检查您的 Web 服务器配置。Apache Web 服务器的可配置性比较高,您可以将 Web 应用程序保存在多个目录中,这取决于本地配置。默认情况下,SUSE Linux Enterprise Server 将 Web 应用程序储存在 /srv/www/cgi-bin/
中。应尽最大可能使每个 Web 应用程序都有一个 AppArmor 配置文件。
找到这些程序后,可以使用 aa-genprof
和 aa-logprof
工具创建或更新其 AppArmor 配置文件。
由于 CGI 程序通过 Apache Web 服务器执行,因此您必须对 Apache 自身的配置文件 usr.sbin.httpd2-prefork
(适用于 SUSE Linux Enterprise Server 上的 Apache 2)进行修改,以添加对每个 CGI 程序的执行权限。例如,添加 /srv/www/cgi-bin/my_hit_counter.pl rPx
一行可授予 Apache 执行 Perl 脚本 my_hit_counter.pl
的权限,而且要求存在专用于 my_hit_counter.pl
的配置文件。如果 my_hit_counter.pl
不具备与之关联的专用配置文件,则规则应为 /srv/www/cgi-bin/my_hit_counter.pl rix
,从而让 my_hit_counter.pl
继承 usr.sbin.httpd2-prefork
配置文件。
某些用户可能感觉为 Apache 可能调用的每个 CGI 脚本指定执行权限比较繁琐。管理员可以将一定的访问权限授予 CGI 脚本的集合,这是一种替代方法。例如,添加 /srv/www/cgi-bin/*.{pl,py,pyc} rix
一行将允许 Apache 执行 /srv/www/cgi-bin/
中所有以 .pl
(Perl 脚本)和 .py
或 .pyc
(Python 脚本)结尾的文件。如上所示,规则的 ix
部分将使 Python 脚本继承 Apache 配置文件,这适合用于您不想为每个 CGI 脚本编写单独的配置文件的情况。
在 Web 应用程序处理 Apache 模块(mod_perl
和 mod_php
)时,如果您需要子进程限制模块 (apache2-mod-apparmor
) 功能,请在于 YaST 或命令行中添加配置文件时使用 ChangeHat 功能。要利用子进程限制,请参见第 35.2 节 “管理 ChangeHat 感知型应用程序”。
对于使用 mod_perl
和 mod_php
的 Web 应用程序,构建其配置文件所需要的处理略有不同。在这种情况下,“program”是 Apache 进程内的模块直接解释的脚本,因此不进行执行。而 AppArmor 版的 Apache 使用与所请求 URI 的名称对应的子配置文件(“帽子”)来调用 change_hat()
。
要执行的脚本所呈现的名称可能不是 URI,取决于 Apache 被配置为在何处查找模块脚本。如果您之前将 Apache 配置为将脚本放置在其他位置,当 AppArmor 指出访问违规事件时,日志文件中会出现不同的名称。请参见第 37 章 “管理已构建配置文件的应用程序”。
对于 mod_perl
和 mod_php
脚本,这是请求的 Perl 脚本或 PHP 页面的名称。例如,添加以下子配置文件将允许 localtime.php
页面执行并访问本地系统时间和区域设置文件:
/usr/bin/httpd2-prefork { # ... ^/cgi-bin/localtime.php { /etc/localtime r, /srv/www/cgi-bin/localtime.php r, /usr/lib/locale/** r, } }
如果尚未定义子配置文件,AppArmor 版的 Apache 将应用 DEFAULT_URI
帽子。要显示网页,使用此子配置文件便足以满足需求。AppArmor 在默认情况下提供的 DEFAULT_URI
帽子如下所示:
^DEFAULT_URI { /usr/sbin/suexec2 mixr, /var/log/apache2/** rwl, @{HOME}/public_html r, @{HOME}/public_html/** r, /srv/www/htdocs r, /srv/www/htdocs/** r, /srv/www/icons/*.{gif,jpg,png} r, /srv/www/vhosts r, /srv/www/vhosts/** r, /usr/share/apache2/** r, /var/lib/php/sess_* rwl }
要将单个 AppArmor 配置文件用于 Apache 处理的所有网页和 CGI 脚本,编辑 DEFAULT_URI
子配置文件是个不错的方法。有关使用 Apache 限制 Web 应用程序的详细信息,请参见第 35 章 “使用 ChangeHat 构建 Web 应用程序的配置文件”。
30.4.2 使网络代理免疫 #
要查找需要构建配置文件的网络服务器守护程序和网络客户端(例如 fetchmail
或 Firefox),您应检查计算机上的开放端口。另外,还请考虑通过这些端口响应的程序,并为其中尽量多的程序提供配置文件。如果您为具有开放网络端口的所有程序提供了配置文件,那么攻击者不突破 AppArmor 配置文件策略,就无法进入计算机上的文件系统。
使用扫描程序(例如 nmap)从计算机外部手动扫描服务器上的开放网络端口,或以 root
身份使用 netstat --inet -n -p
命令从计算机内部扫描。然后检查计算机,以确定哪些程序通过所发现的开放端口进行响应。
有关所有可能的选项的详细参考信息,请参见 netstat
命令的手册页。