ajout d'infos sur les optimisations et HTTP 100 Continue

This commit is contained in:
Gregory Colpart 2023-09-20 12:46:26 +02:00
parent 3df274b21b
commit 663095b461

View file

@ -732,21 +732,60 @@ backend myback
La section `resolvers` peut être configurée avec plusieurs paramètres pour indiquer les timeout, nombres de tentatives, comportement en cas d'erreur… La section `resolvers` peut être configurée avec plusieurs paramètres pour indiquer les timeout, nombres de tentatives, comportement en cas d'erreur…
## Optimisations TCP/kernel ## Haute performance
Sur un serveur servant principalement de proxy/load-balancer, nous conseillons plusieurs optimisations TCP/kernel, à appliquer au niveau "sysctl" : Si HAProxy encaisse un nombre de connexions non négligables, voici nos pistes d'optimisations applicables.
Sources d'inspiration :
* <https://medium.com/@pawilon/tuning-your-linux-kernel-and-haproxy-instance-for-high-loads-1a2105ea553e>
* <https://gist.github.com/jayjanssen/4039319>
* [Haute performance sous Linux](HowtoDebian/Reseau#haute-performance)
### Optimisations TCP/kernel
~~~{.ini} ~~~{.ini}
# Augmentation du nombre de connexions simultanées possibles
net.netfilter.nf_conntrack_max=1000000 net.netfilter.nf_conntrack_max=1000000
# Réduction du délai de timeout FIN net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_fin_timeout=20 net.ipv4.tcp_fin_timeout=20
# Elargissement de la plage de ports locaux utilisables
net.ipv4.ip_local_port_range=1025 65534 net.ipv4.ip_local_port_range=1025 65534
# augmentation du nombre maximum d'orphelins net.ipv4.tcp_max_orphans=262144
net.ipv4.tcp_max_orphans=65536 net.core.somaxconn=100000
net.core.netdev_max_backlog=100000
fs.file-max=2000000
~~~ ~~~
### Optimisations systemd
~~~
$ cat /etc/systemd/system/haproxy.service.d/limits.conf
[Service]
LimitNOFILE=500000
~~~
### Optimisations haproxy.cfg
~~~
global
maxconn 500000
#nbproc 2
# cpu-map 1 0
# cpu-map 2 1
tune.maxrewrite 8000
tune.http.maxhdr 800
tune.bufsize 60000
tune.ssl.cachesize 1000000
defaults
maxconn 500000
~~~
> *Note* : à partir d'HAProxy 2.5, les « optimisations » concernant le CPU ne sont plus nécessaires
#### maxconn global vs defaults
Attention, le `maxconn` (global) fixe une limite globale à HAProxy.
Il n'est pas surchargé par le `maxconn` (defaults) qui va s'appliquer à tous les *frontend* et pourra lui être surchargé au cas par cas.
## Utiliser l'API runtime ## Utiliser l'API runtime
HaProxy propose une API accessible via un socket ou un port permettant de lui envoyer dynamiquement des commandes. HaProxy propose une API accessible via un socket ou un port permettant de lui envoyer dynamiquement des commandes.
@ -779,7 +818,7 @@ HaProxy propose une API accessible via un socket ou un port permettant de lui en
### Afficher les certificats SSL utilisés ### Afficher les certificats SSL utilisés
A partir de HaProxy 2.2 (Debian Bullseye, ou Buster avec les backports) : A partir de HaProxy 2.2 :
~~~ ~~~
# echo "show ssl cert" | socat stdio unix-connect:/run/haproxy/admin.sock # ou autre chemin de socket configuré dans "stats socket" # echo "show ssl cert" | socat stdio unix-connect:/run/haproxy/admin.sock # ou autre chemin de socket configuré dans "stats socket"
@ -875,6 +914,29 @@ backend be_letsencrypt
Le processus qui générera ensuite le certificat devra générer un fichier pour HAProxy, contenant la concaténation du certificat, l'éventuelle chaîne intermédiaire, la clé privée, les eventuels paramètres Diffie-Helmann et l'éventuelle réponse OCSP. Le processus qui générera ensuite le certificat devra générer un fichier pour HAProxy, contenant la concaténation du certificat, l'éventuelle chaîne intermédiaire, la clé privée, les eventuels paramètres Diffie-Helmann et l'éventuelle réponse OCSP.
## Attaques (D)DOS
### Fail2Ban
[Fail2Ban](HowtoFail2Ban) est indépendant de HAProxy, mais peut être utilisé pour bloquer des requêtes en amont pour qu'elles n'atteignent pas HAProxy.
Cela nous a été utile dans certains cas d'attaques DDOS avec plusieurs centaines de milliers de requêtes (`maxconn 500000` atteint) où HAProxy devenait lent à traiter les requêtes.
Exemple d'une règle qui bannit en fonction d'un entête `Host:` spécifique :
~~~
[haproxy-bad-host]
enabled = true
port = http,https
logpath = /var/log/haproxy.log
banaction = iptables-multiport
maxretry = 1
bantime = 86400
findtime = 60
failregex = ^%(__prefix_line)s<HOST>.*<NOSRV> .* \{www\.example\.com/bad\}
~~~
## HAPEE HAProxy Enterprise Edition ## HAPEE HAProxy Enterprise Edition
HAProxy est également disponible en édition « Enterprise », avec des fonctionnalités supplémentaires, un support direct et des outils additionnels. HAProxy est également disponible en édition « Enterprise », avec des fonctionnalités supplémentaires, un support direct et des outils additionnels.
@ -902,7 +964,7 @@ Exemples avec la version 2.4 (LTS actuelle) :
* binaire principal : `/opt/hapee-2.6/sbin/hapee-lb` * binaire principal : `/opt/hapee-2.6/sbin/hapee-lb`
* vérification de config : `/opt/hapee-2.6/sbin/hapee-lb -c -V -f /etc/hapee-2.6/hapee-lb.cfg` * vérification de config : `/opt/hapee-2.6/sbin/hapee-lb -c -V -f /etc/hapee-2.6/hapee-lb.cfg`
## Outils complémentaires ### Outils complémentaires
Des outils complémentaires sont proposés : Des outils complémentaires sont proposés :
@ -969,3 +1031,29 @@ tcp-check send User-Agent:\ Haproxy\ Health\ Check\r\n
tcp-check send \r\n tcp-check send \r\n
tcp-check expect rstring HTTP/1\..\ 200 comment check\ HTTP\ response tcp-check expect rstring HTTP/1\..\ 200 comment check\ HTTP\ response
~~~ ~~~
### HTTP 100 CONTINUE
Le protocole HTTP définit une utilisation spécifique pour l'envoi « décalé » d'un gros payload.
Par exemple un client va envoyer un :
~~~
POST /callback
Content-Type: application/pdf
Content-Length: 123456
Expect: 100-continue
~~~
Le serveur va alors lui répondre `HTTP/1.1 100 Continue` et ensuite seulement le client enverra le contenu du PDF puis le serveur enverra la réponse finale `HTTP/1.1 200 OK`.
Plus d'infos sur :
* <https://http.dev/100>
* <https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/100>
HAProxy doit bien retransmettre ces différentes, or nous avons constaté qu'avec HAProxy 1.8, il ne retransmet pas la réponse `HTTP/1.1 100 Continue` au client ([comme signalé ici])(https://github.com/haproxy/haproxy/issues/1321)
ce qui provoque au final un timeout et une erreur 502 renvoyée par HAProxy (c'est compliqué à déboguer car la réponse `HTTP/1.1 100 Continue` n'est loguée nul part en général.
Solution pour contourner : passer en version supérieure (par exemple HAProxy 2.4)