使用 Ansible 添加 iptables 规则
许多系统和应用程序需要对某些端口和协议进行某些访问。使用Ansible安装这些系统时,还需要打开所需的端口,以便系统能够正常运行。由于Ansible中没有iptables模块,因此需要shell命令来添加iptables规则。
例如,这里有一个任务,它添加一个iptables规则以允许Apache在端口80上进行通信。
- name: Apache | add apache iptable rule command: /sbin/iptables -I INPUT 1 -p tcp --dport http -j ACCEPT -m comment --comment "Apache" sudo: true
一旦到位,您可能需要保存和/或重新启动iptables以便永久保存规则。下面两条规则会保存iptables规则并重启iptables服务。请注意,这些命令特定于Ubuntu,因此可能不适用于您的系统设置。
- name: save iptables command: iptables-save sudo: true - name: restart iptables service: name=ufw state=restarted sudo: true
这允许Apache进行通信,但问题是当Ansible任务第二次运行时,将添加第二个iptables规则。这可能会导致问题,尤其是当Ansible一遍又一遍地运行以维护服务器的配置时。为此,必须添加另一个步骤以在添加规则之前检测规则的存在。这是通过使用shell模块打印可用的iptables规则并将它们存储到变量中来完成的。Ansible关键字“register”允许将当前任务的任何返回值保存为变量,在这种情况下,注册的变量称为“iptablesrules”。
- name: Apache | get iptables rules shell: iptables -L register: iptablesrules sudo: true
有了这个,我们现在可以运行iptables插入命令,只有当我们找不到与我们想要添加的规则匹配的规则时。对iptablesrules.stdout参数运行find函数以在内容中查找单词“Apache”。这与在iptables规则创建中使用的注释相匹配。这是修改后的任务。
- name: Apache | add apache iptable rule command: /sbin/iptables -I INPUT 1 -p tcp --dport http -j ACCEPT -m comment --comment "Apache" sudo: true when: iptablesrules.stdout.find("Apache") == -1
现在唯一的问题是,当检查Ansibleplaybook是否会按预期执行时(通过使用--check标志),添加的条件将失败。这是因为在这种情况下生成的iptablesrules变量没有完成,因此Ansible会出错并抱怨缺少变量。解决这个问题的方法是强制iptables规则变量注册表任务始终运行,即使我们处于检查模式。为此,我们将always_run标志添加到任务中。
- name: Apache | get iptables rules shell: iptables -L register: iptablesrules always_run: yes sudo: true
这是完整的整个剧本。请注意,更好的做法是使用createiptablessave和restart任务作为处理程序,并从需要的任务中通知它们。这允许在为其他服务生成iptables规则时重用它们。
--- - name: Apache | get iptables rules shell: iptables -L register: iptablesrules always_run: yes sudo: true - name: Apache | add apache iptable rule command: /sbin/iptables -I INPUT 1 -p tcp --dport http -j ACCEPT -m comment --comment "Apache" sudo: true when: iptablesrules.stdout.find("Apache") == -1 - name: save iptables command: iptables-save sudo: true - name: restart iptables service: name= ufw state=restarted sudo: true