# Cómo configurar HAProxy como proxy inverso con multiples dominios

- Link: https://binariocero.com/linux/como-configurar-haproxy-como-proxy-inverso-con-multiples-dominios
- Published: 2024-06-05T07:32:58+02:00
- Author: Juan José Fernández Durán

![Loading](https://binariocero.com/wp-content/plugins/page-views-count/ajax-loader-
2x.gif)

## Guía Avanzada de Configuración de HAProxy

La configuración avanzada de HAProxy como proxy inverso permite optimizar y asegurar
la distribución del tráfico entre múltiples servidores backend, garantizando alta
disponibilidad y rendimiento. Para implementar estas configuraciones, es esencial
definir reglas de balanceo de carga más sofisticadas, como el balanceo basado en
sesiones o cookies, o el uso de algoritmos avanzados como "leastconn" para asignar
nuevas conexiones al servidor con menos conexiones activas. Además, se pueden implementar
controles de salud personalizados mediante sondas HTTP/HTTPS para monitorear el 
estado de los servidores backend y retirar automáticamente aquellos que no respondan
correctamente. También es posible integrar HAProxy con certificados SSL/TLS para
cifrar el tráfico y utilizar ACLs (listas de control de acceso) para gestionar y
restringir el acceso a ciertos recursos, basándose en una variedad de parámetros
como la IP del cliente, el encabezado HTTP, o los patrones de URL. Con estas configuraciones
avanzadas, HAProxy no solo actúa como un simple distribuidor de tráfico, sino que
se convierte en una herramienta integral para la gestión eficiente y segura de la
infraestructura web.

### Global Configuration

    ```wp-block-preformatted
    global    log /dev/log    local0    log /dev/log    local1 notice    chroot /var/lib/haproxy    stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners    stats timeout 30s    user haproxy    group haproxy    daemon    maxconn 32768    ca-base /etc/ssl/certs    crt-base /etc/ssl/private    ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384    ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256    ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
    ```

 * **log /dev/log local0 y local1 notice**: Define los destinos de registro (logging)
   y los niveles de severidad. `local0` y `local1` son las facilidades de syslog.
 * **chroot /var/lib/haproxy**: Cambia el directorio raíz de HAProxy para aumentar
   la seguridad.
 * **stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners**:
   Crea un socket UNIX para comandos de administración.
 * **stats timeout 30s**: Tiempo de espera para las conexiones en el socket de estadísticas.
 * **user haproxy y group haproxy**: Ejecuta HAProxy con los permisos de usuario
   y grupo especificados.
 * **daemon**: Ejecuta HAProxy en segundo plano.
 * **maxconn 32768**: Establece el número máximo de conexiones simultáneas.
 * **ca-base y crt-base**: Directorios base para certificados SSL.
 * **ssl-default-bind-ciphers y ssl-default-bind-ciphersuites**: Define las suites
   de cifrado por defecto para conexiones SSL.
 * **ssl-default-bind-options**: Opciones SSL adicionales, como la versión mínima
   de TLS permitida.

### Default Configuration

    ```wp-block-preformatted
    defaults    log     global    mode    http    option  httplog    option  dontlognull    option forwardfor    timeout  http-request 60s    timeout connect 600s    timeout client  600s    timeout server  600s    errorfile 400 /etc/haproxy/errors/400.http    errorfile 403 /etc/haproxy/errors/403.http    errorfile 408 /etc/haproxy/errors/408.http    errorfile 500 /etc/haproxy/errors/500.http    errorfile 502 /etc/haproxy/errors/502.http    errorfile 503 /etc/haproxy/errors/503.http    errorfile 504 /etc/haproxy/errors/504.http
    ```

 * **log global**: Usa los parámetros de logging definidos en la sección `global`.
 * **mode http**: Establece el modo de operación HTTP.
 * **option httplog**: Activa el registro HTTP detallado.
 * **option dontlognull**: No registra conexiones nulas.
 * **option forwardfor**: Añade una cabecera `X-Forwarded-For` con la IP del cliente.
 * **timeout http-request 60s**: Tiempo de espera para solicitudes HTTP.
 * **timeout connect 600s**: Tiempo de espera para conexiones TCP.
 * **timeout client 600s y timeout server 600s**: Tiempo de espera para las interacciones
   entre cliente y servidor.
 * **errorfile 4xx/5xx**: Archivos de error personalizados para códigos HTTP específicos.

### Estadísticas

    ```wp-block-preformatted
    listen stats    bind  *:9000    mode  http    stats enable    stats hide-version    stats refresh 10s    stats show-node    stats uri  /server-status
    ```

 * *_bind :9000_: Escucha en el puerto 9000.
 * **mode http**: Operación en modo HTTP.
 * **stats enable**: Habilita la interfaz de estadísticas.
 * **stats hide-version**: Oculta la versión de HAProxy en la interfaz de estadísticas.
 * **stats refresh 10s**: Actualiza las estadísticas cada 10 segundos.
 * **stats show-node**: Muestra el nombre del nodo.
 * **stats uri /server-status**: Define la URI para acceder a las estadísticas.

### Frontends

#### HTTP Frontend

    ```wp-block-preformatted
    frontend www80_front    bind *:80    mode http    option httplog    acl is_example1.com hdr_end(host) -i example1.com    acl is_example2.com hdr_end(host) -i example2.com    acl is_www.example2.com hdr_end(host) -i www.example2.com    acl is_example3.com hdr_end(host) -i example3.com    acl is_www.example3.com hdr_end(host) -i www.example3.com    use_backend example180 if is_example1.com    use_backend example280 if is_example2.com    use_backend example280 if is_www.example2.com    use_backend example380 if is_example3.com    use_backend example380 if is_www.example3.com
    ```

 * *_bind :80_: Escucha en el puerto 80.
 * **mode http**: Operación en modo HTTP.
 * **option httplog**: Activa el registro HTTP detallado.
 * **acl is_example.com**: Define reglas ACL para verificar el nombre del host.
 * **use_backend example80**: Usa el backend correspondiente si la condición ACL
   se cumple.

#### HTTPS Frontend

    ```wp-block-preformatted
    frontend www443_front    mode tcp    option tcplog    bind *:443    acl tls req.ssl_hello_type 1    tcp-request inspect-delay 1s    tcp-request content accept if tls    acl is_example1.com_443 req.ssl_sni -i example1.com    acl is_example2.com_443 req.ssl_sni -i example2.com    acl is_www.example2.com_443 req.ssl_sni -i www.example2.com    acl is_example3.com_443 req.ssl_sni -i example3.com    acl is_www.example3.com_443 req.ssl_sni -i www.example3.com    use_backend example1443 if is_example1.com_443    use_backend example2443 if is_example2.com_443    use_backend example2443 if is_www.example2.com_443    use_backend example3443 if is_example3.com_443    use_backend example3443 if is_www.example3.com_443
    ```

 * *_bind :443_: Escucha en el puerto 443.
 * **mode tcp**: Operación en modo TCP.
 * **option tcplog**: Activa el registro TCP detallado.
 * **acl tls req.ssl_hello_type 1**: Verifica si es una conexión TLS.
 * **tcp-request inspect-delay 1s**: Tiempo de espera para inspección de contenido
   TCP.
 * **tcp-request content accept if tls**: Acepta la solicitud si es una conexión
   TLS.
 * **acl is_example.com_443**: Define reglas ACL para verificar el SNI (Server Name
   Indication).
 * **use_backend example443**: Usa el backend correspondiente si la condición ACL
   se cumple.

### Backends

#### Example 1

    ```wp-block-preformatted
    backend example180    mode http    server apache80 192.168.20.12:80 send-proxy checkbackend example1443    mode tcp    option ssl-hello-chk    server apache443 192.168.20.12:443 send-proxy check
    ```

 * **mode http/tcp**: Define el modo de operación del backend.
 * **server apache80/apache443**: Define el servidor backend y su IP y puerto.
 * **send-proxy**: Envia información PROXY al servidor backend.
 * **check**: Habilita la verificación de estado del servidor.

#### Example 2

    ```wp-block-preformatted
    backend example280    mode http    server apache80 192.168.20.15:80 send-proxy checkbackend example2443    mode tcp    option ssl-hello-chk    server apache443 192.168.20.15:443 send-proxy check
    ```

#### Example 3

    ```wp-block-preformatted
    backend example380    mode http    server apache80 192.168.20.14:80 send-proxy checkbackend example3443    mode tcp    option ssl-hello-chk    server apache443 192.168.20.14:443 send-proxy check
    ```

Configuración final completa del fichero de haproxy como proxy inverso con multiples
dominios:

    ```wp-block-code
    global
        log /dev/log    local0
        log /dev/log    local1 notice
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
        stats timeout 30s
        user haproxy
        group haproxy
        daemon
        maxconn 32768

        # Default SSL material locations
        ca-base /etc/ssl/certs
        crt-base /etc/ssl/private

        # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
        ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
        ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
        ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets

    defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        option forwardfor
        timeout  http-request 60s
        timeout connect 600s
        timeout client  600s
        timeout server  600s
        errorfile 400 /etc/haproxy/errors/400.http
        errorfile 403 /etc/haproxy/errors/403.http
        errorfile 408 /etc/haproxy/errors/408.http
        errorfile 500 /etc/haproxy/errors/500.http
        errorfile 502 /etc/haproxy/errors/502.http
        errorfile 503 /etc/haproxy/errors/503.http
        errorfile 504 /etc/haproxy/errors/504.http

    listen  stats
        bind  *:9000
        mode  http
        stats enable
        stats hide-version
        stats refresh 10s
        stats show-node
        stats uri  /server-status

    frontend www80_front
        bind *:80
        mode http
        option httplog

        acl is_example1.com hdr_end(host) -i example1.com
        acl is_example2.com hdr_end(host) -i example2.com
        acl is_www.example2.com hdr_end(host) -i www.example2.com
        acl is_example3.com hdr_end(host) -i example3.com
        acl is_www.example3.com hdr_end(host) -i www.example3.com

        use_backend example180 if is_example1.com
        use_backend example280 if is_example2.com
        use_backend example280 if is_www.example2.com
        use_backend example380 if is_example3.com
        use_backend example380 if is_www.example3.com

    frontend www443_front
        mode tcp
        option tcplog
        bind *:443
        acl tls req.ssl_hello_type 1
        tcp-request inspect-delay 1s
        tcp-request content accept if tls

        acl is_example1.com_443 req.ssl_sni -i example1.com
        acl is_example2.com_443 req.ssl_sni -i example2.com
        acl is_www.example2.com_443 req.ssl_sni -i www.example2.com
        acl is_example3.com_443 req.ssl_sni -i example3.com
        acl is_www.example3.com_443 req.ssl_sni -i www.example3.com

        use_backend example1443 if is_example1.com_443
        use_backend example2443 if is_example2.com_443
        use_backend example2443 if is_www.example2.com_443
        use_backend example3443 if is_example3.com_443
        use_backend example3443 if is_www.example3.com_443

    backend example180
        mode http
        server apache80 192.168.20.12:80 send-proxy check

    backend example1443
        mode tcp
        option ssl-hello-chk
        server apache443 192.168.20.12:443 send-proxy check

    backend example280
        mode http
        server apache80 192.168.20.15:80 send-proxy check

    backend example2443
        mode tcp
        option ssl-hello-chk
        server apache443 192.168.20.15:443 send-proxy check

    backend example380
        mode http
        server apache80 192.168.20.14:80 send-proxy check

    backend example3443
        mode tcp
        option ssl-hello-chk
        server apache443 192.168.20.14:443 send-proxy check
    ```

### Explicación

 * **Frontend HTTP (www80_front)**: Escucha en el puerto 80 y utiliza reglas ACL
   para redirigir el tráfico HTTP basado en el host.
    - Por ejemplo, el tráfico destinado a `example1.com` se dirige al backend `example180`.
 * **Frontend HTTPS (www443_front)**: Escucha en el puerto 443 y utiliza reglas 
   ACL para redirigir el tráfico HTTPS basado en el SNI (Server Name Indication).
    - Por ejemplo, el tráfico destinado a `example1.com` se dirige al backend `example1443`.
 * **Backends**: Define los servidores backend a los que se dirige el tráfico.
    - `example180` y `example1443` corresponden a `example1.com`.
    - `example280` y `example2443` corresponden a `example2.com`.
    - `example380` y `example3443` corresponden a `example3.com`.

Esta configuración permite manejar múltiples dominios y subdominios en los puertos
HTTP y HTTPS, redirigiendo el tráfico a los backends correspondientes según las 
reglas definidas.

### Conclusión

Esta configuración de HAProxy permite gestionar múltiples dominios y subdominios
en los puertos HTTP y HTTPS. Las ACLs se utilizan para dirigir el tráfico a los 
backends apropiados, asegurando que cada solicitud se maneje correctamente según
el dominio solicitado. La seguridad se refuerza
