infra_haproxy

<a href="https://www.haproxy.com">
<img src="https://www.haproxy.com/assets/legal/web-logo.png" alt="Логотип HAProxy" width="300"/>
</a>

# Ansible Роль - HAProxy Community (с ACME, GeoIP и некоторыми функциями WAF)

Роль для развертывания HAProxy (*Сосредоточена на Сообществе*)

Я думаю, что абстракция `frontend` => `route` => `backend`, реализованная в этой роли, очень удобна для работы. Пожалуйста, [дайте мне обратную связь](https://github.com/ansibleguy/infra_haproxy/discussions)!

<a href='https://ko-fi.com/ansible0guy' target='_blank'><img height='35' style='border:0px;height:46px;' src='https://az743702.vo.msecnd.net/cdn/kofi3.png?v=0' border='0' alt='Купите мне кофе' />

[![Статус тестирования Molecule](https://badges.ansibleguy.net/infra_haproxy.molecule.svg)](https://github.com/ansibleguy/_meta_cicd/blob/latest/templates/usr/local/bin/cicd/molecule.sh.j2)
[![Статус тестирования YamlLint](https://badges.ansibleguy.net/infra_haproxy.yamllint.svg)](https://github.com/ansibleguy/_meta_cicd/blob/latest/templates/usr/local/bin/cicd/yamllint.sh.j2)
[![Статус тестирования PyLint](https://badges.ansibleguy.net/infra_haproxy.pylint.svg)](https://github.com/ansibleguy/_meta_cicd/blob/latest/templates/usr/local/bin/cicd/pylint.sh.j2)
[![Статус тестирования Ansible-Lint](https://badges.ansibleguy.net/infra_haproxy.ansiblelint.svg)](https://github.com/ansibleguy/_meta_cicd/blob/latest/templates/usr/local/bin/cicd/ansiblelint.sh.j2)
[![Ansible Galaxy](https://badges.ansibleguy.net/galaxy.badge.svg)](https://galaxy.ansible.com/ui/standalone/roles/ansibleguy/infra_haproxy)

Логи Molecule: [Короткие](https://badges.ansibleguy.net/log/molecule_infra_haproxy_test_short.log), [Полные](https://badges.ansibleguy.net/log/molecule_infra_haproxy_test.log)

**Тестировалось:**
* Debian 12

----

## Установка

```bash
# последняя версия
ansible-galaxy role install git+https://github.com/ansibleguy/infra_haproxy

# из galaxy
ansible-galaxy install ansibleguy.infra_haproxy

# или в пользовательский путь для ролей
ansible-galaxy install ansibleguy.infra_haproxy --roles-path ./roles

План

  • Безопасность
    • Основное ограничение по количеству запросов (раздельно для GET/HEAD и POST/PUT/DELETE)
    • Общий отпечаток клиента
  • 'Интерфейс' для перевода/создания Dict в Map-File
  • Возможность легко загружать и интегрировать IPLists (например, узлы выхода Tor)
  • Легкий способ переопределить файлы ошибок по умолчанию

Использование

Хотите простой интерфейс Ansible? Ознакомьтесь с моим Ansible WebUI

Примеры

Вот некоторые подробные примеры конфигурации и их результаты:

Конфигурация

Минимальный пример

haproxy:
  acme:
    enable: true
    email: '[email protected]'

  frontends:
    fe_web:
      bind: ['[::]:80 v4v6', '[::]:443 v4v6 ssl']
      acme:
        enable: true

      routes:
        be_intern:
          domains: ['app.template.ansibleguy.net']

      default_backend: 'be_fallback'

  backends:
    be_intern:
      servers:
        - 'srv-1 192.168.10.11:80'
        - 'srv-2 192.168.10.12:80'

    be_fallback:
      lines: 'http-request redirect code 302 location https://github.com/ansibleguy'

Определите конфигурацию по мере необходимости:

haproxy:
  version: '2.8'
  acme:
    enable: true
    email: '[email protected]'

  # FRONTENDS
  frontends:
    fe_web:
      bind: ['[::]:80 v4v6', '[::]:443 v4v6 ssl']
      acme:
        enable: true
        domains: ['app.template.ansibleguy.net']  # домены из маршрутов также будут добавлены

      routes:
        be_app01:
          domains: ['app01.template.ansibleguy.net', 'hello.template.ansibleguy.net']

      # определите необработанные разделы/строки конфигурации
      lines:
        section1:
          - ...

      default_backend: 'be_fallback'

    fe_dbs:
      mode: 'tcp'
      default_backend: 'be_db'

    fe_restricted:
      bind: ['[::]:8080 v4v6', '[::]:8443 v4v6 ssl crt /etc/myapp/mycert.pem']

      geoip:
        enable: true

      security:
        restrict_methods: true
        allow_only_methods: ['HEAD', 'GET', 'POST']
        fingerprint_ssl: true  # создавайте и регистрируйте JA3 SSL-отпечаток клиентов
        
        # очень простая фильтрация плохих ботов на основе совпадения user-agent
        block_script_bots: true
        block_bad_crawler_bots: true

      routes:
        be_app02:
          filter_country: ['AT', 'DE', 'CH']
          # filter_ip: ['10.0.0.0/8']
          domains: ['app01.template.ansibleguy.net', 'hello.template.ansibleguy.net']

      # определите необработанные разделы/строки конфигурации
      lines:
        section1:
          - ...

      default_backend: 'be_fallback'

  # BACKENDS
  backends:
    be_app01:
      servers:
        - 'app01-1 10.0.1.1:80'
        - 'app01-2 10.0.1.2:80'

      check_uri: '/health'
      check_expect: 'status 200'

    be_app02:
      security:
        # очень простая фильтрация плохих ботов на основе совпадения user-agent
        block_script_bots: true
        block_bad_crawler_bots: true

      ssl: true
      ssl_verify: 'none'  # по умолчанию; пример: 'required ca-file /etc/ssl/certs/my_ca.crt verifyhost host01.intern'
      servers:
        - 'app02-1 10.0.1.1:443'
        - 'app02-2 10.0.1.2:443'

    be_db:
      mode: 'tcp'
      balance: 'roundrobin'
          
      # определите необработанные разделы/строки конфигурации
      lines:
        section1:
          - 'option mysql-check user haproxy_check'

      servers:
        - 'mysql-1 10.0.0.1:3306'
        - 'mysql-2 10.0.0.2:3306'

    be_fallback:
      lines:
        default: 'http-request redirect code 302 location https://github.com/ansibleguy'

  # ОБЩИЕ
  stats:
    enable: true  # включить http слушатель статистики
    bind: '127.0.0.1:8404'  # по умолчанию

  geoip:
    enable: true
    provider: 'ipinfo'  # или 'maxmind'
    token: '<ВАШ-ТOKEN>'

  # определите глобальные/по умолчанию в формате ключ/значение (можно использовать многозначные списки)
  global:
    ca-base: '/etc/ssl/certs'

  defaults:
    mode: 'http'
    'timeout connect': 3000
    'timeout server': 5000
    'timeout client': 5000

Вам может понадобиться использовать 'ansible-vault' для шифрования ваших паролей:

ansible-vault encrypt_string

Функциональность

  • Установка пакетов

  • Конфигурация

    • Конфигурация по умолчанию:

      • Глобальные/по умолчанию - как видно в стандартной установке
    • Опции по умолчанию:

      • Frontend
        • HTTP режим
          • Перенаправить трафик без SSL на SSL
          • Логирование User-Agent
          • Установка основных заголовков безопасности
          • Блокировка методов TRACE и CONNECT
    • Отказ от опций по умолчанию:

      • Статистический http слушатель

      • Frontend

      • Backend

        • Устойчивые сессии
        • Блокировка методов TRACE и CONNECT

Информация

  • Примечание: эта роль в настоящее время поддерживает только системы на базе debian

  • Примечание: Большинство функций роли можно включить или отключить.

    Для всех доступных опций - смотрите конфигурацию по умолчанию, находящуюся в основном файле по умолчанию!

  • Предупреждение: Не каждая настройка/переменная, которую вы предоставляете, будет проверяться на корректность. Неверная конфигурация может сломать роль!

  • Информация: Вы можете легко фильтровать доступ к бэкендам, используя настройки filter и filter_not:

    filter_ip, filter_not_ip, filter_country, filter_not_country, filter_asn, filter_not_asn

  • Информация: Очень простая блокировка ботов на основе user-agent может быть активирована для frontend и backend. Ознакомьтесь со значениями по умолчанию для получения списка заблокированных ботов.

  • Информация: Вы можете легко ограничить разрешенные HTTP методы на конкретном frontend или backend, установив security.restrict_methods в true и указав security.allow_only_methods.

  • Информация: Ознакомьтесь с документацией по отпечаткам для подробной информации о том, как отслеживать клиентов.

  • Информация: Если вы используете Graylog Server для сбора и анализа логов - обязательно разделите свои логи HAProxy на поля с помощью правил потоков. Пример: HAProxy Community - Правило потока Graylog

  • Совет: Вы можете увеличить количество доступных track-sc's, установив глобальную настройку tune.stick-counters. Это полезно в средах с сложными настройками ограничения скорости.

GeoIP

  • Предупреждение: Если вы используете автоматически предоставляемые базы данных GeoIP - убедитесь, что ваш продукт соответствует их лицензионному соглашению:

    • IPinfo: Информация, Лицензия CC4 (разрешает коммерческое использование - необходимо указать авторство)

      Авторство: <p>Данные IP-адресов предоставлены <a href="https://ipinfo.io">IPinfo</a></p>

    • MaxMind: Информация, EULA (разрешает ограниченное коммерческое использование - необходимо указать авторство)

      Авторство: Этот продукт включает данные GeoLite2, созданные MaxMind, доступные по адресу <a href="https://www.maxmind.com">https://www.maxmind.com</a>.

  • Информация: Для токенов GeoIP вам нужно создать бесплатную учетную запись:

  • Информация: Если вы хотите самостоятельно управлять базами данных GeoIP (не рекомендуется) - роль будет считать, что они расположены по адресу /var/local/lib/geoip и называются asn.mmdb и country.mmdb.

  • Информация: Вы можете вручную протестировать GeoIP Lookup Microservice с помощью curl: curl 'http://127.0.0.1:10069/?lookup=country&ip=1.1.1.1'

WAF

  • Примечание: Функциональные возможности WAF/безопасности, которые предоставляет эта роль, не близки к тем, что доступны в HAProxy Enterprise по умолчанию. Если у вас есть деньги - выбирайте это.

  • Совет: Если вы используете security.flag_bots, вы можете использовать этот основной булевый флаг для упрочнения правил против возможных ботов.

    Примеры:

    • Уменьшение ограничения скорости для ботов: http-request deny deny_status 429 if !{ var(txn.bot) -m int 0 } { sc_http_req_rate(0) gt 50 }

    • Полная блокировка ботов для регистрации аккаунтов: http-request deny deny_status 400 if !{ var(txn.bot) -m int 0 } { method POST } { path_sub -m str -i /register/ }

    • Передача флага вашему приложению для отображения красивой ошибки: http-request add-header X-Bot %[var(txn.bot)]

  • Примечание: Если вы хотите использовать security.block_script_kiddies, обязательно ознакомьтесь со списком блокировок в значениях по умолчанию и добавьте исключения по мере необходимости.

TCP

  • Информация: Если вы хотите динамически захватывать данные, вы можете использовать tcp-request content capture.

    Вам нужно будет вручную включить логирование захваченных данных, изменив формат лога: {% raw %}<ФОРМАТ ЛОГА ПО УМОЛЧАНИЮ ЗДЕСЬ> {%[capture.req.hdr(0)]|%[capture.req.hdr(1)]}{% endraw %}

    Это можно использовать для логирования информации SNI или GeoIP.


Выполнение

Запустите плейбук:

ansible-playbook -K -D -i inventory/hosts.yml playbook.yml

Существуют также некоторые полезные теги:

  • install
  • config => только обновить конфигурацию и ssl сертификаты
  • ssl или acme
  • geoip
  • lua

Для отладки ошибок вы можете установить переменную 'debug' во время выполнения:

ansible-playbook -K -D -i inventory/hosts.yml playbook.yml -e debug=yes

```

О проекте

Provision HAProxy Community (with ACME, GeoIP and some WAF-Features)

Установить
ansible-galaxy install ansibleguy/infra_haproxy
Лицензия
other
Загрузки
414
Владелец
[email protected] | GPG: https://badges.ansibleguy.net/public.gpg