Как настроить HAProxy для нескольких SSL-сертификатов

8

Мне нужно настроить HAProxy с двумя разными SSL-сертификатами

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

Теперь я узнал из поста о сбое сервера ( настройка нескольких сертификатов SSL в Haproxy ), как использовать 2 сертификата, однако сервер продолжает использовать первый сертификат, упомянутый для обоих доменов.

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

Как сообщить HAProxy, какой сертификат использовать в зависимости от URL?

Полная конфигурация:

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
Мерлин
источник
Можете выложить свой полный конфиг?
Грегл
конечно. Я обновил вопрос.
Мерлин
В приведенном выше фрагменте конфигурации вы перечисляете две crtдирективы в своей bindстроке, но в полной конфигурации у вас есть только одна ... Это предназначено? У этого сертификата есть записи SAN, или это подстановочный знак?
Грегл
извините за ошибку, я взял конфиг после того, как убрал строку. Моя цель - разрешить отдельные ssl-сертификаты для отдельных доменов, и я довольно новичок в HAProxy. Добавлен второй сертификат в конфиге, указанном выше.
Мерлин,
Какой клиент вы используете, где он предоставляет неправильный сертификат?
Грегл

Ответы:

9

Убедитесь, что вы используете HAProxy 1.6 или выше

Этот вопрос немного старый, но я столкнулся с той же самой проблемой с конфигурациями, подобными OP.

HAProxy 1.5 принимает множественный crtсинтаксис для bindопции; однако при ответе он использует только первый сертификат.

HAProxy 1.6, кажется, отвечает сертификатом на основе запроса вызывающего абонента. Это не требует каких-либо специальных sniACL в конфигурации.

Вот пример, который работает на 1.6, но не используется cert2.pemпри ответе на запросы place2.comна 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
источник
2

Как вы тестируете, какой сертификат предоставляет haproxy? Если вы используете openssl s_client, -servername api.domain.comимейте в виду, что для отправки SNI-информации требуется дополнительный параметр ( ), который haproxy должен решить, какой сертификат предоставить.

romble
источник
Я не уверен, что понимаю ваш ответ. В приведенном выше примере используется строка: use_backend bk_cert1 if {ssl_fc_sni my.example.com}, однако я использую по одному бэкэнду для обоих и настраиваю apache для различения на основе URL-адресов, что делать. Возможно ли использовать несколько сертификатов SSL с одним бэкэндом?
Мерлин
1
Да, ты не понимаешь мой ответ. Я сомневаюсь в вашей методологии тестирования, а не в вашей текущей конфигурации.
Вомбл
Ну, насколько я понимаю, в представленном мною конфиге не так много тестирования. Единственное, что он проверяет, это если указанный домен прошел через https или нет, и если нет, он перенаправляет на https. Но это не вопрос. Мне интересно, как назначить конкретные сертификаты для соответствующего URL-адреса.
Мерлин
3
«Однако сервер продолжает использовать первый сертификат, упомянутый для обоих доменов» - что является основанием для этого утверждения в вашем вопросе, если не в вашем собственном тестировании?
Уомбл