1 votes

HAProxy "tcp-request connection reject" ne fonctionne pas comme prévu

J'ai essayé de mettre en place un système pour bloquer les ips s'ils agissent de manière malveillante. Il semble que cela fonctionne dans les tests, mais j'ai des résultats mitigés dans mon environnement réel.

Ce que j'ai essayé de faire est de bloquer les connexions si elles ont un taux d'erreur > 10, un nombre d'erreurs > 50 ou un taux de demandes > 150.

Tout d'abord, mon proxy frontal a la configuration :

stick-table type ip size 100k expire 30s store http_err_rate(10000),http_err_cnt,http_req_rate(10000)
tcp-request connection track-sc0 src
tcp-request connection accept if { src -f /etc/haproxy/whitelist.lst }
tcp-request connection reject if { sc0_http_err_rate gt 10 }
tcp-request connection reject if { sc0_http_err_cnt gt 50 }
tcp-request connection reject if { sc0_http_req_rate gt 150 }

J'ai récemment eu une IP faisant un scan qui n'était pas bloqué par haproxy, avant de bloquer par ip-tables j'ai vérifié les statistiques sur l'IP qui ont montré :

echo "show table clientsecure key x.x.x.x" | socat stdio /var/run/haproxy.stat
# table: clientsecure, type: ip, size:102400, used:23
xx: key=x.x.x.x use=8 exp=0 http_req_rate(10000)=144 http_err_cnt=34235 http_err_rate(10000)=150

J'ai l'impression d'avoir une incompréhension fondamentale de la configuration de haproxy.

Est-ce que j'utilise correctement le stick-table avec les règles de connexion tcp-request suivantes ?

La règle "tcp-request connection reject" bloque-t-elle les connexions entrantes si une seule règle correspond, ou doivent-elles toutes correspondre ?

Editar:

Après d'autres tests, je me suis rendu compte que les règles ne sont vérifiées que lors des nouvelles connexions. Donc l'utilisation de "option httpclose" arrêtera les gens dès qu'ils atteindront les limites. Évidemment, ce n'est pas l'idéal pour des raisons de vitesse, donc je vais expérimenter avec les délais d'attente keep-alive.

3voto

hymced Points 135

Parce que je ne suivais que la connexion sur le front-end, toute connexion maintenue en vie serait toujours capable d'exécuter des requêtes. Donc la solution est :

Front-end :

  • créer un tableau collant juste avec un gpc
  • suivre le connexion src utilisant sc1
  • créer un acl "is-abuser" si le gpc > 0
  • rejeter la connexion si "is-abuser"

Backends :

  • commencer le tableau de collants avec le taux d'erreurs, le nombre d'erreurs, le taux de demandes.
  • suivre le contenu src utilisant sc2
  • créer des acls d'abus pour les taux d'erreur, les comptages, le taux de demande
  • créer un acl pour augmenter le gpc suivi à partir de la table du front-end stick-table en utilisant sc1_inc_gpc
  • rejeter le contenu si les acl d'abus correspondent et fonctionnent alors augmenter l'acl de gpc

Exemple similaire que j'ai trouvé directement dans le manuel (en utilisant sc0 et sc1 à la place de sc1, sc2 dans l'explication ci-dessus) :

#Track per-frontend and per-backend counters, block abusers at the frontend when the backend detects abuse(and marks gpc0).
frontend http
    # Use General Purpose Couter 0 in SC0 as a global abuse counter
    # protecting all our sites
    stick-table type ip size 1m expire 5m store gpc0
    tcp-request connection track-sc0 src
    tcp-request connection reject if { sc0_get_gpc0 gt 0 }
    ...
    use_backend http_dynamic if { path_end .php }

backend http_dynamic
    # if a source makes too fast requests to this dynamic site (tracked
    # by SC1), block it globally in the frontend.
    stick-table type ip size 1m expire 5m store http_req_rate(10s)
    acl click_too_fast sc1_http_req_rate gt 10
    acl mark_as_abuser sc0_inc_gpc0(http) gt 0
    tcp-request content track-sc1 src
    tcp-request content reject if click_too_fast mark_as_abuser

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