ansibleguy.infra_haproxy

<a href="https://www.haproxy.com">
<img src="https://www.haproxy.com/assets/legal/web-logo.png" alt="Logo de HAProxy" width="300"/>
</a>

# Rol de Ansible - HAProxy Community (con ACME, GeoIP y algunas características de WAF)

Rol para desplegar HAProxy (*Enfoque en la Versión Community*)

Creo que la abstracción `frontend` => `route` => `backend` implementada por este Rol es muy agradable para trabajar. ¡Por favor, [dame tu opinión](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='Invítame un café' />

[![Estado de Prueba de 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)
[![Estado de Prueba de 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)
[![Estado de Prueba de 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)
[![Estado de Prueba de 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)

Registros de Molecule: [Corto](https://badges.ansibleguy.net/log/molecule_infra_haproxy_test_short.log), [Completo](https://badges.ansibleguy.net/log/molecule_infra_haproxy_test.log)

**Probado:**
* Debian 12

----

## Instalación

```bash
# última versión
ansible-galaxy role install git+https://github.com/ansibleguy/infra_haproxy

# desde galaxy
ansible-galaxy install ansibleguy.infra_haproxy

# o para una ruta de roles personalizada
ansible-galaxy install ansibleguy.infra_haproxy --roles-path ./roles

Hoja de Ruta

  • Seguridad
    • Límite de tasa básico (GET/HEAD y POST/PUT/DELETE separados)
    • Huella digital genérica del cliente
  • 'Interfaz' para traducción/creación de Dict a Map-File
  • Opción para descargar e integrar listas de IP fácilmente (como nodos de salida de Tor)
  • Forma sencilla de sobrescribir los archivos de error predeterminados

Uso

¿Quieres una interfaz gráfica simple de Ansible? Revisa mi Ansible WebUI

Ejemplos

Aquí algunos ejemplos de configuración detallados y sus resultados:

Configuración

Ejemplo mínimo

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'

Define la configuración según tus necesidades:

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']  # los dominios de rutas también se agregarán

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

      # definir secciones/filas de configuración en crudo para agregar
      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  # crear y registrar la huella digital JA3 SSL de los clientes
        
        # filtrado muy básico de bots dañinos según la coincidencia de 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']

      # definir secciones/filas de configuración en crudo para agregar
      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:
        # filtrado muy básico de bots dañinos según la coincidencia de user-agent
        block_script_bots: true
        block_bad_crawler_bots: true

      ssl: true
      ssl_verify: 'none'  # predeterminado; ejemplo: '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'
          
      # definir secciones/filas de configuración en crudo para agregar
      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'

  # GENERAL
  stats:
    enable: true  # habilitar el listener de estadísticas http
    bind: '127.0.0.1:8404'  # predeterminado

  geoip:
    enable: true
    provider: 'ipinfo'  # o 'maxmind'
    token: '<TU-TOKEN>'

  # definir globals/defaults como pares clave/valor (listas de múltiples valores utilizables)
  global:
    ca-base: '/etc/ssl/certs'

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

Es posible que desees usar 'ansible-vault' para encriptar tus contraseñas:

ansible-vault encrypt_string

Funcionalidad

  • Instalación de paquetes

  • Configuración

    • Configuración por defecto:

      • Globales/Por defecto - como se ve en instalaciones predeterminadas
    • Opciones predeterminadas:

      • Frontend
        • Modo HTTP
          • Redirigir tráfico no SSL a SSL
          • Registro de User-Agent
          • Configuración de encabezados de seguridad básicos
          • Bloqueo de métodos TRACE y CONNECT
    • Opciones predeterminadas desactivadas:

      • Listener http de estadísticas

      • Frontend

      • Backend

        • Sesiones persistentes
        • Bloqueo de métodos TRACE y CONNECT

Información

  • Nota: este rol actualmente solo admite sistemas basados en debian

  • Nota: La mayoría de la funcionalidad del rol se puede optar por habilitar o deshabilitar.

    Para todas las opciones disponibles - consulta la configuración predeterminada ubicada en el archivo de defaults principal!

  • Advertencia: No todas las configuraciones/variables que proporcionas serán verificadas por su validez. ¡Una mala configuración podría romper el rol!

  • Información: Puedes filtrar fácilmente el acceso a los backends utilizando los ajustes filter y filter_not:

    filter_ip, filter_not_ip, filter_country, filter_not_country, filter_asn, filter_not_asn

  • Información: Un bloqueo muy básico basado en el user-agent de bots de script y de mala calidad se puede activar para frontends y backends. Consulta los defaults para ver la lista de bots que están bloqueados.

  • Información: Puedes restringir fácilmente los métodos HTTP permitidos en un frontend o backend específico configurando security.restrict_methods en true y especificando security.allow_only_methods

  • Información: Consulta los Documentos de Huella Digital para obtener información detallada sobre cómo podrías querer rastrear clientes.

  • Información: Si estás usando Graylog Server para recopilar y analizar tus registros - asegúrate de dividir tus registros de HAProxy en campos usando reglas de pipeline. Ejemplo: HAProxy Community - Regla de Pipeline de Graylog

  • Consejo: Puedes aumentar la cantidad de track-sc disponibles configurando la opción global tune.stick-counters. Esto puede ser útil en entornos con configuraciones complejas de límite de tasa.

GeoIP

  • Advertencia: Si utilizas las bases de datos de GeoIP autoprovisionadas - asegúrate que tu producto siga su acuerdo de licencia:

    • IPinfo: Información, Licencia CC4 (permite uso comercial - necesitas agregar una atribución)

      Atribución: <p>Datos de direcciones IP proporcionados por <a href="https://ipinfo.io">IPinfo</a></p>

    • MaxMind: Información, EULA (permite uso comercial limitado - necesitas agregar una atribución)

      Atribución: Este producto incluye datos GeoLite2 creados por MaxMind, disponibles en <a href="https://www.maxmind.com">https://www.maxmind.com</a>.

  • Información: Para los tokens de GeoIP deberás crear una cuenta gratuita:

  • Información: Si deseas gestionar las bases de datos de GeoIP por ti mismo (no recomendado) - el rol asumirá que están colocadas en /var/local/lib/geoip y se llaman asn.mmdb & country.mmdb.

  • Información: Puedes probar el Microservicio de Búsqueda de GeoIP manualmente usando curl: curl 'http://127.0.0.1:10069/?lookup=country&ip=1.1.1.1'

WAF

  • Nota: El conjunto de características de WAF/seguridad que proporciona este rol no se aproxima a lo que disponible en HAProxy Enterprise por defecto. Si tienes el dinero - ve por ello.

  • Consejo: Si usas security.flag_bots puedes usar esta bandera booleana básica para endurecer las reglas para posibles bots.

    Ejemplos:

    • Limitar la tasa para bots: http-request deny deny_status 429 if !{ var(txn.bot) -m int 0 } { sc_http_req_rate(0) gt 50 }

    • Negar el registro de cuentas para bots: http-request deny deny_status 400 if !{ var(txn.bot) -m int 0 } { method POST } { path_sub -m str -i /register/ }

    • Pasar la bandera a tu aplicación para mostrar un error bonito: http-request add-header X-Bot %[var(txn.bot)]

  • Nota: Si quieres usar security.block_script_kiddies asegúrate de revisar la lista de bloqueo en los defaults y agregar exclusiones según sea necesario.

TCP

  • Información: Si deseas capturar datos dinámicamente, puedes utilizar tcp-request content capture.

    Debes habilitar el registro de los datos capturados manualmente modificando el formato de registro: {% raw %}<FORMATO DE REGISTRO POR DEFECTO AQUÍ> {%[capture.req.hdr(0)]|%[capture.req.hdr(1)]}{% endraw %}

    Esto se puede utilizar para registrar la SNI o la información de GeoIP.


Ejecución

Ejecuta el playbook:

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

También hay algunas etiquetas útiles disponibles:

  • install
  • config => solo actualizar configuración y certificados SSL
  • ssl o acme
  • geoip
  • lua

Para depurar errores - puedes establecer la variable 'debug' en tiempo de ejecución:

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

```

Acerca del proyecto

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

Instalar
ansible-galaxy install ansibleguy.infra_haproxy
Licencia
other
Descargas
972
Propietario
[email protected] | GPG: https://badges.ansibleguy.net/public.gpg