5 votes

Comment faire pour que HAProxy route TCP en fonction de SNI (en utilisant openssl s_client pour tester) ?

Je veux utiliser HAProxy pour terminer les connexions TCP cryptées par TLS et pour transmettre le trafic TCP non crypté à divers backends en fonction de l'indication du nom du serveur utilisé pour initier la connexion TLS.

J'ai 3 services fonctionnant sur un serveur dorsal, chacun sur un port différent (5001, 5002, 5003). HAProxy se lie au port 5000. J'aimerais acheminer les connexions vers les deux premiers services par nom ou vers le troisième s'il n'y a pas de correspondance. J'initie la connexion à HAProxy en utilisant openssl s_client . Cependant, dans les journaux, je peux voir que les connexions ne sont jamais acheminées que vers le serveur par défaut, c'est-à-dire que le SNI semble être ignoré.

DNS :

A record     demo.sni.example.com     1.2.3.4
CNAME        1.sni.example.com        pointing to demo.sni.example.com   
CNAME        2.sni.example.com        pointing to demo.sni.example.com   

Par exemple, je voudrais que le routage suivant se produise :

SNI = 1.sni.example.com:5000 -> 1.2.3.4:5001
SNI = 2.sni.example.com:5000 -> 1.2.3.4:5002
anything else on port 5000 -> 1.2.3.4:5003

haproxy.cfg :

global
  log stdout  format raw  local0 info

defaults
  timeout client 30s
  timeout server 30s
  timeout connect 5s
  option tcplog

frontend tcp-proxy
  bind :5000 ssl crt combined-cert-key.pem
  mode tcp
  log global
  tcp-request inspect-delay 5s
  tcp-request content accept if { req_ssl_hello_type 1 }

  use_backend bk_sni_1 if { req.ssl_sni -i 1.sni.example.com }
  use_backend bk_sni_2 if { req.ssl_sni -i 2.sni.example.com }
  default_backend bk_default

backend bk_sni_1
  mode tcp
  log global
  balance roundrobin
  server server1 1.2.3.4:5001 check

backend bk_sni_2
  mode tcp
  log global
  balance roundrobin
  server server1 1.2.3.4:5002 check

backend bk_default
  mode tcp
  log global
  balance roundrobin
  server server1 1.2.3.4:5003 check

combined-cert-key.pem est un fichier de certificat auto-signé plus la clé où le CN est l'IP du serveur ( 1.2.3.4 ) et il y a des SANs de toutes les valeurs DNS et de l'IP.

Les connexions initiées à l'aide de openssl s_client :

J'ai essayé de me connecter via le DNS (enregistrements A et CNAME, ainsi que l'IP) :

echo test | openssl s_client -connect demo.sni.example.com:5000 -servername 1.sni.example.com
echo test | openssl s_client -connect 1.sni.example.com:5000 -servername 1.sni.example.com
echo test | openssl s_client -connect 1.2.3.4:5000 -servername 1.sni.example.com

Cependant, toutes les connexions sont acheminées vers le backend par défaut. bk_default .

Pourquoi HAProxy ne reconnaît-il pas le nom de serveur SNI ? (J'utilise la dernière image docker HAProxy : https://hub.docker.com/_/haproxy )

7voto

John Points 223

La réponse est d'utiliser ssl_fc_sni au lieu de req.ssl_sni . Le premier est destiné aux sessions terminées par SSL, tandis que le second est destiné aux sessions où le TCP passe directement.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X