Eu tenho HAProxy para meus dois sites, um deles público e outro privado.
www.mysite.com private.mysite.com
Atm, estou usando haproxy assim:
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
O que isso deve fazer é solicitar um certificado de cliente (opcionalmente) e continuar. Se o domínio não for www.example.com e o visitante não puder fornecer o certificado correto ou o caminho for / ghost / e o visitante não puder fornecer o certificado correto, deverá ser redirecionado para https://www.example.com
Até agora, isso funciona bem. No entanto, recebi reclamações dos usuários de Mac que navegavam no meu site com o Safari de que continuavam sendo solicitados pelo certificado quando navegavam em https://www.example.com/, enquanto, por exemplo, o Firefox apenas solicita quando navega em https: //private.example .com / ou https://www.example.com/ghost/ .
Aparentemente, é assim que o Safari funciona, então não posso consertar isso. Minha ideia era usar o SNI para dividir entre diferentes 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
Claro que isso não funciona porque
uma. Não posso ter dois frontends escutando na porta 443 com apenas um IP público b. Ainda não encontrei uma maneira de dizer "use_frontend if domain_www" ou algo assim. (Use apenas back-end ou use-server)
Eu também tentei fazê-lo com três servidores 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
Isso funciona, mas o problema aqui é que o haproxy-private solicita o certificado do cliente, mas a solicitação não chega ao navegador. De alguma forma, haproxy-sni descarta o pedido.
Além disso, agora tenho três servidores haproxy que não são desejáveis (embora seja uma opção possível se não encontrar uma solução melhor).
De preferência, eu gostaria de algo assim (inventado .. não sei as opções reais)
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
...
Eu espero que alguém possa me ajudar com isso...
as versões recentes do haproxy suportam uma configuração chamada
crt-list
que permite especificar diferentes configurações de TLS com base no certificado correspondentevocê pode usá-lo assim:
haproxy.conf:
crt-list.conf:
mais informações: https://cbonte.github.io/haproxy-dconv/1.9/configuration.html#5.1-crt-list
observação sobre segurança: sempre corresponda seus nomes de host (sensíveis) ao SNI
ssl_fc_sni
, não ao nome do host HTTP. Caso contrário, um invasor poderá ignorar sua autenticação de certificado de cliente enviando o TLS SNI de,www.example.org
mas defina o nome do host HTTP comoprivate.example.org
!fonte
ca-file
cenário diferente .