Saltstack

使用 Saltstack 高效管理 IPtables

  • September 1, 2021

我正在嘗試使用 SaltStack 配置靈活的 iptables 管理解決方案,但我發現它比我想像的要難。

我的主要要求:能夠有一個支柱來保存我的 IP 列表,這些 IP 應該被列入白名單,以便在所有 minions 上進行 SSH 訪問。這個 IP 列表當然會不時改變:一些 IP 被添加,一些 IP 被刪除。我面臨的問題是已刪除的 IP - 當我從支柱文件中刪除它們時,SaltStack 不會從 minions 中刪除實際的白名單。

我能找到的唯一解決方法是創建一個名為“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'

/srv/salt/iptables-default.sls:

{% 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 %}

我花了幾個小時找出管理各種 iptables 設置 w Salt 的最佳方法,最好的解決方案似乎是結合

  1. flat iptables 配置文件(作為 jinja 模板)
  2. 僅當平面文件更改時才讓 salt 執行 iptables 刷新 + 恢復

這就是我在環境中使用它的方式,並且效果很好。我嘗試使用 salt Iptables 狀態,但它變得非常麻煩且難以管理,並且您必須iptables.flush在每次高狀態執行時都強制執行,

以下是完全避免使用支柱的更簡單和更易於管理的方法,


使用 {{ grains.id }}.j2 作為佈局為每個主機創建一個平面文件,

cat /srv/salt/state/iptables/files/nycweb1.j2


##############################################################
## This file is managed by SALTSTACK - Do not modify manually
##############################################################

*filter
:INPUT ACCEPT
:FORWARD ACCEPT
:OUTPUT ACCEPT

## Allow all loopback (lo0) traffic
-A INPUT -i lo -j ACCEPT

## Drop all traffic to 127/8 that doesn't use lo0
-A INPUT ! -i lo -d 127.0.0.0/8 -j DROP

## Accept inbound traffic for already established connections.
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

## Effectively allow all outbound traffic.
-A OUTPUT -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT

## Allow ping
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT

## Blacklist
-A INPUT -s 0.0.0.0/32 -p tcp -m tcp --dport 22 -j REJECT --reject-with icmp-port-unreachable

## Whitelist     
-A INPUT -s 121.236.129.235/32 -p tcp -m tcp --dport 22 -j ACCEPT {# NY office pub #}
-A INPUT -s 192.168.10.0/24 -p tcp -m tcp --dport 22 -j ACCEPT {# NY office priv #}


COMMIT


*nat
:PREROUTING ACCEPT
:INPUT ACCEPT
:OUTPUT ACCEPT
:POSTROUTING ACCEPT
-A PREROUTING -p tcp -m tcp --dport 27015 -j DNAT --to-destination 192.168.38.20
-A OUTPUT -p tcp -m addrtype --src-type LOCAL --dst-type LOCAL -m tcp --dport 1266 -j DNAT --to-destination 169.254.1.1:443
-A POSTROUTING -s 192.168.1.2/32 -d 10.3.4.65/32 -p tcp -m tcp --dport 48854 -j MASQUERADE
-A POSTROUTING -d 10.0.2.15/24 -p tcp -m tcp --dport 27045 -j SNAT --to-source 192.168.99.11 {# description #}

COMMIT
{# EOF #}

創建狀態文件,

cat /srv/salt/state/iptables/init.sls

# STATE - IPTABLES

{% set iptables_file = '/etc/sysconfig/iptables' %}

iptables_pkg:
   pkg.installed:
       - name: iptables

{{ iptables_file }}:
   file.managed:
       - user: root
       - group: root
       - mode: 644
       - source: salt://{{ slspath }}/files/{{ grains.id }}.j2
       - template: jinja

flush_tables:
   iptables.flush:
       - table: filter
       - family: ipv4
       - onchanges:
           - file: "{{ iptables_file }}"

restore_tables: 
   cmd.run:
       - name: "/usr/sbin/iptables-restore < {{ iptables_file }}"
       - onchanges:
           - file: "{{ iptables_file }}"

就是這樣,當您在目標上執行 highstate 時,它們只會在平面文件被修改時執行刷新+恢復。您的配置也是原生 iptables 格式,而不是支柱格式

現在應用狀態,或將其添加到您的高狀態

salt nycweb01 state.sls iptables

引用自:https://serverfault.com/questions/887920