Ansible 配置远程防火墙需适配 firewalld/ufw/iptables,用 set_fact 动态识别服务类型,通过结构化变量定义规则,确保服务启用、规则持久化与重载,并集成校验及安全流程实现幂等、可复用、防自锁。

在 Linux 中用 Ansible 配置远程防火墙规则,关键是让操作可复用、可验证、不破坏现有连接(比如别把自己锁在外面),同时适配不同系统的默认防火墙服务。
识别并适配目标主机的防火墙类型
不同发行版默认用的防火墙不同:RHEL/CentOS 8+ 默认 firewalld,Ubuntu/Debian 常用 ufw,老系统可能直接跑 iptables。不能硬写死模块,否则跨系统就失败。
- 用 command + set_fact 检测实际运行的服务,例如:
systemctl is-active firewalld成功就设firewall_type: firewalld - 对 Ubuntu 主机优先用 ufw 模块,语义清晰且自带安全默认;RHEL 系列用 firewalld 模块更原生
- 避免用 shell 模块执行
iptables -A—— 它不幂等,重复运行会叠加重复规则
用变量定义规则,而不是硬编码端口
把防火墙规则变成结构化数据,方便按环境开关、灰度发布或审计比对。
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
- 定义
firewall_rules变量为列表,每项含type(port / service / rich_rule)、port、source、state(enabled / disabled) - 生产环境可关 SSH:
{ type: "port", port: "22", protocol: "tcp", state: "disabled" };测试环境保留state: "enabled" - 支持富规则,例如只允许某网段访问数据库:
rich_rule: 'rule family="ipv4" source address="10.10.0.0/16" port port="3306" protocol="tcp" accept'
确保规则真正生效,不只是“加了”
加了规则但服务没启、没重载,等于白配。必须显式控制服务状态和规则持久性。
- 启动并启用服务:
service: name=firewalld state=started enabled=yes - firewalld 规则必须设
permanent: yes+immediate: yes,再通过 handler 或 command 执行firewall-cmd --reload - iptables 需持久化:RedHat 系列写入
/etc/sysconfig/iptables,Debian 系列用iptables-persistent保存 - 加校验任务,如
firewall-cmd --list-all或ufw status verbose抽样检查输出,异常时fail
融入整体安全流程,避免孤立配置
防火墙不是单独一步,要和 SSH 加固、SELinux、内核参数统一编排。
- 复用成熟角色,比如
devsec.hardening集合,它已内置 firewall 角色并自动适配 OS 类型 - Playbook 中按顺序执行:用户创建 → SSH 密钥认证 → 系统更新 → 防火墙配置 → 内核调优 → SELinux 设置
- 所有步骤保持幂等性,反复运行结果一致,不会因多跑一次导致锁死 SSH 或规则重复叠加










