红帽 Ansible 自动化平台是一个用于实施企业级自动化的平台,因此也是满足安全审计需求的一款理想工具。安全防护包含多个层面,但本文着重探讨如何缓解受管主机上 SSH 攻击的风险。尽管安全风险无法完全消除,但您可以通过强化受管主机来尽可能降低其中一部分风险(尤其是暴力攻击),并缓解其他风险(通过仅允许来自授权主机的 SSH 连接、强制执行 sudo 等措施)。本文采用了 Ansible 自动化平台,而大部分强化配置会应用于受管主机(编辑 sshd_config、sssd.conf 和 access.conf 等文件),因此,您可以将这些配置概念应用到其他集中式配置工具中,如红帽卫星等。
本文演示了如何使用此模式来强化受管主机配置:
- 在 AD/LDAP 中创建多个服务帐户来通过 SSH 登录主机:
- 存储在 AD/LDAP 中的公钥用于 SSH 登录公钥身份验证
- 存储在 AD/LDAP 中的密码仅用于 sudo(不适用于 SSH 登录)
- 在任何受管主机上:
- 服务帐户只能从 Ansible 自动化平台执行节点进行登录(从其他任何位置尝试登录都会遭到拒绝)
- 使用 sudo 对任何服务帐户进行特权升级都需要提供密码

设置
首先实施标准的非强化部署,这通常包括:
- 一个 Ansible 自动化平台服务帐户
- 用于通过 SSH 登录主机
- 在 AD/LDAP 中创建并具有一个随机密码
- 在任何主机上:
- 服务帐户可以使用密码进行登录
- 服务帐户可以不用密码执行 sudo
强化配置
许多公司仅为每一项服务创建一个服务帐户。在这个 Ansible 自动化平台场景中,我们只创建了一个服务帐户,供 Ansible 自动化平台用于连接所有受管主机。但是,倘若此服务帐户因任何原因而被泄露,攻击者就能够访问任何受管主机。
这是您必须完成的第一个更改。安全防护是分层的,其中一个重要的基础步骤就是创建多个不同的服务帐户。实施这一步骤并没有一种通用的方法。请检查您的架构,并根据您的基础架构确定一种最可行的方法。以下是创建不同服务帐户的一些常见策略:
- 位置或数据中心:为每个数据中心创建一个服务帐户
- 部门或域:为每个部门或域创建一个服务帐户
- 操作系统:为每种主机类型(红帽企业 Linux 7、8、9 等)创建一个服务帐户
- 用途:为主应用的每种主机用途(数据库、Apache、Kafka)创建一个服务帐户
- 安全性:为每个安全区域(DMZ、内部区域 1 等)创建一个服务帐户
为所有服务帐户创建一个通用组。这样,您可以更轻松地允许一个服务帐户,同时拒绝对所有其他帐户的访问。
使用 AD/LDAP 的 SSH 公钥身份验证
基于公钥来进行服务帐户的 SSH 身份验证。尽管与密码相比,公钥存在一些不足之处,但采用密钥验证机制可以消除 SSH 登录暴力攻击效果。
首先,将各个服务帐户的 SSH 公钥添加到 AD/LDAP 中 altSecurityIdentities
属性。
在每一受管主机上,将 ssh 附加到 /etc/sssd/sssd.conf
中的服务列表:
services = nss, pam, ssh
将 ldap_user_extra_attrs
和 ldap_user_ssh_public_key
参数添加到 /etc/sssd/sssd.conf
的 [domain]
部分中:
[domain/example.com] ldap_user_extra_attrs = altSecurityIdentities ldap_user_ssh_public_key = altSecurityIdentities
AuthorizedKeysCommandUser
选项指定用于运行 AuthorizedKeysCommand
的用户账户。建议您为此使用一个专用的用户,因此请将以下 SSH 参数添加到 /etc/ssh/sshd_config
中:
AuthorizedKeysCommand /usr/bin/sss_ssh_authorizedkeys AuthorizedKeysCommandUser nobody
如需更多信息,请参阅红帽客户门户上的在 Active Directory 中存储用户 SSH 密钥以进行 SSH 身份验证。
拒绝密码身份验证
将以下 SSH 参数添加到所有受管主机上的 /etc/ssh/sshd_config
中,以拒绝使用 SSH 密码进行身份验证(将<Service Account>
Match User <Service Account> PasswordAuthentication no Match all
执行 sudo 需要密码
对于 sudo,要求提供服务帐户的密码。为此,请在 /etc/sudoers.d
中创建一个以服务帐户组命名的新文件,并添加如下这一行:
%<Service Account Group> ALL=(ALL:ALL) ALL
例如,如果组名称为 aapsas
:
$ cat /etc/sudoers.d/aapsas %appsas ALL=(ALL:ALL) ALL
虽然安全防护最佳实践建议仅添加一些被允许的特定命令来运行 sudo,但 Ansible 自动化平台无法做到这一点。对于受管主机,Ansible 自动化平台与目标计算机通信(最常见的是通过 SSH),并且复制和执行一个 Python 脚本。
允许来自授权 Ansible 自动化平台执行节点的连接
最后的强化配置是,仅允许服务帐户从 Ansible 自动化平台执行节点或 LOCAL
(用于 sudo)建立 SSH 连接。为此,您可以在 /etc/security/access.conf 中添加一行内容。第一行允许来自 Ansible 自动化平台和 LOCAL 的连接,另一行则禁止所有其他服务帐户。
+: <Service Account> : <AAP Execution Nodes IPS> LOCAL -: <Service Account Group> : ALL
自动完成所有配置
本文提供了为 SSH 登录进行受管主机强化所需的步骤,但这是 Ansible 自动化平台,因此您不必全部手动完成。这里介绍的所有配置步骤都可以使用模板模块来轻松实现自动化。为配置文件 /etc/security/access.conf
、/etc/sssd/sssd.conf
和 /etc/ssh/sshd_config
制作模板。
您将更改目标主机的连接安全参数,请务必谨慎操作!配置错误可能会引发 sshd 服务故障,或者向不必要的用户授予访问权限,等等。在传播更改之前,请仔细检查您的工作。
当然,良好的安全防护并非一劳永逸的配置。为受管主机强化 SSH 配置是一个持续过程中的重要一步,Ansible 自动化平台让这一切变得更加简便!
关于作者
Alberto Gonzalez de Dios is a Senior Cloud consultant: Automation and OpenShift specialist. He joined Red Hat in 2018, and he is certified in Azure, AWS and Red Hat (Red Hat Certified Architect Level II).