# Роль `firewall`

Ansible-роль для управления firewalld на Linux-серверах. Основана на [linux-system-roles/firewall](https://github.com/linux-system-roles/firewall). Устанавливает firewalld, отключает конкурирующие сервисы и применяет конфигурацию зон, сервисов, портов, правил и интерфейсов через встроенный модуль `firewall_lib`.

## Поддерживаемые платформы

- RHEL / CentOS / AlmaLinux / Rocky Linux 7, 8, 9
- Fedora
- SLES 15

## Требования

- systemd
- Python 3 на управляемом узле
- Для EL7: пакеты `NetworkManager` и `python-ipaddress` (устанавливаются ролью автоматически)

## Переменные роли

| Переменная | Тип | Умолчание | Описание |
|---|---|---|---|
| `firewall` | list / map | `[]` | Список объектов конфигурации firewalld (см. ниже) |
| `firewall_disable_conflicting_services` | bool | `false` | Остановить и отключить `nftables`, `iptables`, `ufw` при наличии |
| `firewall_transactional_update_reboot_ok` | bool / null | `null` | Разрешить автоматическую перезагрузку на transactional-update системах (SLES) |

## Структура переменной `firewall`

Переменная `firewall` — список объектов. Каждый объект описывает одно или несколько действий с firewalld. Поля могут комбинироваться в одном объекте.

### Управление зонами и сервисами

```yaml
firewall:
  - zone: internal
    state: enabled          # enabled / disabled / present / absent
    permanent: true
    service:
      - ssh
      - http
      - https
    port:
      - '8080/tcp'
      - '9090/tcp'
    source:
      - 10.0.0.0/8
      - 192.168.0.0/16
```

### Привязка интерфейса к зоне

```yaml
firewall:
  - interface: ens192
    zone: internal
    state: enabled
    permanent: true
```

### Смена зоны по умолчанию

```yaml
firewall:
  - set_default_zone: internal
    state: enabled
    permanent: true
```

### Проброс портов (DNAT)

```yaml
firewall:
  - zone: public
    forward_port:
      - port: 8080
        proto: tcp
        toport: 80
        toaddr: 192.168.1.10
    state: enabled
    permanent: true
```

### Маскарадинг

```yaml
firewall:
  - zone: external
    masquerade: true
    state: enabled
    permanent: true
```

### Rich rules

```yaml
firewall:
  - zone: public
    rich_rule: 'rule family="ipv4" source address="1.2.3.4" drop'
    state: enabled
    permanent: true
```

### Управление ipset

```yaml
firewall:
  - ipset: blocklist
    ipset_type: hash:ip
    ipset_entries:
      - 1.2.3.4
      - 5.6.7.8
    state: enabled
    permanent: true
```

### Сброс к заводским настройкам

```yaml
firewall:
  - previous: replaced
```

Удаляет всю кастомную конфигурацию перед применением новых правил.

## Сбор фактов

Если переменная `firewall` не задана или пуста, роль сохраняет текущую конфигурацию firewalld в факт `firewall_config`.

Для подробного вывода:

```yaml
firewall:
  - detailed: true
```

## Пример использования (из vm01-balancer.yml / vm02-balancer.yml)

```yaml
- name: Настройка балансировщика
  hosts: vm01-balancer
  roles:
    - firewall

  vars:
    firewall_disable_conflicting_services: true
    firewall_transactional_update_reboot_ok: true

    firewall:
      - zone: internal
        state: enabled
        permanent: true
        service:
          - ssh
          - zabbix-agent
          - ntp
          - dns
          - http
          - https
        port:
          - '10050/tcp'
        source:
          - 10.0.0.0/8
          - 172.16.0.0/12
          - 192.168.0.0/16

      - zone: internal
        state: disabled
        permanent: true
        service:
          - cockpit
          - dhcpv6-client
          - mdns
          - samba-client

      - zone: public
        state: enabled
        permanent: true
        service:
          - ntp
          - dns
          - http
          - https

      - zone: public
        state: disabled
        permanent: true
        service:
          - ssh
          - cockpit
          - dhcpv6-client
          - mdns
          - samba-client

      - set_default_zone: internal
        state: enabled
        permanent: true

      - interface: ens192
        zone: internal
        state: enabled
        permanent: true

      - interface: ens224
        zone: public
        state: enabled
        permanent: true
```

## Внутреннее устройство

Основная логика реализована в `library/firewall_lib.py` — кастомном Ansible-модуле с тремя бэкендами:

- **OnlineAPIBackend** — взаимодействие с работающим firewalld через D-Bus
- **InMemoryBackend** — генерация diff без изменений (для `--check`/`--diff` режимов)
- **OfflineCLIBackend** — использует `firewall-offline-cmd` (для сборки контейнеров)

Факты собираются через отдельный модуль `library/firewall_lib_facts.py`.
