SELinux 移除了 NSA 的名字二十年来，安全增强型 Linux（SELinux）一直是主线内核的一部分，它提供了一个实施访问控制安全策略的安全模块，现在已被广泛用于增强生产型 Linux 服务器和其他系统的安全性。SELinux 最初是美国国家安全局（NSA）开发并贡献给 Linux 内核的，并且多年来一直参与贡献，因此其正式的名称是 “NSA SELinux”。但鉴于 NSA 不良的信誉，它一直被怀疑在 SELinux 代码中埋有不为人知的后门，虽然并没有公开的证据可以证明这一点。由于社区的质疑，以及 SELinux 越来越多的由社区参与开发，Linux 内核将从 6.6 开始，NSA SELinux 的名称中将不再包含 “NSA”。消息来源：Phoronix老王点评：虽然我对 NSA 也持不信任的态度，但是我对这一做法不以为然。OpenAI 称以变革的方式使用受版权保护的材料并不违反版权OpenAI 针对作者们提起的一系列诉讼做出了回应，这些诉讼指控 OpenAI 非法使用他们的作品未经许可的副本训练了 ChatGPT。OpenAI 请求法院驳回除一项直接著作权侵权外的所有指控。OpenAI 称作者们 “误解了版权的范围，没有考虑到限制和例外情况（包括合理使用）”。OpenAI 认为，即使 ChatGPT 庞大数据集中的 “极小一部分” 包含了作者们的书籍，但 “创新者以变革的方式使用受版权保护的材料并不违反版权”。OpenAI 辩称，与试图通过传播版权材料直接获利的剽窃者不同，他们的目标是 “教会其模型推导出人类语言的基本规则”，并提醒法庭注意：“虽然作者可以为其图书注册版权，但该图书中与‘词频、句法模式和主题标记’相关的‘统计信息’却不在版权保护范围之内”。消息来源：Ars Technica老王点评：从一定意义上，这些诉讼反映了当前 AI 技术发展与版权法之间的矛盾，其判决可以视为未来 AI 领域的一个重要法律参考。值得持续关注。微软使用类似恶意软件的弹窗让人们放弃谷歌有人反馈，当他使用 Chrome 浏览器时，他的 Windows 11 弹出了一个窗口，要求将 Chrome 浏览器中的默认搜索引擎切换为微软必应。它并不是一个普通的通知，它既没有出现在通知中心，也与 Windows 11 向你推荐新功能的部分无关。它是一个以某种方式出现在临时目录中的可执行文件，并带有微软的数字签名。这种行为让用户感觉像“被安装了恶意软件”一样。微软回应称，他们“已经意识到了这些报告，并暂停了这一通知”。消息来源：The Verge老王点评：我本来想说，“已经为微软许可证付费的用户有理由不受这种广告、分析的影响，而开源的操作系统就可以避免这种情况”，但是我想起来 Canonical 也做过类似的事情，所以我无话可说。
硬核观察 #781 DeepMind 用游戏的方式打破了矩阵相乘 50 年来的记录
DeepMind 用游戏的方式打破了矩阵相乘 50 年来的记录矩阵乘法问题是一种关键的计算类型，它是许多不同应用的核心，从屏幕上显示图像到模拟复杂的物理学。加快这种计算可能会对成千上万的日常计算机任务产生重大影响。但想优化矩阵相乘的步骤很难。DeepMind 将该问题变成一种三维棋盘游戏 TensorGame。训练了一个新版本的 AlphaZero，称为 AlphaTensor，来玩这个游戏，以尽可能少的动作赢得游戏。AlphaTensor 发现了一种将两个四乘四的矩阵相乘的方法，只需要 47 步，基本的高中数学方法需要 64 步，而之前的最佳方法是德国数学家在 1969 年发明的 49 步的方法。此外，“AlphaTensor 在超过 70 种不同大小的矩阵中击败了现有的最佳算法。”消息来源：Technology Review老王点评：没想到 AI 居然可以在数学上找到更好的算法，果然人力有时而穷。此外，对矩阵相乘的改进，应该会从底层提升很多你想不到的地方的性能。英特尔推动 GPU 通用编程库 SYCL 的发展如今在加速计算和 GPU 领域，CUDA 只能在英伟达的 GPU 上运行，AMD 的 CUDA 可以在 AMD 的 GPU 上运行，但你不能用 CUDA 为英特尔的 GPU 编程。因此，英特尔推动开源 SYCL 规范的发展，该规范旨在为 GPU 和加速计算做几十年前 Java 为应用开发所做的工作。SYCL 是一种用 C++ 语言进行数据并行编程的方法，它看起来很像 CUDA，可以在英特尔、AMD 和英伟达的 GPU 上运行，而无需改变你的代码。消息来源：Venture Beat老王点评：这就是一个英特尔的 CUDA，但是以开放的名义。SELinux 继续废弃运行时禁用功能SELinux 已经废弃了运行时禁用功能，即通过编辑配置文件或 sys 文件系统来即时禁用它。但相关的代码和功能尚未从内核中删除，Linux 6.1 仍然具有处理 SELinux 运行时禁用的废弃能力。在最新的 Linux 6.1 的合并请求中，SELinux 删除了对该能力的一个文档参考，向废弃该能力小小的迈了一步，其它的部分几乎没有什么大的变化。一种简单和非侵入性的正确禁用 SELINUX 的方法是，在启动 Linux 时可以将 selinux=0 作为一个内核参数传递进去。消息来源：Phoronix老王点评：抛开 SELinux 的 NSA 背景不谈，SELinux 其实安全但繁琐，所以运行时禁用 SELinux 往往成为了一种偷懒行为或安全缺陷。
黑掉你的系统，了解为什么配置 SELinux 作为你的第一道容器防线是很重要的。当有些事情在你的 Linux 环境中不能正常工作时，最简单的方法就是禁用 安全增强型 Linux Security-Enhanced Linux （SELinux）。而当它突然可以工作了，你就会忘记了禁用这件事 —— 这是一个常见的陷阱，意味着你已经失去了一个非常强大的安全工具。随着容器、微服务和分布式架构的兴起，威胁也在上升。这是由于一个老的、众所周知的问题：速度。容器的优势在于它们能让你快速行动，做更多的事情，并迅速改变。这意味着容器的采用已经飞速发展，但它所提供的速度也意味着你会遇到更多的问题和漏洞。当你越来越快地做更多的事情时，这自然会发生。如何减轻威胁正如孙子所说，“不战而屈人之兵”。当涉及到容器的基本防御时，这句话真的很有共鸣。为了避免问题（战斗），确保你的容器主机是安全的，你可以使用 SELinux 作为你的第一道防线。SELinux 是一个开源项目，于 2000 年发布，2003 年集成到 Linux 内核中。根据 红帽公司的解释，“SELinux 是 Linux 系统 的一个安全架构，允许管理员对谁可以访问系统有更多的控制。它最初是由美国国家安全局（NSA）开发的，是使用 Linux 安全模块（LSM）对 Linux 内核 的一系列补丁。”开始吧当你想到容器时，首先想到的可能是 Docker。Docker 在 2013 年出现后掀起了一场容器采用革命。它是容器爆炸性流行的主要原因之一，但如上所述，大量采用增加了用户对安全风险的脆弱性。在你用 SELinux 保护你的 Docker 容器之前，你需要设置一些东西。前置条件安装并配置了 CentOS 8/RHEL 8。安装并配置好 Docker CE创建两个账户：root 和 非 root 用户（下面的例子中是 mcalizo）。如果你需要在你的 RHEL 8/CentOS 8 服务器上设置 Docker，你可以按照这些 说明。如果你运行的是 RHEL 8，你需要在开始之前删除预装的 Podman 和 runc 包。首先，确保 SELinux 被启用：[mcalizo@Rhel82 ~]$ sestatus SELinux status: enabled SELinuxfs mount: /sys/fs/selinux SELinux root directory: /etc/selinux Loaded policy name: targeted Current mode: enforcing Mode from config file: enforcing Policy MLS status: enabled Policy deny_unknown status: allowed Memory protection checking: actual (secure) Max kernel policy version: 31 [mcalizo@Rhel82 ~]$ 然后，验证你的操作系统版本和 Docker 正在运行。以 root 身份登录并运行：[root@rhel82 ~]# cat /etc/redhat-release Red Hat Enterprise Linux release 8.2 (Ootpa) [root@rhel82 ~]# [root@rhel82 ~]# systemctl status docker ● docker.service - Docker Application Container Engine Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled) Active: active (running) since Wed 2020-10-28 19:10:14 EDT; 15s ago Docs: https://docs.docker.com Main PID: 30768 (dockerd) Tasks: 8 Memory: 39.0M CGroup: /system.slice/docker.service └─30768 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock Oct 28 19:10:13 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:13.889602941-04:00" level=error msg="> Oct 28 19:10:13 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:13.903413613-04:00" level=warning msg> Oct 28 19:10:13 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:13.903427451-04:00" level=warning msg> Oct 28 19:10:13 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:13.903538271-04:00" level=info msg="L> Oct 28 19:10:14 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:14.132060506-04:00" level=info msg="D> Oct 28 19:10:14 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:14.308943088-04:00" level=info msg="L> Oct 28 19:10:14 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:14.319438549-04:00" level=info msg="D> Oct 28 19:10:14 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:14.319570298-04:00" level=info msg="D> Oct 28 19:10:14 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:14.333419209-04:00" level=info msg="A> Oct 28 19:10:14 rhel82.home.labs.com systemd[1]: Started Docker Application Container Engine 检查你的 Docker 版本：[root@rhel82 ~]# docker --version Docker version 19.03.13, build 4484c46d9d 黑掉主机了解一个问题的最好方法之一就是去体验它。因此，我将告诉你，如果你的安全设置不当，向 Docker 主机注入恶意代码是多么容易。为了能够在 Docker 主机上做坏事，“恶意”的非 root 用户（本教程中为 mcalizo）必须是可以实例化 Docker 容器的组的成员。首先，确认 mcalizo 用户属于哪个组：[root@Rhel82 ~]# groups mcalizo mcalizo : mcalizo 输出显示，mcalizo 只属于它自己的组。这意味着 mcalizo 不能实例化 Docker 容器，如果它试图这样做，将会得到这个错误：[mcalizo@Rhel82 ~]$ docker run -it --rm centos:latest /bin/sh docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.40/containers/create: dial unix /var/run/docker.sock: connect: permission denied. See 'docker run --help'. 要允许 mcalizo 实例化容器，将用户加入 docker 组：[root@Rhel82 ~]# usermod -G docker -a mcalizo [root@Rhel82 ~]# groups mcalizo mcalizo : mcalizo docker 接下来，部署一个 fedora:latest 的容器，并登录到实例化的容器中去探索它：[mcalizo@Rhel82 ~]$ docker run -it --rm fedora:latest /bin/sh Unable to find image 'fedora:latest' locally latest: Pulling from library/fedora ee7e89337106: Pull complete Digest: sha256:b9ec86d36fca7b1d3de39cd7c258e8d90c377d312c21a7748071ce49069b8db4 Status: Downloaded newer image for fedora:latest sh-5.0# cat /etc/redhat-release Fedora release 33 (Thirty Three) 当你登录到新创建的容器时，你可以看到你是以 root 身份自动登录的：sh-5.0# whoami root sh-5.0# 作为 root 用户，你可以在这个容器中做任何事情，这意味着你可以利用容器主机，做很多破坏。因为你可以实例化一个容器，即使你不属于主机的 sudoers 账户，你也可以对主机做一些事情。退出你刚刚创建的容器，并创建一个新的容器来演示这个漏洞：[mcalizo@Rhel82 ~]$ docker run -it --rm -v /:/exploit fedora:latest /bin/bash [root@131043f2e306 /]# -v 选项 将 Docker 主机的 / 目录挂载到 /exploit 目录下的容器：[root@131043f2e306 /]#ls exploit/ bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var 因为它已被挂载，你可以在 Docker 主机上做任何事情。例如，你可以删除文件、编辑特定的配置来破害系统，甚至安装木马程序或其他恶意软件来窃取重要信息。为什么会发生这种情况？你可能想知道，既然 SELinux 处于强制模式，为什么会出现这种情况？深入挖掘 SELinux，看看哪里出了问题。验证 SELinux 是否有一个 Docker 上下文：[mcalizo@Rhel82 ~]$ ps -eZ | grep docker system_u:system_r:container_runtime_t:s0 30768 ? 00:00:04 dockerd [mcalizo@Rhel82 ~]$ 正如预期的那样，它确实有。这意味着 SELinux 管理着 Docker 守护进程。检查 Docker 守护进程，看看 SELinux 是否默认启用：[mcalizo@Rhel82 ~]$ docker info | grep Security -A3 Security Options: seccomp Profile: default Kernel Version: 4.18.0-193.el8.x86_64 Docker 守护进程中的 SELinux 在默认情况下是 不启用 的。 这就是问题所在！要解决这个问题，按 文档 说明，通过更新或创建文件 /etc/docker/daemon.json 来启用 SELinux 来控制和管理 Docker（你必须有 root 权限才能这样做）：[root@Rhel82 ~]# cat /etc/docker/daemon.json { "selinux-enabled": true } [root@Rhel82 ~]# [root@Rhel82 ~]# systemctl restart docker 在创建或更新该文件并重启 Docker 后，你应该看到 Docker 守护进程中启用了 SELinux 支持：[root@Rhel82 ~]# systemctl restart docker [mcalizo@Rhel82 root]$ docker info | grep Security -A3 Security Options: seccomp Profile: default selinux [mcalizo@Rhel82 root]$ 虽然仍然可以在你的 Docker 容器上挂载 Docker 主机中的特定文件系统，但不再允许更新或访问该文件：[mcalizo@Rhel82 root]$ docker run -it --rm -v /:/exploit fedora:latest /bin/bash [root@ecb5836da1f6 /]# touch /exploit/etc/shadow.sh touch: cannot touch '/exploit/etc/shadow.sh': Permission denied [root@ecb5836da1f6 /]# 了解更多你在容器世界中的第一道防线取决于你对容器主机的操作系统的设置有多强。有许多方法可以实现 Linux 的安全性，包括市场上可供选择的方案，以增强你的安全态势。SELinux 是一个额外的安全层，默认情况下内置于 Linux 发行版 中。为了借助它保护你的系统不被破坏，请确保 SELinux 保持开启状态。如果你想了解更多，请参阅：如何在 CentOS 8 / RH 上安装 Docker CEDocker 安全速查表dockerd 文档卷的使用文档什么是 SELinux？via: https://opensource.com/article/20/11/selinux-containers作者：Mike Calizo 选题：lujun9972 译者：wxy 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
系统管理员的 SELinux 指南：这个大问题的 42 个答案
获取有关生活、宇宙和除了有关 SELinux 的重要问题的答案“一个重要而普遍的事实是，事情并不总是你看上去的那样 …” ―Douglas Adams，《银河系漫游指南》安全、坚固、遵从性、策略是末世中系统管理员的四骑士。除了我们的日常任务之外 —— 监控、备份、实施、调优、更新等等 —— 我们还需要负责我们的系统安全。即使这些系统是第三方提供商告诉我们该禁用增强安全性的系统。这看起来像《碟中碟》中 Ethan Hunt 的工作一样。面对这种窘境，一些系统管理员决定去服用蓝色小药丸，因为他们认为他们永远也不会知道如生命、宇宙、以及其它一些大问题的答案。而我们都知道，它的答案就是这个 42。按《银河系漫游指南》的精神，这里是关于在你的系统上管理和使用 SELinux 这个大问题的 42 个答案。SELinux 是一个标签系统，这意味着每个进程都有一个标签。每个文件、目录、以及系统对象都有一个标签。策略规则负责控制标签化的进程和标签化的对象之间的访问。由内核强制执行这些规则。两个最重要的概念是：标签化（文件、进程、端口等等）和类型强制（基于不同的类型隔离不同的的进程）。正确的标签格式是 user:role:type:level（可选）。 多级别安全 Multi-Level Security （MLS）强制的目的是基于它们所使用数据的安全级别，对进程（域）强制实施控制。比如，一个秘密级别的进程是不能读取极机密级别的数据。 多类别安全 Multi-Category Security （MCS）强制相互保护相似的进程（如虚拟机、OpenShift gears、SELinux 沙盒、容器等等）。在启动时改变 SELinux 模式的内核参数有：autorelabel=1 → 强制给系统重新标签化selinux=0 → 内核不加载 SELinux 基础设施的任何部分enforcing=0 → 以 许可 permissive 模式启动如果给整个系统重新标签化：# touch /.autorelabel # reboot 如果系统标签中有大量的错误，为了能够让 autorelabel 成功，你可以用许可模式引导系统。检查 SELinux 是否启用：# getenforce临时启用/禁用 SELinux：# setenforce [1|0]SELinux 状态工具：# sestatus配置文件：/etc/selinux/configSELinux 是如何工作的？这是一个为 Apache Web Server 标签化的示例：* 二进制文件：`/usr/sbin/httpd`→`httpd_exec_t` * 配置文件目录：`/etc/httpd`→`httpd_config_t` * 日志文件目录：`/var/log/httpd` → `httpd_log_t` * 内容目录：`/var/www/html` → `httpd_sys_content_t` * 启动脚本：`/usr/lib/systemd/system/httpd.service` → `httpd_unit_file_d` * 进程：`/usr/sbin/httpd -DFOREGROUND` → `httpd_t` * 端口：`80/tcp, 443/tcp` → `httpd_t, http_port_t`在 `httpd_t` 安全上下文中运行的一个进程可以与具有 `httpd_something_t` 标签的对象交互。许多命令都可以接收一个 -Z 参数去查看、创建、和修改安全上下文：* `ls -Z` * `id -Z` * `ps -Z` * `netstat -Z` * `cp -Z` * `mkdir -Z`当文件被创建时，它们的安全上下文会根据它们父目录的安全上下文来创建（可能有某些例外）。RPM 可以在安装过程中设定安全上下文。这里有导致 SELinux 出错的四个关键原因，它们将在下面的 15 - 21 条中展开描述：* 标签化问题 * SELinux 需要知道一些东西 * SELinux 策略或者应用有 bug * 你的信息可能被损坏标签化问题：如果在 /srv/myweb 中你的文件没有被正确的标签化，访问可能会被拒绝。这里有一些修复这类问题的方法：* 如果你知道标签：`# semanage fcontext -a -t httpd_sys_content_t '/srv/myweb(/.*)?'` * 如果你知道和它有相同标签的文件：`# semanage fcontext -a -e /srv/myweb /var/www` * 恢复安全上下文（对于以上两种情况）：`# restorecon -vR /srv/myweb`标签化问题：如果你是移动了一个文件，而不是去复制它，那么这个文件将保持原始的环境。修复这类问题：* 使用标签来改变安全上下文：`# chcon -t httpd_system_content_t /var/www/html/index.html` * 使用参考文件的标签来改变安全上下文：`# chcon --reference /var/www/html/ /var/www/html/index.html` * 恢复安全上下文（对于以上两种情况）：`# restorecon -vR /var/www/html/`如果 SELinux 需要知道 HTTPD 在 8585 端口上监听，使用下列命令告诉 SELinux：# semanage port -a -t http_port_t -p tcp 8585SELinux 需要知道是否允许在运行时改变 SELinux 策略部分，而无需重写 SELinux 策略。例如，如果希望 httpd 去发送邮件，输入：# setsebool -P httpd_can_sendmail 1SELinux 需要知道 SELinux 设置的关闭或打开的一系列布尔值：* 查看所有的布尔值：`# getsebool -a` * 查看每个布尔值的描述：`# semanage boolean -l` * 设置某个布尔值：`# setsebool [_boolean_] [1|0]` * 将它配置为永久值，添加 `-P` 标志。例如：`# setsebool httpd_enable_ftp_server 1 -P`SELinux 策略/应用可能有 bug，包括：* 不寻常的代码路径 * 配置 * 重定向 `stdout` * 泄露的文件描述符 * 可执行内存 * 错误构建的库开一个工单（但不要提交 Bugzilla 报告；使用 Bugzilla 没有对应的服务）你的信息可能被损坏了，假如你被限制在某个区域，尝试这样做：* 加载内核模块 * 关闭 SELinux 的强制模式 * 写入 `etc_t/shadow_t` * 修改 iptables 规则用于开发策略模块的 SELinux 工具：# yum -y install setroubleshoot setroubleshoot-server。安装完成之后重引导机器或重启 auditd 服务。使用 journalctl 去列出所有与 setroubleshoot 相关的日志：# journalctl -t setroubleshoot --since=14:20使用 journalctl 去列出所有与特定 SELinux 标签相关的日志。例如：# journalctl _SELINUX_CONTEXT=system_u:system_r:policykit_t:s0当 SELinux 错误发生时，使用setroubleshoot 的日志，并尝试找到某些可能的解决方法。例如：从 journalctl 中：Jun 14 19:41:07 web1 setroubleshoot: SELinux is preventing httpd from getattr access on the file /var/www/html/index.html. For complete message run: sealert -l 12fd8b04-0119-4077-a710-2d0e0ee5755e # sealert -l 12fd8b04-0119-4077-a710-2d0e0ee5755e SELinux is preventing httpd from getattr access on the file /var/www/html/index.html. ***** Plugin restorecon (99.5 confidence) suggests ************************ If you want to fix the label, /var/www/html/index.html default label should be httpd_syscontent_t. Then you can restorecon. Do # /sbin/restorecon -v /var/www/html/index.html 日志：SELinux 记录的信息全在这些地方：* `/var/log/messages` * `/var/log/audit/audit.log` * `/var/lib/setroubleshoot/setroubleshoot_database.xml`日志：在审计日志中查找 SELinux 错误：# ausearch -m AVC,USER_AVC,SELINUX_ERR -ts today针对特定的服务，搜索 SELinux 的 访问向量缓存 Access Vector Cache （AVC）信息：# ausearch -m avc -c httpdaudit2allow 实用工具可以通过从日志中搜集有关被拒绝的操作，然后生成 SELinux 策略允许的规则，例如：* 产生一个人类可读的关于为什么拒绝访问的描述：`# audit2allow -w -a` * 查看允许被拒绝的类型强制规则：`# audit2allow -a` * 创建一个自定义模块：`# audit2allow -a -M mypolicy`，其中 `-M` 选项将创建一个特定名称的强制类型文件（.te），并编译这个规则到一个策略包（.pp）中：`mypolicy.pp mypolicy.te` * 安装自定义模块：`# semodule -i mypolicy.pp`配置单个进程（域）运行在许可模式：# semanage permissive -a httpd_t如果不再希望一个域在许可模式中：# semanage permissive -d httpd_t禁用所有的许可域：# semodule -d permissivedomains启用 SELinux MLS 策略：# yum install selinux-policy-mls。 在 /etc/selinux/config 中：SELINUX=permissive SELINUXTYPE=mls 确保 SELinux 运行在许可模式：# setenforce 0使用 fixfiles 脚本来确保在下一次重启时文件将被重新标签化：# fixfiles -F onboot # reboot创建一个带有特定 MLS 范围的用户：# useradd -Z staff_u john使用 useradd 命令，映射新用户到一个已存在的 SELinux 用户（上面例子中是 staff_u）。查看 SELinux 和 Linux 用户之间的映射：# semanage login -l为用户定义一个指定的范围：# semanage login --modify --range s2:c100 john调整用户家目录上的标签（如果需要的话）：# chcon -R -l s2:c100 /home/john列出当前类别：# chcat -L修改类别或者创建你自己的分类，修改如下文件：/etc/selinux/_<selinuxtype>_/setrans.conf以某个特定的文件、角色和用户安全上下文来运行一个命令或者脚本：# runcon -t initrc_t -r system_r -u user_u yourcommandhere* `-t` 是文件安全上下文 * `-r` 是角色安全上下文 * `-u` 是用户安全上下文在容器中禁用 SELinux：* 使用 Podman：`# podman run --security-opt label=disable ...` * 使用 Docker：`# docker run --security-opt label=disable ...`如果需要给容器提供完全访问系统的权限：* 使用 Podman：`# podman run --privileged ...` * 使用 Docker：`# docker run --privileged ...` 就这些了，你已经知道了答案。因此请相信我：不用恐慌，去打开 SELinux 吧。作者简介Alex Callejas 是位于墨西哥城的红帽公司拉丁美洲区的一名技术客服经理。作为一名系统管理员，他已有超过 10 年的经验。在基础设施强化方面具有很强的专业知识。对开源抱有热情，通过在不同的公共事件和大学中分享他的知识来支持社区。天生的极客，当然他一般选择使用 Fedora Linux 发行版。这里有更多关于他的信息。via: https://opensource.com/article/18/7/sysadmin-guide-selinux作者：Alex Callejas 选题：lujun9972 译者：qhwdw, FSSlc 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
从蓝瘦“想哭”到 SELinux 看操作系统安全何在
最近一周，来自网络的 “想哭”勒索病毒 （ Wannacry Ransomware ） 在世界各地同时上演了一部绑匪大片，台词华丽，演技出色，当仁不让地新晋世界第一网红。全球各国除了默默忙于两弹一星足不出户的朝鲜外，无不为之动容。一时间，包括“想哭”病毒在内的各种病毒的各种传闻也火爆网络，我们并不准备跟风刷屏，只是打算本着实事求是的精神，科学的探讨一下如何与它们和睦相处、谈笑风生。“想哭”病毒的前世今生首先，让我们先简要回顾一下主角“想哭”病毒的前世今生。“想哭”病毒是基于网络攻击框架二次开发的结果，它利用了 NSA（美国国家安全局）的前辈们留下的非物质文化遗产： 永恒之蓝 （ ETERNAL BLUE ） 模块，针对 Windows SMB 服务的实现漏洞植入恶意代码，再结合自己的创新：加密用户文件和显示勒索声明，一代网红勒索病毒由此诞生。从病毒本身的设计流程来看，似乎并不需要高深的编码技巧或深厚的理论根基，然而这也恰恰是这一事件中最值得我们警惕的地方：NSA 泄漏的攻击模块远不止永恒之蓝一种，借助已有攻击框架进行二次开发的难度又如此之低，所以，可以预期，一大波未知的病毒正在来袭的路上。是不是细思极恐？所谓“知彼知己，百战不 殆 （ die ） ”，要想不 die，先要充分了解对手，所以接下来我们进一步了解一下什么是病毒？病毒是如何以危险方式危害公共安全的？又是怎样进入我们的系统的？病毒是什么，其实是老生常谈了，经常关注医疗卫生领域的朋友都知道：病毒由一段基因与蛋白质构成，自身不能实现新陈代谢，通过适当的途径侵入宿主体内，通过宿主细胞的代谢系统实现复制传播。跑题了？好吧，不要在意这些细节，我们改几个字就能用了：病毒由一段可执行代码与数据构成，自身不能在裸机上运行，通过适当的途径侵入宿主操作系统，通过宿主系统中的存储和网络实现复制传播。Wirth 教授教导我们：算法+数据结构=程序，病毒=代码+数据=算法+数据结构=程序没错，病毒就是一类特殊的计算机程序，广义上称为恶意软件。与自然界病毒的最大不同之处在于，它们不是纯天然的，而是 100% 人工打造。通常它们怀着对人类的深深的恶意来到世上，行为各不相同，有的在你的屏幕上画个圈圈诅咒你，有的会窃取你设备中的隐私照片，还有的会眨眼间转走你银行卡上的购房首付款......显然，它们的目标还是很一致的：危害人类设备，破坏世界和平。又扯远了，我们接着来看病毒是如何入侵操作系统的。病毒的入侵无外乎两个途径：主动和被动。所谓主动是针对目标系统尝试发起扫描和攻击，一般是远程发起，当发现了自己能吃定的漏洞之后，就通过各种阴险手段（其实技术实现上大多还是很优雅的）攫取系统权限，进而将恶意代码注入宿主系统中伺机作恶，对此没什么概念的小伙伴可以自行脑补一下《异形》中的人类被寄生的过程。病毒入侵的另一种方式，我们称之为被动方式。这种方式并不需要系统存在漏洞或缺陷，需要的是用户的经验、常识或智商存在缺陷。它们通过各种伪装诱骗用户去打开或运行自己，包括形形色色让你心动的邮件、链接、不明来源的安装程序等等，一旦获得机会运行，它们会悄无声息的在你的系统中安营扎寨、留下多道后门，然后为所欲为，这类病毒又被形象地称为（特洛伊）木马。如何应对各种病毒威胁了解了病毒的来龙去脉之后，我们就可以开始讨论如何应对各种病毒层出不穷的威胁了。对于大多数用户，良好的使用习惯是第一位的。堡垒往往从内部被攻克，再安全的操作系统，再强大的安全机制，都难以阻止用户自我毁灭的脚步。良好的使用习惯中最重要的，是安全更新，安全更新，安全更新！为什么呢？这要先谈一下操作系统漏洞的由来。漏洞实际是软件缺陷的一种，也就是俗称的 bug，是由于软件开发人员的疏忽而导致程序没有按照预期的方式运行。软件缺陷多种多样，有些很呆，有些很萌，也并不都会对系统安全构成威胁。那些侥幸逃脱开发和测试人员的轮番围剿，随着软件的发布散落人间的软件缺陷，一旦被黑客们发现、策反，并借助自己在系统内部的有利位置，披着合法软件的外衣，做出送人头、坑队友的恶劣行径时，就成为软件系统的公敌：漏洞。越是庞大和复杂的软件越容易产生漏洞，不幸的是操作系统就是一类极其庞大而复杂的软件系统。虽然操作系统漏洞常常难以完全避免，然而某个漏洞一旦被发现，开发厂商都会在第一时间发布安全更新对问题进行修复。以这次勒索病毒为例，针对被利用的 SMB 服务漏洞，事实上早在一个月前微软就公布了漏洞警告和补丁，提供了安全更新，那些开启自动更新并及时修复了漏洞的用户，他们可以用省下的三个比特币吃着火锅唱着歌，完全不用担心绑匪。所以请划重点：操作系统安全更新非常重要，不论个人用户、企业用户还是系统管理员，不论服务器，桌面还是移动终端，不论 Windows，Linux 还是 MacOS，都应该尽可能及时地从操作系统厂商处获取安全更新。其次，杀毒软件也可以起到一定的安全增强的作用，多数杀毒软件可以借助病毒库对已有病毒的特征进行分析比对，一旦发现用户即将运行的程序中含有病毒或恶意程序，会及时提醒用户，或者自动清除。因此，杀毒软件可以在很大程度上防御已知的、以被动方式入侵系统的病毒。那么，积极地安全更新、安装杀毒软件就可以解决所有病毒威胁了么？很不幸，事实并非如此。安全更新和杀毒软件之于病毒威胁正如强身健体之于疾病隐患，可以大幅降低几率，却难以完全避免。为什么？这要从 零日 （ 0-day ） 漏洞说起。零日漏洞，听起来就很霸气的一个名字，仿佛给人一种世界末日的感觉。它并不是指具体的某个或某类漏洞，而是指被黑客发现后立刻用来发起攻击的漏洞，这些漏洞尚未公开，用户不知道，软件厂商也不了解，应对时间为零。所以，这类漏洞没有检测工具，没有修复方法，传统被动升级防御、病毒特征比对的方式毫无用处，一旦被用来发起攻击，普通系统是毫无招架能力的。那么有没有可以防御零日漏洞的安全的操作系统呢？安全的操作系统与 SELinux一提到安全的操作系统，总会涌现出很多真知灼见，最脍炙人口的莫过于：“所有操作系统都有漏洞，所以没有绝对安全的操作系统；所以 Windows 也好，Linux 也好，MacOS 也好，都一样不安全。”说的好有道理，我竟无言以对，因为前半句就是对本文前半部分的总结，理论正确，逻辑自洽，没什么可黑的。后半句的逻辑却似乎有点烧脑，如果它成立的话，我们不妨试着推广一下，比如：“任何物质都是有毒性的，没有什么是绝对无毒的。砒霜吃了会中毒，水喝多了也会中毒，所以砒霜和水一样不安全。”毒理学有句名言：一切谈毒性不谈剂量的行为都是耍流氓。同样，任何谈操作系统安全不谈体系架构的行为也是耍流氓。所以面对这种耍流氓的行为，接下来我们要严肃的谈一谈操作系统的安全体系架构。多年前，永恒之蓝的始作蛹者 NSA 为了防御自家系统，开发了一套安全框架，多年后这套框架被贡献给了 Linux 内核，这就是 SELinux。作为造成这次世界性灾难的幕后大 boss，NSA 为自己定制的 SELinux 又是怎样的一套防具呢？SELinux 全称 Security Enhanced Linux ，是针对 Linux 的全面安全增强，相比一般的发现漏洞-修复漏洞这种被动挨打的模式，SELinux 具备主动防御能力，可以抵御包括零日漏洞在内的多种攻击。那么 SELinux 是如何做到的呢？访问控制是操作系统安全体系中的最核心最关键的机制，它决定了系统中什么样的资源可以被哪些用户以什么样的方式来访问，也就是说普通用户能做什么，入侵者能做什么，应用软件能做什么，恶意软件能做什么，都是访问控制系统决定的。SELinux 的核心访问机制是 强制访问控制 （ Mandatory Access Control ） ，简称 MAC，SELinux 的安全特性是建立在 MAC 基础之上的。那么 MAC 何德何能，堪负如此重任？说到 MAC 强制访问控制就不得不说它的前辈 自主访问控制 （ Discretionary Access Control ） ，简称 DAC。传统的操作系统，Windows、MacOS、以及包括早期 Linux 在内的各种Unix的系统权限管理都是采用的自主访问控制，自主访问控制将用户（或用户组）简化为一个标识，系统中的资源（比如文件）都会带上用户标识和对应的访问权限信息，通过这种方式赋予不同用户不同的访问权限，操作系统通过对用户标识的比对和权限信息决定一个用户是否能访问某个资源。打个比方，你认为你家里的东西是只属于你的，在 DAC 看来，只要能进屋的人都对这个屋子里的东西拥有权限，那么你自己开门进屋睡觉也好，小偷撬门进去拿走金银细软也好，都是合法的。在操作系统中也是如此，几乎所有操作系统中都有一个身影，叫管理员，Administrator 也好，root 也好，都是一群在系统中权力无限大，对任何资源都有完全访问权限的家伙。多数系统服务是以管理员权限运行的，如果它们存在漏洞，被劫持去做一些它们本不该做的事情的时候，DAC 是不会阻拦的，因为它无法区分某个动作是程序正常行为还是恶意行为。在它眼里，身份就是权力的象征，只要认可了你的管理员身份，你说什么都是对的，你做什么都是合法的。那么 MAC 机制又是怎样的呢？与 DAC 中的混沌不同，MAC 是一个充满秩序的世界，一个一举一动要提出申请的世界。在 MAC 中，一切访问计划都要事先写入安全策略，没有明确的策略允许的任何访问都会被禁止。在上个例子中，作为家中的主人，你需要能够在家睡觉，也是需要明确制定计划的，你需要添加的安全策略看起来是这样的：定义资源类型： 床定义安全域： 休息定义角色： 主人访问规则： 允许 主人 休息时 使用床如果系统对于你家中的资源访问只添加了这一条安全策略，那么你仍然可以安心的在家睡觉，小偷无论用何种方式进入你家都将寸步难行，接触任何东西的行为都会被禁止，并且一切被禁止的行为尝试都将被另一套完善的监控系统：审计日志记录在案。明白了这个例子，回到操作系统中我们就很容易看懂 MAC 是如何防范系统带来的安全威胁的：假设我们有一个存在缓冲区溢出漏洞的文件共享服务，与多数系统服务一样使用管理员权限运行。攻击者通过精心构建一个特殊的数据包发送给服务器，使存在漏洞服务器正常的执行流程被劫持，转而执行修改管理员密码的操作。在 DAC 控制下的传统操作系统中，一旦攻击生效，那么管理员密码会被这个平时八竿子打不着的文件服务器修改，攻击者随后可以很容易的登录进入系统。而在 MAC 系统中，文件服务器的可访问的文件是严格受限的，安全策略类似于：允许 系统管理员角色 运行文件服务器 该进程允许访问被共享文件。安全策略的定义了该服务可以访问的所有资源，攻击者在攻击了文件服务器后，希望修改管理员密码，它需要访问的是 SAM 或 passwd 等的密码管理文件，由于文件服务器进程仅被策略仅允许访问需要被共享的文件，因此对密码管理文件的操作将被拒绝，攻击失效。这种情况下最坏的情形是，攻击者可能非法访问共享文件，因为它仍在安全策略允许范围内。尽管如此，一个系统级的安全漏洞对整个操作系统的影响被限制在了非常小的范围内。通过细粒度的划分访问权限，将所有应用和服务的访问限制在最小范围内，这就是强制访问控制保护系统不受已知及未知漏洞攻击的原理。其实 MAC 和 DAC 并不是水火不容的，在包括 SELinux 在内的多数安全框架中，它们是共同生效的，所有的资源（或者准确的说叫客体）访问请求首先要经过 DAC 权限判定，验证通过之后再进一步进行 MAC 的安全策略判定，只有同时符合自主访问控制和强制访问控制规则后才能获得访问权限。SELinux 中，有三大类 MAC 策略模型，分别是 TE（类型增强），RBAC（角色访问控制）以及 MLS（多级别安全)，每一类模型都针对系统已有服务和应用提供了大量安全策略。一个使用了 SELinux 的典型的服务器操作系统环境，内核中会包含 10 万条以上的安全策略。计算机信息系统的安全等级了解了 SELinux 及其强制访问框架后，看到攻防两端都造诣深厚的 NSA，你可能会惊叹于矛尖盾厚的美国在信息安全领域的强大的实力。然而我国在这个陆上有东风，海上有航母，天空有北斗的时代，在信息安全这样重要的领域当然不会碌碌无为。我国很早就对信息安全领域展开了全面的研究，公安部对信息安全的各个领域提出了一些列标准，最早在 GB 17859-1999 标准中就根据需求将计算机信息系统的安全级别由低到高，划分为 1-5 共五个等级。在 GB/T 20272-2006 中更进一步对操作系统安全技术提出了具体要求。从国标安全第三级开始要求操作系统提供强制访问控制，除了要实现 SELinux 中的各类安全模型架构外，还根据最小特权原则开创性的引入三权分立的概念，将普通操作系统中权限不受控制的管理员根据职责分解为系统管理员，安全管理员，审计管理员三个角色。系统管理员负责“行政”体系，也就是系统中的配置管理，类似网络配置、服务启停（安全服务除外）、设备管理等等；安全管理员负责“立法”，负责安全策略制定、加载以及安全服务的开启；审计管理员的职责类似“司法”，制定违规访问的记录，安全服务的关闭。三个角色的权限之间互相制约，从而避免了恶意入侵者通过获取管理员权限对操作系统的全面控制。同时标准还对用户数据的私密性、完整性提出了严格的保护要求，要求操作系统通过安全标签保障用户数据不被非法读取和篡改。国标安全四级除了在访问控制和数据保护上提出更为严格要求之外，还要求设计者对操作系统的安全策略模型、安全功能模块进行形式化验证，并进行隐蔽信道分析，对系统抵御攻击能力进行评估，也是目前已有操作系统能达到的最高安全等级。目前普华、凝思等国产操作系统厂商已经开发出了符合国标安全四级的安全操作系统，提供了远高于普通 SELinux 的底层安全保护。结语信息安全是全方位的，尽管病毒与恶意入侵并非只针对操作系统，单一从操作系统层面无法解决所有的安全问题，然而作为所有上层应用的最底层软件支撑，操作系统却在最终执行层面承载着一切上层软件的安全机制，脱离操作系统构建的安全体系，如同沙滩上的城堡，即使再坚固也将最终失去根基。
如何在 CentOS 7 中在 HHVM 和 Nginx 之上安装 WordPress
HHVM （HipHop Virtual Machine） 是一个用于执行以 PHP 和 Hack 语言编写的代码的虚拟环境。它是由 Facebook 开发的，提供了当前 PHP 7 的大多数功能。要在你的服务器上运行 HHVM，你需要使用 FastCGI 来将 HHVM 和 Nginx 或 Apache 衔接起来，或者你也可以使用 HHVM 中的内置 Web 服务器 Proxygen。在这篇教程中，我将展示给你如何在 Nginx Web 服务器的 HHVM 上安装 WordPress。这里我使用 CentOS 7 作为操作系统，所以你需要懂一点 CentOS 操作的基础。先决条件CentOS 7 - 64位Root 权限步骤 1 - 配置 SELinux 并添加 EPEL 仓库在本教程中，我们将使用 SELinux 的强制模式，所以我们需要在系统上安装一个 SELinux 管理工具。这里我们使用 setools 和 setrobleshoot 来管理 SELinux 的各项配置。CentOS 7 已经默认启用 SELinux，我们可以通过以下命令来确认：# sestatus # getenforce 如图，你能够看到，SELinux 已经开启了强制模式。接下来就是使用 yum 来安装 setools 和 setroubleshoot 了。# yum -y install setroubleshoot setools net-tools 安装好这两个后，再安装 EPEL 仓库。# yum -y install epel-release 步骤 2 - 安装 NginxNginx (发音：engine-x) 是一个高性能、低内存消耗的轻量级 Web 服务器软件。在 CentOS 中可以使用 yum 命令来安装 Nginx 包。确保你以 root 用户登录系统。使用 yum 命令从 CentOS 仓库中安装 nginx。# yum -y install nginx 现在可以使用 systemctl 命令来启动 Nginx，同时将其设置为跟随系统启动。# systemctl start nginx # systemctl enable nginx 为确保 Nginx 已经正确运行于服务器中，在浏览器上输入服务器的 IP，或者如下使用 curl 命令检查显示结果。# curl 192.168.1.110 我这里使用浏览器来验证。步骤 3 - 安装并配置 MariaDBMariaDB 是由原 MySQL 开发者 Monty Widenius 开发的一款开源数据库软件，它由 MySQL 分支而来，与 MySQL 的主要功能保持一致。在这一步中，我们要安装 MariaDB 数据库并为之配置好 root 密码，然后再为所要安装的 WordPress 创建一个新的数据库和用户。安装 mariadb 和 mariadb-server：# yum -y install mariadb mariadb-server 启动 MariaDB 并添加为服务，以便随系统启动。# systemctl start mariadb # systemctl enable mariadb 现在 MariaDB 已经启动了，还需要为 mariadb/mysql 数据库配置 root 用户密码。输入以下命令来设置 MariaDB root 密码。# mysql_secure_installation 提示设置 root 用户密码时，输入新密码进行设置：Set root password? [Y/n] Y New password: Re-enter new password: Remove anonymous users? [Y/n] Y ... Success! Disallow root login remotely? [Y/n] Y ... Success! Remove test database and access to it? [Y/n] Y Reload privilege tables now? [Y/n] Y ... Success! 这样就设置好了 MariaDB 的 root 密码。现在登录到 MariaDB/MySQL shell 并为 WordPress 的安装创建一个新数据库 wordpressdb 和新用户 wpuser，密码设置为 wpuser@。为你的设置选用一个安全的密码。登录到 MariaDB/MySQL shell：# mysql -u root -p 接着输入你刚刚设置的 root 用户密码。创建数据库和用户：MariaDB [(none)]> create database wordpressdb; MariaDB [(none)]> create user wpuser@localhost identified by 'wpuser@'; MariaDB [(none)]> grant all privileges on wordpressdb.* to wpuser@localhost identified by 'wpuser@'; MariaDB [(none)]> flush privileges; MariaDB [(none)]> \q 现在安装好了 MariaDB，并为 WordPress 创建好了数据库。步骤 4 - 安装 HHVM对于 HHVM，我们需要安装大量的依赖项。作为选择，你可以从 GitHub 下载 HHVM 的源码来编译安装，也可以从网络上获取预编译的包进行安装。在本教程中，我使用的是预编译的安装包。为 HHVM 安装依赖项：# yum -y install cpp gcc-c++ cmake git psmisc {binutils,boost,jemalloc,numactl}-devel \ > {ImageMagick,sqlite,tbb,bzip2,openldap,readline,elfutils-libelf,gmp,lz4,pcre}-devel \ > lib{xslt,event,yaml,vpx,png,zip,icu,mcrypt,memcached,cap,dwarf}-devel \ > {unixODBC,expat,mariadb}-devel lib{edit,curl,xml2,xslt}-devel \ > glog-devel oniguruma-devel ocaml gperf enca libjpeg-turbo-devel openssl-devel \ > mariadb mariadb-server libc-client make 然后是使用 rpm 安装从 HHVM 预编译包镜像站点 下载的 HHVM 预编译包。# rpm -Uvh http://mirrors.linuxeye.com/hhvm-repo/7/x86_64/hhvm-3.15.2-1.el7.centos.x86_64.rpm # ln -s /usr/local/bin/hhvm /bin/hhvm 安装好 HHVM 之后使用如下命令按了验证：# hhvm --version 为了能使用 PHP 命令，可以把 hhvm 命令设置为 php。这样在 shell 中输入 php 命令的时候，你会看到和输入 hhvm 命令一样的结果。# sudo update-alternatives --install /usr/bin/php php /usr/bin/hhvm 60 # php --version 步骤 5 - 配置 HHVM这一步中，我们来配置 HHVM 以系统服务来运行。我们不通过端口这种常规的方式来运行它，而是选择使用 unix socket 文件的方式，这样运行的更快速一点。进入 systemd 配置目录，并创建一个 hhvm.service 文件。# cd /etc/systemd/system/ # vim hhvm.service 复制粘贴如下配置到文件中去。[Unit] Description=HHVM HipHop Virtual Machine (FCGI) After=network.target nginx.service mariadb.service [Service] ExecStart=/usr/local/bin/hhvm --config /etc/hhvm/server.ini --user nginx --mode daemon -vServer.Type=fastcgi -vServer.FileSocket=/var/run/hhvm/hhvm.sock [Install] WantedBy=multi-user.target 保存文件退出 vim。接下来，进入 hhvm 目录并编辑 server.ini 文件。# cd /etc/hhvm/ # vim server.ini 将第 7 行 hhvm.server.port 替换为 unix socket，如下：hhvm.server.file_socket = /var/run/hhvm/hhvm.sock 保存文件并退出编辑器。我们已在 hhvm 服务文件中定义了 hhvm 以 nginx 用户身份运行，所以还需要把 socket 文件目录的属主变更为 nginx。然后我们还必须在 SELinux 中修改 hhvm 目录的权限上下文以便让它可以访问这个 socket 文件。# chown -R nginx:nginx /var/run/hhvm/ # semanage fcontext -a -t httpd_var_run_t "/var/run/hhvm(/.*)?" # restorecon -Rv /var/run/hhvm 服务器重启之后，hhvm 将不能运行，因为没有存储 socket 文件的目录，所有还必须在启动的时候自动创建一个。使用 vim 编辑 rc.local 文件。# vim /etc/rc.local 将以下配置粘贴到文件末行。# mkdir -p /var/run/hhvm/ # chown -R nginx:nginx /var/run/hhvm/ # semanage fcontext -a -t httpd_var_run_t "/var/run/hhvm(/.*)?" # restorecon -Rv /var/run/hhvm 保存文件并退出 vim。然后给文件赋予执行权限。# chmod +x /etc/rc.local 重新加载 systemd 服务，启动 hhvm 并设置为随系统启动。# systemctl daemon-reload # systemctl start hhvm # systemctl enable hhvm 要确保无误，使用 netstat 命令验证 hhvm 运行于 socket 文件。# netstat -pl | grep hhvm 步骤 6 - 配置 HHVM 和 Nginx在这个步骤中，我们将配置 HHVM 已让它运行在 Nginx Web 服务中，这需要在 Nginx 目录创建一个 hhvm 的配置文件。进入 /etc/nginx 目录，创建 hhvm.conf 文件。# cd /etc/nginx/ # vim hhvm.conf 粘贴以下内容到文件中。location ~ \.(hh|php)$ { root /usr/share/nginx/html; fastcgi_keep_conn on; fastcgi_pass unix:/var/run/hhvm/hhvm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }然后，保存并退出。接下来，编辑 nginx.conf 文件，添加 hhvm 配置文件到 include 行。# vim nginx.conf 添加配置到第 57 行的 server 指令中。include /etc/nginx/hhvm.conf; 保存并退出。然后修改 SELinux 中关于 hhvm 配置文件的权限上下文。# semanage fcontext -a -t httpd_config_t /etc/nginx/hhvm.conf # restorecon -v /etc/nginx/hhvm.conf 测试 Nginx 配置并重启服务。# nginx -t # systemctl restart nginx 记住确保测试配置没有错误。步骤 7 - 通过 HHVM 和 Nginx 创建虚拟主机在这一步中，我们要为 Nginx 和 hhvm 创建一个新的虚拟主机配置文件。这里我使用域名 natsume.co 来作为例子，你可以使用你主机喜欢的域名，并在配置文件中相应位置以及 WordPress 安装过程中进行替换。进入 nginx 的 conf.d 目录，我们将在该目录存储虚拟主机文件。# cd /etc/nginx/conf.d/ 使用 vim 创建一个名为 natsume.conf 的配置文件。# vim natsume.conf 粘贴以下内容到虚拟主机配置文件中。server { listen 80; server_name natsume.co; # note that these lines are originally from the "location /" block root /var/www/hakase; index index.php index.html index.htm; location / { try_files $uri $uri/ =404; } error_page 404 /404.html; location = /50x.html { root /var/www/hakase; } location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/var/run/hhvm/hhvm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } 保存并退出。在这个虚拟主机配置文件中，我们定义该域名的 Web 根目录为 /var/www/hakase。目前该目录还不存在，所有我们要创建它，并变更属主为 nginx 用户和组。# mkdir -p /var/www/hakase # chown -R nginx:nginx /var/www/hakase 接下来，为该文件和目录配置 SELinux 上下文。# semanage fcontext -a -t httpd_config_t "/etc/nginx/conf.d(/.*)?" # restorecon -Rv /etc/nginx/conf.d 最后，测试 nginx 配置文件以确保没有错误后，重启 nginx：# nginx -t # systemctl restart nginx 步骤 8 - 安装 WordPress在步骤 5 的时候，我们已经为 WordPress 配置好了虚拟主机，现在只需要下载 WordPress 和使用我们在步骤 3 的时候创建的数据库和用户来编辑数据库配置就好了。进入 Web 根目录 /var/www/hakase 并使用 Wget 命令下载 WordPress：# cd /var/www/hakase # wget wordpress.org/latest.tar.gz 解压 latest.tar.gz 并将 wordpress 文件夹中所有的文件和目录移动到当前目录：# tar -xzvf latest.tar.gz # mv wordpress/* . 下一步，复制一份 wp-config-sample.php 并更名为 wp-config.php，然后使用 vim 进行编辑：# cp wp-config-sample.php wp-config.php # vim wp-config.php 将 DB_NAME 设置为 wordpressdb、DB_USER 设置为 wpuser 以及 DB_PASSWORD 设置为 wpuser@。define('DB_NAME', 'wordpressdb'); define('DB_USER', 'wpuser'); define('DB_PASSWORD', 'wpuser@'); define('DB_HOST', 'localhost'); 保存并退出。修改关于 WordPress 目录的 SELinux 上下文。# semanage fcontext -a -t httpd_sys_content_t "/var/www/hakase(/.*)?" # restorecon -Rv /var/www/hakase 现在打开 Web 浏览器，在地址栏输入你之前为 WordPress 设置的域名，我这里是 natsume.co。选择语言并点击 继续 Continue 。根据自身要求填写站点标题和描述并点击 安装 Wordpress Install Wordpress "。耐心等待安装完成。你会见到如下页面，点击 登录 Log In 来登录到管理面板。输入你设置的管理员用户账号和密码，在此点击 登录 Log In 。现在你已经登录到 WordPress 的管理面板了。Wordpress 的主页：至此，我们已经在 CentOS 7 上通过 Nginx 和 HHVM 成功安装 Wordpress。参考链接https://www.nginx.com/blog/nginx-se-linux-changes-upgrading-rhel-6-6/译者简介：GHLandy —— 划不完粉腮柳眉泣别离。via: https://www.howtoforge.com/tutorial/how-to-install-wordpress-with-hhvm-and-nginx-on-centos-7/作者：Muhammad Arul 译者：GHLandy 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
今年是我们一起庆祝 SELinux 纪念日的第十个年头了（LCTT 译者注：本文发表于 2013 年）。真是太难以置信了！SELinux 最初在 Fedora Core 3 中被引入，随后加入了红帽企业版 Linux 4。从来没有使用过 SELinux 的家伙，你可要好好儿找个理由了……SElinux 是一个标签型系统。每一个进程都有一个标签。操作系统中的每一个文件/目录 客体 （ object ） 也都有一个标签。甚至连网络端口、设备，乃至潜在的主机名都被分配了标签。我们把控制访问进程的标签的规则写入一个类似文件的客体标签中，这些规则我们称之为 策略 （ policy ） 。内核强制实施了这些规则。有时候这种“强制”被称为 强制访问控制体系 （ Mandatory Access Control ） （MAC）。一个客体的拥有者对客体的安全属性并没有自主权。标准 Linux 访问控制体系，拥有者/分组 + 权限标志如 rwx，常常被称作 自主访问控制 （ Discretionary Access Control ） （DAC）。SELinux 没有文件 UID 或拥有权的概念。一切都被标签控制，这意味着在没有至高无上的 root 权限进程时，也可以设置 SELinux 系统。注意： SELinux 不允许你摒弃 DAC 控制。SELinux 是一个并行的强制模型。一个应用必须同时支持 SELinux 和 DAC 来完成特定的行为。这可能会导致管理员迷惑为什么进程被拒绝访问。管理员被拒绝访问是因为在 DAC 中有些问题，而不是在 SELinux 标签。类型强制让我们更深入的研究下标签。SELinux 最主要的“模型”或“强制”叫做 类型强制 （ type enforcement ） 。基本上这意味着我们根据进程的类型来定义其标签，以及根据文件系统客体的类型来定义其标签。打个比方想象一下在一个系统里定义客体的类型为猫和狗。猫（CAT）和狗（DOG）都是 进程类型 （ process type ） 。我们有一类希望能与之交互的客体，我们称之为食物。而我希望能够为食物增加类型：cat_food （猫的食物）和 dog_food（狗的食物）。作为一个策略制定者，我可以说一只狗有权限去吃狗粮（dog_chow），而一只猫有权限去吃猫粮（cat_chow）。在 SELinux 中我可以将这条规则写入策略中。allow cat cat_chow:food eat;允许 猫 猫粮：食物 吃；allow dog dog_chow:food eat;允许 狗 狗粮：食物 吃；有了这些规则，内核会允许猫进程去吃打上猫粮标签 cat_chow 的食物，允许狗去吃打上狗粮标签 dog_chow 的食物。此外，在 SELinux 系统中，由于禁止是默认规则，这意味着，如果狗进程想要去吃猫粮 cat_chow，内核会阻止它。同理，猫也不允许去接触狗粮。现实例子我们将 Apache 进程标为 httpd_t，将 Apache 上下文标为 httpd_sys_content_t 和 httpdsys_content_rw_t。假设我们把信用卡数据存储在 MySQL 数据库中，其标签为 msyqld_data_t。如果一个 Apache 进程被劫持，黑客可以获得 httpd_t 进程的控制权，从而能够去读取 httpd_sys_content_t 文件并向 httpd_sys_content_rw_t 文件执行写操作。但是黑客却不允许去读信用卡数据（mysqld_data_t），即使 Apache 进程是在 root 下运行。在这种情况下 SELinux 减轻了这次闯入的后果。多类别安全强制打个比方上面我们定义了狗进程和猫进程，但是如果你有多个狗进程：Fido 和 Spot，而你想要阻止 Fido 去吃 Spot 的狗粮 dog_chow 怎么办呢?一个解决方式是创建大量的新类型，如 Fido_dog 和 Fido_dog_chow。但是这很快会变得难以驾驭因为所有的狗都有差不多相同的权限。为了解决这个问题我们发明了一种新的强制形式，叫做 多类别安全 （ Multi Category Security ） （MCS）。在 MCS 中，我们在狗进程和狗粮的标签上增加了另外一部分标签。现在我们将狗进程标记为 dog:random1(Fido) 和 dog:random2(Spot)。我们将狗粮标记为 dog_chow:random1(Fido) 和 dog_chow:random2(Spot)。MCS 规则声明如果类型强制规则被遵守而且该 MCS 随机标签正确匹配，则访问是允许的，否则就会被拒绝。Fido (dog:random1) 尝试去吃 cat_chow:food 被类型强制拒绝了。Fido (dog:random1) 允许去吃 dog_chow:random1。Fido (dog:random1) 去吃 spot(dog_chow:random2)的食物被拒绝。现实例子在计算机系统中我们经常有很多具有同样访问权限的进程，但是我们又希望它们各自独立。有时我们称之为 多租户环境 （ multi-tenant environment ） 。最好的例子就是虚拟机。如果我有一个运行很多虚拟机的服务器，而其中一个被劫持，我希望能够阻止它去攻击其它虚拟机和虚拟机镜像。但是在一个类型强制系统中 KVM 虚拟机被标记为 svirt_t 而镜像被标记为 svirt_image_t。 我们允许 svirt_t 可以读/写/删除标记为 svirt_image_t 的上下文。通过使用 libvirt 我们不仅实现了类型强制隔离，而且实现了 MCS 隔离。当 libvirt 将要启动一个虚拟机时，它会挑选出一个 MCS 随机标签如 s0:c1,c2，接着它会将 svirt_image_t:s0:c1,c2 标签分发给虚拟机需要去操作的所有上下文。最终，虚拟机以 svirt_t:s0:c1,c2 为标签启动。因此，SELinux 内核控制 svirt_t:s0:c1,c2 不允许写向 svirt_image_t:s0:c3,c4，即使虚拟机被一个黑客劫持并接管，即使它是运行在 root 下。我们在 OpenShift 中使用类似的隔离策略。每一个 gear（user/app process）都有相同的 SELinux 类型（openshift_t）（LCTT 译注：gear 为 OpenShift 的计量单位）。策略定义的规则控制着 gear 类型的访问权限，而一个独一无二的 MCS 标签确保了一个 gear 不能影响其他 gear。请观看下面的视频来看 OpenShift gear 切换到 root 会发生什么。多级别安全强制另外一种不经常使用的 SELinux 强制形式叫做 多级别安全 （ Multi Level Security ） （MLS）；它开发于上世纪 60 年代，并且主要使用在受信操作系统上如 Trusted Solaris。其核心观点就是通过进程使用的数据等级来控制进程。一个 secret 进程不能读取 top secret 数据。MLS 很像 MCS，除了它在强制策略中增加了支配的概念。MCS 标签必须完全匹配，但一个 MLS 标签可以支配另一个 MLS 标签并且获得访问。打个比方不讨论不同名字的狗，我们现在来看不同种类。我们现在有一只格雷伊猎犬和一只吉娃娃。我们可能想要允许格雷伊猎犬去吃任何狗粮，但是吉娃娃如果尝试去吃格雷伊猎犬的狗粮可能会被呛到。我们把格雷伊猎犬标记为 dog:Greyhound，把它的狗粮标记为 dog_chow:Greyhound，把吉娃娃标记为 dog:Chihuahua，把它的狗粮标记为 dog_chow:Chihuahua。使用 MLS 策略，我们可以使 MLS 格雷伊猎犬标签支配吉娃娃标签。这意味着 dog:Greyhound 允许去吃 dog_chow:Greyhound 和 dog_chow:Chihuahua。但是 dog:Chihuahua 不允许去吃 dog_chow:Greyhound。当然，由于类型强制， dog:Greyhound 和 dog:Chihuahua 仍然不允许去吃 cat_chow:Siamese，即使 MLS 类型 GreyHound 支配 Siamese。现实例子有两个 Apache 服务器：一个以 httpd_t:TopSecret 运行，一个以 httpd_t:Secret 运行。如果 Apache 进程 httpd_t:Secret 被劫持，黑客可以读取 httpd_sys_content_t:Secret 但会被禁止读取 httpd_sys_content_t:TopSecret。但是如果运行 httpd_t:TopSecret 的 Apache 进程被劫持，它可以读取 httpd_sys_content_t:Secret 数据和 httpd_sys_content_t:TopSecret 数据。我们在军事系统上使用 MLS，一个用户可能被允许读取 secret 数据，但是另一个用户在同一个系统上可以读取 top secret 数据。结论SELinux 是一个功能强大的标签系统，控制着内核授予每个进程的访问权限。最主要的特性是类型强制，策略规则定义的进程访问权限基于进程被标记的类型和客体被标记的类型。也引入了另外两个控制手段，分离有着同样类型进程的叫做 MCS，而 MLS，则允许进程间存在支配等级。*所有的漫画都来自 Máirín Duffy作者简介：Daniel J Walsh - Daniel Walsh 已经在计算机安全领域工作了将近 30 年。Daniel 于 2001 年 8 月加入红帽。via: https://opensource.com/business/13/11/selinux-policy-guide作者：Daniel J Walsh 译者：xiaow6 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
在 Linux 上用 SELinux 或 AppArmor 实现强制访问控制（MAC）
为了解决标准的“用户-组-其他/读-写-执行”权限以及访问控制列表的限制以及加强安全机制，美国国家安全局（NSA）设计出一个灵活的 强制访问控制 （ Mandatory Access Control ） （MAC）方法 SELinux（Security Enhanced Linux 的缩写），来限制标准的权限之外的种种权限，在仍然允许对这个控制模型后续修改的情况下，让进程尽可能以最小权限访问或在系统对象（如文件，文件夹，网络端口等）上执行其他操作。SELinux 和 AppArmor 加固 Linux 安全另一个流行并且被广泛使用的 MAC 是 AppArmor，相比于 SELinux 它提供更多的特性，包括一个学习模式，可以让系统“学习”一个特定应用的行为，以及通过配置文件设置限制实现安全的应用使用。在 CentOS 7 中，SELinux 合并进了内核并且默认启用 强制 （ Enforcing ） 模式（下一节会介绍这方面更多的内容），与之不同的是，openSUSE 和 Ubuntu 使用的是 AppArmor 。在这篇文章中我们会解释 SELinux 和 AppArmor 的本质，以及如何在你选择的发行版上使用这两个工具之一并从中获益。SELinux 介绍以及如何在 CentOS 7 中使用Security Enhanced Linux 可以以两种不同模式运行： 强制 （ Enforcing ） ：这种情况下，SELinux 基于 SELinux 策略规则拒绝访问，策略规则是一套控制安全引擎的规则。 宽容 （ Permissive ） ：这种情况下，SELinux 不拒绝访问，但如果在强制模式下会被拒绝的操作会被记录下来。SELinux 也能被禁用。尽管这不是它的一个操作模式，不过也是一种选择。但学习如何使用这个工具强过只是忽略它。时刻牢记这一点！使用 getenforce 命令来显示 SELinux 的当前模式。如果你想要更改模式，使用 setenforce 0（设置为宽容模式）或 setenforce 1（强制模式）。因为这些设置重启后就失效了，你需要编辑 /etc/selinux/config 配置文件并设置 SELINUX 变量为 enforcing、permissive 或 disabled ，保存设置让其重启后也有效：如何启用和禁用 SELinux 模式还有一点要注意，如果 getenforce 返回 Disabled，你得编辑 /etc/selinux/config 配置文件为你想要的操作模式并重启。否则你无法利用 setenforce 设置（或切换）操作模式。setenforce 的典型用法之一包括在 SELinux 模式之间切换（从强制到宽容或相反）来定位一个应用是否行为不端或没有像预期一样工作。如果它在你将 SELinux 设置为宽容模式正常工作，你就可以确定你遇到的是 SELinux 权限问题。有两种我们使用 SELinux 可能需要解决的典型案例：改变一个守护进程监听的默认端口。给一个虚拟主机设置 /var/www/html 以外的文档根路径值。让我们用以下例子来看看这两种情况。例 1：更改 sshd 守护进程的默认端口大部分系统管理员为了加强服务器安全首先要做的事情之一就是更改 SSH 守护进程监听的端口，主要是为了阻止端口扫描和外部攻击。要达到这个目的，我们要更改 /etc/ssh/sshd_config 中的 Port 值为以下值（我们在这里使用端口 9999 为例）：Port 9999 在尝试重启服务并检查它的状态之后，我们会看到它启动失败：# systemctl restart sshd # systemctl status sshd 检查 SSH 服务状态如果我们看看 /var/log/audit/audit.log，就会看到 sshd 被 SELinux 阻止在端口 9999 上启动，因为它是 JBoss 管理服务的保留端口（SELinux 日志信息包含了词语“AVC”，所以应该很容易把它同其他信息区分开来）：# cat /var/log/audit/audit.log | grep AVC | tail -1 检查 Linux 审计日志在这种情况下大部分人可能会禁用 SELinux，但我们不这么做。我们会看到有个让 SELinux 和监听其他端口的 sshd 和谐共处的方法。首先确保你有 policycoreutils-python 这个包，执行：# yum install policycoreutils-python 查看 SELinux 允许 sshd 监听的端口列表。在接下来的图片中我们还能看到端口 9999 是为其他服务保留的，所以我们暂时无法用它来运行其他服务：# semanage port -l | grep ssh 当然我们可以给 SSH 选择其他端口，但如果我们确定我们不会使用这台机器跑任何 JBoss 相关的服务，我们就可以修改 SELinux 已存在的规则，转而给 SSH 分配那个端口：# semanage port -m -t ssh_port_t -p tcp 9999 这之后，我们就可以用前一个 semanage 命令检查端口是否正确分配了，即使用 -lC 参数（list custom 的简称）：# semanage port -lC # semanage port -l | grep ssh 给 SSH 分配端口我们现在可以重启 SSH 服务并通过端口 9999 连接了。注意这个更改重启之后依然有效。例 2：给一个虚拟主机设置 /var/www/html 以外的 文档根路径 （ DocumentRoot ） 如果你需要用除 /var/www/html 以外目录作为 文档根目录 （ DocumentRoot ） 设置一个 Apache 虚拟主机（也就是说，比如 /websrv/sites/gabriel/public_html）：DocumentRoot “/websrv/sites/gabriel/public_html” Apache 会拒绝提供内容，因为 index.html 已经被标记为了 default_t SELinux 类型，Apache 无法访问它：# wget http://localhost/index.html # ls -lZ /websrv/sites/gabriel/public_html/index.html 被标记为 default\_t SELinux 类型和之前的例子一样，你可以用以下命令验证这是不是 SELinux 相关的问题：# cat /var/log/audit/audit.log | grep AVC | tail -1 检查日志确定是不是 SELinux 的问题要将 /websrv/sites/gabriel/public_html 整个目录内容标记为 httpd_sys_content_t，执行：# semanage fcontext -a -t httpd_sys_content_t "/websrv/sites/gabriel/public_html(/.*)?" 上面这个命令会赋予 Apache 对那个目录以及其内容的读取权限。最后，要应用这条策略（并让更改的标记立即生效），执行：# restorecon -R -v /websrv/sites/gabriel/public_html 现在你应该可以访问这个目录了：# wget http://localhost/index.html 访问 Apache 目录要获取关于 SELinux 的更多信息，参阅 Fedora 22 中的 SELinux 用户及管理员指南。AppArmor 介绍以及如何在 OpenSUSE 和 Ubuntu 上使用它AppArmor 的操作是基于写在纯文本文件中的规则定义，该文件中含有允许权限和访问控制规则。安全配置文件用来限制应用程序如何与系统中的进程和文件进行交互。系统初始就提供了一系列的配置文件，但其它的也可以由应用程序在安装的时候设置或由系统管理员手动设置。像 SELinux 一样，AppArmor 以两种模式运行。在 强制 （ enforce ） 模式下，应用被赋予它们运行所需要的最小权限，但在 抱怨 （ complain ） 模式下 AppArmor 允许一个应用执行受限的操作并将操作造成的“抱怨”记录到日志里（/var/log/kern.log，/var/log/audit/audit.log，和其它放在 /var/log/apparmor 中的日志）。日志中会显示配置文件在强制模式下运行时会产生错误的记录，它们中带有 audit 这个词。因此，你可以在 AppArmor 的 强制 （ enforce ） 模式下运行之前，先在 抱怨 （ complain ） 模式下尝试运行一个应用并调整它的行为。可以用这个命令显示 AppArmor 的当前状态：$ sudo apparmor_status 查看 AppArmor 的状态上面的图片指明配置 /sbin/dhclient，/usr/sbin/，和 /usr/sbin/tcpdump 等处在 强制 （ enforce ） 模式下（在 Ubuntu 下默认就是这样的）。因为不是所有的应用都包含相关的 AppArmor 配置，apparmor-profiles 包给其它没有提供限制的包提供了配置。默认它们配置在 抱怨 （ complain ） 模式下运行，以便系统管理员能够测试并选择一个所需要的配置。我们将会利用 apparmor-profiles，因为写一份我们自己的配置已经超出了 LFCS 认证的范围了。但是，由于配置都是纯文本文件，你可以查看并学习它们，为以后创建自己的配置做准备。AppArmor 配置保存在 /etc/apparmor.d 中。让我们来看看这个文件夹在安装 apparmor-profiles 之前和之后有什么不同：$ ls /etc/apparmor.d 查看 AppArmor 文件夹内容如果你再次执行 sudo apparmor_status，你会在 抱怨 （ complain ） 模式看到更长的配置文件列表。你现在可以执行下列操作。将当前在 强制 （ enforce ） 模式下的配置文件切换到 抱怨 （ complain ） 模式：$ sudo aa-complain /path/to/file 以及相反的操作（抱怨 –> 强制）：$ sudo aa-enforce /path/to/file 上面这些例子是允许使用通配符的。举个例子：$ sudo aa-complain /etc/apparmor.d/* 会将 /etc/apparmor.d 中的所有配置文件设置为 抱怨 （ complain ） 模式，反之$ sudo aa-enforce /etc/apparmor.d/* 会将所有配置文件设置为 强制 （ enforce ） 模式。要完全禁用一个配置，在 /etc/apparmor.d/disabled 目录中创建一个符号链接：$ sudo ln -s /etc/apparmor.d/profile.name /etc/apparmor.d/disable/ 要获取关于 AppArmor 的更多信息，参阅官方的 AppArmor wiki 以及 Ubuntu 提供的文档。总结在这篇文章中我们学习了一些 SELinux 和 AppArmor 这两个著名的强制访问控制系统的基本知识。什么时候使用两者中的一个或是另一个？为了避免提高难度，你可能需要考虑专注于你选择的发行版自带的那一个。不管怎样，它们会帮助你限制进程和系统资源的访问，以提高你服务器的安全性。关于本文你有任何的问题，评论，或建议，欢迎在下方发表。不要犹豫，让我们知道你是否有疑问或评论。via: http://www.tecmint.com/mandatory-access-control-with-selinux-or-apparmor-linux/作者：Gabriel Cánepa 译者：alim0x 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
回到 Kernel 2.6 时代，那时候引入了一个新的安全系统，用以提供访问控制安全策略的机制。这个系统就是 Security Enhanced Linux (SELinux)，它是由美国国家安全局（NSA）贡献的，它为 Linux 内核子系统引入了一个健壮的 强制控制访问 （ Mandatory Access Control ） 架构。如果你在之前的 Linux 生涯中都禁用或忽略了 SELinux，这篇文章就是专门为你写的：这是一篇对存在于你的 Linux 桌面或服务器之下的 SELinux 系统的介绍，它能够限制权限，甚至消除程序或守护进程的脆弱性而造成破坏的可能性。在我开始之前，你应该已经了解的是 SELinux 主要是红帽 Red Hat Linux 以及它的衍生发行版上的一个工具。类似地， Ubuntu 和 SUSE（以及它们的衍生发行版）使用的是 AppArmor。SELinux 和 AppArmor 有显著的不同。你可以在 SUSE，openSUSE，Ubuntu 等等发行版上安装 SELinux，但这是项难以置信的挑战，除非你十分精通 Linux。说了这么多，让我来向你介绍 SELinux。DAC vs. MACLinux 上传统的访问控制标准是 自主访问控制 （ Discretionary Access Control ） （DAC）。在这种形式下，一个软件或守护进程以 User ID（UID）或 Set owner User ID（SUID）的身份运行，并且拥有该用户的目标（文件、套接字、以及其它进程）权限。这使得恶意代码很容易运行在特定权限之下，从而取得访问关键的子系统的权限。另一方面， 强制访问控制 （ Mandatory Access Control ） （MAC）基于保密性和完整性强制信息的隔离以限制破坏。该限制单元独立于传统的 Linux 安全机制运作，并且没有超级用户的概念。SELinux 如何工作考虑一下 SELinux 的相关概念: 主体 （ Subjects ） 目标 （ Objects ） 策略 （ Policy ） 模式 （ Mode ） 当一个 主体 （ Subject ） （如一个程序）尝试访问一个 目标 （ Object ） （如一个文件）， SELinux 安全服务器 （ SELinux Security Server ） （在内核中）从 策略数据库 （ Policy Database ） 中运行一个检查。基于当前的 模式 （ mode ） ，如果 SELinux 安全服务器授予权限，该主体就能够访问该目标。如果 SELinux 安全服务器拒绝了权限，就会在 /var/log/messages 中记录一条拒绝信息。听起来相对比较简单是不是？实际上过程要更加复杂，但为了简化介绍，只列出了重要的步骤。模式SELinux 有三个模式（可以由用户设置）。这些模式将规定 SELinux 在主体请求时如何应对。这些模式是： Enforcing （ 强制 ） — SELinux 策略强制执行，基于 SELinux 策略规则授予或拒绝主体对目标的访问 Permissive （ 宽容 ） — SELinux 策略不强制执行，不实际拒绝访问，但会有拒绝信息写入日志 Disabled （ 禁用 ） — 完全禁用 SELinux图 1：getenforce 命令显示 SELinux 的状态是 Enforcing 启用状态。默认情况下，大部分系统的 SELinux 设置为 Enforcing。你要如何知道你的系统当前是什么模式？你可以使用一条简单的命令来查看，这条命令就是 getenforce。这个命令用起来难以置信的简单（因为它仅仅用来报告 SELinux 的模式）。要使用这个工具，打开一个终端窗口并执行 getenforce 命令。命令会返回 Enforcing、Permissive，或者 Disabled（见上方图 1）。设置 SELinux 的模式实际上很简单——取决于你想设置什么模式。记住：永远不推荐关闭 SELinux。为什么？当你这么做了，就会出现这种可能性：你磁盘上的文件可能会被打上错误的权限标签，需要你重新标记权限才能修复。而且你无法修改一个以 Disabled 模式启动的系统的模式。你的最佳模式是 Enforcing 或者 Permissive。你可以从命令行或 /etc/selinux/config 文件更改 SELinux 的模式。要从命令行设置模式，你可以使用 setenforce 工具。要设置 Enforcing 模式，按下面这么做：打开一个终端窗口执行 su 然后输入你的管理员密码执行 setenforce 1执行 getenforce 确定模式已经正确设置（图 2）图 2：设置 SELinux 模式为 Enforcing。要设置模式为 Permissive，这么做：打开一个终端窗口执行 su 然后输入你的管理员密码执行 setenforce 0执行 getenforce 确定模式已经正确设置（图 3）图 3：设置 SELinux 模式为 Permissive。注：通过命令行设置模式会覆盖 SELinux 配置文件中的设置。如果你更愿意在 SELinux 命令文件中设置模式，用你喜欢的编辑器打开那个文件找到这一行：SELINUX=permissive 你可以按你的偏好设置模式，然后保存文件。还有第三种方法修改 SELinux 的模式（通过 bootloader），但我不推荐新用户这么做。策略类型SELinux 策略有两种： Targeted （ 目标 ） — 只有目标网络进程（dhcpd，httpd，named，nscd，ntpd，portmap，snmpd，squid，以及 syslogd）受保护 Strict （ 严格 ） — 对所有进程完全的 SELinux 保护你可以在 /etc/selinux/config 文件中修改策略类型。用你喜欢的编辑器打开这个文件找到这一行：SELINUXTYPE=targeted 修改这个选项为 targeted 或 strict 以满足你的需求。检查完整的 SELinux 状态有个方便的 SELinux 工具，你可能想要用它来获取你启用了 SELinux 的系统的详细状态报告。这个命令在终端像这样运行：sestatus -v 你可以看到像图 4 那样的输出。图 4：sestatus -v 命令的输出。仅是皮毛和你预想的一样，我只介绍了 SELinux 的一点皮毛。SELinux 的确是个复杂的系统，想要更扎实地理解它是如何工作的，以及了解如何让它更好地为你的桌面或服务器工作需要更加地深入学习。我的内容还没有覆盖到疑难解答和创建自定义 SELinux 策略。SELinux 是所有 Linux 管理员都应该知道的强大工具。现在已经向你介绍了 SELinux，我强烈推荐你回到 Linux.com（当有更多关于此话题的文章发表的时候）或看看 NSA SELinux 文档 获得更加深入的指南。LCTT - 相关阅读：鸟哥的 Linux 私房菜——程序管理与 SELinux 初探via: https://www.linux.com/learn/docs/ldp/883671-an-introduction-to-selinux作者：Jack Wallen 译者：alim0x 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出