J'ai HAProxy pour mes deux sites, l'un public et l'autre privé.
www.mysite.com private.mysite.com
Atm, j'utilise haproxy comme ceci:
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
Ce que cela devrait faire, c'est demander un certificat client (facultatif) et continuer. Si le domaine n'est pas www.example.com et que le visiteur ne peut pas fournir le bon certificat ou que le chemin est / ghost / et que le visiteur ne peut pas fournir le bon certificat, il doit être redirigé vers https://www.example.com
Jusqu'à présent, cela fonctionne bien. Cependant, j'ai reçu des plaintes d'utilisateurs de Mac naviguant sur mon site avec Safari, qui leur demandaient constamment le certificat lorsqu'ils naviguaient sur https://www.example.com/ alors que, par exemple, Firefox ne demandait que lors de la navigation sur https: //private.example .com / ou https://www.example.com/ghost/ .
Apparemment, c'est comme ça que Safari fonctionne, donc je ne peux pas résoudre ce problème. Mon idée était d'utiliser SNI pour diviser les différents 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
Bien sûr, cela ne fonctionne pas car
une. Je ne peux pas avoir deux frontends écoutant sur le port 443 avec une seule IP publique b. Je n'ai pas encore trouvé un moyen de dire "use_frontend if domain_www" ou quelque chose comme ça. (Uniquement use_backend ou use-server)
J'ai également essayé de le faire avec trois serveurs haproxy
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
Cela fonctionne, le problème ici est cependant que haproxy-private demande le certificat client, mais la demande n'atteint pas le navigateur. D'une manière ou d'une autre, haproxy-sni abandonne la demande.
De plus, j'ai maintenant trois serveurs haproxy ce qui n'est pas souhaitable (bien qu'une option possible si je ne peux pas trouver une meilleure solution).
De préférence, je voudrais quelque chose comme ça (composé .. ne sais pas les vraies options)
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
...
J'espère que quelqu'un peut me aider...
les versions récentes de haproxy prennent en charge un paramètre appelé
crt-list
qui vous permet de spécifier différents paramètres TLS en fonction du certificat correspondantvous pouvez l'utiliser comme ceci:
haproxy.conf:
crt-list.conf:
plus d'informations: https://cbonte.github.io/haproxy-dconv/1.9/configuration.html#5.1-crt-list
remarque sur la sécurité: toujours faire correspondre vos noms d'hôtes (sensibles) avec SNI
ssl_fc_sni
, pas le nom d'hôte HTTP. Sinon, un attaquant pourrait éventuellement contourner l'authentification de votre client en envoyant le TLS SNI dewww.example.org
mais définissez le nom d'hôte HTTP surprivate.example.org
!la source
ca-file
cadre différent .