Cómo configurar HAProxy para múltiples certificados SSL

8

Necesito configurar HAProxy con dos certificados SSL diferentes

  1. www.ejemplo.com
  2. api.example.com

Ahora aprendí de una publicación en serverfault ( Configurar múltiples certificados SSL en Haproxy ) cómo usar 2 certificados, sin embargo, el servidor continúa usando el primer certificado mencionado para ambos dominios.

Config:

frontend apache-https
    bind 192.168.56.150:443 ssl crt /certs/crt1.pem crt /certs/cert2.pem
    reqadd X-Forwarded-Proto:\ https
    default_backend apache-http

backend apache-http
    redirect scheme https if { hdr(Host) -i www.example.com } !{ ssl_fc }
    redirect scheme https if { hdr(Host) -i api.example.com } !{ ssl_fc }
    ...

¿Cómo decirle a HAProxy qué certificado usar según la URL?

Configuración completa:

global
    log /dev/log    local0
    log /dev/log    local1 notice
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    user haproxy
    group haproxy
    daemon

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

    ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
    ssl-default-bind-options no-sslv3
    tune.ssl.default-dh-param 2048 // better with 2048 but more processor intensive

defaults
        log     global
        mode    http
        option tcplog
        option  dontlognull
        timeout connect 5000
        timeout client  50000
        timeout server  50000

frontend apache-http
        bind 0.0.0.0:80
        mode http
        option http-server-close                # needed for forwardfor
        option forwardfor                       # forward IP Address of client
        reqadd X-Forwarded-Proto:\ http
        default_backend apache-http
        stats enable

frontend apache-https
        bind 0.0.0.0:443 ssl crt cer1.pem cert2.pem
        reqadd X-Forwarded-Proto:\ https
        default_backend apache-http

backend apache-http
        redirect scheme https if { hdr(Host) -i db.example.com } !{ ssl_fc }
        redirect scheme https if { hdr(Host) -i api2.example.com } !{ ssl_fc }
        balance roundrobin
        cookie SERVERID insert indirect nocache
        server www-1 10.0.0.101:80 cookie S1 check
        server www-2 10.0.0.102:80 cookie S2 check
        server www-3 10.0.0.103:80 cookie S3 check
esmerejón
fuente
¿Puedes publicar tu configuración completa?
GregL
Por supuesto. He actualizado la pregunta.
merlin
En la configuración recortada anterior, enumera dos crtdirectivas en su bindlínea, pero en la configuración completa solo tiene una ... ¿Es eso lo que se pretende? ¿Ese certificado tiene entradas SAN o es un comodín?
GregL
perdón por mi error, tomé la configuración después de quitar la línea. Mi objetivo es permitir certificados SSL individuales para dominios individuales y soy bastante nuevo en HAProxy. Se agregó el segundo certificado en la configuración mencionada anteriormente.
merlin
¿Qué cliente está utilizando cuando proporciona el certificado incorrecto?
GregL

Respuestas:

9

Asegúrese de estar ejecutando HAProxy 1.6 o superior

Esta pregunta es un poco vieja, pero me encontré exactamente con el mismo problema con configuraciones similares al OP.

HAProxy 1.5 acepta la crtsintaxis múltiple en una bindopción; sin embargo, solo usa el primer certificado cuando responde.

HAProxy 1.6 parece responder con el certificado basado en la solicitud de la persona que llama. Esto no parece requerir ninguna sniACL especial en la configuración.

Aquí hay un ejemplo que funciona en 1.6, pero no se usa cert2.pemal responder a solicitudes de place2.com1.5:

frontend http-in
        bind *:80
        bind *:443 ssl crt cert1.pem crt cert2.pem
        mode http

        acl common_dst hdr(Host) -m str place1.com place2.com

        use_backend be_common if common_dst

backend be_common
        # nothing special here.
davidzarlengo
fuente
2

¿Cómo está probando qué certificado haproxy presenta? Si está utilizando openssl s_client, tenga en cuenta que requiere un parámetro adicional ( -servername api.domain.com) para enviar la información de SNI que haproxy necesita para decidir qué certificado presentar.

womble
fuente
No estoy seguro si entiendo tu respuesta. El ejemplo mencionado anteriormente usa la línea: use_backend bk_cert1 if {ssl_fc_sni my.example.com} sin embargo, estoy desatando un backend para ambos y configuro apache para distinguir en función de la URL qué hacer. ¿Son posibles múltiples certificados SSL con un backend?
merlin
1
Sí, no entiendes mi respuesta. Dudo de su metodología de prueba, no de su configuración actual.
womble
Bueno, por lo que entiendo, no hay muchas pruebas en la configuración que presenté. Lo único que prueba es si el dominio especificado ha pasado por https o no y si no, se redirige a https. Pero esta no es la pregunta. Me pregunto cómo dedicar certificados específicos a una URL correspondiente.
Merlin
3
"sin embargo, el servidor continúa usando el primer certificado mencionado para ambos dominios": ¿cuál es la base de esta afirmación en su pregunta, si no es su propia prueba?
womble