Saltstack을 사용하여 효율적으로 IPtables 관리

Saltstack을 사용하여 효율적으로 IPtables 관리

SaltStack으로 유연한 iptables 관리 솔루션을 구성하려고 하는데 생각보다 어렵습니다.

나의 주요 요구 사항: 모든 하수인의 SSH 액세스를 위해 화이트리스트에 추가되어야 하는 IP 목록을 유지하는 기둥을 가질 수 있어야 합니다. 물론 이 IP 목록은 때때로 변경됩니다. 일부 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'

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

답변1

나는 Salt를 사용하여 다양한 iptables 설정을 관리하는 가장 좋은 방법을 찾는 데 몇 시간을 보냈고 가장 좋은 해결책은 다음을 조합하는 것 같습니다.

  1. 플랫 iptables 구성 파일(jinja 템플릿)
  2. 솔트에서 iptables 플러시를 수행하고 플랫 파일이 변경된 경우에만 복원합니다.

이것이 내 환경에 있는 방법이며 매우 잘 작동합니다. 나는 솔트 Iptables 상태를 사용해 보았지만 매우 번거롭고 관리하기 어려워지며 iptables.flush모든 highstate 실행에서 강제로 수행해야 합니다.

다음은 기둥 사용을 완전히 방지하는 더 간단하고 관리하기 쉬운 접근 방식입니다.


{{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 형식입니다.

이제 상태를 적용하거나 highstate에 추가하세요.

salt nycweb01 state.sls iptables

답변2

이러한 종류의 작업을 위해 iptables에서 사용할 IP 주소 목록을 유지하면서 "ipset" 구성 파일을 템플릿화하고 허용 또는 거부 목록에 대해 이를 참조하는 iptables 규칙을 사용합니다. ipset은 대규모 세트에 대한 가치가 있으며 이러한 방식으로 관리하면 "주소 제거" 문제가 제거됩니다. 변경사항이 있을 때마다 세트가 완전히 다시 로드됩니다.

우리는 엄격한 멤버십 및 액세스 요구 사항을 갖춘 수천 대의 서버 네트워크를 중앙에서 관리하고 있으므로 솔트와 jinja 템플릿을 사용하여 /etc/sysconfig/ipset을 렌더링하는 것이 합리적입니다.

관련 정보