Ansible 执行特权命令时如何安全配置 sudoers 避免密码泄露

文章导读
Ansible 执行特权命令时,最安全的方式是在目标主机配置 sudoers 允许特定用户免密执行,而不是在 Ansible 调用时传递 sudo 密码。适用场景为自动化运维环境,风险边界在于必须严格保护 Ansible 控制用户的 SSH 私钥权限。
📋 目录
  1. A 命令速用版
  2. B 为什么会这样
  3. C 分步处理
  4. D 怎么验证是否生效
  5. E 常见坑
  6. F 常见问题
  7. G 参考来源
A A

Ansible 执行特权命令时,最安全的方式是在目标主机配置 sudoers 允许特定用户免密执行,而不是在 Ansible 调用时传递 sudo 密码。适用场景为自动化运维环境,风险边界在于必须严格保护 Ansible 控制用户的 SSH 私钥权限。

先说结论:通过 sudoers 配置 NOPASSWD 规则替代密码传递,能消除密码在传输和日志中的泄露风险。

  • 先判断:确认 Ansible 控制用户是否已通过 SSH 密钥认证登录。
  • 优先做:在目标主机 /etc/sudoers.d/ 目录下为 Ansible 用户添加免密规则。
  • 再验证:使用 ansible -m command -a "whoami" `--become` 测试提权是否无需密码。

命令速用版

直接在目标主机编辑 sudoers 配置文件,添加免密规则。

# 进入编辑模式,切勿直接 vim 编辑 sudoers
visudo -f /etc/sudoers.d/ansible_user

# 添加以下内容,将 ansible 替换为实际登录用户名
ansible ALL=(ALL) NOPASSWD: ALL

# 保存退出后,在控制机测试
ansible all -m command -a "whoami" `--become`

为什么会这样

传递 sudo 密码会在进程列表、日志文件或 Ansible Vault 中留下明文或加密凭据,增加泄露面。

Ansible 默认通过 SSH 连接目标主机,若每次提权都要求输入 sudo 密码,用户往往倾向于将密码存入 vault 文件或通过命令行参数传递。一旦控制机被入侵或日志被窃取,攻击者可获取 sudo 密码。配置 sudoers 免密后,权限验证依赖 SSH 私钥,只要私钥保管得当,自动化流程无需接触明文密码。

分步处理

按顺序完成用户创建、密钥分发、sudoers 配置和权限回收。

步骤 1:准备专用账户
不要在目标主机使用 root 直接登录,创建专用运维账户。

Ansible 执行特权命令时如何安全配置 sudoers 避免密码泄露
# 在目标主机执行
useradd -m -s /bin/bash ansible
mkdir -p /home/ansible/.ssh
chmod 700 /home/ansible/.ssh

步骤 2:分发 SSH 公钥
将控制机的公钥写入目标主机 authorized_keys。

# 在控制机执行
ssh-copy-id ansible@target_host

步骤 3:配置 sudoers 免密
使用 visudo 命令编辑,确保语法正确。

# 在目标主机执行
visudo -f /etc/sudoers.d/ansible
# 写入:ansible ALL=(ALL) NOPASSWD: ALL
# 确保文件权限为 440
chmod 440 /etc/sudoers.d/ansible

步骤 4:限制命令范围(可选)
若安全要求高,仅允许特定命令免密。

# 仅允许重启 nginx 和查看日志
ansible ALL=(ALL) NOPASSWD: /usr/sbin/service nginx restart, /usr/bin/tail -f /var/log/*

怎么验证是否生效

通过 Ansible 命令检查提权后的用户身份和是否需要密码交互。

验证命令:

Ansible 执行特权命令时如何安全配置 sudoers 避免密码泄露
ansible all -i target_host, -m command -a "whoami" `--become` -u ansible

预期结果:

  • 输出包含 "root",说明提权成功。
  • 命令执行过程中没有提示输入 SSH 密码或 sudo 密码。
  • 若使用 -vvv 参数,日志中不应出现 password 相关字段。

检查 sudoers 语法:

sudo visudo -c -f /etc/sudoers.d/ansible
# 输出 parsed OK 表示配置无误

常见坑

配置 sudoers 时容易因语法错误或权限问题导致无法提权或安全风险。

  • 文件权限错误:/etc/sudoers.d/ 下的文件权限必须是 440 或 400,属主为 root,否则 sudo 会拒绝读取。
  • 命令路径不全:限制命令时必须写绝对路径,例如 /usr/bin/systemctl 而不是 systemctl,否则规则不生效。
  • 私钥泄露风险:开启 NOPASSWD 后,SSH 私钥等同于 root 权限,必须严格控制控制机私钥的访问权限(chmod 600)。
  • Defaults 要求 tty:部分系统默认配置 requiretty,会导致 Ansible 后台执行失败,需在 sudoers 中添加 Defaults:ansible !requiretty。

常见问题

必须使用密码时如何安全传递?

若合规要求必须使用密码,建议使用 Ansible Vault 加密密码文件,并通过 `--ask-become-pass` 手动输入。

配置生效后还能审计操作吗?

可以,sudo 默认会将执行命令记录到 /var/log/secure 或 /var/log/auth.log,配置 NOPASSWD 不影响日志审计。

如何回收权限?

删除 /etc/sudoers.d/ 下对应用户配置文件,或在该文件中注释掉相关规则,无需重启服务立即生效。

参考来源

  • Ansible Official Documentation, "Become (Privilege Escalation)", https://docs.ansible.com/ansible/latest/playbook_guide/playbook_privilege_escalation.html
  • Linux Man Pages, "sudoers", https://www.man7.org/linux/man-pages/man5/sudoers.5.html