使用 Ansible 进行安全加固

作者:Mark Dotson

Ansible 是 Michael DeHaan 和其他人在 2012 年开发和发布的开源自动化工具。DeHaan 称其为“通用自动化管道”(有关文章“Ansible 的架构:超越配置管理”的链接,请参阅“资源”)。它不仅可以用于自动化配置管理,而且还擅长编排、系统配置、零停机滚动更新和应用程序部署。Ansible 可以用于保持所有系统配置完全符合您的要求,如果您有许多相同的系统,Ansible 将确保它们保持相同。对于 Linux 系统管理员来说,Ansible 是实施和维护强大安全态势不可或缺的工具。

Ansible 可以使用安全 Shell (SSH) 而不是其他配置管理软件包(如 Puppet 和 Chef)使用的更常见的客户端-服务器方法来部署和配置多台 Linux 服务器(Red Hat、Debian、CentOS、OS X、任何 BSD 和其他系统)(Chef 确实有一个不需要服务器的单机版本)。使用 SSH 是一种更安全的方法,因为流量是加密的。安全 Shell 传输层协议用于 Ansible 服务器和目标主机之间的通信。身份验证使用 Kerberos、公钥身份验证或密码完成。

多年前,当我开始从事系统管理工作时,一位资深同事给了我一个简单的成功公式。他说:“记住,自动化,自动化,自动化。” 如果这是真的,我相信这是真的,那么 Ansible 可以成为任何管理员职业生涯中取得成功的关键工具。如果您没有一些真正优秀的自动化工具,则每项任务都必须手动完成。这会浪费大量时间,而时间是宝贵的。Ansible 使管理许多服务器几乎毫不费力成为可能。

Ansible 使用一种非常简单的方法,称为 playbook 来编排配置。Playbook 是一组用 YAML 编写的指令,告诉 Ansible 服务器要在目标主机上执行哪些“剧本”。YAML 是一种非常简单、人类可读的标记语言,在设置配置方案时,它为用户提供了精细的粒度。它与 Ansible 一起作为依赖项安装。Ansible 使用 YAML 是因为它比常见的数据格式(如 JSON 和 XML)更容易编写。YAML 的学习曲线非常低,因此可以很快掌握。例如,图 1 中显示的简单 playbook 使目标 Web 服务器上的 Apache RPM 保持最新状态。

图 1. 将 Apache 升级到最新版本的示例 Playbook

从 Ansible 管理服务器,您可以创建一个 cron 作业,定期将 playbook 推送到目标主机,从而确保您始终拥有最新版本的 Apache Web 服务器。

使用 YAML,您可以指示 Ansible 定位特定的服务器组、您要以其身份运行的远程用户、要分配的任务以及许多其他详细信息。您可以为每个任务命名,这使得 playbook 更易于阅读。您可以设置变量,并使用循环和条件语句。如果您更新了需要重启服务的配置文件,Ansible 会使用称为处理程序的任务来通知系统需要重启服务。处理程序也可以用于其他事情,但这是最常见的。

重用先前编写的 playbook 中的某些任务的能力是另一个很棒的功能。Ansible 使用称为角色的机制来实现这一点。角色是组织单元,用于在主机组上实现特定的配置。一个角色可以包括一组变量值、处理程序和任务,这些值、处理程序和任务可以分配给主机组,或与特定模式对应的主机。例如,您可以创建一个角色,用于在一组目标服务器上安装和配置 MySQL。角色使这项任务变得非常简单。

除了智能自动化之外,您还可以使用 Ansible 的临时命令同时联系所有目标主机。临时命令可以在命令行上执行。当您想查看所有目标机器或仅其中一部分的特定类型的输出时,这是一种非常快速的方法。例如,如果您想查看名为 dbservers 的组中所有主机的运行时间,您将以 root 用户身份键入


# ansible dbservers -a /usr/bin/uptime

输出结果将如图 2 所示。

图 2. 显示所有目标的运行时间输出的临时命令示例

如果要指定特定用户,请按以下方式使用命令


# ansible dbservers -a /usr/bin/uptime -u username

如果您以特定用户身份运行命令,但想以 root 用户身份执行操作,则可以通过 sudo 运行它,并让 Ansible 询问 root 密码


# ansible dbservers -a /usr/bin/uptime -u username 
 ↪--sudo [ask-sudo-pass]

您还可以使用 -U 选项切换到其他用户


# ansible dbservers -a /usr/bin/uptime -u username 
 ↪-U otheruser --sudo
# [ask-sudo-pass]

有时,您可能希望使用 12 个并行 fork 或进程运行命令


# ansible dbservers -a /usr/bin/uptime -f 12

这将通过使用 12 个并发进程而不是默认值 5 来更快地完成作业。如果您想为 fork 数量设置永久默认值,则可以在 Ansible 配置文件中设置它,该文件位于 /etc/ansible/ansible.cfg。

也可以通过使用 -m 选项在临时模式下使用 Ansible 模块。在此示例中,Ansible 使用 ping 模块 ping 目标主机


# ansible dbservers -m ping

图 3. 在此示例中,Ansible 使用 ping 模块 ping 目标主机。

在我撰写本文时,Michael DeHaan 宣布,在几周后,将向 Ansible 1.5 版本添加一个新的命令行工具,该工具将能够加密配置中的各种数据。新工具将称为 ansible-vault。它将通过使用新的 --ask-vault-pass 选项来实现。根据 DeHaan 的说法,您在 YAML 中为配置编写的任何内容都可以使用密码通过 ansible-vault 进行加密。

服务器安全加固对于任何 IT 企业都至关重要。我们必须面对这样一个事实,即我们正在保护的资产已经成为了信息战区。几乎每天,我们都会听到企业系统沦为恶意个人的牺牲品。Ansible 可以帮助我们管理员保护我们的系统。我已经开发了一种非常简单的方法来使用 Ansible 以及一个名为 Aqueduct 的开源项目来加固 RHEL6 Linux 服务器。这些机器按照国防信息系统局 (DISA) 制定的标准进行保护。DISA 发布了针对各种操作系统的安全技术实施指南 (STIG),为管理员提供了保护系统的可靠指南。

在典型的客户端-服务器设置中,远程客户端守护程序与服务器守护程序通信。通常,这种通信是明文的(未加密),尽管 Puppet 和 Chef 有他们自己的专有机制来加密流量。SSH 中公钥身份验证 (PKI) 的实施多年来已经过安全专家和系统管理员的充分审查。出于我的目的,我强烈偏好 SSH。通常,使用专有客户端-服务器守护程序比使用 SSH 的风险更大。它们可能相对较新,并且可能会被使用缓冲区溢出攻击策略或拒绝服务攻击的恶意个人攻陷。任何时候我们可以减少服务器上运行的服务总数,它都会更安全。

要安装当前版本的 Ansible(在撰写本文时为 1.4.3),您将需要 Python 2.4 或更高版本以及企业 Linux 附加软件包 (EPEL) 存储库 RPM。为了本文的目的,我将 Ansible 与另一个名为 Aqueduct 的开源项目中的一组脚本一起使用。然而,这不是 Ansible 的要求。如果您尚未使用 Git,您还需要安装 Git。Git 将用于拉取 Aqueduct 软件包。

Fotis Networks 的高级安全架构师 Vincent Passaro 主导了 Aqueduct 项目,该项目包括 bash 脚本和 Puppet 清单的开发。这些脚本和清单旨在部署 STIG 中提供的加固指南。还包括 CIS(互联网安全中心)基准和其他几个基准。在 Aqueduct 首页,Passaro 说:“内容目前正在(由我)为 Red Hat Enterprise Linux 5 (RHEL 5) 草案 STIG、CIS 基准、NISPOM、PCI 开发”,但我还找到了 RHEL6 bash 脚本。我将这些 bash 脚本组合起来,构建了一个非常基本的 Ansible playbook,以简化 RHEL6 系统的安全加固。我通过使用包含的名为 script 的 Ansible 模块完成了这项工作。

根据 Ansible 文档,“script 模块接受脚本名称,后跟以空格分隔的参数列表。路径中的本地脚本将被传输到远程节点,然后执行。给定的脚本将在远程节点上的 shell 环境中处理。与 raw 模块非常相似,此模块不需要远程系统上的 Python。”

Ansible 模块是 API 用于执行任务的特定用途的小代码片段。文档指出,“Ansible 模块是可重用的魔法单元,可以被 Ansible API 或 ansible 或 ansible-playbook 程序使用。” 我认为它们非常像函数或子例程。Ansible 附带了许多准备就绪的模块供使用。管理员还可以使用任何编程语言编写模块以满足特定需求。许多 Ansible 模块是幂等的,这意味着如果不需要进行更改,它们不会对您的系统进行更改。换句话说,重复运行这些模块是安全的,不必担心它们会破坏东西。例如,默认情况下,运行一个设置某个文件权限的 playbook 将仅在该文件的权限与 playbook 中指定的权限不同时更新该文件的权限。

对于我的需求,script 模块工作完美。每个 Aqueduct bash 脚本都对应于 STIG 文档中给出的加固建议。这些脚本根据 STIG 文档的编号部分命名。

在我的测试环境中,我有一个小型高性能计算集群,由一个管理节点和十个计算节点组成。对于此测试,SSH 服务器守护程序配置为 root 用户的公钥身份验证。要在 RHEL6 上安装 Ansible,必须首先安装 EPEL 存储库。从 EPEL 站点下载 EPEL RPM(请参阅“资源”)。

然后,在您的管理节点上安装它


# rpm -ivh epel-release-6-8.noarch.rpm

现在,您已准备好安装 Ansible


# yum install ansible

Ansible 的主配置文件位于 /etc/ansible/ansible.cfg。除非您想添加自己的自定义设置,否则可以使用默认设置对其进行配置。

现在,在 /etc/ansible 中创建一个名为 prod 的目录。您将在其中复制 Aqueduct STIG bash 脚本。此外,在 /etc/ansible 中创建一个名为 plays 的目录,您将在其中保存 Ansible playbook。创建另一个名为 manual-check 的目录。这将保存包含必须手动检查的信息的脚本。接下来,必须在 /etc/ansible 中创建一个 hosts 文件。它简称为 hosts。图 4 显示了我是如何为十个计算节点配置它的。

图 4. 我的测试集群的 /etc/hosts 文件

八个计算节点是典型的节点,但两个配备了 GPGPU,因此有两个组:“hosts”和“gpus”。提供每个节点的 IP 地址(如果您的 DNS 设置正确,也可以提供主机名)。通过这个微小的配置,Ansible 现在就可以工作了。要测试它,请在临时模式下使用 Ansible,并在您的管理节点上执行以下命令


# ansible all -m ping

如果这导致每个主机都显示“success”消息,则一切正常。

必须使用 Git 下载 Aqueduct 脚本。如果您的管理节点上没有 Git,则


# yum install git

Git “是一个分布式版本控制和源代码管理 (SCM) 系统,重点是速度”(维基百科)。用于获取 Aqueduct 软件包的脚本和清单的命令行如下所示


# git clone git://git.fedorahosted.org/git/aqueduct.git

这将在当前目录下创建一个名为 aqueduct 的目录。RHEL6 的 bash 脚本位于 aqueduct/compliance/bash/stig/rhel-6/prod 中。现在,将所有脚本复制到 /etc/ansible/prod。STIG 的某些其他方面需要通过手动运行脚本或阅读脚本并执行所需的操作来检查。这些脚本位于 aqueduct/compliance/bash/stig/rhel-6/manual-check 中。将这些脚本复制到 /etc/ansible/manual-check。

现在脚本已就位,必须编写 playbook 以将其部署到所有目标主机。将 playbook 复制到 /etc/ansible/plays。确保所有脚本都是可执行的。图 5 显示了我的名为 aqueduct.yml 的简单 playbook 的内容。

图 5. 在所有目标上执行 STIG 脚本的简单 Playbook

在一些 STIG 脚本中,需要进行一些编辑才能使其正确执行。诚然,更优雅的解决方案是用自定义 Ansible 模块替换 STIG 脚本。然而,目前,我正在采取更简单的方法,即从我的自定义 Ansible playbook 中调用 STIG 脚本,如上所述。script 模块使这成为可能。接下来,只需在管理节点上使用以下命令执行 playbook


# ansible-playbook aqueduct.yml

此操作在我的十个节点上大约需要五分钟才能运行,前提是剧本在目标主机上并行运行。Ansible 生成详细的输出,显示每个剧本和主机的进度。当 Ansible 完成剧本运行时,所有目标机器都应以相同方式加固,并显示摘要。在这种情况下,一切都运行成功。

图 6. 显示 STIG Playbook 成功执行的输出

对于系统安全加固,Ansible 和 Aqueduct 的组合是保持系统免受入侵者侵害的强大生产力。

如果您曾经担任过系统管理员,您就会知道像这样的工具可以节省多少时间。我对 Ansible 了解得越多,它就变得越有用。我一直在思考实施它的新方法。随着我的系统管理职责更多地转向使用虚拟技术,我计划使用 Ansible 来快速配置和管理我的虚拟配置。我还正在寻找更多途径来探索如何管理高性能计算系统,因为这是我的主要职责。Michael DeHaan 开发了另一个名为 Cobbler 的工具,它非常适合利用 Red Hat 的安装方法 Kickstart 来快速构建系统。Cobbler 和 Ansible 一起创建了一个令人印象深刻的系统管理武器库。

作为系统管理员,我们生活在一个激动人心的时代。富有创造力的开发人员正在发明一系列令人惊叹的工具,这些工具不仅使我们的工作更轻松,而且更有趣。我只能想象未来会怎样。但有一点是肯定的:我们将负责越来越多的系统。这归功于 Ansible 等技术的自动化魔力,这些技术使单个管理员能够管理数百甚至数千台服务器。这些工具只会不断改进,就像它们一直以来所做的那样。随着安全变得越来越重要,它们的重要性只会增加。

资源

Ansible 的架构:超越配置管理: http://blog.ansibleworks.com/2013/11/29/ansibles-architecture-beyond-configuration-management

Michael DeHaan 的博客: http://michaeldehaan.net

Git 主页: https://git-scm.cn

Aqueduct 主页: http://www.vincentpassaro.com/open-source-projects/aqueduct-red-hat-enterprise-linux-security-development

Ansible 文档: https://docs.ansible.org.cn/index.html

EPEL 存储库主页: https://fedoraproject.org/wiki/EPEL

DISA RHEL6 STIG: http://iase.disa.mil/stigs/os/unix/red_hat.html

加载 Disqus 评论