Fail2ban es una herramienta open source que monitorea los archivos log en busca de accesos fallidos, una vez identifica un acceso fallido fail2ban dependiendo de la configuración que se le haya creado procederá a bloquear el puerto o servicio a la IP que intenta acceder de forma “sospechosa”. Fail2ban se vale del firewall del sistema operativo para realizar los respectivos bloqueos.
En algunas ocasiones nos encontramos con que tengamos en nuestros registros de log las siguientes líneas
May 26 12:03:57 centos8 postgres[6426]: [9-1] 2023-05-26 12:03:57.742 -05 {192.168.30.108} [6426] pablin@postgres FATAL: password authentication failed for user "pablin" May 26 12:03:39 centos8 postgres[6422]: [8-1] 2023-05-26 12:03:39.017 -05 {192.168.30.108} [6422] [unknown]@[unknown] LOG: connection received: host=192.168.30.108 port=54454 May 26 12:03:53 centos8 postgres[6424]: [9-1] 2023-05-26 12:03:53.197 -05 {192.168.30.108} [6424] pablin@postgres FATAL: password authentication failed for user "pablin" May 26 12:03:53 centos8 postgres[6424]: [9-2] 2023-05-26 12:03:53.197 -05 {192.168.30.108} [6424] pablin@postgres DETAIL: Connection matched pg_hba.conf line 86: "host #011all #011#011all #011#0110.0.0.0/0 #011#011md5" May 26 12:03:55 centos8 postgres[6425]: [8-1] 2023-05-26 12:03:55.294 -05 {192.168.30.108} [6425] [unknown]@[unknown] LOG: connection received: host=192.168.30.108 port=45128 May 26 12:03:55 centos8 postgres[6425]: [9-1] 2023-05-26 12:03:55.302 -05 {192.168.30.108} [6425] pablin@postgres FATAL: password authentication failed for user "pablin" May 26 12:03:55 centos8 postgres[6425]: [9-2] 2023-05-26 12:03:55.302 -05 {192.168.30.108} [6425] pablin@postgres DETAIL: Connection matched pg_hba.conf line 86: "host #011all #011#011all #011#0110.0.0.0/0 #011#011md5" May 26 12:03:57 centos8 postgres[6426]: [8-1] 2023-05-26 12:03:57.733 -05 {192.168.30.108} [6426] [unknown]@[unknown] LOG: connection received: host=192.168.30.108 port=37390 May 26 12:03:57 centos8 postgres[6426]: [9-1] 2023-05-26 12:03:57.742 -05 {192.168.30.108} [6426] pablin@postgres FATAL: password authentication failed for user "pablin" May 26 12:03:57 centos8 postgres[6426]: [9-2] 2023-05-26 12:03:57.742 -05 {192.168.30.108} [6426] pablin@postgres DETAIL: Connection matched pg_hba.conf line 86: "host #011all #011#011all #011#0110.0.0.0/0 #011#011md5"
Claramente podemos sospechar que alguien está intentando acceder a nuestra base de datos de forma ilegal.
Para estos casos es menester agregar en fail2ban una regla que permita identificar estos intentos fallidos y bloquear la dirección ip del servidor que origina esta conexión.
!!OJO!! realizar esta configuración no bloqueará la cuenta del usuario en postgres, lo que se crea aquí es una regla en firewall que bloquea toda conexión entrante desde la dirección ip “sospechosa”. Por tanto, tener en cuenta que si desde una IP origen se conectan varios usuarios a un servidor de base de datos, todos los usuarios que se intenten conectar desde esta ip serán bloqueados.
Teniendo en cuenta lo anterior, proceda con cautela.
Debemos configurar postgresql para que genere logs de acceso fallido. Esto lo hacemos editando el archivo postgresql.conf que generalmente podemos encontrarlo en /var/lib/pgsql/VERSION/data d
log_destination = 'stderr,syslog'
logging_collector = on
log_connections = on
log_line_prefix = '%m {%h} [%p] %q%u@%d
' log_statement = 'all' log_timezone = 'America/Bogota'
En el caso del log_line_prefix hemos definido una serie de directivas que indican respectivamente el timestamp en milisegundos, el servidor remoto, el número de proceso, el nombre de usuario y el nombre de la base de datos.
Un ejemplo sería la siguiente línea
May 26 16:25:57 centos8 postgres[1742]: [9-1] 2023-05-26 16:25:57.779 -05 {192.168.30.130} [1742] pablin@postgres LOG: connection authorized: user=pablin database=postgres application_name=psql
Una vez editado el archivo postgresql.con, reiniciamos el servicio de postgres, un ejemplo sería el siguiente…
[root@centos8 ~]# systemctl restart postgresql-13.service [root@centos8 ~]#
Verificamos el estado del servicio
[root@centos8 ~]# systemctl status postgresql-13.service ● postgresql-13.service - PostgreSQL 13 database server Loaded: loaded (/usr/lib/systemd/system/postgresql-13.service; enabled; vendor preset: disabled) Active: active (running) since Fri 2023-05-26 17:51:30 -05; 2s ago Docs: https://www.postgresql.org/docs/13/static/ Process: 1990 ExecStartPre=/usr/pgsql-13/bin/postgresql-13-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS) Main PID: 1995 (postmaster) Tasks: 8 (limit: 24860) Memory: 17.0M CGroup: /system.slice/postgresql-13.service ├─1995 /usr/pgsql-13/bin/postmaster -D /var/lib/pgsql/13/data/ ├─1998 postgres: logger ├─2000 postgres: checkpointer ├─2001 postgres: background writer ├─2002 postgres: walwriter ├─2003 postgres: autovacuum launcher ├─2004 postgres: stats collector └─2005 postgres: logical replication launcher May 26 17:51:30 centos8.5.unixpad.local postmaster[1995]: 2023-05-26 17:51:30.199 -05 {} [1995] HINT: Future log output will appear in directory "log". May 26 17:51:30 centos8.5.unixpad.local postgres[1995]: [1-2] 2023-05-26 17:51:30.199 -05 {} [1995] HINT: Future log output will appear in directory "log". May 26 17:51:30 centos8.5.unixpad.local postgres[1995]: [2-1] 2023-05-26 17:51:30.199 -05 {} [1995] LOG: starting PostgreSQL 13.11 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.5.0 20210514 (Red> May 26 17:51:30 centos8.5.unixpad.local postgres[1995]: [3-1] 2023-05-26 17:51:30.199 -05 {} [1995] LOG: listening on IPv4 address "0.0.0.0", port 5432 May 26 17:51:30 centos8.5.unixpad.local postgres[1995]: [4-1] 2023-05-26 17:51:30.199 -05 {} [1995] LOG: listening on IPv6 address "::", port 5432 May 26 17:51:30 centos8.5.unixpad.local postgres[1995]: [5-1] 2023-05-26 17:51:30.238 -05 {} [1995] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" May 26 17:51:30 centos8.5.unixpad.local postgres[1995]: [6-1] 2023-05-26 17:51:30.303 -05 {} [1995] LOG: listening on Unix socket "/tmp/.s.PGSQL.5432" May 26 17:51:30 centos8.5.unixpad.local postgres[1999]: [7-1] 2023-05-26 17:51:30.345 -05 {} [1999] LOG: database system was shut down at 2023-05-26 17:51:30 -05 May 26 17:51:30 centos8.5.unixpad.local postgres[1995]: [7-1] 2023-05-26 17:51:30.380 -05 {} [1995] LOG: database system is ready to accept connections May 26 17:51:30 centos8.5.unixpad.local systemd[1]: Started PostgreSQL 13 database server. [root@centos8 ~]#
Con los cambios realizados, procedemos a configurar los archivos correspondientes a fail2ban. Ellos son dos
/etc/fail2ban/jail.d/postgresql.conf
[root@centos8 fail2ban]# cat jail.d/postgresql.conf [postgresql] enabled = true filter = postgresql logpath = /var/log/messages maxretry = 3 bantime = 20 port = 5432 [root@centos8 fail2ban]#
/etc/fail2ban/filter.d/postgresql.conf
[root@centos8 fail2ban]# cat /etc/fail2ban/filter.d/postgresql.conf [Definition] failregex = \{<HOST>\} .+? FATAL: password authentication failed for user .+$ [root@centos8 fail2ban]#
Una vez tengamos estos dos archivos configurados, podemos reiniciar el servicio de fail2ban
[root@centos8 fail2ban]# systemctl restart fail2ban [root@centos8 fail2ban]#
Y verificamos el estado del servicio
[root@centos8 fail2ban]# systemctl status fail2ban ● fail2ban.service - Fail2Ban Service Loaded: loaded (/usr/lib/systemd/system/fail2ban.service; enabled; vendor preset: disabled) Active: active (running) since Fri 2023-05-26 18:00:12 -05; 5s ago Docs: man:fail2ban(1) Process: 2051 ExecStop=/usr/bin/fail2ban-client stop (code=exited, status=0/SUCCESS) Process: 2053 ExecStartPre=/bin/mkdir -p /run/fail2ban (code=exited, status=0/SUCCESS) Main PID: 2055 (fail2ban-server) Tasks: 5 (limit: 24860) Memory: 13.2M CGroup: /system.slice/fail2ban.service └─2055 /usr/bin/python3.6 -s /usr/bin/fail2ban-server -xf start May 26 18:00:12 centos8.5.unixpad.local systemd[1]: fail2ban.service: Succeeded. May 26 18:00:12 centos8.5.unixpad.local systemd[1]: Stopped Fail2Ban Service. May 26 18:00:12 centos8.5.unixpad.local systemd[1]: Starting Fail2Ban Service... May 26 18:00:12 centos8.5.unixpad.local systemd[1]: Started Fail2Ban Service. May 26 18:00:12 centos8.5.unixpad.local fail2ban-server[2055]: Server ready [root@centos8 fail2ban]#
Luego de ello podemos revisar el archivo /var/log/messages con el fin de acceder de forma fallida para probar el funcionamiento de fail2ban
May 26 18:02:58 centos8 postgres[2085]: [8-1] 2023-05-26 18:02:58.940 -05 {192.168.30.108} [2085] [unknown]@[unknown] LOG: connection received: host=192.168.30.108 port=60408 May 26 18:02:58 centos8 postgres[2085]: [9-1] 2023-05-26 18:02:58.960 -05 {192.168.30.108} [2085] postgres@postgres FATAL: password authentication failed for user "postgres" May 26 18:02:58 centos8 postgres[2085]: [9-2] 2023-05-26 18:02:58.960 -05 {192.168.30.108} [2085] postgres@postgres DETAIL: Connection matched pg_hba.conf line 86: "host #011all #011#011all #011#0110.0.0.0/0 #011#011md5" May 26 18:03:13 centos8 postgres[2088]: [8-1] 2023-05-26 18:03:13.206 -05 {192.168.30.108} [2088] [unknown]@[unknown] LOG: connection received: host=192.168.30.108 port=60652 May 26 18:03:13 centos8 postgres[2088]: [9-1] 2023-05-26 18:03:13.221 -05 {192.168.30.108} [2088] postgres@postgres FATAL: password authentication failed for user "postgres" May 26 18:03:13 centos8 postgres[2088]: [9-2] 2023-05-26 18:03:13.221 -05 {192.168.30.108} [2088] postgres@postgres DETAIL: Connection matched pg_hba.conf line 86: "host #011all #011#011all #011#0110.0.0.0/0 #011#011md5" May 26 18:03:14 centos8 postgres[2089]: [8-1] 2023-05-26 18:03:14.815 -05 {192.168.30.108} [2089] [unknown]@[unknown] LOG: connection received: host=192.168.30.108 port=60668 May 26 18:03:14 centos8 postgres[2089]: [9-1] 2023-05-26 18:03:14.827 -05 {192.168.30.108} [2089] postgres@postgres FATAL: password authentication failed for user "postgres" May 26 18:03:14 centos8 postgres[2089]: [9-2] 2023-05-26 18:03:14.827 -05 {192.168.30.108} [2089] postgres@postgres DETAIL: Connection matched pg_hba.conf line 86: "host #011all #011#011all #011#0110.0.0.0/0 #011#011md5" [root@centos8 fail2ban]#
El sistema ha registrado los intentos fallidos, procedemos entonces a verificar el archivo /var/log/fail2ban.log
2023-05-26 18:03:00,168 fail2ban.filter [2055]: INFO [postgresql] Found 192.168.30.108 - 2023-05-26 18:02:58 2023-05-26 18:03:14,187 fail2ban.filter [2055]: INFO [postgresql] Found 192.168.30.108 - 2023-05-26 18:03:13 2023-05-26 18:03:15,389 fail2ban.filter [2055]: INFO [postgresql] Found 192.168.30.108 - 2023-05-26 18:03:14 2023-05-26 18:03:15,691 fail2ban.actions [2055]: NOTICE [postgresql] Ban 192.168.30.108
Nos damos cuenta que el sistema a bloqueado el acceso a la IP por la palabra Ban
El tiempo del bloqueo podemos determinarlo en la configuración que definimos, en este caso el parámetro quedó configurado a 20 segundos, podemos definir que el tiempo sea de 10 meses o más o menos, depende de las necesidades que se tengan.
Saludos.