Ansible 安全最佳实践:从基础到生产级
一、最核心:SSH 认证安全
- 绝对不要用密码明文
- 禁止在 inventory、playbook 里写
ansible_ssh_pass、ansible_password明文 - 禁止用
sshpass跑生产环境
- 禁止在 inventory、playbook 里写
- 必须用 SSH 密钥登录
- 控制节点生成密钥:
ssh-keygen - 分发公钥:
ssh-copy-id user@host - 被控端禁用密码登录:
PasswordAuthentication no
- 控制节点生成密钥:
- 密钥加密码保护
- 生成密钥时设置 passphrase
- 使用
ssh-agent避免反复输密码
二、Ansible Vault 加密敏感数据
所有密码、密钥、token 都用 Vault 加密。
1. 创建加密变量文件
Bash
ansible-vault create secrets.yml
写入:
YAML
db_password: xxx
api_key: xxx
2. 编辑加密文件
Bash
ansible-vault edit secrets.yml
3. 运行 playbook 时指定 vault
Bash
ansible-playbook site.yml --ask-vault-pass
或使用 vault 密码文件(权限设为 0600)。
三、Inventory 安全
- 不要把 inventory 放代码仓库
- 权限严格:
chmod 600 hosts - 不使用全局变量暴露密码
- 生产环境使用动态 inventory(AWS/Azure/VMware)而非静态清单
四、文件与权限安全
- playbook、配置文件权限 0600
- 临时文件安全
- Ansible 会在被控端生成临时文件,默认权限较宽松
- 在
ansible.cfg中设置:remote_tmp = /var/tmp/ansible-$USER allow_world_readable_tmpfiles = no
- 日志不要泄露敏感信息
no_log = true- 对敏感任务单独加:
- name: 导入密钥 command: ... no_log: true
五、ansible.cfg 安全配置
TOML
[defaults]
# 不检查主机密钥(内网可开,公网不建议)
host_key_checking = False
# 日志安全
log_path = /var/log/ansible.log
no_target_syslog = True
# 禁止从当前目录加载库
library = /usr/share/ansible
# 超时
timeout = 10
[ssh_connection]
# 开启 pipelining 减少 SSH 连接,更安全更快
pipelining = True
六、执行权限最小化
-
不要全程用 root
- 使用普通用户 + sudo
- 在 inventory 中:
ansible_user=ops ansible_become=yes ansible_become_method=sudo
-
sudo 权限最小化
-
不要给 NOPASSWD:ALL,只授权必要命令。
七、传输与执行安全
- 控制节点与被控节点内网通信
- 禁用 Telnet、rsh 等不安全协议
- 开启 SSH 安全加固:
- 禁用 SSH 协议 v1
- 禁用空密码
- 限制允许登录用户
八、Playbook 编写安全
- 不使用
shell/command除非必要 - 优先使用 Ansible 模块(更安全、幂等)
- 变量过滤敏感内容:
vars: password: "{``{ vault_db_pass }}"
- 不把密钥、密码输出到控制台
九、版本与漏洞安全
- 保持 Ansible 最新版
- 定期更新依赖:
pip list --outdated - 不用第三方未知角色,或严格审计后再用
十、生产环境终极安全方案
- SSH 密钥 + 密钥密码
- Ansible Vault 加密所有敏感配置
- 普通用户 + sudo 最小权限
- 内网隔离,禁止外网直接管理
- 日志审计、执行记录
- CI/CD 中使用秘钥管理系统(HashiCorp Vault、AWS Secrets Manager)
安全加固配置案例(可直接用于生产环境)
apl
[defaults]
# 主机清单
inventory = ./inventory/hosts.ini
# 远程用户与权限
remote_user = ansible
ask_pass = false
host_key_checking = true
# 超时与并发
timeout = 15
forks = 10
# 日志(避免泄露敏感信息)
log_path = ./ansible.log
no_target_syslog = true
no_log = false
# 安全:禁止加载当前目录恶意模块
library = /usr/share/ansible/plugins/modules
action_plugins = /usr/share/ansible/plugins/action
# 角色与回调安全
roles_path = ./roles
callback_whitelist = profile_tasks
# fact 缓存(可选)
gathering = smart
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_facts
fact_caching_timeout = 86400
# 禁止显示警告时泄露路径
allow_world_readable_tmpfiles = no
executable = /bin/bash
[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false
[ssh_connection]
# 减少连接次数,更安全更快
pipelining = true
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=yes
control_path = %(directory)s/ansible-ssh-%%h-%%p-%%r