Vraag HAProxy met SNI en verschillende SSL-instellingen


Ik heb HAProxy voor mijn twee sites, een van hen openbaar en een privé.

www.mysite.com private.mysite.com

Atm, ik gebruik haproxy als volgt:

frontend mysite_https
  bind *.443 ssl crt /etc/mycert.pem ca-file /etc/myca.pem verify optional no-sslv3
  mode http
  acl domain_www     hdr_beg(host) -i www.
  acl domain_private hdr_beg(host) -i private.
  acl path_ghost     path_beg         /ghost/
  acl clientcert     ssl_c_used

  redirect location https://www.example.com if path_ghost !clientcert
  redirect location https://www.example.com if !domain_www !clientcert

  use_backend bknd_private if domain_private
  use_backend bknd_www     if domain_www

  default_backend bknd_www

Wat dit moet doen is een clientcertificaat aanvragen (optioneel) en doorgaan. Als het domein geen www.example.com is en de bezoeker niet het juiste certificaat kan verstrekken of als het pad / ghost / is en de bezoeker niet het juiste certificaat kan verstrekken, moet het worden omgeleid naar https://www.example.com

Tot nu toe werkt dit prima. Ik kreeg echter klachten van Mac-gebruikers die op mijn site met Safari aan het bladeren waren, dat ze steeds om het certificaat worden gevraagd wanneer ze browsen https://www.example.com/ overwegende dat Firefox bijvoorbeeld alleen vraagt ​​tijdens het browsen https://private.example.com/ of https://www.example.com/ghost/.

Dat is blijkbaar net hoe Safari werkt, dus dat kan ik niet oplossen. Mijn idee was om SNI te gebruiken om te splitsen tussen verschillende frontends

frontend mysite_https
  bind *.443 ssl crt /etc/mycert.pem no-sslv3

frontend private_https
  bind *.443 ssl crt /etc/mycert.pem ca-file /etc/myca.pem verify optional no-sslv3

Dat werkt natuurlijk niet omdat

een. Ik kan niet twee frontends hebben die op poort 443 luisteren met slechts één publieke IP b. Ik heb nog geen manier gevonden om "use_frontend if domain_www" of iets dergelijks te zeggen. (Alleen use_backend of use-server)

Ik heb het ook geprobeerd met drie haproxy-servers

frontend haproxy-sni
bind *:443 ssl crt /etc/mycert.pem no-sslv3
mode tcp

tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }

acl domain_www ssl_fc_sni_end -i www.example.com

use-server server1 haproxy-private.lan  if !domain_www
use-server server2 haproxy-public.lan   if domain_www

Dit werkt, het probleem hier is echter dat haproxy-private om het clientcertificaat vraagt, maar dat de aanvraag de browser niet bereikt. Op de een of andere manier laat haproxy-sni het verzoek vallen.

Ook heb ik nu drie haproxy-servers die niet wenselijk is (hoewel een mogelijke optie als ik geen betere oplossing kan vinden).

Het liefst zou ik zoiets willen (verzonnen .. weet niet wat de echte opties zijn)

frontend mysite_https
  bind *.443 ssl crt /etc/mycert.pem no-sslv3
  mode http

  acl domain_www     hdr_beg(host) -i www.
  acl domain_private hdr_beg(host) -i private.
  acl path_ghost     path_beg         /ghost/

  ssl_options ca-file /etc/myca.pem verify optional if !www_domain          # made up!
  ssl_options ca-file /etc/myca.pem verify optional if !path_ghost          # made up!

  acl clientcert     ssl_c_used

  redirect location https://www.example.com if path_ghost !clientcert
  redirect location https://www.example.com if !domain_www !clientcert
  ...

Ik hoop dat iemand me hiermee kan helpen ...


7
2018-01-27 11:51


oorsprong




antwoorden:


Ik heb een oplossing voor dit probleem gevonden, waarvoor geen extra servers of services nodig zijn. Ik weet niet helemaal zeker of dit geen nieuwe problemen oplevert. Voor mij lijkt het nu te werken.

De manier waarop ik het deed, was om een ​​frontend te maken voor elk domein waarvoor verschillende ssl-instellingen nodig waren. Vervolgens stel ik de bindoptie van die frontends in op hoge poorten (deze zijn niet bereikbaar via het publiek!).

Ik creëerde een andere frontend die luisterde op poort: 443 om verkeer te verdelen op basis van SNI en de back-endservers in te stellen op 127.0.0.1:high-port.

Op deze manier heb ik een soort van lus gemaakt in haproxy

[incoming]->[haproxy:443]->[haproxy:7000]->[www.intern.lan]
[incoming]->[haproxy:443]->[haproxy:8000]->[private.intern.lan]

Hier is het configuratie gedeelte.

frontend frnd_snipt                                             # Frontend_SNI-PassThrough (snipt)
  bind *:443                                                    # Do not use bind *:8443 ssl crt etc....!
  option tcplog
  mode tcp 

  tcp-request inspect-delay 5s
  tcp-request content accept if { req_ssl_hello_type 1 } 

  acl subdomain_is_www   req_ssl_sni -i www.example.com
  acl subdomain_is_www   req_ssl_sni -i example.com
  acl subdomain_is_private req_ssl_sni -i private.example.com

  use_backend bknd_snipt_private if subdomain_is_private
  use_backend bknd_snipt_www  if subdomain_is_www

backend bknd_snipt_www
  mode tcp                                              # tcp mode must match the frontend mode - already set as default in [global]
  server snipt-www 127.0.0.1:7000                       # run without "check", otherwise haproxy checks itself all the time!

backend bknd_snipt_private
  mode tcp     
  server snipt-private 127.0.0.1:8000                   # also, don't add "ssl" when in tcp mode. "ssl" is an http mode option (result in "NO-SRV" when set in tcp)

##### NORMAL HAPROXY PART #####
frontend www_example_com                                # this frontend can be in tcp or http mode...
  bind *:7000 ssl crt /etc/mycert.pem no-sslv3          # www. frontend with normal https
  mode http
  option httplog


frontend private_example_com
  bind *:8000 ssl crt /etc/mycert.pem ca-file /etc/myca.pem verify optional no-sslv3        # private. frontend with client certificate request.
  mode http
  option httplog
  ... # whatever you have in your frontend

Als iemand hier gedachten over heeft, of enig idee waarom dit een slecht idee zou kunnen zijn, laat het me weten. Het werkt, maar ik vraag me af waarom use_frontend geen optie is. Misschien omdat het iets is dat om welke reden dan ook niet mag worden gedaan.


10
2018-01-31 10:29



Goed idee. Ik kon ook geen documentatie over deze opstelling vinden. Zijn de prestaties vergelijkbaar met deze HAProxy-lus? - JB.
Sry, ik weet niet hoe performant het is omdat A: het niet lang heeft gebruikt (vanwege bron-ip-filters), B: geen hoogteverkeersite hebben, waar prestatieoptimalisatie interessanter zou zijn ... - mohrphium
Ik heb net apache2 voor haproxy gezet, wat werkt, maar een beetje dom is omdat single-point-of-failure voor hapeoxy cluster en (denk ik) prestatieproblemen (ik denk dat hap sneller is dan ap2, geen echte gegevens heeft over dat wel.) - mohrphium