# REGEX : filtre fail2ban pour nginx

**URL:** <https://www.debian-fr.org/t/regex-filtre-fail2ban-pour-nginx/63541>\
**Category:** Programmation\
**Created:** [Février 21, 2016, 8:49 UTC](https://www.debian-fr.org/t/regex-filtre-fail2ban-pour-nginx/63541 "2016-02-21T20:49:29Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![anon96191775](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/71c47a/32.png) [@anon96191775](https://www.debian-fr.org/u/anon96191775)\
**Post date:** [Février 21, 2016, 8:49 UTC](https://www.debian-fr.org/t/regex-filtre-fail2ban-pour-nginx/63541/1 "2016-02-21T20:49:29Z")

</div>

Depuis peu j’ai ouvert mon port 80 sur l’extérieur, et je découvre les joies du remplissage de log.  
J’ai eu en particulier une IP plutôt insistante qui a testé l’existence d’une bonne quantité de fichiers, jetée par une 404 à chaque fois :

`dave@HAL9000:/var/log$ grep "81.17.20.38" nginx/error.log | wc -l
924
dave@HAL9000:/var/log$ grep "81.17.20.38" nginx/error.log | head -n1
2014/09/09 22:30:59 [error] 17799#0: *18 open() "/home/dave/dotslashplay.it/html/w00tw00t.at.blackhats.romanian.anti-sec:)" failed (2: No such file or directory), client: 81.17.20.38, server: localhost, request: "GET /w00tw00t.at.blackhats.romanian.anti-sec:) HTTP/1.1", host: "*.*.*.*"
dave@HAL9000:/var/log$ grep "81.17.20.38" nginx/error.log | tail -n1
2014/09/10 01:39:28 [error] 17799#0: *947 open() "/home/dave/dotslashplay.it/html/phpMyAdmin3/scripts/setup.php" failed (2: No such file or directory), client: 81.17.20.38, server: localhost, request: "GET /phpMyAdmin3/scripts/setup.php HTTP/1.1", host: "*.*.*.*"`

Pour bloquer ce genre de scan (pour limiter la charge sur mon serveur), je pensais créer une règle fail2ban qui bloque les IP enchaînant au moins 10 erreurs 404 en une minute.

Le 10 erreurs en une minute, c’est OK avec :

`findtime = 60
maxretry = 10`

Par contre je bloque pour la regex à utiliser dans le champ failregex. Je cherche à repérer les lignes contenant la chaîne “No such file or directory”, mais n’ayant jamais manipulé d’expressions régulières je n’ai aucune idée de la façon dont je dois le formuler.

Merci d’avance pour votre aide !

---

<div class="post-metadata">

**Author:** ![anon96191775](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/71c47a/32.png) [@anon96191775](https://www.debian-fr.org/u/anon96191775)\
**Post date:** [Février 21, 2016, 8:49 UTC](https://www.debian-fr.org/t/regex-filtre-fail2ban-pour-nginx/63541/2 "2016-02-21T20:49:30Z")

</div>

Merci à captnfab sur le chan #debian-facile sur freenode pour sa solution :

`17:53:06 +captnfab | vv222: tu veux filtrer juste les lignes avec No such file or directory ou tu veux plus de précision ?
17:53:16 +captnfab | (salut vv222 :) )
17:54:29 vv222 | (salut aussi)
17:54:42 vv222 | Juste les lignes avaec cette expression, je pense que ça suffira.
17:55:02 vv222 | Et ça me paraît poser moins de risques de faux-positifs que de filtrer sur "404".
17:56:49 +captnfab | genre « .*No such file or directory.* » alors
17:57:09 +captnfab | .* signifie « n'importe quel caratcère, autant de fois que nécessaire »
17:57:39 +captnfab | donc en gros, la regex signifie «whatever No such file or directory whatever»`

---

<div class="post-metadata">

**Author:** ![ricardo](https://www.debian-fr.org/user_avatar/www.debian-fr.org/ricardo/32/3864_2.png) [@ricardo](https://www.debian-fr.org/u/ricardo)\
**Post date:** [Février 21, 2016, 8:49 UTC](https://www.debian-fr.org/t/regex-filtre-fail2ban-pour-nginx/63541/3 "2016-02-21T20:49:31Z")

</div>

C’est woutwout, il est connu depuis longtemps mais pas méchant.  
[strike]maxretry = 10[/strike] ==\>maxretry = 1

---

<div class="post-metadata">

**Author:** ![anon96191775](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/71c47a/32.png) [@anon96191775](https://www.debian-fr.org/u/anon96191775)\
**Post date:** [Février 21, 2016, 8:49 UTC](https://www.debian-fr.org/t/regex-filtre-fail2ban-pour-nginx/63541/4 "2016-02-21T20:49:31Z")

</div>

Avec [mono]maxretry = 1[/mono], je risque de bloquer toute origine tombant sur du 404, non ?  
Il n’y a pas de risque de bloquer des utilisateurs légitimes avec ça ?

Encore qu’à la réflexion mon site est pour l’instant limité à une unique page, alors à peu près tout ce qui tente de piocher autre chose a de grandes chances d’être une attaque.

---

<div class="post-metadata">

**Author:** ![anon96191775](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/71c47a/32.png) [@anon96191775](https://www.debian-fr.org/u/anon96191775)\
**Post date:** [Février 21, 2016, 8:49 UTC](https://www.debian-fr.org/t/regex-filtre-fail2ban-pour-nginx/63541/5 "2016-02-21T20:49:36Z")

</div>

Bon, les logs de nginx m’indiquent clairement que ma nouvelle règle fail2ban ne fonctionne pas…

[code]dave@HAL9000:/var/log/nginx$ grep “218.38.136.36” access.log | wc -l  
55

dave@HAL9000:/var/log/nginx$ grep “218.38.136.36” access.log | head -n1  
218.38.136.36 - - [11/Sep/2014:10:33:00 +0200] “GET /muieblackcat HTTP/1.1” 404 168 “-” “-”

dave@HAL9000:/var/log/nginx$ grep “218.38.136.36” access.log | tail -n1  
218.38.136.36 - - [11/Sep/2014:10:33:34 +0200] “GET [//phpMyAdmin-2.5.5/index.php](https://phpMyAdmin-2.5.5/index.php) HTTP/1.1” 404 168 “-” “-”[/code]

La règle en question :

[code]dave@HAL9000:/etc/fail2ban$ cat jail.d/nginx.conf  
[nginx-http-auth]  
enabled = true

[nginx-404]  
enabled = true  
findtime = 60  
maxretry = 10  
filter = nginx-404  
port = http,https  
logpath = /var/log/nginx/access.log

dave@HAL9000:/etc/fail2ban$ cat filter.d/nginx-404.conf

# fail2ban filter configuration for nginx

[Definition]

failregex = ._404 168._, client: , server: \S+, request: “\S+ \S+ HTTP/\d+.\d+”, host: “\S+”\s\*$

ignoreregex =[/code]

Évidemment, rien de suspect dans les logs de fail2ban qui aurait pu m’aiguiller :

`dave@HAL9000:/var/log$ tail fail2ban.log
2014-09-11 16:08:37,263 fail2ban.filter [5318]: INFO Added logfile = /var/log/nginx/access.log
2014-09-11 16:08:37,263 fail2ban.filter [5318]: INFO Set maxRetry = 10
2014-09-11 16:08:37,264 fail2ban.filter [5318]: INFO Set findtime = 60
2014-09-11 16:08:37,264 fail2ban.actions[5318]: INFO Set banTime = 600
2014-09-11 16:08:37,269 fail2ban.jail [5318]: INFO Jail 'ssh' started
2014-09-11 16:08:37,272 fail2ban.jail [5318]: INFO Jail 'nginx-http-auth' started
2014-09-11 16:08:37,293 fail2ban.jail [5318]: INFO Jail 'vsftpd' started
2014-09-11 16:08:37,305 fail2ban.jail [5318]: INFO Jail 'postfix' started
2014-09-11 16:08:37,308 fail2ban.jail [5318]: INFO Jail 'recidive' started
2014-09-11 16:08:37,317 fail2ban.jail [5318]: INFO Jail 'nginx-404' started`

J’en appelle à vos lumières, je soupçonne fortement ma ligne [mono]failregex[/mono] de /etc/fail2ban/filter.d/nginx-404.conf d’être mal construite.

---

<div class="post-metadata">

**Author:** ![vohu](https://www.debian-fr.org/user_avatar/www.debian-fr.org/vohu/32/4108_2.png) [@vohu](https://www.debian-fr.org/u/vohu)\
**Post date:** [Février 21, 2016, 8:49 UTC](https://www.debian-fr.org/t/regex-filtre-fail2ban-pour-nginx/63541/6 "2016-02-21T20:49:36Z")

</div>

essaye voir ton filtre sur le log directement, avec grep -E. Au moins tu verras directement le résultat

---

<div class="post-metadata">

**Author:** ![anon96191775](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/71c47a/32.png) [@anon96191775](https://www.debian-fr.org/u/anon96191775)\
**Post date:** [Février 21, 2016, 8:49 UTC](https://www.debian-fr.org/t/regex-filtre-fail2ban-pour-nginx/63541/7 "2016-02-21T20:49:36Z")

</div>

Le filtre lui-même semble efficace :

`dave@HAL9000:/var/log/nginx$ grep -E ".*404 168.*" access.log | wc -l
1007`  
C’est donc probablement dans la suite de la ligne [mono]failregex[/mono] que se cache mon erreur…  
M’en vais me brancher le man de fail2ban en perfusion, en espérant en sortir quelque chose de pertinent.

---

<div class="post-metadata">

**Author:** ![vohu](https://www.debian-fr.org/user_avatar/www.debian-fr.org/vohu/32/4108_2.png) [@vohu](https://www.debian-fr.org/u/vohu)\
**Post date:** [Février 21, 2016, 8:49 UTC](https://www.debian-fr.org/t/regex-filtre-fail2ban-pour-nginx/63541/8 "2016-02-21T20:49:36Z")

</div>

t’as répondu trop vite, j’étais en train d’éditer 🙂

Je disais :

Je me demande aussi comment fail2ban gère le fait que t’aies plusieurs regex séparées par des “,”. S’il les cumule, le résultat à peu de chance de fonctionner, car si je prends juste failregex = ._404 168._, client: si ta première regex peu donner un résultat, la 2ème à peu de chance d’aboutir, car il faudrait que ta ligne ne contienne que "client: "

j’aurai essayé un truc du genre :  
failregex = ._404 168._, ._client: ._, ._server: \S+._, …

---

<div class="post-metadata">

**Author:** ![anon96191775](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/71c47a/32.png) [@anon96191775](https://www.debian-fr.org/u/anon96191775)\
**Post date:** [Février 21, 2016, 8:49 UTC](https://www.debian-fr.org/t/regex-filtre-fail2ban-pour-nginx/63541/9 "2016-02-21T20:49:37Z")

</div>

Bon, je viens de découvrir l’outil fail2ban-regex qui devrait me donner un coup de main.  
Pour le moment, quoi que j’essaie je ne rencontre que deux possibilités :  
\_soit je ne mets que [mono]._404 168._[/mono] dans ma regex, qui dans ce cas matche avec les lignes concernés de mes logs mais fail2ban me renvoie l’erreur suivante :

```auto

```

\_soit je mets la ligne complète, avec ou sens encadrement par des [mono].\*[/mono] (le reste de l’expression est une simple copie de ce qui se trouve dans le fichier /etc/fail2ban/filter.d/nginx-http-auth.conf, fourni par le paquet fail2ban), et là ça ne matche plus.

* * *

J’ai enfin trouvé la page de manuel REGEX(7), je commence déjà à pleurer des larmes de sang…

---

<div class="post-metadata">

**Author:** ![vohu](https://www.debian-fr.org/user_avatar/www.debian-fr.org/vohu/32/4108_2.png) [@vohu](https://www.debian-fr.org/u/vohu)\
**Post date:** [Février 21, 2016, 8:49 UTC](https://www.debian-fr.org/t/regex-filtre-fail2ban-pour-nginx/63541/10 "2016-02-21T20:49:37Z")

</div>

Tu as essayé ce qu’il y a ici ? : [fail2ban.org/wiki/index.php/NginX](http://www.fail2ban.org/wiki/index.php/NginX)

Au pire tu crées plusieurs groupes de règles pour nginx (ca t’évite de mettre plusieurs regex dans la même commande)

---

<div class="post-metadata">

**Author:** ![anon96191775](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/71c47a/32.png) [@anon96191775](https://www.debian-fr.org/u/anon96191775)\
**Post date:** [Février 21, 2016, 8:49 UTC](https://www.debian-fr.org/t/regex-filtre-fail2ban-pour-nginx/63541/11 "2016-02-21T20:49:37Z")

</div>

`dave@HAL9000:/var/log/nginx$ grep -E ".*404 168.*" /var/log/nginx/access.log | wc -l
1007`

[code]dave@HAL9000:/var/log/nginx$ fail2ban-regex /var/log/nginx/access.log “._404 168._”

# Running tests

Use failregex line : ._404 168._  
Traceback (most recent call last):  
File “/usr/bin/fail2ban-regex”, line 430, in   
fail2banRegex.readRegex(cmd\_regex, ‘fail’) or sys.exit(-1)  
File “/usr/bin/fail2ban-regex”, line 227, in readRegex  
’add%sRegex’ % regextype.title())(regex.getFailRegex())  
File “/usr/share/fail2ban/server/filter.py”, line 95, in addFailRegex  
raise e  
server.failregex.RegexException: No ‘host’ group in ‘._404 168._’[/code]

[code]dave@HAL9000:/var/log/nginx$ fail2ban-regex /var/log/nginx/access.log "._404 168._, client: "

# Running tests

Use failregex line : ._404 168._, client:   
Use log file : /var/log/nginx/access.log

# Results

Failregex: 0 total

Ignoreregex: 0 total

Date template hits:  
|- [# of hits] date format  
| [1247] Day/MONTH/Year:Hour:Minute:Second  
`-

Lines: 1247 lines, 0 ignored, 0 matched, 1247 missed  
Missed line(s): too many to print. Use --print-all-missed to print all 1247 lines[/code]  
Je sens que quelque chose d’évident m’échappe…  
En tous cas mon insistance avec [mono]client: [/mono] ne m’amènera nulle part tel que c’est parti. M’est avis que l’absence du terme “client:” dans les lignes que je cherche à filtrer ne doit pas y être étranger.

Bon, ce n’est apparemment pas en tâtonnant que je vais trouver quelque chose qui fonctionne, j’ai peur de ne plus avoir d’échappatoire à la lecture de [mono]man 7 regex[/mono].

---

<div class="post-metadata">

**Author:** ![vohu](https://www.debian-fr.org/user_avatar/www.debian-fr.org/vohu/32/4108_2.png) [@vohu](https://www.debian-fr.org/u/vohu)\
**Post date:** [Février 21, 2016, 8:49 UTC](https://www.debian-fr.org/t/regex-filtre-fail2ban-pour-nginx/63541/12 "2016-02-21T20:49:37Z")

</div>

Oui je crois… qu’il va falloir. Il faut y passer un jour !

sinon : [expreg.com/memo.php](http://www.expreg.com/memo.php)

C’est sûr que si “client” n’est pas dans tes log, ça va coincer. Moi ce qui m’intrigue, c’est ces virgules…

---

<div class="post-metadata">

**Author:** ![anon96191775](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/71c47a/32.png) [@anon96191775](https://www.debian-fr.org/u/anon96191775)\
**Post date:** [Février 21, 2016, 8:49 UTC](https://www.debian-fr.org/t/regex-filtre-fail2ban-pour-nginx/63541/13 "2016-02-21T20:49:37Z")

</div>

Sauvé, je vais pouvoir remettre mon apprentissage des regex à demain ![:041](https://www.debian-fr.org/uploads/default/original/1X/bfe857c9119752799c3eac55ca37a50312c51282.gif "applaudit")  
La ligne suivante fait l’affaire :

```auto
failregex = ^<HOST> -.*404 168.*
```

source :  
[snippets.aktagon.com/snippets/55 … h-fail2ban](http://snippets.aktagon.com/snippets/554-how-to-secure-an-nginx-server-with-fail2ban)

---

<div class="post-metadata">

**Author:** ![vohu](https://www.debian-fr.org/user_avatar/www.debian-fr.org/vohu/32/4108_2.png) [@vohu](https://www.debian-fr.org/u/vohu)\
**Post date:** [Février 21, 2016, 8:49 UTC](https://www.debian-fr.org/t/regex-filtre-fail2ban-pour-nginx/63541/14 "2016-02-21T20:49:37Z")

</div>

![:079](https://www.debian-fr.org/uploads/default/original/1X/905412cc2e3f543d94c645aa4231b1f3197e2548.gif "flagelle")

---

<div class="post-metadata">

**Author:** ![ricardo](https://www.debian-fr.org/user_avatar/www.debian-fr.org/ricardo/32/3864_2.png) [@ricardo](https://www.debian-fr.org/u/ricardo)\
**Post date:** [Février 21, 2016, 8:49 UTC](https://www.debian-fr.org/t/regex-filtre-fail2ban-pour-nginx/63541/15 "2016-02-21T20:49:42Z")

</div>

[quote=“vv222”]Avec [mono]maxretry = 1[/mono], je risque de bloquer toute origine tombant sur du 404, non ?  
Il n’y a pas de risque de bloquer des utilisateurs légitimes avec ça ?

Encore qu’à la réflexion mon site est pour l’instant limité à une unique page, alors à peu près tout ce qui tente de piocher autre chose a de grandes chances d’être une attaque.[/quote]  
Tous mes maxretry sont entre 1 et 3 maxi avec ssh = 1
