NOPE LinkedIn

Catégories:
firewall

HAProxy to load balance HTTPS traffic

Article Original

Ces notes visent à comprendre ce que propose HAProxy pour équilibrer la charge du trafic HTTPS et la différence entre le mode HTTP et le mode TCP. Il est destiné aux administrateurs qui passent d’une ancienne implémentation d’équilibreur de charge à une nouvelle.

Avant de commencer, vous devez comprendre les bases des communications HTTPS et les principes des équilibreurs de charge et des fichiers de configuration HAProxy.

Contexte

Nous sommes en train d’améliorer notre couche de communication technologique avec nos clients et partenaires ainsi que de viser une disponibilité de service de 99,99 % à partir de 99,9 %. Notre infrastructure d’équilibreur de charge est un élément pour y parvenir. Il nécessite désormais la capacité d’équilibrer la charge du trafic TLS en fonction des sous-domaines et de rediriger correctement le trafic vers les bons backends.

Après avoir envisagé différentes solutions, nous avons décidé de conserver HAProxy car nous n’avions qu’à passer à la version 1.8 pour améliorer le support SNI et les contrôles de santé SNI. Cela a nécessité beaucoup plus de recherches que prévu pour bien comprendre les protocoles TLS et la différence entre les 2 modes de fonctionnement (TCP vs HTTP) dans HAProxy.

Voici un bref résumé pour vous aider à décider de l’itinéraire dont vous avez besoin ou que vous souhaitez emprunter.

HAProxy modes: TCP vs HTTP

Avec HAProxy, nous avons 2 options pour équilibrer la charge en fonction de l’indicateur de nom de serveur (SNI) :

  • Terminaison de session SSL au load balancer (Mode HTTP)
  • Intercommunication transparente entre le client et le serveur (Mode TCP)

SSL Termination — Mode HTTP

In the case of HAProxy, SSL session termination is done by using the HTTP mode and providing the load balancer with the proper certificates and associated chains. The traffic looks like this:

graph LR A -- SSL --> B B -- SSL --> A B -- Non SSL --> C C -- Non SSL --> B A([Client]) B(["fa:fa-shield-alt Load Balancer"]) C([Server])

Dans ce scénario, HAProxy vous permet de décider si vous souhaitez que le trafic entre l’équilibreur de charge et le serveur soit chiffré ou non. Le trafic crypté devrait être la norme même sur un réseau sécurisé, mais certains serveurs principaux ne le prennent pas toujours en charge, en particulier dans le cas d’applications héritées.

En mode HTTP, vous pouvez utiliser l’indicateur ssl_fc_sni ou les informations d’en-tête de l’hôte (hdr(host)) pour filtrer la session entrante et l’acheminer vers le serveur principal approprié.

Les avantages de la solution sont :

  • Fonctionne à la couche 7 et offre plus de fonctionnalités pour acheminer correctement le trafic et réécrire les données pour les serveurs principaux
  • Les serveurs dorsaux hérités peuvent être présentés comme des sites Web TLS

Et, dans notre cas, le gros inconvénient de cette méthode est :

  • Les certificats clients sont arrêtés au niveau des équilibreurs de charge et ne sont pas transmis tels quels au serveur principal.

Bien que HAProxy vous permette d’extraire chaque bit d’information du certificat client et de le placer dans l’en-tête des données envoyées au serveur, cela signifie que votre application doit lire les informations d’en-tête au lieu des informations de certificat. Pour nous, cela signifiait passer beaucoup de temps à réécrire le code hérité.

Transparent passthrough — Mode TCP

Pour le passthrough, HAProxy doit travailler sur la couche TCP (mode TCP). Le trafic ressemble à ceci :

graph LR A -- SSL --o B -- SSL --> C C -- SSL --o B -- SSL --> A A([Client]) B(["fa:fa-shield-alt Load Balancer"]) C([Server])
Étant donné que HAProxy ne déchiffre pas les données HTTPS, nous devons toujours obtenir les informations dont nous avons besoin pour router correctement. Heureusement, le protocole et la communication TLS sont les suivants :
sequenceDiagram autonumber Client->>Server: Client Hello Server->>Client: Server Hello
Certificate
Server Key Exchange*
Certificate Request*
Server Hello Done Client->>Server: Certificate*
Client Key Exchange
Certificate Verify*
[ChargeCipherSpec]
Finished Server->>Client: [ChargeCipherSpec]
Finished Server->>Client: Application Data Client->>Server: Application Data
Figure 1: Source Et suivant RFC5246, le protocole TLS permet au message ClientHello de contenir des extensions. L’une de ces extensions est l’extension server_name. HAProxy peut récupérer les informations SNI du message ClientHello :

tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
acl acl_app1 req_ssl_sni -i app1.domain.com
use_backend bk_app1 if acl_app1

Dans ce mode, vous utilisez la valeur req_ssl_sni pour filtrer la session entrante et l’acheminer vers le serveur principal approprié. ssl_fc_sni n’est pas disponible en mode TCP ni l’en-tête (hdr(host)) car le trafic est crypté.

Les avantages de la solution sont :

  • Les certificats clients sont envoyés aveuglément aux serveurs principaux appropriés basés sur SNI
  • Pas besoin de déployer les certificats et les chaînes de serveur sur les équilibreurs de charge
  • Et, dans notre cas, nous n’avons pas besoin de mettre à jour le code hérité

Le choix du mode TCP a parfaitement fonctionné dans notre cas d’utilisation et nous a permis de prendre en charge le code hérité et les mécanismes d’authentification (certificat client)

Nos prochaines étapes

Dans notre cas, les certificats clients et les PKI personnalisées nécessitent une grande quantité de ressources pour le code et l’infrastructure. Ainsi, nous avons décidé de passer lentement à une autre méthode d’authentification.

La nouvelle solution nous offre :

  • Meilleure disponibilité
  • Gestion réduite pour nous et nos clients du composant d’authentification dans notre écosystème.
  • Réduction des voies d’attaques supplémentaires en signant chaque demande
  • Capacités d’inscription même en cas de perte de centres de données

Et, puisqu’il s’agit d’un article sur HAProxy, il améliore les ensembles de fonctionnalités que nous pouvons utiliser en mettant à niveau notre couche d’équilibrage de charge en mode HTTP.

Resssources: HAProxy 1.8 configuration manual: A good example of client certificate information rewriting: