我用ansible为centos 7中的firewalld添加了一些规则。但我必须重新加载firewalld守护进程,这样服务才能正常工作。有什么想法吗?
这是我的可靠代码:
- name: Add port to firewalld
firewalld:
port: "{{ item }}"
permanent: yes
state: enabled
when: ansible_distribution == 'CentOS' or ansible_distribution == 'Red Hat Enterprise Linux'
loop:
- 8080/tcp
- 8000/tcp
- 8090/tcp
- 8040/tcp
首先使用with_items
作为端口列表,如下所示:
- name: Add port to firewalld
firewalld:
port: "{{ item }}"
permanent: yes
state: enabled
when: ansible_distribution == 'CentOS' or ansible_distribution == 'Red Hat Enterprise Linux'
loop:
- 8080/tcp
- 8000/tcp
- 8090/tcp
- 8040/tcp
如果端口不是固定的,您也可以使用以下代码输入端口,并将其用作变量:
- hosts: localhost
gather_facts: no
vars_prompt:
- name: ports
prompt: "Enter port(s) number"
private: no
tasks:
- name: add port
firewalld:
service: "{{ item }}"
permanent: yes
immediate: yes
state: enabled
with_items: "{{ ports.split(',') }}"
关于重新加载firewalld,这里提到了,我们不能使用状态参数重新加载firealld,所以使用下面的systemd模块:
- name: reload service firewalld
systemd:
name: firewalld
state: reloaded
firewalld模块具有立即选项,该选项在firewall cmd cli工具中执行相同的重新加载。
- name: Add port to firewalld
firewalld:
port: "{{ item }}"
permanent: yes
state: enabled
immediate: true
正如coments中提到的,Firewalld可以用"service"或"systemctl"命令或它自己的特定命令重新加载:
firewall-cmd --reload
结果没有差别。这两种方式都在不中断任何活动网络连接的情况下加载新规则,就像直接使用iptables时一样。在下面的示例中,使用了firewalld的特定命令。
如果你只是想创建一个任务,我建议使用ansible中的命令模块来执行这个命令。或者你可以这样写一个处理程序:
- name: reload firewalld
command: firewall-cmd --reload
只需将处理程序放在角色内部的handlers/main.yml文件中即可。然后在你的任务中,你可以用调用该处理程序
notify: reload firewalld
这样,Ansible只在Ansible运行结束时执行处理程序。我在RHEL7上成功地测试了这一点,它应该在CentOS/Locky/Alma以及更新的版本8和9上都能正常工作。
您可以使用服务或systemd模块。
#Supports init systems include BSD init, OpenRC, SysV, Solaris SMF, systemd, upstart.
- name: Restart service
service:
name: firewalld
state: restarted
#Controls systemd services on remote hosts.
- name: Restart service
systemd:
state: restarted
daemon_reload: yes
name: firewalld
如果使用permanent
条件,则可以使用immediate
选项。
示例:
- name: Apply Base Services
ansible.posix.firewalld:
service: "{{ item }}"
state: enabled
zone: public
permanent: yes
immediate: true
loop:
- http
- https
应用此规则后,firewalld
将自动重新加载。
您已经得到了许多优秀的答案。还有另一种可能的方法(尽管重新加载部分与cstoll的答案相同(。
如果您确信除了Ansible之外没有其他人会操纵firewalld规则,那么您可以使用模板直接在/etc/firewalld/zones中生成区域XML文件。您仍然需要添加
notify: reload firewalld
以及相应的处理程序,如cstoll的回答中所示。
这种方法的主要优点是,它可以比一次添加一个规则更快、更简单。
这种方法的缺点是,它不会保留在Ansible之外添加到firewalld的任何规则。第二个缺点是它不会进行任何错误检查;您可以很容易地创建无效的区域文件。firewall cmd命令(以及firewalld模块(将验证每个规则的有效性。例如,它检查分区是否重叠。