Salt stack 基于SaltStack的IPtables管理

Salt stack 基于SaltStack的IPtables管理,salt-stack,Salt Stack,我试图用SaltStack配置一个灵活的iptables管理解决方案,但我发现这比我想象的要难 我的主要要求是:能够有一个支柱,在那里我保留一个IP列表,该列表应该被列为白名单,以便在所有仆从上进行SSH访问。这个IP列表当然会时不时地改变:一些IP被添加,一些IP被删除。我面临的问题是删除的IP——当我从支柱文件中删除它们时,SaltStack不会从仆从中删除实际的白名单 我能找到的唯一解决办法是创建一个名为“removed ips”的新密钥,每当我想删除一个IP时,我都会将它添加到那里。第二

我试图用SaltStack配置一个灵活的iptables管理解决方案,但我发现这比我想象的要难

我的主要要求是:能够有一个支柱,在那里我保留一个IP列表,该列表应该被列为白名单,以便在所有仆从上进行SSH访问。这个IP列表当然会时不时地改变:一些IP被添加,一些IP被删除。我面临的问题是删除的IP——当我从支柱文件中删除它们时,SaltStack不会从仆从中删除实际的白名单

我能找到的唯一解决办法是创建一个名为“removed ips”的新密钥,每当我想删除一个IP时,我都会将它添加到那里。第二个for循环将删除它。当然,这是一个非常讨厌的解决方法,有没有更好的方法

/srv/pillar/iptables-default.sls:

iptables-default:
  whitelisted-ips:
    - '55.55.55.55'
    - '66.66.66.66'
    - '77.77.77.77'
  removed-ips:
    - '88.88.88.88'
{% for ip in salt['pillar.get']('iptables-default:whitelisted-ips') %}
Whitelist OSF IP {{ip}} for SSH access:
  iptables.append:
    - table: filter
    - family: ipv4
    - chain: INPUT
    - jump: ACCEPT
    - match: state
    - connstate: NEW
    - source: '{{ ip }}'
    - dport: 22
    - proto: tcp
    - save: True
{% endfor %}

{% for ip in salt['pillar.get']('iptables-default:removed-ips') %}
Remove old IPs that are not needed anymore:
  iptables.delete:
    - table: filter
    - family: ipv4
    - chain: INPUT
    - jump: ACCEPT
    - match: state
    - connstate: NEW
    - source: {{ ip }}
    - dport: 22
    - proto: tcp
    - save: True
{% endfor %}
/srv/salt/iptables-default.sls:

iptables-default:
  whitelisted-ips:
    - '55.55.55.55'
    - '66.66.66.66'
    - '77.77.77.77'
  removed-ips:
    - '88.88.88.88'
{% for ip in salt['pillar.get']('iptables-default:whitelisted-ips') %}
Whitelist OSF IP {{ip}} for SSH access:
  iptables.append:
    - table: filter
    - family: ipv4
    - chain: INPUT
    - jump: ACCEPT
    - match: state
    - connstate: NEW
    - source: '{{ ip }}'
    - dport: 22
    - proto: tcp
    - save: True
{% endfor %}

{% for ip in salt['pillar.get']('iptables-default:removed-ips') %}
Remove old IPs that are not needed anymore:
  iptables.delete:
    - table: filter
    - family: ipv4
    - chain: INPUT
    - jump: ACCEPT
    - match: state
    - connstate: NEW
    - source: {{ ip }}
    - dport: 22
    - proto: tcp
    - save: True
{% endfor %}

在根据支柱数据附加规则之前刷新所有规则。因此,添加一个刷新状态,并在所有其他添加规则的状态中要求此状态-这确保在添加规则之前刷新运行一次

未经测试的示例

flush_all_rules:
  iptables.flush:
    - table: filter
    - family: ipv4

{% for ip in salt['pillar.get']('iptables-default:whitelisted-ips') %}
Whitelist OSF IP {{ip}} for SSH access:
  iptables.append:
    - table: filter
    - family: ipv4
    # [...]
    - require:
      - iptables: flush_all_rules
{% endfor %}

与使用salt的iptables状态不同,我喜欢管理/etc/iptables/rules.v4和v6,如下所示:

firewall-ipv4:
  pkg.installed:
    - pkgs:
      - iptables
      - iptables-persistent
  file.managed:
    - name: /etc/iptables/rules.v4
    - source: salt://firewall/files/rules.jinja
    - template: jinja
    - context:
        slspath: {{ slspath }}
        family: ipv4
  cmd.wait:
    - name: iptables-restore rules.v4
    - cwd: /etc/iptables
    - order: last
    - watch: 
      - file: firewall-ipv4

{{ similar for v6... }}
其中rules.jinja从支柱生成规则集。这种方法的好处是,当支柱规则被删除时,它会做正确的事情,而不需要对每个highstate进行刷新(即更改)。缺点是它不会注意到并从本地机器恢复对防火墙的手动更改

我有一个使用这种技术的公式。忽略关于兼容性问题的自述说明,它在当前的salt上运行良好。还是上次我检查的时候