Назад | Перейти на главную страницу

Управление iptables с помощью ansible в огромной среде

Как лучше всего управлять iptables из одной точки и иметь возможность редактировать что-либо на локальном сервере.

Нам нужно добавить некоторые правила, централизованные на всех серверах, но у нас есть определенные серверы с особыми требованиями, которые должны иметь свой собственный набор правил.

Я думал о сценарии bash с несколькими включениями, который управляется централизованно с помощью ansible и включает управление на локальном сервере. Это хороший подход? А может есть что лучше?

Мы не можем создавать шаблоны yml2 для ansible, потому что между конкретными хостами слишком большая разница.

Приведите примеры централизованного управления iptables.

ufw

Ansible имеет ufw модуль для обработки правил брандмауэра. В roles/common/tasks/main.yml, который есть на всех моих серверах, у меня есть (среди прочего):

- name: Install ufw
  apt: name=ufw
- name: Allow ssh through firewall
  ufw: proto=tcp port=22 rule=allow
- name: Set ufw policy
  ufw: state=enabled direction=incoming policy=deny

редактировать: Необходимо разрешить ssh перед установкой политики по умолчанию на «запретить» (изначально все было наоборот), иначе вы можете быть заблокированы между двумя шагами.

Затем для каждой роли у меня есть дополнительные правила брандмауэра для этой роли. Например, в roles/nginx/tasks/main.yml, У меня есть (среди прочего) это:

- name: Allow nginx firewall
  ufw: proto=tcp port=80 rule=allow
- name: Allow nginx ssl firewall
  ufw: proto=tcp port=443 rule=allow

Итак, на всех моих серверах nginx открыты порты 80 и 443.

Таким образом, вы можете создать любую общую конфигурацию, которую хотите, и добавить дополнительные правила в более конкретные роли.

ферма

Если у вас есть правила, которые ufw не может справиться, одно решение, которое я думаю, будет работать хорошо, это ferm; он может делать почти все, и вы можете настроить его для чтения правил из каталогов, таких как /etc/ferm/input.d/, /etc/ferm/output.d/, /etc/ferm/forward.d/и т.д. Вы можете сделать свой common роль подготовить необходимое ferm конфигурации, а затем другие роли помещают файлы в эти каталоги.

простые iptables

Ваше требование иметь ansible указывать правила в дополнение к правилам, указанным другим способом, необычно и, по-видимому, не подходит для использования ansible. К сожалению, я не вижу другого способа сделать это, кроме простого iptables, что было бы довольно некрасиво. Вот пример открытия порта 80 в roles/nginx/tasks/main.yml (непроверено):

- name: Check if port 80 is allowed
  shell: iptables -L | grep -q "Allow http" && echo -n yes || echo -n no
  register: check_allow_http
  changed_when: no
  always_run: yes

- name: Allow port 80
  command: >
    iptables -A INPUT -p tcp -m tcp --dport 80
    -m comment --comment "Allow http" -j ACCEPT
  when: check_allow_http.stdout == "no"
  notify:
  - Save iptables

где Save iptables это обработчик, который выполняет iptables-save. Все вышеперечисленное довольно утомительно писать, но это может быть уместно, особенно если у вас есть только несколько правил, которыми нужно управлять. ansible.

lineinfile

Если вы хотите управлять правилами в конфигурации iptables без перезаписи существующих правил или централизованного управления iptables в шаблоне, используйте модуль Ansible lineinfile:

- name: ensure iptables allows established and related traffic
  lineinfile:
    dest=/etc/sysconfig/iptables
    state=present 
    regexp="^.*INPUT.*ESTABLISHED,RELATED.*ACCEPT" 
    insertafter="^:OUTPUT " line="-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT" 
    backup=yes
  notify: restart iptables


- name: ensure iptables is configured to allow ssh traffic (port 22/tcp)
  lineinfile:
    dest=/etc/sysconfig/iptables 
    state=present 
    regexp="^.*INPUT.*tcp.*22.*ACCEPT" 
    insertafter="^.*INPUT.*ESTABLISHED,RELATED.*ACCEPT" line="-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT" 
    backup=yes
  notify: restart iptables

Вот обработчик перезапуска iptables:

- name: restart iptables
  service: name=iptables state=restarted

Я создал роль для управления правилами iptables со следующими функциями:

  • Поддержка практически всех правил iptables
  • Разрешить детальное добавление / переопределение правил для определенных хостов
  • Легко вставлять переменные в правила
  • Разрешить порядок правил
  • Простота
  • Постоянство (перезагрузка правил при загрузке)

Проверьте mikegleasonjr.firewall на Анзибл Галактика или на github

Мы написали для этого специальный модуль под названием iptables_raw что позволяет нам легко управлять iptables. Все объясняется в этом Сообщение блога. Вот пример того, как использовать модуль:

# Allow all IPv4 traffic coming in on port 80
- iptables_raw:
    name=allow_tcp_80
    rules='-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT'

# Delete the above rule
- iptables_raw:
    name=allow_tcp_80
    state=absent