如何使用 Ansible 重新加载 Firewalld 服务?

How to reload Firewalld service using Ansible?

我在 centos 7 中用 ansible 给 firewalld 添加了一些规则。但是我必须重新加载 firewalld 守护进程,这样服务才能正常工作。有什么想法吗?

这是我的ansible代码:

- 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

您可以使用服务或 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

首先使用 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,它提到 here 我们不能使用状态参数重新加载 firewalld 所以使用 systemd 模块如下:

- name: reload service firewalld
  systemd:
    name: firewalld
    state: reloaded

我来晚了一点,但鉴于之前的所有答案似乎只是推测我会提供另一个意见。 Firewalld 不会使用 'service' 或 'systemctl' 命令重新加载,而是使用它自己的特定命令重新加载:

firewall-cmd --reload

这是因为通过这种方式,您可以在不中断任何活动网络连接的情况下加载新规则,就像直接使用 iptables 时那样。 鉴于此,我认为使用 service 或 systemctl 不是一个好的解决方案。 所以如果你只想创建一个任务,我建议使用 ansible 的命令模块来执行这个命令。或者你可以像这样写一个处理程序:

- name: reload firewalld
  command: firewall-cmd --reload

只需将处理程序放在您角色内的 handlers/main.yml 文件中。然后在您的任务中,您可以使用以下方式调用该处理程序:

notify: reload firewalld

这样 Ansible 只会在 Ansible 结束时执行处理程序 运行。我在 RHEL7 上成功测试了这个。

firewalld 模块有即时选项,它在 firewall-cmd cli 工具中执行相同的重新加载。

- name: Add port to firewalld
  firewalld:
    port: "{{ item }}"
    permanent: yes
    state: enabled
    immediate: true

您已经得到了很多很好的答案。还有另一种可能的方法(尽管重新加载部分与 cstoll 的回答相同)。

如果您确定除了 Ansible 之外没有其他人会操纵 firewalld 规则,您可以使用模板直接在 /etc/firewalld/zones 中生成区域 XML 文件。您仍然需要添加

notify: reload firewalld

和相应的处理程序,如 cstoll 的回答。

这种方法的主要优点是它比一次添加一个规则要快得多,也简单得多。

这种方法的缺点是它不会保留在 Ansible 之外添加到 firewalld 的任何规则。第二个缺点是它不会做任何错误检查;您可以轻松创建无效区域文件。 firewall-cmd 命令(以及 firewalld 模块)将验证每条规则的有效性。例如,它检查区域是否重叠。