Como configurar o HAProxy para vários certificados SSL

8

Preciso configurar o HAProxy com dois certificados SSL diferentes

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

Agora eu aprendi com uma postagem no serverfault ( Configurar vários certificados SSL no Haproxy ) como usar 2 certificados, no entanto, o servidor continua usando o primeiro certificado mencionado para os dois domínios.

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 }
    ...

Como dizer ao HAProxy qual certificado usar, dependendo da URL?

Configuração 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
Merlin
fonte
Você pode postar sua configuração completa?
GregL
certo. Eu atualizei o quesiton.
merlin
Na configuração cortada acima, você lista duas crtdiretivas em sua bindlinha, mas na configuração completa você tem apenas uma ... Isso é intencional? Esse certificado possui entradas SAN ou é um curinga?
GregL
desculpe meu erro, tirei a configuração depois que removi a linha. Meu objetivo é permitir certificados SSL individuais para domínios individuais e sou bastante novo no HAProxy. Adicionado o segundo certificado na configuração listada acima.
merlin
Qual cliente você está usando, onde está fornecendo o certificado errado?
GregL

Respostas:

9

Verifique se você está executando o HAProxy 1.6 ou superior

Essa pergunta é um pouco antiga, mas encontrei exatamente o mesmo problema com configurações semelhantes ao OP.

O HAProxy 1.5 aceita a crtsintaxe múltipla em uma bindopção; no entanto, ele usa apenas o primeiro certificado ao responder.

O HAProxy 1.6 parece responder com o certificado com base na solicitação do chamador. Isso não parece exigir nenhuma sniACL especial na configuração.

Aqui está um exemplo que funciona na versão 1.6, mas falha ao usar cert2.pemao responder a solicitações para place2.coma 1.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
fonte
2

Como você está testando qual certificado haproxy está apresentando? Se você estiver usando openssl s_client, lembre-se de que ele requer um parâmetro adicional ( -servername api.domain.com) para enviar as informações do SNI que haproxy precisa para decidir qual certificado apresentar.

mulher
fonte
Não tenho certeza se entendi sua resposta. O exemplo mencionado acima usa a linha: use_backend bk_cert1 se {ssl_fc_sni my.example.com}, no entanto, estou cancelando o envio de um back-end para ambos e configure o apache para distinguir com base no URL o que fazer. São possíveis vários certificados SSL com um back-end?
merlin
1
Sim, você não entende minha resposta. Eu duvido da sua metodologia de teste, não da sua configuração atual.
womble
Bem, tanto quanto eu entendo, não há muitos testes na configuração que apresentei. A única coisa que ele faz é testar se o domínio especificado passou por https ou não e, caso contrário, ele é redirecionado para https. Mas essa não é a questão. Eu estou querendo saber como dedicar certificados específicos a um URL de correspondência múltipla.
merlin
3
"no entanto, o servidor continua a usar o primeiro certificado mencionado para os dois domínios" - qual é a base para essa afirmação na sua pergunta, senão no seu próprio teste?
womble