Hello ! je suis plutôt dev, donc je maitrise pas beaucoup les questions liées au serveur.
Sur un VPS que je loue chez OVH depuis ~1 an, je viens de déployer un nouveau site perso
Constant des grosses lenteurs par moment entre mon navigateur local et les réponses du serveur vps distant, j'ai jeté un oeil sur les fichiers access.log de mes 3 sites (je tourne avec apache2)
Et j'ai constaté que je reçois chaque seconde une dizaine de requêtes 400 HTTP
Ça me semble clairement anormal ! j'ai donc desactivé mes sites (a2dissite), j'ai meme coupé le port 80 d'apache. Mais ces requêtes persistent et je sais pas trop où chercher et si ça peut expliquer les problèmes de lenteurs énoncés plus haut...
Je précise aussi que mes 3 sites hébergés sur mon vps sont configuré en https avec des certificats non auto-signés
Thanks for any help :)
Serveur VPS bombardé de requêtes HTTP 400
Related questions
- Perte de mot de passe
48589
26.05.2023 13:36
- Comment configurer/utiliser un SMTP depuis un VPS ?
47240
07.10.2019 10:49
- Je connais que le mutu et besoin de node js
46790
14.04.2017 13:34
- Qu'est-ce vcore?
45836
06.01.2017 19:20
- Envoi Email via SMTP (port 587) sur VPS Pro1
44817
27.01.2017 10:02
- [résolu] Serveur Mysql - hôte inconnu
42448
19.01.2017 16:21
- Mon VPS à Timed Out
42171
15.03.2017 22:50
- Délai de livraison VPS
41874
11.07.2018 15:15
- Problème avec statisitique Plesk
39291
29.03.2017 07:44
- Accès externe base de données
38783
18.07.2018 10:29
Bonjour,
Y a-t-il quelque chose dans error.log ?
Si vous visitez votre site avec http://12.34.56.78 (votre adresse IP) est-ce que ça renvoie un 400?
Si vous visitez votre site avec http://11234567890.ovh.net1234567890.ovh.net (le FQDN de votre VPS) est-ce que ça renvoie un 400?
Si vous visitez votre site avec http://example.net (l'URL de chacun des 3 sites hébergés) est-ce que ça renvoie un 400?
Merci pour ta réponse :)

Lorsque j'accède aux URL de mes 3 sites, les pages se chargent bien et sans erreur (donc des 200 et pas de soucis lié au certificat SSL).
Par contre, si j'utilise en URL l'adresse IP de mon serveur VPS ou le FQDN, j'obtient une mise en garde de mon naviageur (cause : SSL_ERROR_BAD_CERT_DOMAIN)
Si je passe outre la mise en garde de mon navigateur, j'arrive sur un de mes 3 sites (et code HTTP 200)
Est-ce que le soucis viendrait de là ? comment puis je "désactiver" ces deux points d'entrées vers mon serveur ?
Cordialement
Bonjour,
je vous arrête tout de suite, le message d'erreur du certificat ne génère pas d'erreur 400.
Au vu de vos logs cela pourrais ressembler a une attaque de type "slowloris" dont le but est de saturer le serveur web sans utiliser beaucoup de bande passante (vecteur L7 qui vise la parti applicative).
Est-ce que vous avez mis en place un système de monitoring pour voir l'utilisation de vos ressources (cpu/ram/disk/worker paapche/worker php etc.) ?
Si oui, je pense que vous avez une saturation des workers.
Si non, je vous invite à mettre en place un monitoring pour voir c'est quoi qui sature.
Cordialement, janus57
Bonjour !
J'ai pensé à une attaque aussi donc j'ai regardé et testé plusieurs choses depuis hier :
Ouvrir un terminal et jeter un oeil sur htop. Je regarde de temnps en temps son état et je ne vois rien d'inquiétant côté RAM et côté processeur
Du côté des logs, je me retrouve avec des fichiers pesant quelques dizaines de Mo (le plus gros fait 250Mo), donc ça prends de la place mais ce n'est pour l'instant pas plus inquiétant que ça
(je suis ouvert à des solutions de monitoring plus "robustes" !)
J'ai également suivi le guide OVH pour installer un parefeu (lien : https://docs.ovh.com/ie/en/dedicated/firewall-network/), guide que j'ai suivi à la lettre car je n'y connais pas grand chose. Et à la fin du guide, mon serveur se faisait toujours bombarder de requetes aboutissant à du 400
Pour terminer, je me suis intéressé à fail2ban que je ne connaissais. J'ai mis en place cette nuit les règles suivantes :
> cat /etc/fail2ban/jail.local
# detect password authentication failures
https://unix.stackexchange.com/a/654005 apache]
enabled = true
port = http,https
filter = apache-auth
logpath = /var/log/apache*/*error.log
maxretry = 3
findtime = 600
bantime = 86400
# detect potential search for exploits and php vulnerabilities
[apache-noscript]
enabled = true
port = http,https
filter = apache-noscript
logpath = /var/log/apache*/*error.log
maxretry = 3
findtime = 600
bantime = 86400
# detect Apache overflow attempts
[apache-overflows]
enabled = true
port = http,https
filter = apache-overflows
logpath = /var/log/apache*/*error.log
maxretry = 2
findtime = 600
bantime = 86400
# detect failures to find a home directory on a server
[apache-nohome]
enabled = true
port = http,https
filter = apache-nohome
logpath = /var/log/apache*/*error.log
maxretry = 2
findtime = 600
bantime = 86400
[apache-fakegooglebot]
enabled = true
port = http,https
logpath = %(apache_access_log)s
maxretry = 1
ignorecommand = %(ignorecommands_dir)s/apache-fakegooglebot
[apache-badbots]
# Ban hosts which agent identifies spammer robots crawling the web
# for email addresses. The mail outputs are buffered.
enabled = true
port = http,https
logpath = %(apache_access_log)s
bantime = 48h
maxretry = 1
##To stop DOS attack from remote host.
[http-get-dos]
enabled = true
port = http,https
filter = http-get-dos
logpath = /var/log/apache*/access.log
maxretry = 400
findtime = 400
bantime = 200
ignoreip = 127.0.0.1
action = iptables[name=HTTP, port=http, protocol=tcp]
[iptables-dropped]
enabled = true
filter = iptables-dropped
banaction = iptables-allports
port = all
logpath = /var/log/messages
bantime = 1800
maxretry = 3
Les 'jails' de mon fichier 'jail.local' sont bien prises en compte :
> sudo fail2ban-client status
Status
|- Number of jail: 9
`- Jail list: apache, apache-badbots, apache-fakegooglebot, apache-nohome, apache-noscript, apache-overflows, http-get-dos, iptables-dropped, sshd
J'ai des IP qui se font Ban par fail2ban (mais que dans la 'jail' sshd, pas dans une des 'jail' apache* , je trouve ça un peu bizarre... peut etre que les configuration au dessus de mes jail apache ne sont pas bonne ? ce qui peut etre très possible étant donné mes connaissances vis à vis du problkème que je rencontre et vis à vis fail2ban que je découvre...)
> sudo cat /var/log/fail2ban.log* | grep Ban
2022-06-13 07:07:59,185 fail2ban.actions [529]: NOTICE [sshd] Ban 23.94.194.115
2022-06-13 07:08:32,529 fail2ban.actions [529]: NOTICE [sshd] Ban 43.156.122.114
2022-06-13 07:09:10,601 fail2ban.actions [529]: NOTICE [sshd] Ban 182.156.209.222
2022-06-13 07:09:18,831 fail2ban.actions [529]: NOTICE [sshd] Ban 186.10.125.209
2022-06-13 07:09:30,867 fail2ban.actions [529]: NOTICE [sshd] Ban 139.59.21.115
2022-06-13 07:11:15,736 fail2ban.actions [529]: NOTICE [sshd] Ban 213.136.90.174
2022-06-13 07:11:45,799 fail2ban.actions [529]: NOTICE [sshd] Ban 154.194.12.69
2022-06-13 07:14:50,174 fail2ban.actions [529]: NOTICE [sshd] Ban 43.156.124.5
2022-06-13 07:18:09,188 fail2ban.actions [529]: NOTICE [sshd] Ban 118.27.106.123
2022-06-13 07:18:55,509 fail2ban.actions [529]: NOTICE [sshd] Ban 104.248.89.194
2022-06-13 07:19:05,742 fail2ban.actions [529]: NOTICE [sshd] Ban 23.94.194.115
2022-06-13 07:19:11,811 fail2ban.actions [529]: NOTICE [sshd] Ban 43.154.104.24
2022-06-13 07:19:45,166 fail2ban.actions [529]: NOTICE [sshd] Ban 178.35.169.154
2022-06-13 07:20:36,453 fail2ban.actions [529]: NOTICE [sshd] Ban 139.59.21.115
2022-06-13 07:20:55,694 fail2ban.actions [529]: NOTICE [sshd] Ban 43.156.122.114
2022-06-13 07:21:33,806 fail2ban.actions [529]: NOTICE [sshd] Ban 186.10.125.209
2022-06-13 07:22:10,109 fail2ban.actions [529]: NOTICE [sshd] Ban 27.74.254.115
2022-06-13 07:22:56,385 fail2ban.actions [529]: NOTICE [sshd] Ban 213.136.90.174
2022-06-13 07:24:10,698 fail2ban.actions [529]: NOTICE [sshd] Ban 154.194.12.69
2022-06-13 07:25:34,062 fail2ban.actions [529]: NOTICE [sshd] Ban 104.248.62.102
2022-06-13 07:26:21,350 fail2ban.actions [529]: NOTICE [sshd] Ban 43.154.171.84
2022-06-13 07:29:57,842 fail2ban.actions [529]: NOTICE [sshd] Ban 118.27.106.123
2022-06-13 07:31:46,106 fail2ban.actions [529]: NOTICE [sshd] Ban 139.59.21.115
2022-06-13 07:33:49,576 fail2ban.actions [529]: NOTICE [sshd] Ban 27.74.254.115
2022-06-13 07:33:50,797 fail2ban.actions [529]: NOTICE [sshd] Ban 186.10.125.209
2022-06-13 07:34:22,899 fail2ban.actions [529]: NOTICE [sshd] Ban 213.136.90.174
2022-06-13 07:37:13,410 fail2ban.actions [529]: NOTICE [sshd] Ban 104.248.62.102
2022-06-13 07:38:07,498 fail2ban.actions [529]: NOTICE [sshd] Ban 43.154.171.84
2022-06-13 07:38:16,138 fail2ban.actions [529]: NOTICE [sshd] Ban 177.229.215.234
2022-06-13 07:40:44,582 fail2ban.actions [529]: NOTICE [sshd] Ban 104.248.89.194
2022-06-13 07:45:30,321 fail2ban.actions [529]: NOTICE [sshd] Ban 27.74.254.115
2022-06-13 07:46:31,019 fail2ban.actions [529]: NOTICE [sshd] Ban 186.10.125.209
2022-06-13 07:48:59,939 fail2ban.actions [529]: NOTICE [sshd] Ban 104.248.62.102
2022-06-13 07:49:51,227 fail2ban.actions [529]: NOTICE [sshd] Ban 43.154.171.84
2022-06-13 07:50:01,263 fail2ban.actions [529]: NOTICE [sshd] Ban 177.229.215.234
2022-06-13 07:50:59,390 fail2ban.actions [529]: NOTICE [sshd] Ban 46.19.137.50
2022-06-13 07:57:09,964 fail2ban.actions [529]: NOTICE [sshd] Ban 27.74.254.115
2022-06-13 08:01:50,508 fail2ban.actions [529]: NOTICE [sshd] Ban 43.154.171.84
2022-06-13 08:02:04,542 fail2ban.actions [529]: NOTICE [sshd] Ban 177.229.215.234
2022-06-13 08:02:39,206 fail2ban.actions [529]: NOTICE [sshd] Ban 104.248.89.194
2022-06-13 08:14:18,245 fail2ban.actions [529]: NOTICE [sshd] Ban 43.129.209.91
2022-06-13 08:16:07,008 fail2ban.actions [529]: NOTICE [sshd] Ban 167.99.158.168
2022-06-13 08:16:50,289 fail2ban.actions [529]: NOTICE [sshd] Ban 43.128.101.73
2022-06-13 08:24:37,536 fail2ban.actions [529]: NOTICE [sshd] Ban 104.248.89.194
2022-06-13 08:25:21,615 fail2ban.actions [529]: NOTICE [sshd] Ban 43.129.209.91
Et malgré tout, du coup, mon serveur se fait toujours flooder par des requêtes qui aboutissent à des 400 :
> sudo tail -f /var/log/apache2/site1_access.log /var/log/apache2/site2_access.log /var/log/apache2/site2_access.log
...
180.190.87.231 - - [13/Jun/2022:08:30:15 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
111.71.212.176 - - [13/Jun/2022:08:30:15 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
39.112.83.149 - - [13/Jun/2022:08:30:15 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
115.186.169.59 - - [13/Jun/2022:08:30:15 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
61.15.198.157 - - [13/Jun/2022:08:30:15 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
183.222.197.241 - - [13/Jun/2022:08:30:15 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
114.45.171.90 - - [13/Jun/2022:08:30:15 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
61.62.148.146 - - [13/Jun/2022:08:30:15 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
1.173.221.202 - - [13/Jun/2022:08:30:15 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
27.82.146.136 - - [13/Jun/2022:08:30:15 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
27.109.247.56 - - [13/Jun/2022:08:30:15 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
180.177.24.124 - - [13/Jun/2022:08:30:15 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
116.49.174.155 - - [13/Jun/2022:08:30:15 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
61.231.235.55 - - [13/Jun/2022:08:30:15 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
14.192.212.91 - - [13/Jun/2022:08:30:15 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
219.91.104.20 - - [13/Jun/2022:08:30:15 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
60.49.40.31 - - [13/Jun/2022:08:30:15 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
60.49.40.31 - - [13/Jun/2022:08:30:15 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
171.97.223.126 - - [13/Jun/2022:08:30:15 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
61.38.43.211 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
120.231.123.126 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
221.184.60.12 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
113.43.210.22 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
180.190.87.231 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
115.43.157.151 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
122.100.135.240 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
117.183.115.211 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
223.86.195.24 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
122.100.145.152 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
112.120.167.195 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
36.229.143.45 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
110.26.97.247 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
121.171.109.192 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
113.254.111.51 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
112.104.89.188 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
14.192.212.91 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
36.238.159.112 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
219.91.104.20 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
198.16.63.120 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
115.87.13.52 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
61.231.235.55 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
121.6.78.165 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
121.109.135.202 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
183.227.201.149 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
61.38.43.211 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
112.120.167.195 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
180.94.189.179 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
59.149.254.6 - - [13/Jun/2022:08:30:16 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
...
Pour terminer, j'ai également testé cette nuit la mise en place de rules iptables (iptables que je découvre aussi). J'ai par exemple testé cette chaine de règle :
/sbin/iptables -N SYN_FLOOD
/sbin/iptables -A INPUT -p tcp --syn -j SYN_FLOOD
/sbin/iptables -A SYN_FLOOD -m limit --limit 10/s --limit-burst 10 -j RETURN
/sbin/iptables -A SYN_FLOOD -j DROP
(en m'inspirant de cette source : [https://unix.stackexchange.com/a/654005 )
Lorsque je saisie la règle '-A SYN_FLOOD -j DROP', le flood s'arrète bien ! (super !) mais mes sites deviennent eux aussi inaccessibles lorsque je saisi leurs URL dans un de mes navigateurs x)
Et la aussi, mes connaissances sont encore très/trop basiques pour comprendre ce que font réellement ces règles iptables, et pourquoi ça ne fait pas tout à fait ce que je veux et comment les modifier pour régler ça...
C'est une attaque, ça c'est sur.
Je pense comme @janus57 que tes workers apaches sont certainements saturés.
Visiblement, les requêtes arrivent via l'IP directe de la machine. Donc ce que tu pourrais déjà faire pour régler rapidement le problème (peut être provisoirement seulement) :
-Comander une adresse IP failover et la configurer.
-Configurer les vhosts (y compris celui par défaut qui répond dans ton cas) pour qu'ils ne répondent qu'à la nouvelle adresse IP FO.
-Avec Iptables, dropper les requêtes sur l'ancienne IP ET sur le port 80 et 443
-Attendre de voir si l'attaque évolue
Cette attaque est certainement trop lente pour être prise en charge par la mitigeation OVH.
Bonjour,
Est-ce que ces erreurs 400 laissent une trace dans error.log ?
Ce n'est pas une attaque syn flood, c'est probablement tout le contraire.
Syn flood attaque au niveau du protocole réseau (connexion TCP incomplètes) ce qui met le kernel à mal.
ici on est sur des connexions TCP/port 80 ou port 443 abouties, ça parle en HTTP(S) mais de manière volontairement insatisfaisante.
pour avoir une idée rapide du nombre de connexions ouvertes:
netstat -t -n | grep -c ":80.*ESTABLISHED"
netstat -t -n | grep -c ":443.*ESTABLISHED"
Je n'ai pas d'expérience pour pouvoir indiquer à partir de combien ça devient suspect, voire dangereux pour la stabilité de Apache ou Nginx.
Et j'ai regardé et justement non ! ce qui expliquerai pourquoi rien ne rentre dans la plupart de mes fails apaches.
J'ai toutefois deux jails apache qui, j'ai l'impression, basent leur taff sur mes fichiers access.log, mais comme je l'ai marqué dans ma réponse précédente, aucune ip se fait ban dans ces jails de ce que j'ai observé ce matin
voila ce que ça donne de mon côté : 0 (http) et 248 (https)
Hier j'ai fermé l'écoute du port 80 et les attaques ont continué donc j'en ai déduis que ça passait effectivement par le https/443
Je testerai ça dans la journée, mais je suis perplexe vis à vis de cette approche
=> je suppose que l'attaquant récupère les domaines que j'utilise, donc si je change les IP il est probable que les attaques continuent/recommencent étant donné qu'on peut retrouver l'ip à travers les domaines que j'utilise (ou je dis une bétise ?)
Non ce n'est pas une bétise. Cela va peut être se produire, ou pas.
Les requêtes demandent le vhost par défaut alors... c'est sur l'IP.
C'est bien ce que je craignais (par exemple historiquement les 404 y étaient, mais 404 c'est tellement commun que Apache Foundation a décidé de ne plus traiter ça comme erreur)
Si tu arrives à écrire la regexp qui identifie les erreurs 400 dans access.log, attention aussi à la charge induite sur f2b lui-même, quand un log se remplit de 20 ou 50 lignes par seconde.
Si les IPs sont nombreuses, fail2ban avec sa configuration d'origine n'arriverra pas à le gérer (il faut voir du coté de Ipset pour cette approche).
Si en plus ce sont des IPs spoofées, netfilter pourrait bannir des Ips légitimes comme celle de Google par exemple.
je suis pas sorti du sable haha
Il faudra que je me documente pour savoir comment mettre en place une jail sur fail2ban qui permette de détecter les 400 qui ont lieu un peu trop souvent sur une IP donnée, et alors de ban cette IP
Ça peut poser des soucis de perf côté fail2ban qui va devoir carburer, mais pour l'instant ça me semble être la seule approche qui peut réellement fonctionner
Si jamais vous sauriez m'orienter vers un tuto/documentation sur internet qui se rapproche que je vais essayer de faire, je suis preneur ! (ne connaissant pas encore très bien fail2ban, mes recherches ne sont pas très efficaces encore)
Peut être. En tout cas c'est très interressant.
Peux tu déjà compter le nombre d'IPs différentes qu'il y a dans ton log Apache :
>awk '{print $2}' /var/log/apache2/access.log | sort | uniq -c | wc -l
Et nous donner la date de départ de ce log.
Tu est sous Debian ? si oui qu'elle version ?
yes !
Alors ...! mes logs sont dispatchés dans 3 sites et sont compressés chaque mois ( les deux dernis mois) dans différents fichiers.
Sans regarder dedans, je constate que les logs sont anormalement volumineux depuis Mai (30Mo en étant compressé) et malheureusement mes log au dela sont supprimés, donc sa sera difficile de remonter au commencement de l'attaque... (en fait mon serveur se faisait bombarder sans que je m'en rende compte)
Je suis sous Debian GNU/Linux 10 (buster)
Je ne cherche pas à connaitre la date du début de l'attaque. mais un ordre d'idée du nombre d'IP qui te requête.
>mes logs sont dispatchés dans 3 sites
Ok donc tu as 3 fichiers de log, un pour chaque site défini dans les vhosts.
Mais les erreurs http 400. Elles sont dans quel fichier de log ?
Je change la commande pour cibler (grossièrement) les 400 :
`awk '{print $2}' /var/log/apache2/le_fichier_avec_les_400 | grep " 400 " | sort | uniq -c | wc -l`
Ça ne cible qu'un site sur les trois (le premier site que j'ai installé d'ailleur)
> sudo awk '{print $2}' /var/log/apache2/site1.log | sort | uniq -c | wc -l
Résultat : 24032
Si je dis pas de bétises, ça concerne les logs de ce mois ci du coup
Pour les 2 autres sites, j'ai 6 et 26 (des nombres beaucoup plus normaux)
L'attaque semble se focus sur la racine de mon serveur http :
...
60.83.104.180 - - [13/Jun/2022:10:41:45 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
61.221.174.234 - - [13/Jun/2022:10:41:45 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
60.241.89.31 - - [13/Jun/2022:10:41:45 +0200] "GET / HTTP/1.0" 400 0 "-" "-"
...
J'ai l'impression du coup qu'apache redirige du coup ces logs sur le premier site que j'ai install
=> j'écris pas ici les url réelles de mes sites, pas que je souhaite les cacher, juste que ça me semble pas pertinent de les donner...
J'ai remarqué (grace à un autre poste que https://serverfault.com/questions/1103136/apache-on-debian-server-flooded-by-a-lot-of-400-how-to-protect-from-it/1103138?noredirect=1#comment1439834_1103138 j'ai ouvert sur serverfault ici) que le bombardement opère à travers le protocole HTTP version 1.0
Alors que mes sites, lorsque je vais dessus, c'est le protocole http 1.1 qui est utilisé
Du coup, une approche qui me semble pas trop déconnante pourrait en fait consister à config apache pour qu'il n'accepte que les requêtes HTTP v1.1 et versions supérieures
Mais j'ai un peu peur que ça ban des requetes légitimes (comme les requetes envoyés par google, facebook, ... je sais pas si ils sont tous calibré sur de l'HTTP de version supérieure à 1.0), je me documenterai la dessus...
C'est parceque ton 1er site est configuré sur le default vhost.
Le problème avec la stratégie d'un fichier de log par vhost c'est entre autre
-Difficulté à voir ce qu'il se passe sur le serveur
-Dificulté avec F2B (quels sont les fichiers qui sont surveillés du coup)
- Performances
- quand il ya bcp de vhost Apache va finir par crasher (bon ce n'est pas ton cas)
L'autre approche est d'avoir un log comun et d'éventuelement le splitter au moment du logrotate.
Bref, 25 mille IP ça commence à être pas mal, mais c'est peu pour du spoofing IP depuis le début du mois.
Si tu ne souhiate pas utiliser les IP FO. Tu peux tenter un bannissement des IPs mais tu ne pourras pas le faire avec Iptables car ta bande passante va s'effondrer.
Installe Ipset
`apt install ipset`
Crée un set des mauvaises Ip :
`ipset create badip_apache hash:ip maxelem 1000000`
Collecte les bad IP :
`sudo awk '{print $2}' /var/log/apache2/site1.log | sort | uniq -c > /root/badip_apache`
Ajoute les bad Ip dans le set :
`while read -r ip; do ; ipset add badip_apache "$ip" > /dev/null; done < /root/badip_apache`
Place le set badip_apache au début des régles iptables
`iptables -I INPUT -m set --match-set badip_apache src -j DROP`
Regarde le log et dis nous :
`tail -f /var/log/apache2/site1.log`
EDIT : attention, j'ai edit plusieurs fois pour corriger des coquilles dans les commandes
J'ai un `-bash: syntax error near unexpected token `;'` j'essaie de voir d'où ça vient...
J'ai eu un soucis de permission aussi avec la commande :
que j'ai remplacé du coup par :
`sudo awk '{print $2}' /var/log/apache2/site1.log | sort | uniq -c | sudo tee /root/badip_apache`
Merci en tout cas de prendre le temps pour le soucis que je rencontre :D
J'avance en // sur cette histoire de HTTP version 1.0 à désactiver...
Arf oui désolé, j'ai l'habitude (vilaine) d'être root en permannence.
>J'ai un -bash: syntax error near unexpected token;'` j'essaie de voir d'où ça vient...
ça vient du fait que je fait du copier / coller des mes scripts ... mais qui sont sur plusieurs lignes...
`while read -r ip; do ipset add badip_apache "$ip" > /dev/null; done ; < /root/badip_apache`
?
ça semble mieux marcher :D par contre la commande n'est toujours pas terminée... je garde un oeil sur `htop` et pour le moment mon serveur ne s'affole pas
Oui ya 25 000 ips à ajouter. C'est de l'indexé donc c'est long à ajouter mais ça va préserver ta BP.
C'est quoi comme VPS ?
C'est de la prod sensible/importante ?
Il s'agit de l'offre VPS : "VPS 2016 Cloud RAM 2"
Avec les caractéristiques suivantes :
* Processeur :2 vCores
* Mémoire vive : 12 Go
* Stockage : 50 Go
Il s'agit pas de prod sensible/importante , dans mes 3 sites j'ai :
- un site de presentation perso
- une plateforme dont je me sers pour les cours que je fais avec mes élèves
- et le dernier par contre, un site qui peut avoir vocation à croitre (une sorte de onvasortir spé sur les évent dansant)
Pour le dernier cas, selon son évo, je le migrerai peut etre sur une offre plus consistante qu'un VPS (mais vu que c'est plus onéreux, je reste la dessus pour l'instant)
Bon, c'est polutôt cool alors :)
De mémoire, les VPS actuels sont bien mieux que les 2016.
je jete un oeil de temps en temps avec `htop`, je dépasse très rarement les 15/20% d'utilisation de RAM et de proc pour l'instant
Tu peux :
`ipset -L badip_apache | wc -l`
Pour voir où il en est.
Ça me sors 8
Je sais pas trop à quoi ça correspond mais ça me ne semble pas beaucoup hahaha
La commande sans le `| wc -l` me donne :
Name: badip_apache
Type: hash:ip
Revision: 4
Header: family inet hashsize 1024 maxelem 1000000
Size in memory: 88
References: 0
Number of entries: 0
Members:
C'est pas bon du tout... La cible est 25000
`iptables -L -n | wc -l`
?
Ça me donne : 21..et après quelques seconces, maintenant 22
Sans le `| wc -l` ça me donne...
target prot opt source destination
REJECT all -- 103.215.139.109 0.0.0.0/0 reject-with icmp-port-unreachable
REJECT all -- 128.199.107.100 0.0.0.0/0 reject-with icmp-port-unreachable
REJECT all -- 187.51.208.158 0.0.0.0/0 reject-with icmp-port-unreachable
REJECT all -- 143.244.174.143 0.0.0.0/0 reject-with icmp-port-unreachable
REJECT all -- 176.79.211.68 0.0.0.0/0 reject-with icmp-port-unreachable
REJECT all -- 108.166.190.135 0.0.0.0/0 reject-with icmp-port-unreachable
REJECT all -- 103.254.198.67 0.0.0.0/0 reject-with icmp-port-unreachable
REJECT all -- 43.154.101.119 0.0.0.0/0 reject-with icmp-port-unreachable
REJECT all -- 129.226.176.245 0.0.0.0/0 reject-with icmp-port-unreachable
RETURN all -- 0.0.0.0/0 0.0.0.0/0
Ok la boucle ne fonctionne pas :(
ctrl+c pour la terminer.
Tu peux regarder si le fichier /root/badip_apache contient bien une IP par ligne stp ?
hmmm le fichier contient seulement ceci :
`1506904 -`
Je reregarde les commandes que tu as mi voir si un $ mal positionné en serait pas la cause...
`sudo awk '{print $2}' /var/log/apache2/site1.log | sort | uniq -c > /root/badip_apache`
À mais oui, ça doit être plutot :
`sudo awk '{print $2}' /var/log/apache2/site1.log | sort | uniq -c > /root/badip_apache`
chez moi
Je reprend toussa
Il faut bien une IP par ligne ?
Actuellement avec {print $1} j'ai :
...
9 99.246.107.118
5 99.246.112.211
1 99.246.40.140
12 99.247.0.93
709 99.254.40.94
69 99.255.164.153
...
Je suppose que c'est voulu, sinon tu n'aurai pas utilisé le paramètre c de la commande uniq
C'est le -c qui est de trop.
Pfff désolé je suis sur plusieurs fronts ce matin :(
pas de soucis ;)
alors j'ai bien un fichier badip_apache qui est remplis d'ip :
> sudo head /root/badip_apache && sudo tail /root/badip_apache
100.2.163.118
100.2.187.184
100.2.2.233
100.2.9.48
100.33.9.205
100.34.233.47
100.35.46.5
100.35.66.207
100.37.252.37
100.38.37.159
99.39.119.24
99.41.90.65
99.42.140.200
99.42.141.57
99.64.246.26
99.67.151.20
99.7.216.132
99.72.224.125
99.82.242.255
99.92.208.227
La commande `while read -r ip; do ipset add badip_apache "$ip" > /dev/null; done ; < /root/badip_apache` tourne, mais le résultat de `sudo iptables -L -n | wc -l` reste toujours à 25
Je regarde dans la boucle où ça coince...
À c'est peut etre parce que je suis pas en root, et du coup le '`< /root/badip_apache`' foire
Non c'est pas ça, le fichier est en lecture pour tout les mode...( '`-rw-r--r--`' )
J'ai callé un sudo dans le while mais c'est pas mieux...
`while read -r ip; do sudo ipset add badip_apache "$ip" > /dev/null; done ; < /root/badip_apache`
je vais finir par trouver hein ;)
Passe root stp :
`su -`
puis
`for ip in $(cat /root/badip_apache); do ipset add badip_apache "$ip"; done ;`
(testé) :)
j'ai pu régler le soucis sans passer par le `su -` (en mode truant en callant le badip_apache dans /tmp avec les droits +777)
Et il y avait un ; de trop dans le while, la commande finale du coup :
`while read -r ip; do ipset add badip_apache "$ip" > /dev/null; done < /tmp/badip_apache`
c'est en train de tourner ! et le résultat de la commande '`sudo ipset -L badip_apache | wc -l`' évolue bien
Alors j'ai pu ajouter les iptables avec ta dernière commande :
`sudo iptables -I INPUT -m set --match-set badip_apache src -j DROP`
Le flood s'est arrété net ! mais... je n'arrive plus à accéder à mes sites :/
(navigateur qui tourne en boucle quand j'essai d'aller sur un de mes 3 sites)
Je redémarre le serveur pour clean les dernières règles iptables ajoutées et ré-up mes sites du coup ! (au passage, ça a coupé mon accès ssh aussi, je redémarre du coup à l'aide du panneau de config d'ovh)
Après vérification tout de même, je constant que dans mes logs. le bombarement s'est effectivement arrété pendant une minute (le temps de redémarrer le serveur)
AAAA mais attends c'est normal ! j'ai complètement oublié d'adapter la ligne où on récolte les IP pour lui préciser quand meme que je ne veux prendre en compte que les 400 ! Allez je reprend tout !
Aie.
C'est certainement a cause du filtre sur la 400 :
`awk '{print $2}' /var/log/apache2/le_fichier_avec_les_400 | grep " 400 " | sort | uniq -c | wc -l`
la partie grep " 400 " est trop permissive.
Elle va aussi choper des IP si le document uploadé par apache fait 400o par exemple.
Il faudrai le faire plus sérieursement avec awk par exemple pour être sur de tomber sur le code de retour 400 dans le log.
Si tu fais
`grep [TON ADRESSE IP] /root/badip_apache`
Tu est bien dedans ?
En atentand le awk supprime ton adresse IP du fichier...
Alors.. !
J'ai donc capturé toutes les ip qui avec les pattern ' 400 ' et 'HTTP/1.0' et suivis la liste de tes commandes avec les corrections intermédiaires
Le access.log s'est beaucoup calmé, je reçois maintenant environ 5 requetes suivant les pattern ci-dessus chaque seconde (alors qu'avant, c'était plusieurs dizines par secondes)
Mais du coup la mauvaise nouvelle semble être que je me fais attaquer continuellement par de nouvelles IP
Bon déjà ça va offrir un peu de répit aux workers d'apache et ça m'a permi de mieux comprendre comment ce type de défense fonctionne
Pour la suite :
=> je vais tester côté fail2ban une jail qui va capturer toutes les requêtes basées sur HTTP/1.0 et qui obtiennent un 400
=> je continue de voir comment désactiver le HTTP version 1.0 côté apache (il faut que je le fasse avec le module rewrite, je devrai trouver après quelques essais/recherches)
Merci en tout cas pour ton aide ! je mets à jour ce poste en fonction de mes avancées
Modifie la commande de F2B (dans li fichier de config) pour qu'il utilise "ipset add" plutôt qu'iptables.
Ajoute des IP FO. Idéalemment une par site, une pour le SSH et une pour les envois de mail (avec les conf qui vont bien). C'est plus souple dans plein de situation.
Tien nous au courant, l'attaque va peut être évoluer.
(@TTY j'ai pas vu ta réponse entre temps)
Alors le blocage côté apache ne fonctionne pas :
=> le seul moyen (à priori) de bloquer les requêtes entrantes consiste à utiliser le module rewrite afin de capturer la requête entrante et, si elle respecte un pattern, de la rediriger vers une 403 (ce qui déjà n'efface pas vraiment le problème étant que le flood va persister)
Mais pire encore, le type d'attque que je me prend exploite à priori une faille du protocol HTTP lui même, et donc le paquet qu'on m'envoi est configuré de telle sorte à échapper complètement aux contrôles qui pourraient être fait côté apache
Donc pas trop le choix, soit j'automatise un peu plus la solution amenée par @TTY , soit je passe par la création d'une jail avec fail2ban (mais je suppoer que fail2ban utilise sous le capot exactement la même approche que celle de @TTY)
Je vais privilégier fail2ban étant donné qu'on peut facilement configurer des règles de filtrages avancée et limiter ainsi, au mieux, le ban d'IP légitimes
Je n'ai peut être pas tout suivi, ce que tu voulais faire avec Apache mais le flood va continuer oui.
Pour automatiser cela avec F2B, il va faloir créer un filtre avec une regex spécifique et surtout modifier la commande de bannissement de celui-ci pour utiliser ipset pour le ban/unban
Avec Ipset, tu peux mettre un temps de rétention (sur F2B) des Ip tres long sans trop dégrader les perf.
Pense tout de même aux IP FO. Je suppose que tu n'en a aucune. Celle dont tu dispose ne devrait répondre qu'à SSHD.
Ce n'est pas dit que l'attaque s'adapte vu qu'il requete l'IP principale du VPS sans nom de domaine.
Si cette Ip principale ne répond plus qu'à SSH les requêtes merdiques n'arriverons plus à Apache.
Vérifie aussi qu'Apache est en MOD_EVENT, plus résiliant dans ce genre situation.
Regarde si les IPs source ne viennent pas quelques pays (Chine et Russie...) ou quelques ASN (digital ocean :D ) . Si oui, bannis les avec Ipset.
Tu as, pour le moment, pas mal de vecteurs d'actions pour mitigier tout ça en attendant que l'attaquant se lasse.
Bonjour,
j'ai pas lu tout les échanges intermédiaires, mais dans un cas comme ça perso je serais passé derrière cloudflare, et autoriser uniquement cloudflare à taper sur apache.
Cela permet dans un premier temps de se débarrasser du bruit de fond qui n'arrive pas à passer les sécurité de base de cloudflare et après de mettre en place des bannissement de pays/asn sans avoir d'impact sur le VPS.
Cordialement, janus57
Oui bonne apparoche mais ce cas, ce sont des requêtes sur l'adresse IP sans passer par un domaine.
Bonjour,
comme dit dans mon message "autoriser uniquement cloudflare à taper sur apache", donc automatiquement il y aura un rejet avec les règles iptables qui vont bien.
Donc l'attaquant aura pas le choix de passer par le domaine qui sera derrière cloudflare.
Cordialement, janus57
Cette approche à l'air vraiment top. Tu l'as expérimentée ?
Tu géres la white list avec iptables ?
Edit : https://community.cloudflare.com/t/apache-blocking-direct-requests-that-bypass-cloudflare-when-using-mod-remoteip/210963
De simples directives Apache suffisent. Je ne connait pas trop Cloud Flare mais je vais tester ça ! Merci pour l'idée @janus57 !
@MatthieuL4, cette approche réglerait certainement tes soucis.
Bonjour,
Perso j'aurais fait un ipset sur port 80+443 pour whiteliser.
Début de piste : https://jahed.dev/2020/04/05/using-iptables-and-ipset-to-whitelist-cloudflare/
Cordialement, janus57
Alors après quelques jours de tests, l'approche fail2ban n'est pas vraiment satisfaisante
Le bombardement de 400 se retrouve 'à peine' ralentit, et mon serveur utilise le plus gros de ses ressources pour faire fonctionner fail2ban en temps réel
Je me penche alors sur l'approche cloudflare
Pour la gestion du BAN de toutes les IP hormis celles de cloudflare , je vais m'appuyer https://developers.cloudflare.com/fundamentals/get-started/setup/allow-cloudflare-ip-addresses/ sur ce tuto officiel (utilisant iptables)
=> je suis en train de modifier les DNS d'ovh pour utiliser ceux de cloudflare , une fois les modifs effectives, je crée la whiteliste côté apache2 et ban tout ce qui ne provient pas de cloudflare
J'ai une petite question du coup, comme je bidouille dans des trucs qui sont pas trop mes domaines de prédilections, est-ce que les manips au dessus suffisent 'en théorie' ou est-ce que je rate quelque chose ?
Du coup si j'ai bien compris, cloudflare (et tout autre boite du même genre) installe du côté de ses DNS des parefeu/outils/... qui permettent de filtrer en amont les bonnes requêtes entrantes des mauvaises ?
C'est ce que je craignais :(
Bon courage en tout cas, pour la suite de ta formation "sur le tas".
J'ai aussi trouvé cet échange très intéressant.
merci pour ton aide :)