> ## Content Index
> Fetch the complete content index at: https://blog.firenetwork.it/llms.txt
> Use this file to discover other available public pages before exploring further.

# Fail2Ban - Un cane da guardia per NGINX
- URL: https://blog.firenetwork.it/fail2ban-un-cane-da-guardia-per-nginx/
- Published: 2025-06-19T18:32:43.000Z
- Updated: 2025-06-24T15:11:56.000Z
- Description: Fail2Ban è un software che utilizza iptables per bloccare automaticamente i client che continuano a fallire i tentativi di accesso, che provano a sfruttare vulnerabilità dei servizi web, e molto altro. Vediamo insieme come implementarlo sulla nostra infrastruttura.
- Author: Samuele Gabbrielli
- Tags: Guide, NGINX, #Import 2026-03-12 20:23

# Introduzione

Nelle guide precedenti abbiamo visto come implementare NGINX per svolgere varie funzioni, come:

- [Reverse Proxy](https://blog.firenetwork.it/come-creare-un-reverse-proxy-con-nginx/)
- [Terminatore SSL](https://blog.firenetwork.it/come-creare-un-reverse-proxy-con-nginx/)
- [Load Balancer per server DNS](https://blog.firenetwork.it/nginx-creare-un-load-balancer-per-server-dns-2/)

Ma nell'[articolo di introduzione ad NGINX](https://blog.firenetwork.it/introduzione-ad-nginx/), ho specificato che un software di questo tipo ci permette anche di aumentare notevolmente la sicurezza dell'infrastruttura.

Come può farlo, di preciso?

Innanzitutto, facendo passare tutto il traffico da NGINX è possibile approfittare di questo accentramento per concentrare sui nodi NGINX tutte le configurazioni di sicurezza a livello di firewall e regole di ispezione del traffico.

In questa guida, vedremo come implementare una soluzione open source che utilizza il firewall **iptables** e **criteri di lettura dei log** per rilevare e bloccare i tentativi di intrusione: [Fail2Ban](https://github.com/fail2ban/fail2ban?ref=blog.firenetwork.it)

# Installazione

*(testato su Ubuntu Server 24.04)*

Fail2Ban si installa con pochi e semplici comandi, vediamoli insieme.

Installate **fail2ban** ed **iptables**

```
sudo apt install fail2ban iptables
```

Controllate lo stato del servizio di fail2ban

```
fail2ban-client status
```

Create il file jail.local partendo dal file di template jail.conf

```
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
```

💡

d'ora in poi, modificate solo il file ****.local** che abbiamo appena creato, perchè è questo he Fail2Ban andrà a leggere

Con questo si conclude lo step di installazione.

Andiamo ora a vedere come configurare Fail2Ban per abilitare le regole che ci servono e personalizzarne il comportamento.

# Configurazione

## Come funziona la configurazione

- Il file di configurazione che abbiamo appena creato (**jail.local**) contiene una lista di regole che Fail2Ban applicherà **leggendo i file di log** che andremo ad indicare al suo interno.
- Ogni regola che andremo a creare diverrà una **jail** (dall'inglese, *prigione*). Un client che soddisfa i requisiti indicati nella jail (ad esempio, 3 tentativi di accesso non riusciti) verrà messo nella jail corrispondente a quella regola.
- Dentro ad ogni regola è anche specificata una **lista di azioni da intraprendere**. Dal più banale "blocca questo client sul firewall" ad "invia una notifica telegram", è possibile indicare varie azioni da far compiere a Fail2Ban
- Un client che viene *spedito in prigione*, verrà bloccato **esclusivamente utilizzando le regole specificate in quella jail** (ad esempio, se ho una regola per SSH ed una per un server web, ed un client sbaglia l'autenticazione SSH, potrà comunque utilizzare il server web)

## Creare delle eccezioni

Prima di andare avanti con la configurazione, è il caso di censire alcune eccezioni su Fail2Ban per evitare di bloccarci da soli durante i nostri test.

Modificate il file *jail.local*

```
nano /etc/fail2ban/jail.local 
```

Andate alla riga del parametro **ignoreip** ed aggiungete le subnet e/o gli indirizzi che Fail2Ban non deve mai bannare

Per esempio, per ignorare **192.168.120.1** e tutta la rete **192.168.0.0**:

```
ignoreip = 192.168.0.0/24,192.168.120.1
```

## Creare una regola per l'autenticazione SSH

In questo esempio diremo a Fail2Ban di bloccare per 4 ore tutti i client che sbagliano 3 volte la password di SSH nell'arco di 30 secondi.

Modifichiamo il file *jail.local*

```
nano /etc/fail2ban/jail.local 
```

Impostiamo la sezione **\[sshd\]** relativa ad SSH come segue:

```
[sshd]
enabled = true
filter = sshd
maxretry = 3
port    = ssh
backend = systemd
findtime = 30
bantime = 4h
```

- **enabled** → indica se la jail è attiva o meno
- **filter** → fa riferimento al filtro presente in */etc/fail2ban/filter.d/* relativo ad *sshd*. Questo file contiene informazioni relative a come interpretare i file di log di sshd
- **maxretry** → il numero massimo di tentativi errati, in questo caso relativi all'autenticazione tramite SSH
- **port →** la porta da usare per la regola di firewall, che viene creata nel caso in cui un client debba essere bloccato. Indicando **ssh** come in questo esempio, verrà usata la porta di default di SSH (22)
- **backend** → indica che per leggere i log di sshd, Fail2Ban dovrà utilizzare systemd (perchè sshd è un servizio di systemd)
- **findtime** → il tempo massimo (in questo caso, essendo senza unità di misura è in secondi) che deve passare tra i tentativi massimi (in questo caso 3) affinchè la regola sia soddisfatta
- **bantime** → dopo quante ore cancellare il blocco sul firewall per ciascun client che viene bannato

Come avrete notato, in questo esempio non è specificata alcuna azione da intraprendere alla soddisfazione della regola. Quando non specificata, l'azione che viene intrapresa è quella indicata al parametro **action\_** nel file **jail.local**, sotto alla sezione **\[DEFAULT\]**

Di default, questa azione crea una regola su **iptables** che rifiuta le connessioni del client da bloccare, **sulla porta indicata nella regola**.

---

Ora che abbiamo configurato la nostra prima regola, riavviamo il servizio di fail2ban per testarne il funzionamento

```
sudo systemctl restart fail2ban.service
systemctl status fail2ban.service
```

Provate, **da un client che non sia stato configurato nel parametro *ignoreip***, ad autenticarvi tramite SSH alla macchina sbagliando la password più volte. Dopo tre tentativi, dovreste perdere la connessione.

Potete monitorare il funzionamento in due modi:

- Leggendo in diretta il log di Fail2Ban

```
tail -f /var/log/fail2ban.log
```

- Controllando lo status della Jail sshd

```
fail2ban-client status sshd

```

Dato che si tratta di un test, potete ora sbannare manualmente il vostro client

```
sudo fail2ban-client set %nomejail% unbanip %indirizzoIP%
```

## Creare una regola per NGINX

Se state usando NGINX come reverse Proxy, può esservi molto utile configurare alcune *jail* relative ad NGINX. In questo esempio ne configureremo due:

- *nginx-http-auth* che monitora i vostri webserver in reverse proxy che espongono autenticazione http, e ci permetterà di bannare i client che falliscono l'autenticazione troppe volte
- *nginx-bad-clients* (che andremo ad importare in quanto regola personalizzata) che blocca gran parte dei bot che cercano di rilevare le vulnerabilità dei vostri servizi web

💡

I seguenti passaggi devono essere eseguiti sulla macchina in cui è installato NGINX

Prima di tutto, modifichiamo il file *jail.local*

```
nano /etc/fail2ban/jail.local 
```

Impostiamo la regola **\[nginx-http-auth\]**

```
[nginx-http-auth]

enabled  = true
port     = http,https
logpath = /var/log/nginx/error.log
```

Poi creiamo la regola **\[nginx-bad-clients\]** (vi consiglio di farlo vicino alle altre regole relative ad NGINX, per comodità)

```
[nginx-bad-clients]
port     = http,https
filter   = nginx-bad-clients
logpath  = /var/log/nginx/*access.log
maxretry = 3
findtime = 30s
bantime  = 4h
enabled  = true
```

Notate come il valore di **logpath** sia diverso per le due regole. Questo perchè:

- **nginx-http-auth** controlla esclusivamente i tentativi di accesso falliti, che vengono loggati in error.log
- **nginx-bad-clients** controlla invece i comportamenti dei client che accedono (anche se con successo) a vari path dei vostri servizi web usando dei pattern sospetti

**nginx-bad-clients** quini agisce anche quando il client non sta facendo di per sé qualcosa di sbagliato, ma sta palesemente curiosando in giro

Come ho specificato poco fa, il filtro **nginx-bad-clients** in realtà non esiste di default su Fail2Ban, perché si tratta di un filtro custom. Andiamo a crearlo

Create il filtro **nginx-bad-clients**

```
nano /etc/fail2ban/filter.d/nginx-bad-clients.local
```

Incollate il seguente contenuto

```
# Fail2Ban filter to match web requests for misbehaving clients
#
 
[INCLUDES]
 
# Load regexes for filtering
before = botsearch-common.conf
 
[Definition]
 
failregex = ^<HOST> - \S+ \[\] "[^"]*" 429 .+$
            ^<HOST> - \S+ \[\] "[^"]*" 404 .+$
 
ignoreregex = 
 
datepattern = {^LN-BEG}%%ExY(?P<_sep>[-/.])%%m(?P=_sep)%%d[T ]%%H:%%M:%%S(?:[.,]%%f)?(?:\s*%%z)?
              ^[^\[]*\[({DATE})
              {^LN-BEG}
 
# DEV Notes:
# Based on nginx-botsearch filter
# 
# Author: Dan Langille
```

Una volta salvato, riavviate fail2ban e controllate che non abbia segnalato errori

```
sudo systemctl restart fail2ban.service
systemctl status fail2ban.service
```

Come indicato per sshd, potete controllare lo stato di fail2ban e delle nostre nuove jail tramite i seguenti comandi:

- Leggendo in diretta il log di Fail2Ban

```
tail -f /var/log/fail2ban.log
```

- Controllando lo status della Jail nginx-bad-clients e nginx-http-auth

```
fail2ban-client status nginx-bad-clients
fail2ban-client status nginx-http-auth
```

## Come inviare notifiche Telegram

Nell'introduzione alla configurazione, ho menzionato la possibilità di inviare notifiche Telegram quando Fail2Ban banna (o sbanna) un client.

Integrazioni come questa, e molte altre, sono possibili grazie al grado di personalizzazione che Fail2Ban ci offre.

In questo esempio, vediamo come configurare l'invio notifiche tramite Telegram.

Prima di tutto, creiamo la cartella /etc/failban/scripts dove tenere questo ed i nostri altri script personalizzati

```
sudo mkdir /etc/fail2ban/scripts
```

Creare il file **/etc/fail2ban/scripts/fail2ban-telegram.sh** col seguente contenuto (modificando il bot token ed i chat id):

```
sudo nano /etc/fail2ban/scripts/fail2ban-telegram.sh
```

```
#!/bin/bash

# Sends text messages using Telegram
# to alert webmaster of banning.

# Require one argument, one of the following
# start
# stop
# ban
# unban
# Optional second argument: Ip for ban/unband

# Display usage information
function show_usage {
  echo "Usage: $0 action <ip>"
  echo "Where action start, stop, ban, unban"
  echo "and IP is optional passed to ban, unban"
  exit
}

# Send notification
function send_msg {
  apiToken=<bottoken>
  chatId=<chatid>
  url="https://api.telegram.org/bot$apiToken/sendMessage"

  curl -s -X POST $url -d chat_id=$chatId -d text="$1"
  exit
}

# Check for script arguments
if [ $# -lt 1 ]
then
  show_usage
fi

# Take action depending on argument
if [ "$1" = 'start' ]
then
  msg='Fail2ban+just+started.'
  send_msg $msg
elif [ "$1" = 'stop' ]
then
  msg='Fail2ban+just+stopped.'
  send_msg $msg
elif [ "$1" = 'ban' ]
then
  msg=$([ "$2" != '' ] && echo "Fail2ban+just+banned+$2+on+service+$3." || echo 'Fail2ban+just+banned+an+ip+on+service+$3.' )
  send_msg $msg
elif [ "$1" = 'unban' ]
then
  msg=$([ "$2" != '' ] && echo "Fail2ban+just+unbanned+$2+on+service+$3." || echo "Fail2ban+just+unbanned+an+ip+on+service+$3." )
  send_msg $msg
else
  show_usage
fi
```

Creare il file **/etc/fail2ban/action.d/telegram.conf** col seguente contenuto:

```
sudo nano /etc/fail2ban/action.d/telegram.conf
```

```
# Fail2Ban configuration file
#
# Author: MushaGH
#
#

[Definition]

# Option:  actionstart
# Notes.:  command executed once at the start of Fail2Ban.
# Values:  CMD
#
actionstart = /etc/fail2ban/scripts/fail2ban-telegram.sh start

# Option:  actionstop
# Notes.:  command executed once at the end of Fail2Ban
# Values:  CMD
#
actionstop = /etc/fail2ban/scripts/fail2ban-telegram.sh stop

# Option:  actioncheck
# Notes.:  command executed once before each actionban command
# Values:  CMD
#
actioncheck =

# Option:  actionban
# Notes.:  command executed when banning an IP. Take care that the
#          command is executed with Fail2Ban user rights.
# Tags:    See jail.conf(5) man page
# Values:  CMD
#
actionban = /etc/fail2ban/scripts/fail2ban-telegram.sh ban <ip> <name>

# Option:  actionunban
# Notes.:  command executed when unbanning an IP. Take care that the
#          command is executed with Fail2Ban user rights.
# Tags:    See jail.conf(5) man page
# Values:  CMD
#
actionunban = /etc/fail2ban/scripts/fail2ban-telegram.sh unban <ip> <name>

[Init]

init = 123
```

Riavviare Fail2Ban e controllare che non dia errore relativo al modulo telegram

```
sudo systemctl restart fail2ban.service
systemctl status fail2ban.service
```

Se non viene segnalato alcun errore, possiamo implementare l'azione "telegram" sulle nostre jail

Modifichiamo il file jail.local

```
sudo nano /etc/fail2ban/jail.local
```

Ed aggiungiamo a tutte le jail dove vogliamo abilitare le notifiche telegram il parametro **action**

```
action = iptables[name=SSH,port=22,protocol=tcp]
         telegram
```

In questo esempio, la action è relativa alla jail *sshd*. Dobbiamo specificare una azione per riga:

- **iptables\[name,port,protocol\]** crea una regola firewall su *iptables* che blocca tutte le comunicazioni sulla porta 22 TCP per l'IP del client da bannare
- **telegram** invece invia una notifica telegram usando i parametri impostati in precedenza

Ripetete questa configurazione su tutte le jail dove abilitare le notifiche Telegram, modificando **name**, **port** e **protocol** a seconda del servizio in questione

Riavviate infine Fail2Ban e controllate che non ci siano errori segnalati

```
sudo systemctl restart fail2ban.service
systemctl status fail2ban.service
```

Adesso quando un client viene bannato, riceverete anche una notifica su Telegram!

---

![](https://blog.firenetwork.it/content/images/2025/06/Written-By-Human-Not-By-AI-Badge-white@2x-4.png)