Назад | Перейти на главную страницу

HAProxy SSL roundrobin не работает, когда SSL завершен и перенаправлен

Я использую следующую конфигурацию для завершения SSL, чтобы я мог проверить запрос, выполнить перезапись URL, ACL и т. Д., А затем перенаправить трафик SSL обратно на мои внутренние серверы. Однако я не могу зациклиться на работе. Я могу зациклиться на работе, если просто использую "режим tcp" и выполняю прямую маршрутизацию tcp, но липкость перестает работать, как только я начинаю завершать SSL во внешнем интерфейсе.

Вот мой конфиг:

frontend https-forward
  bind *:443 ssl crt /etc/haproxy/certs.d/combo.pem

  option http-server-close
  option forwardfor
  reqadd X-Forwarded-Proto:\ https
  reqadd X-Forwarded-Port:\ 443

  capture request header Referrer len 64
  capture request header Content-Length len 10
  capture request header User-Agent len 64

  # set HTTP Strict Transport Security (HTST) header
  rspadd  Strict-Transport-Security:\ max-age=15768000

  # some ACLs and URL rewrites...

  default_backend backstuff

backend backstuff

  log 127.0.0.1 local2 notice

  balance roundrobin
  option ssl-hello-chk
  stick-table type binary len 32 size 30k expire 30m

  acl clienthello req_ssl_hello_type 1
  acl serverhello rep_ssl_hello_type 2

  tcp-request inspect-delay 5s
  tcp-request content accept if clienthello
  tcp-response content accept if serverhello

  stick on payload_lv(43,1) if clienthello
  stick store-response payload_lv(43,1) if serverhello

  server PO1 10.35.59.160:443 ssl verify none maxconn 5000
  server PO2 10.35.59.161:443 ssl verify none maxconn 5000

Причина, по которой вы не можете придерживаться идентификатора сеанса SSL, как при использовании mode http (по умолчанию, если вы явно не укажете mode tcp) заключается в том, что вы пытаетесь сделать это с определенными байтами полезной нагрузки пакета, тогда как на самом деле пакеты уже были декодированы, и эти смещения могут содержать полностью случайные данные.

У вас есть два варианта.

  1. Палка на основе IP-адреса источника

    Если вы не против того, чтобы придерживаться IP-адреса клиента, а не идентификатора сеанса SSL, как вы делаете сейчас, вы можете изменить свою конфигурацию, чтобы она выглядела следующим образом:

    frontend https-forward
      bind *:443 ssl crt /etc/haproxy/certs.d/combo.pem
      mode http
    
      option http-server-close
      option forwardfor
      reqadd X-Forwarded-Proto:\ https
      reqadd X-Forwarded-Port:\ 443
    
      capture request header Referrer len 64
      capture request header Content-Length len 10
      capture request header User-Agent len 64
    
      # set HTTP Strict Transport Security (HTST) header
      rspadd  Strict-Transport-Security:\ max-age=15768000
    
      # some ACLs and URL rewrites...
    
      default_backend backstuff
    
    backend backstuff
      mode http
      log 127.0.0.1 local2 notice
      balance roundrobin
      option ssl-hello-chk
    
      stick-table type ip size 30k expire 30m
      stick on src
    
      server PO1 10.35.59.160:443 ssl verify none maxconn 5000
      server PO2 10.35.59.161:443 ssl verify none maxconn 5000
    

    Ключевыми изменениями являются stick-table и stick on строк, а также явное использование mode http.

    Как вы уже сказали, если многие клиенты, обращающиеся к вашему сайту, находятся за NAT, все они окажутся на одном сервере, так что это не самое плавное распределение, но оно работает и обеспечивает желаемую функциональность.

  2. Использовать идентификатор сеанса SSL, декодированный HAProxy

    Здесь вам нужно использовать знания HAproxy о подключении через ssl_fc_session_id (документы).

    ssl_fc_session_id : двоичный
    Возвращает SSL ID фронтального соединения, когда входящее соединение было выполнено через транспортный уровень SSL / TLS. Полезно привязать данного клиента к серверу. Важно отметить, что некоторые браузеры обновляют свой идентификатор сеанса каждые несколько минут.

    В этом случае вы должны использовать ту же конфигурацию, которую я предоставил выше, но с stick-table и stick строки изменены на:

      stick-table type binary len 32 size 30k expire 30m
      stick on ssl_fc_session_id
    

    Это действительно больше всего похоже на то, чего вы пытаетесь достичь.