Fail2Ban: Filtros

Servicio: SSH puerto 22 o 44

#***********************************
#*********** SSH  ******************
#***********************************
[sshd]
enabled = true
port = ssh,sftp,44
filter = sshd
logpath = %(sshd_log)s
backend = %(sshd_backend)s
bantime = 172800
maxretry = 3

Servicio: SSHD-DDOS este un un servicio que nos va a proteger contra ataques DDOS sobre SSH

  • agregamos
#***********************************
#*********** SSH-DDOS  *************
#***********************************
[sshd-ddos]
enabled  = true
port     = ssh,sftp,44
#filter   = sshd-ddos
filter   = sshd[mode=ddos]
logpath = %(sshd_log)s
backend = %(sshd_backend)s
bantime = 172800
maxretry = 3
  • Y este filtro no viene por defecto lo vamos a crear
nano /etc/fail2ban/filter.d/sshd-ddos.conf
  • Le agregamos
                                                                              
# Fail2ban configuration file
#
# Author: Gustavo Matamoros Gonzalez
#


[Definition]
failregex = ^\s*sshd\(\S+\): Failed \S+ for .* from <HOST> port \S+ ssh2$
            ^\s*sshd\(\S+\): User .+ from <HOST> not allowed because not listed in AllowUsers$
            ^\s*sshd\(\S+\): Did not receive identification string from <HOST>$
ignoreregex =

APACHE

apache-auth.conf

  • apache-auth: Este filtro se utiliza para detectar intentos de autenticación fallidos en un servidor web Apache. Puede ser útil para proteger contra ataques de fuerza bruta dirigidos a las credenciales de autenticación de Apache.
#*********************************** 
#********** APACHE-AUTH   ********** 
#***********************************
[apache-auth]

enabled = true
filter = apache-auth
action = iptables-multiport[name=apache-auth, port="http,https"]
logpath = /var/log/apache2/*access.log
findtime = 600
bantime = 172800
maxretry = 3
  • enabled = true habilita esta regla.
  • filter = apache-auth indica que estamos usando el filtro apache-auth.
  • action = iptables-multiport[name=apache-auth, port="http,https"] configura la acción para bloquear las IP detectadas.
  • logpath debe apuntar al archivo de registro de Apache donde se registran los intentos de autenticación fallidos.
  • findtime especifica el período de tiempo en segundos durante el cual Fail2ban busca intentos repetidos.
  • bantime es el tiempo durante el cual una dirección IP se bloqueará si se supera el número máximo de intentos (maxretry) dentro del período findtime.
  • maxretry establece el número máximo de intentos de autenticación fallidos permitidos antes de que se active el bloqueo.

apache-badbots

  • apache-badbots: Este filtro se encarga de identificar bots maliciosos o «bad bots» que pueden estar intentando acceder a tu sitio web de manera no autorizada. Estos bots pueden consumir recursos del servidor y afectar el rendimiento del sitio.
#*********************************** 
#********** APACHE-BADBOTS  ******** 
#***********************************
[apache-badbots]

enabled = true
port = http,https
filter = apache-badbots
logpath = /var/log/apache2/*access.log
bantime = 172800
maxretry = 1   # El número máximo de intentos antes de bloquear

apache-common

  • apache-common: Este filtro es bastante genérico y se utiliza para detectar patrones comunes de ataques en los registros de Apache. Puede ayudar a detectar actividades sospechosas en general.
#*********************************** 
#********** APACHE-COMMON   ******** 
#***********************************
[apache-common]
enabled = true
port = http,https
filter = apache-common
logpath = /var/log/apache2/*error.log 
          /var/log/apache2/*access.log
bantime = 172800
maxretry = 3
  • La wildcard * en *access.log se utiliza para indicar que la jail apache-common debe buscar archivos de registro de acceso que sigan un patrón específico en el nombre del archivo. En el contexto de la configuración de Fail2ban, el uso de * se interpreta como una comodín para coincidir con múltiples archivos de registro de acceso que tengan nombres similares.
  • Por ejemplo, si tienes archivos de registro de acceso que siguen un patrón de nombres como access.log, access.log.1, access.log.2, etc., el uso de *access.log permitirá que Fail2ban coincida con todos estos archivos.
  • Abrimos el archivo
nano /etc/fail2ban/filter.d/apache-common.conf
  • Y modificamos su contenido
[Definition]
# Generic configuration items (to be used as interpolations) in other
# apache filters.

[INCLUDES]

before = common.conf
# Load customizations if any available
after = apache-common.local

[DEFAULT]

# Apache logging mode:
#   all - universal prefix (logfile, syslog)
#   logfile - logfile only
#   syslog - syslog only
# Use `filter = apache-auth[logging=syslog]` to get more precise regex if apache logs into syslog (ErrorLog syslog).
# Use `filter = apache-auth[logging=all]` to get universal regex matches both logging variants.
logging = logfile

# Apache logging prefixes (date-pattern prefix, server, process etc.):
apache-prefix-syslog = %(__prefix_line)s
apache-prefix-logfile = \[\]\s
apache-prefix-all = (?:%(apache-prefix-logfile)s|%(apache-prefix-syslog)s)?

# Setting for __prefix_line (only `logging=syslog`):
_daemon = (?:apache\d*|httpd(?:/\w+)?)

apache-prefix = <apache-prefix-<logging>>

apache-pref-ignore =

_apache_error_client = <apache-prefix>\[(:?error|<apache-pref-ignore>\S+:\S+)\]( \[pid \d+(:\S+ \d+)?\])? \[client <HOST>(:\d{1,5})?\]

datepattern = {^LN-BEG}

# Common prefix for [error] apache messages which also would include <HOST>
# Depending on the version it could be
# 2.2: [Sat Jun 01 11:23:08 2013] [error] [client 1.2.3.4]
# 2.4: [Thu Jun 27 11:55:44.569531 2013] [core:info] [pid 4101:tid 2992634688] [client 1.2.3.4:46652]
# 2.4 (perfork): [Mon Dec 23 07:49:01.981912 2013] [:error] [pid 3790] [client 204.232.202.107:46301] script '/var/www/timthumb.php' not found or unable to 
#
# Reference: https://github.com/fail2ban/fail2ban/issues/268
#
# Author: Yaroslav Halchenko

apache-nohome y apache-noscript

  • apache-nohome y apache-noscript: Estos filtros se utilizan para detectar intentos de acceso a directorios o archivos inexistentes en el servidor. Esto podría indicar un intento de explorar vulnerabilidades en tu sitio web.
#*********************************** 
#********** APACHE-NOHOME   ******** 
#***********************************
[apache-nohome]

enabled = true
port = http,https
filter = apache-nohome
logpath = /var/log/apache2/*error.log
          /var/log/apache2/*access.log
bantime = 172800
maxretry = 3   # El número máximo de intentos antes de bloquear

#*********************************** 
#********** APACHE-NOSCRIPT ******** 
#***********************************
[apache-noscript]

enabled = true
port = http,https
filter = apache-noscript
logpath = /var/log/apache2/*error.log
          /var/log/apache2/*access.log
bantime = 172800

apache-overflows

  • apache-overflows: Este filtro se encarga de detectar intentos de explotar vulnerabilidades de desbordamiento de búfer u otros tipos de ataques de desbordamiento en el servidor web Apache.
#*********************************** 
#********** APACHE-OVERFLOWS ******* 
#***********************************
[apache-overflows]

enabled = true
port = http,https
filter = apache-overflows
logpath = /var/log/apache2/*error.log
          /var/log/apache2/*access.log
bantime = 172800
maxretry = 2   # El número máximo de intentos antes de bloquear

apache-modsecurity (Investigar para versión 6)

apt install libapache2-mod-security2
  • Habilitar el modulo
a2enmod security2
systemctl restart apache2
#*********************************** 
#****** APACHE-MODSECURITY   ******* 
#***********************************
[apache-modsecurity]

enabled = true
port = http,https
filter = apache-modsecurity
logpath = /var/log/apache2/modsec_audit.log
bantime = 172800
maxretry = 3   # El número máximo de intentos antes de bloquear
nano /etc/fail2ban/filter.d/apache-modsecurity.conf
  • Contenido actual
# Fail2Ban apache-modsec filter
#

[INCLUDES]

# Read common prefixes. If any customizations available -- read them from
# apache-common.local
before = apache-common.conf

[Definition]


failregex = ^%(_apache_error_client)s(?: \[client [^\]]+\])? ModSecurity:\s+(?:\[(?:\w+ \"[^\"]*\"|[^\]]*)\]\s*)*Access denied with code [45]\d\d

ignoreregex =

# https://github.com/SpiderLabs/ModSecurity/wiki/ModSecurity-2-Data-Formats
# Author: Daniel Black
#         Sergey G. Brester aka sebres (review, optimization)
  • Le agregamos
^.*\[client <HOST>\] ModSecurity:
  • Quedando así
# Fail2Ban apache-modsec filter
#

[INCLUDES]

# Read common prefixes. If any customizations available -- read them from
# apache-common.local
before = apache-common.conf

[Definition]


failregex = ^%(_apache_error_client)s(?: \[client [^\]]+\])? ModSecurity:\s+(?:\[(?:\w+ \"[^\"]*\"|[^\]]*)\]\s*)*Access denied with code [45]\d\d
            ^.*\[client <HOST>\] ModSecurity:

ignoreregex =

# https://github.com/SpiderLabs/ModSecurity/wiki/ModSecurity-2-Data-Formats
# Author: Daniel Black
#         Sergey G. Brester aka sebres (review, optimization)
  • Este filtro se basa en patrones comunes que pueden encontrarse en los registros de auditoría de ModSecurity. Busca líneas que comiencen con una marca de tiempo, seguida de un cliente IP (<HOST>) y luego una descripción de eventos que indican acceso denegado o advertencias generadas por ModSecurity.

apache-404

  • apache-404: Detecta múltiples solicitudes 404 (no encontradas) desde una misma dirección IP en un corto período de tiempo, lo que puede ser indicativo de un escaneo o exploración maliciosa.
#*********************************** 
#******      APACHE-404      ******* 
#***********************************
[apache-404]

enabled = true
port = http,https
filter = apache-404
logpath = /var/log/apache2/*error.log
          /var/log/apache2/*access.log
findtime = 600  
bantime = 172800
  • Creamos el filtro
nano /etc/fail2ban/filter.d/apache-404.conf
  • Agregamos el contenido
# Filtro para Fail2ban - apache-404.conf
# Autor: Gustavo Matamoros

[Definition]

failregex = ^<HOST>.*"GET .* 404 \d+$
            ^<HOST>.*"POST .* 404 \d+$

ignoreregex =

apache-botsearch

  • El filtro apache-botsearch en Fail2ban se utiliza para detectar bots que realizan búsquedas maliciosas en tu servidor Apache. Estos bots a menudo buscan vulnerabilidades conocidas en aplicaciones web o exploran recursos en busca de posibles puntos de entrada para explotar.
#*********************************** 
#***** APACHE-BOTSEARCH      ******* 
#***********************************
[apache-botsearch]

enabled = true
port = http,https
filter = apache-botsearch
logpath = /var/log/apache2/*error.log
          /var/log/apache2/*access.log
findtime = 3600 
bantime = 172800
maxretry = 3   # Número máximo de intentos antes de bloquear
  • Ahora vamos a modificar el filtro, abrimos el archivo
nano /etc/fail2ban/filter.d/apache-botsearch.conf
  • Original
# types of scripts that don't exist.
#
#
# This is normally a predefined list of exploitable or valuable web services
# that are hidden or aren't actually installed.
#

[INCLUDES]

# overwrite with apache-common.local if _apache_error_client is incorrect.
# Load regexes for filtering from botsearch-common.conf
before = apache-common.conf
         botsearch-common.conf

[Definition]

prefregex = ^%(_apache_error_client)s (?:AH\d+: )?<F-CONTENT>.+</F-CONTENT>$

failregex = ^(?:File does not exist|script not found or unable to stat): <webroot><block>(, referer: \S+)?\s*$
            ^script '<webroot><block>' not found or unable to stat(, referer: \S+)?\s*$

ignoreregex =

# Webroot represents the webroot on which all other files are based
webroot = /var/www/


# DEV Notes:
#
# Author: Daniel Black
  • Y agregamos
^<HOST>.*"(GET|POST) /.*\.(php|asp|aspx|jsp|cgi|pl|py|rb|exe|dll|sh|bash).* HTTP/.*" 404
  • quedando así
# types of scripts that don't exist.
#
#
# This is normally a predefined list of exploitable or valuable web services
# that are hidden or aren't actually installed.
#

[INCLUDES]

# overwrite with apache-common.local if _apache_error_client is incorrect.
# Load regexes for filtering from botsearch-common.conf
before = apache-common.conf
         botsearch-common.conf

[Definition]

prefregex = ^%(_apache_error_client)s (?:AH\d+: )?<F-CONTENT>.+</F-CONTENT>$

failregex = ^(?:File does not exist|script not found or unable to stat): <webroot><block>(, referer: \S+)?\s*$
            ^script '<webroot><block>' not found or unable to stat(, referer: \S+)?\s*$
            ^<HOST>.*"(GET|POST) /.*\.(php|asp|aspx|jsp|cgi|pl|py|rb|exe|dll|sh|bash).* HTTP/.*" 404

ignoreregex =

# Webroot represents the webroot on which all other files are based
webroot = /var/www/


# DEV Notes:
#
# Author: Daniel Black

apache-fakegooglebot

  • La jail apache-fakegooglebot en Fail2ban se utiliza para detectar intentos de acceso de bots maliciosos que pretenden ser el motor de búsqueda de Google, conocido como «Googlebot». Estos bots intentan engañar al servidor haciéndose pasar por Googlebot, lo que podría ser un indicador de intentos de exploración maliciosa o ataques de scraping.
#*********************************** 
#***** APACHE-FAKEGOOGLEBOT  ******* 
#***********************************
[apache-fakegooglebot]

enabled = true
port = http,https
filter = apache-fakegooglebot
logpath = /var/log/apache2/*error.log
          /var/log/apache2/*access.log
findtime = 3600 
bantime = 172800
maxretry = 3   # Número máximo de intentos antes de bloquear
  • Y ahora modificamos el filtro
nano /etc/fail2ban/filter.d/apache-fakegooglebot.conf
  • Original
# Fail2Ban filter for fake Googlebot User Agents

[Definition]

failregex = ^\s*<HOST> \S+ \S+(?: \S+)?\s+\S+ "[A-Z]+ /\S* [^"]*" \d+ \d+ \"[^"]*\" "[^"]*\bGooglebot/[^"]*"

ignoreregex =

datepattern = ^[^\[]*(\[{DATE}\s*\])
              {^LN-BEG}

# DEV Notes:
#
# Author: Lee Clemens
# Thanks: Johannes B. Ullrich, Ph.D.
# Reference: https://isc.sans.edu/forums/diary/When+Google+isnt+Google/15968/
  • Agregamos
^<HOST>.*"GET .*" 200 \d+ ".*" ".*(Googlebot|Mediapartners-Google|AdsBot-Google).*"
  • quedando así
# Fail2Ban filter for fake Googlebot User Agents

[Definition]

failregex = ^\s*<HOST> \S+ \S+(?: \S+)?\s+\S+ "[A-Z]+ /\S* [^"]*" \d+ \d+ \"[^"]*\" "[^"]*\bGooglebot/[^"]*"
            ^<HOST>.*"GET .*" 200 \d+ ".*" ".*(Googlebot|Mediapartners-Google|AdsBot-Google).*"
ignoreregex =

datepattern = ^[^\[]*(\[{DATE}\s*\])
              {^LN-BEG}

# DEV Notes:
#
# Author: Lee Clemens
# Thanks: Johannes B. Ullrich, Ph.D.
# Reference: https://isc.sans.edu/forums/diary/When+Google+isnt+Google/15968/

apache-shellshock

  • El filtro apache-shellshock.conf en Fail2ban se utiliza para detectar intentos de explotar la vulnerabilidad conocida como «Shellshock» en un servidor web Apache. Shellshock es una vulnerabilidad que afecta a Bash, un intérprete de comandos en sistemas Unix/Linux, y puede ser explotada a través de las solicitudes HTTP para ejecutar comandos arbitrarios en el servidor.
#*********************************** 
#***** APACHE-SHELLSHOCK     ******* 
#***********************************
[apache-shellshock]

enabled = true
port = http,https
filter = apache-shellshock
logpath = /var/log/apache2/*error.log
          /var/log/apache2/*access.log
findtime = 3600
bantime = 172800
maxretry = 3   # Número máximo de intentos antes de bloquear
  • Modificamos el filtro
nano /etc/fail2ban/filter.d/apache-shellshock.conf
  • Original
# Fail2Ban filter to block web requests containing custom headers attempting to exploit the shellshock bug
#
#

[INCLUDES]

# overwrite with apache-common.local if _apache_error_client is incorrect.
before = apache-common.conf

[Definition]

prefregex = ^%(_apache_error_client)s (AH01215: )?/bin/([bd]a)?sh: <F-CONTENT>.+</F-CONTENT>$

failregex = ^warning: HTTP_[^:]+: ignoring function definition attempt(, referer: \S+)?\s*$
            ^error importing function definition for `HTTP_[^']+'(, referer: \S+)?\s*$

ignoreregex =


# DEV Notes:
#
# https://wiki.apache.org/httpd/ListOfErrors for apache error IDs
#
# example log lines: 
# [Thu Sep 25 09:27:18.813902 2014] [cgi:error] [pid 16860] [client 89.207.132.76:59635] AH01215: /bin/bash: warning: HTTP_TEST: ignoring function definition attempt
# [Thu Sep 25 09:29:56.141832 2014] [cgi:error] [pid 16864] [client 162.247.73.206:41273] AH01215: /bin/bash: error importing function definition for `HTTP_TEST'
#
# Author: Eugene Hopkinson (e.hopkinson@gmail.com)
  • Agregamos
^<HOST>.*"(GET|POST|HEAD|PUT|DELETE).*\(\)\s*\{\s*:;\s*}\s*;.*HTTP/1\.1"
  • Quedando así
# Fail2Ban filter to block web requests containing custom headers attempting to exploit the shellshock bug
#
#

[INCLUDES]

# overwrite with apache-common.local if _apache_error_client is incorrect.
before = apache-common.conf

[Definition]

prefregex = ^%(_apache_error_client)s (AH01215: )?/bin/([bd]a)?sh: <F-CONTENT>.+</F-CONTENT>$

failregex = ^warning: HTTP_[^:]+: ignoring function definition attempt(, referer: \S+)?\s*$
            ^error importing function definition for `HTTP_[^']+'(, referer: \S+)?\s*$
            ^<HOST>.*"(GET|POST|HEAD|PUT|DELETE).*\(\)\s*\{\s*:;\s*}\s*;.*HTTP/1\.1"
ignoreregex =


# DEV Notes:
#
# https://wiki.apache.org/httpd/ListOfErrors for apache error IDs
#
# example log lines: 
# [Thu Sep 25 09:27:18.813902 2014] [cgi:error] [pid 16860] [client 89.207.132.76:59635] AH01215: /bin/bash: warning: HTTP_TEST: ignoring function definition attempt
# [Thu Sep 25 09:29:56.141832 2014] [cgi:error] [pid 16864] [client 162.247.73.206:41273] AH01215: /bin/bash: error importing function definition for `HTTP_TEST'
#
# Author: Eugene Hopkinson (e.hopkinson@gmail.com)

NGINX

nginx-http-auth

  • nginx-http-auth: Esta jail se utiliza para detectar intentos de autenticación fallidos en servicios protegidos por autenticación HTTP básica en Nginx.
  • abrimos el archivo
nano /etc/fail2ban/filter.d/nginx-http-auth.conf
  • Original
# fail2ban filter configuration for nginx


[Definition]

mode = normal

mdre-auth = ^\s*\[error\] \d+#\d+: \*\d+ user "(?:[^"]+|.*?)":? (?:password mismatch|was not found in "[^\"]*"), client: <HOST>, server: \S*, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"(?:, referrer: "\S+")?\>
mdre-fallback = ^\s*\[crit\] \d+#\d+: \*\d+ SSL_do_handshake\(\) failed \(SSL: error:\S+(?: \S+){1,3} too (?:long|short)\)[^,]*, client: <HOST>

mdre-normal = %(mdre-auth)s
mdre-aggressive = %(mdre-auth)s
                  %(mdre-fallback)s

failregex = <mdre-<mode>>

ignoreregex =

datepattern = {^LN-BEG}

journalmatch = _SYSTEMD_UNIT=nginx.service + _COMM=nginx

# DEV NOTES:
# mdre-auth:
# Based on samples in https://github.com/fail2ban/fail2ban/pull/43/files
# Extensive search of all nginx auth failures not done yet.
# 
# Author: Daniel Black

# mdre-fallback:
# Ban people checking for TLS_FALLBACK_SCSV repeatedly
# https://stackoverflow.com/questions/28010492/nginx-critical-error-with-ssl-handshaking/28010608#28010608
# Author: Stephan Orlowsky
  • Le agregamos
^<HOST> .* "\S+ (GET|POST|HEAD) .* HTTP/.*" 401
  • Quedando así
# fail2ban filter configuration for nginx


[Definition]

mode = normal

mdre-auth = ^\s*\[error\] \d+#\d+: \*\d+ user "(?:[^"]+|.*?)":? (?:password mismatch|was not found in "[^\"]*"), client: <HOST>, server: \S*, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"(?:, referrer: "\S+")?\>
mdre-fallback = ^\s*\[crit\] \d+#\d+: \*\d+ SSL_do_handshake\(\) failed \(SSL: error:\S+(?: \S+){1,3} too (?:long|short)\)[^,]*, client: <HOST>

mdre-normal = %(mdre-auth)s
mdre-aggressive = %(mdre-auth)s
                  %(mdre-fallback)s

failregex = <mdre-<mode>>
            ^<HOST> .* "\S+ (GET|POST|HEAD) .* HTTP/.*" 401

ignoreregex =

datepattern = {^LN-BEG}

journalmatch = _SYSTEMD_UNIT=nginx.service + _COMM=nginx

# DEV NOTES:
# mdre-auth:
# Based on samples in https://github.com/fail2ban/fail2ban/pull/43/files
# Extensive search of all nginx auth failures not done yet.
# 
# Author: Daniel Black

# mdre-fallback:
# Ban people checking for TLS_FALLBACK_SCSV repeatedly
# https://stackoverflow.com/questions/28010492/nginx-critical-error-with-ssl-handshaking/28010608#28010608
# Author: Stephan Orlowsky
  • Creamos la jail
#*********************************** 
#***** NGINX-HTTP-AUTH       ******* 
#***********************************
[nginx-http-auth]

enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/access.log
findtime = 3600
bantime = 172800
maxretry = 3   # Número máximo de intentos antes de bloquear

nginx-limit-req

  • nginx-limit-req: Esta jail se utiliza para proteger contra ataques de inundación de solicitudes HTTP al limitar la cantidad de solicitudes permitidas desde una dirección IP en un período de tiempo determinado. Esto puede ser útil para prevenir ataques de fuerza bruta o escaneos.
  • Abrimos el archivo
nano /etc/fail2ban/filter.d/nginx-limit-req.conf
  • Original
# Fail2ban filter configuration for nginx :: limit_req
# used to ban hosts, that were failed through nginx by limit request processing rate 
#
# Author: Serg G. Brester (sebres)
#
# To use 'nginx-limit-req' filter you should have `ngx_http_limit_req_module`
# and define `limit_req` and `limit_req_zone` as described in nginx documentation
# http://nginx.org/en/docs/http/ngx_http_limit_req_module.html
#
# Example:
#
#   http {
#     ...
#     limit_req_zone $binary_remote_addr zone=lr_zone:10m rate=1r/s;
#     ...
#     # http, server, or location:
#     location ... {
#       limit_req zone=lr_zone burst=1 nodelay;
#       ...
#     }
#     ...
#   }
#   ...
#

[Definition]

# Specify following expression to define exact zones, if you want to ban IPs limited 
# from specified zones only.
# Example:
#
#   ngx_limit_req_zones = lr_zone|lr_zone2
#
ngx_limit_req_zones = [^"]+

# Use following full expression if you should range limit request to specified 
# servers, requests, referrers etc. only :
#
# failregex = ^\s*\[[a-z]+\] \d+#\d+: \*\d+ limiting requests, excess: [\d\.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: <HOST>, server: \S*, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"(, referrer: "\S+">

# Shortly, much faster and stable version of regexp:
failregex = ^\s*\[[a-z]+\] \d+#\d+: \*\d+ limiting requests, excess: [\d\.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: <HOST>,

ignoreregex =

datepattern = {^LN-BEG}

journalmatch = _SYSTEMD_UNIT=nginx.service + _COMM=nginx
  • Agregamos
^<HOST> .* "(GET|POST|HEAD|PUT|DELETE|OPTIONS) .+" 429
  • Resultado
# Example:
#
#   ngx_limit_req_zones = lr_zone|lr_zone2
#
ngx_limit_req_zones = [^"]+

# Use following full expression if you should range limit request to specified 
# servers, requests, referrers etc. only :
#
# failregex = ^\s*\[[a-z]+\] \d+#\d+: \*\d+ limiting requests, excess: [\d\.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: <HOST>, server: \S*, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"(, referrer: "\S+">

# Shortly, much faster and stable version of regexp:
failregex = ^\s*\[[a-z]+\] \d+#\d+: \*\d+ limiting requests, excess: [\d\.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: <HOST>,
            ^<HOST> .* "(GET|POST|HEAD|PUT|DELETE|OPTIONS) .+" 429
ignoreregex =

datepattern = {^LN-BEG}

journalmatch = _SYSTEMD_UNIT=nginx.service + _COMM=nginx
  • Este filtro buscará líneas en los registros de Nginx que contengan respuestas HTTP 429 (demasiadas solicitudes) y coincidan con solicitudes HTTP GET, POST, HEAD, PUT, DELETE u OPTIONS. El código de estado HTTP 429 es comúnmente utilizado para indicar que se ha superado el límite de solicitud.
#*********************************** 
#***** NGINX-LIMIT-REQ       ******* 
#***********************************
[nginx-limit-req]

enabled = true
port = http,https
filter = nginx-limit-req
logpath = /var/log/nginx/access.log  
findtime = 60 
maxretry = 100  # Número máximo de solicitudes permitidas en el período de tiempo
bantime = 172800

nginx-limit-conn

  • nginx-limit-conn: Ayuda a proteger tu servidor limitando el número máximo de conexiones simultáneas permitidas desde una dirección IP. Esto puede ayudar a mitigar ataques de saturación.
#*********************************** 
#***** NGINX-LIMIT-CONN      ******* 
#***********************************
[nginx-limit-conn]

enabled = true
port = http,https
filter = nginx-limit-conn
logpath = /var/log/nginx/access.log 
findtime = 60 
maxretry = 5 
bantime = 172800
  • Creamos el archivo
nano /etc/fail2ban/filter.d/nginx-limit-conn.conf
  • Agregamos
# Filtro para Fail2ban - nginx-limit-conn.conf

[Definition]

failregex = \[error\] \d+#\d+: \*\d+ limiting connections by zone "\S+", client: <HOST>

ignoreregex =
  • Este filtro buscará líneas en los registros de Nginx que contengan entradas de registro relacionadas con la limitación de conexiones en Nginx.

nginx-botsearch

  • nginx-botsearch: Detecta bots que pueden buscar vulnerabilidades en tu sitio web. La jail nginx-botsearch en Fail2ban se utiliza para proteger tu servidor Nginx contra bots maliciosos que intentan buscar vulnerabilidades en tu sitio web. Estos bots a menudo realizan exploraciones en busca de scripts o puntos de acceso vulnerables que puedan ser explotados.
#*********************************** 
#***** NGINX-BOTSEARCH       ******* 
#***********************************
[nginx-botsearch]

enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/access.log  
findtime = 3600 
bantime = 172800
maxretry = 3  
  • Abrimos el archivo
nano /etc/fail2ban/filter.d/nginx-botsearch.conf
  • Agregamos o modificamos
^<HOST> .* "(GET|POST|HEAD|PUT|DELETE|OPTIONS) .+" 404
  • Resultado
# Fail2Ban filter to match web requests for selected URLs that don't exist
#

[INCLUDES]

# Load regexes for filtering
before = botsearch-common.conf

[Definition]

failregex = ^<HOST> \- \S+ \[\] \"(GET|POST|HEAD) \/<block> \S+\" 404 .+$
            ^ \[error\] \d+#\d+: \*\d+ (\S+ )?\"\S+\" (failed|is not found) \(2\: No such file or directory\), client\: <HOST>\, server\: \S*\, request: \"(GET|POST|HEAD) \/<block> \S+\"\, .*?$
            ^<HOST> .* "(GET|POST|HEAD|PUT|DELETE|OPTIONS) .+" 404
ignoreregex =

datepattern = {^LN-BEG}%%ExY(?P<_sep>[-/.])%%m(?P=_sep)%%d[T ]%%H:%%M:%%S(?:[.,]%%f)?(?:\s*%%z)?
              ^[^\[]*\[({DATE})
              {^LN-BEG}

journalmatch = _SYSTEMD_UNIT=nginx.service + _COMM=nginx

# DEV Notes:
# Based on apache-botsearch filter
# 
# Author: Frantisek Sumsal

nginx-noscript

  • La jail nginx-noscript en Fail2ban se utiliza para proteger tu servidor Nginx contra intentos de acceso a scripts o recursos que no existen en tu sitio web. Los atacantes a menudo intentan acceder a rutas o archivos que no están presentes en tu servidor web para buscar vulnerabilidades o realizar actividades maliciosas.
#*********************************** 
#***** NGINX-NOSCRIPT        ******* 
#***********************************
[nginx-noscript]

enabled = true
port = http,https
filter = nginx-noscript
logpath = /var/log/nginx/access.log 
findtime = 3600 
bantime = 172800
maxretry = 3  
  • Creamos el archivo
nano /etc/fail2ban/filter.d/nginx-noscript.conf
  • Le agregamos
# Filtro para Fail2ban - nginx-noscript.conf

[Definition]

failregex = ^<HOST> .* "(GET|POST|HEAD|PUT|DELETE|OPTIONS) .+\.php

ignoreregex =

NOTA: Por que php

Es cierto que en la configuración de la jail nginx-noscript, se está prestando especial atención a las solicitudes de archivos con extensión «.php». La razón detrás de esto es que los archivos PHP suelen ser scripts que se ejecutan en el servidor web, y los atacantes a menudo intentan buscar vulnerabilidades explotables en estos scripts. Por lo tanto, es común centrarse en archivos PHP en este contexto. Sin embargo, es posible adaptar la configuración para buscar otros tipos de archivos si lo deseas.

La elección de los archivos a monitorear depende de la configuración y las necesidades específicas de tu servidor y sitio web. Por ejemplo, si tu sitio web no utiliza PHP y está basado en otro lenguaje de programación, como Python o Ruby, podrías modificar el filtro para buscar solicitudes a archivos con extensiones relevantes a esos lenguajes.

Aquí hay una explicación más detallada de por qué se enfoca en archivos PHP y cómo podrías adaptar la configuración para otros tipos de archivos:

  • Archivos PHP: Los archivos PHP son comunes en aplicaciones web y pueden contener código ejecutable en el servidor. Los atacantes suelen buscar vulnerabilidades en scripts PHP para intentar inyectar código malicioso o explotar debilidades en la seguridad.
  • Adaptación para otros archivos: Si tu sitio web utiliza un lenguaje de programación diferente o no utiliza scripts ejecutables en el servidor, puedes modificar el filtro para buscar otro tipo de archivo que sea relevante. Por ejemplo, si estás utilizando Python, podrías buscar archivos con extensión «.py». Si estás utilizando Ruby, podrías buscar archivos con extensión «.rb». La idea es monitorear las solicitudes a archivos que sean relevantes para tu tecnología web específica y que puedan representar un riesgo de seguridad si se acceden de manera indebida.

En resumen, la elección de los archivos a monitorear con la jail nginx-noscript debe estar en línea con la tecnología utilizada en tu sitio web y los riesgos de seguridad asociados. Puedes personalizar la configuración para adaptarla a tus necesidades específicas.

nginx-overflows

  • La jail nginx-overflows en Fail2ban se utiliza para proteger tu servidor Nginx contra intentos de explotar vulnerabilidades relacionadas con desbordamientos de búfer u otros tipos de desbordamientos en solicitudes HTTP. Los desbordamientos de búfer son una clase común de vulnerabilidades que pueden ser explotadas por atacantes para ejecutar código malicioso o realizar otras acciones no autorizadas.
#*********************************** 
#***** NGINX-OVERFLOWS       ******* 
#***********************************
[nginx-overflows]

enabled = true
port = http,https
filter = nginx-overflows
logpath = /var/log/nginx/access.log
findtime = 3600 
bantime = 172800
maxretry = 3  
  • Creamos el archivo
nano /etc/fail2ban/filter.d/nginx-overflows.conf
  • Agregamos
# Filtro para Fail2ban - nginx-overflows.conf

[Definition]

failregex = ^<HOST> .* "(GET|POST|HEAD|PUT|DELETE|OPTIONS) .+" 400

ignoreregex =
  • Este filtro buscará líneas en los registros de Nginx que contengan respuestas HTTP 400 (Solicitud incorrecta) y coincidan con solicitudes HTTP GET, POST, HEAD, PUT, DELETE u OPTIONS. Las respuestas HTTP 400 a menudo indican problemas en las solicitudes, que podrían ser causados por intentos de explotar vulnerabilidades.

nginx-nohome

  • La jail nginx-nohome en Fail2ban se utiliza para proteger tu servidor Nginx contra intentos de acceso a rutas o recursos que no están presentes en tu sitio web. Los atacantes a menudo intentan acceder a rutas o directorios que no existen en tu servidor web para buscar vulnerabilidades o realizar actividades maliciosas.
  • Al configurar la jail nginx-nohome, puedes monitorear el registro de acceso de Nginx en busca de patrones de actividad que indiquen intentos de acceso a rutas inexistentes y bloquear las direcciones IP que superen un cierto número de intentos en un período de tiempo especificado.
#*********************************** 
#***** NGINX-NOHOME          ******* 
#***********************************
[nginx-nohome]

enabled = true
port = http,https
filter = nginx-nohome
logpath = /var/log/nginx/access.log
findtime = 3600 
bantime = 172800
maxretry = 3  
  • Creamos el archivo
nano /etc/fail2ban/filter.d/nginx-nohome.conf
  • Agregamos
# Filtro para Fail2ban - nginx-nohome.conf

[Definition]

failregex = ^<HOST> .* "(GET|POST|HEAD|PUT|DELETE|OPTIONS) /~?[a-zA-Z0-9]+(?:/[a-zA-Z0-9]+)*

ignoreregex =
  • Este filtro buscará líneas en los registros de Nginx que contengan solicitudes HTTP a rutas que no existen en tu sitio web. La expresión regular failregex se ajusta para buscar solicitudes a rutas que pueden estar mal formadas o no coinciden con ninguna ruta válida en tu servidor web.

nginx-badbots

  • La jail nginx-badbots en Fail2ban se utiliza para proteger tu servidor Nginx contra bots maliciosos conocidos que intentan realizar actividades maliciosas o que consumen recursos del servidor. Estos bots a menudo intentan realizar exploraciones en busca de vulnerabilidades, realizar spam o sobrecargar tu servidor con solicitudes inútiles.
#*********************************** 
#***** NGINX-BADBOTS         ******* 
#***********************************
[nginx-badbots]

enabled = true
port = http,https
filter = nginx-badbots
logpath = /var/log/nginx/access.log
findtime = 3600 
bantime = 172800
maxretry = 3  
  • Creamos el archivo
nano /etc/fail2ban/filter.d/nginx-badbots.conf
  • Agregamos
# Filtro para Fail2ban - nginx-badbots.conf

[Definition]

failregex = ^<HOST> .* "(GET|POST|HEAD) .+" 444

ignoreregex =
  • Este filtro buscará líneas en los registros de Nginx que contengan solicitudes HTTP (GET, POST, HEAD) que devuelvan una respuesta con el código de estado 444. El código de estado 444 se utiliza a menudo para indicar que una solicitud ha sido bloqueada debido a actividad maliciosa.

nginx-bad-request

  • La jail nginx-bad-request en Fail2ban se utiliza para proteger tu servidor Nginx contra solicitudes HTTP mal formadas o incorrectas que podrían ser indicativas de intentos de explotación o actividades maliciosas. Estas solicitudes pueden incluir parámetros inusuales o inválidos que podrían ser utilizados por atacantes para buscar vulnerabilidades en tu servidor.
#*********************************** 
#***** NGINX-BAD-REQUEST     ******* 
#***********************************
[nginx-bad-request]

enabled = true
port = http,https
filter = nginx-bad-request
logpath = /var/log/nginx/access.log
findtime = 3600 
bantime = 172800
maxretry = 3  
  • Abrimos el archivo
nano /etc/fail2ban/filter.d/nginx-bad-request.conf
  • Original
# Fail2Ban filter to match bad requests to nginx
#

[Definition]

# The request often doesn't contain a method, only some encoded garbage
# This will also match requests that are entirely empty
failregex = ^<HOST> - \S+ \[\] "[^"]*" 400

datepattern = {^LN-BEG}%%ExY(?P<_sep>[-/.])%%m(?P=_sep)%%d[T ]%%H:%%M:%%S(?:[.,]%%f)?(?:\s*%%z)?
              ^[^\[]*\[({DATE})
              {^LN-BEG}

journalmatch = _SYSTEMD_UNIT=nginx.service + _COMM=nginx

# Author: Jan Przybylak
  • Agregmos el filtro
^<HOST> .* "(GET|POST|HEAD|PUT|DELETE|OPTIONS) .+" 400
  • Quedando así:
# Fail2Ban filter to match bad requests to nginx
#

[Definition]

# The request often doesn't contain a method, only some encoded garbage
# This will also match requests that are entirely empty
failregex = ^<HOST> - \S+ \[\] "[^"]*" 400
            ^<HOST> .* "(GET|POST|HEAD|PUT|DELETE|OPTIONS) .+" 400

datepattern = {^LN-BEG}%%ExY(?P<_sep>[-/.])%%m(?P=_sep)%%d[T ]%%H:%%M:%%S(?:[.,]%%f)?(?:\s*%%z)?
              ^[^\[]*\[({DATE})
              {^LN-BEG}

journalmatch = _SYSTEMD_UNIT=nginx.service + _COMM=nginx

# Author: Jan Przybylak

nginx-404

  • Si deseas configurar una jail para registrar y bloquear direcciones IP que realicen un número excesivo de solicitudes de este tipo, puedes seguir estos pasos:
#*********************************** 
#***** NGINX-404             ******* 
#***********************************
[nginx-404]

enabled = true
port = http,https
filter = nginx-404
logpath = /var/log/nginx/access.log
findtime = 3600 
bantime = 172800
maxretry = 5  
  • creamos el archivo
nano /etc/fail2ban/filter.d/nginx-404.conf
  • Agregamos
[Definition]
failregex = <HOST> - - \[.*\] "(GET|POST|HEAD).*HTTP.* 404
            ^<HOST> .* "(GET|POST|HEAD|PUT|DELETE|OPTIONS) .+" 404
ignoreregex =
  • Este filtro buscará líneas en los registros de Nginx que contengan respuestas HTTP con el código de estado 404 (Página no encontrada). Esto ayudará a detectar intentos de acceso a recursos que no existen en tu servidor.

nginx-dos.conf

  • La jail nginx-dos en Fail2ban se utiliza para proteger tu servidor Nginx contra ataques de denegación de servicio (DoS) o ataques de inundación de solicitudes HTTP. Los ataques DoS intentan abrumar tu servidor con un gran volumen de solicitudes, lo que puede agotar los recursos del servidor y hacer que sea inaccesible para los usuarios legítimos.
  • Configurar la jail nginx-dos en Fail2ban te permite detectar y bloquear direcciones IP que realizan un número excesivo de solicitudes HTTP en un corto período de tiempo.
#*********************************** 
#***** NGINX-DOS             ******* 
#***********************************
[nginx-dos]

enabled = true
port = http,https
filter = nginx-dos
logpath = /var/log/nginx/access.log
findtime = 60 
bantime = 172800
maxretry = 100  
  • Creamos el archivo
nano /etc/fail2ban/filter.d/nginx-dos.conf
  • Agregamos
# Filtro para Fail2ban - nginx-dos.conf

[Definition]

failregex = ^<HOST> .* "GET .* HTTP/1\.[01]" 200
            ^<HOST> .* "POST .* HTTP/1\.[01]" 200

ignoreregex =

NGINX-FAVEO(pendiente de revisar)

  • Primero debemos abrir el archivo
nano /etc/fail2ban/jail.local
  • Buscar la linea
[php-url-fopen]
  • Y dejar el contenido así:
[php-url-fopen]

port    = http,https
#logpath = %(nginx_access_log)s
#          %(apache_access_log)s
logpath = /opt/faveo/log/faveo_access_log
  • Luego abrimos:
nano /etc/fail2ban/jail.d/defaults-debian.conf
  • Y lo dejamos así
#***********************************
#**********  NGINX  ****************
#***********************************
[nginx-http-auth]
enabled = true

[nginx-botsearch]
enabled = true

[nginx-limit-req]
enabled = true

#***********************************
#**********  PHP    ****************
#***********************************
[php-url-fopen]
enabled = true

NGINX-GITLAB (pendiente de revisar)

nginx-http-auth

  • nginx-http-auth: Esta jail se utiliza para detectar intentos de autenticación fallidos en servicios protegidos por autenticación HTTP básica en Nginx. Puedes habilitarla para proteger los inicios de sesión en GitLab.
  • Paso 1: Verificar que la autenticación HTTP básica esté habilitada en GitLab
  • En el archivo de configuración de Nginx utilizado para GitLab, generalmente llamado gitlab.rb o gitlab-nginx.conf, asegúrate de que la autenticación HTTP básica esté habilitada. Deberías tener una sección similar a esta:
location ^~ / {
    ...
    auth_basic "GitLab Access";
    auth_basic_user_file /etc/nginx/htpasswd-gitlab;
    ...
}
  • Paso 2: Configurar el filtro para nginx-http-auth
  • abrimos el archivo
nano /etc/fail2ban/filter.d/nginx-http-auth.conf
  • Original
# fail2ban filter configuration for nginx


[Definition]

mode = normal

mdre-auth = ^\s*\[error\] \d+#\d+: \*\d+ user "(?:[^"]+|.*?)":? (?:password mismatch|was not found in "[^\"]*"), client: <HOST>, server: \S*, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"(?:, referrer: "\S+")?\>
mdre-fallback = ^\s*\[crit\] \d+#\d+: \*\d+ SSL_do_handshake\(\) failed \(SSL: error:\S+(?: \S+){1,3} too (?:long|short)\)[^,]*, client: <HOST>

mdre-normal = %(mdre-auth)s
mdre-aggressive = %(mdre-auth)s
                  %(mdre-fallback)s

failregex = <mdre-<mode>>

ignoreregex =

datepattern = {^LN-BEG}

journalmatch = _SYSTEMD_UNIT=nginx.service + _COMM=nginx

# DEV NOTES:
# mdre-auth:
# Based on samples in https://github.com/fail2ban/fail2ban/pull/43/files
# Extensive search of all nginx auth failures not done yet.
# 
# Author: Daniel Black

# mdre-fallback:
# Ban people checking for TLS_FALLBACK_SCSV repeatedly
# https://stackoverflow.com/questions/28010492/nginx-critical-error-with-ssl-handshaking/28010608#28010608
# Author: Stephan Orlowsky
  • Le agregamos
^<HOST> .* "\S+ (GET|POST|HEAD) .* HTTP/.*" 401
  • Quedando así
# fail2ban filter configuration for nginx


[Definition]

mode = normal

mdre-auth = ^\s*\[error\] \d+#\d+: \*\d+ user "(?:[^"]+|.*?)":? (?:password mismatch|was not found in "[^\"]*"), client: <HOST>, server: \S*, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"(?:, referrer: "\S+")?\>
mdre-fallback = ^\s*\[crit\] \d+#\d+: \*\d+ SSL_do_handshake\(\) failed \(SSL: error:\S+(?: \S+){1,3} too (?:long|short)\)[^,]*, client: <HOST>

mdre-normal = %(mdre-auth)s
mdre-aggressive = %(mdre-auth)s
                  %(mdre-fallback)s

failregex = <mdre-<mode>>
            ^<HOST> .* "\S+ (GET|POST|HEAD) .* HTTP/.*" 401

ignoreregex =

datepattern = {^LN-BEG}

journalmatch = _SYSTEMD_UNIT=nginx.service + _COMM=nginx

# DEV NOTES:
# mdre-auth:
# Based on samples in https://github.com/fail2ban/fail2ban/pull/43/files
# Extensive search of all nginx auth failures not done yet.
# 
# Author: Daniel Black

# mdre-fallback:
# Ban people checking for TLS_FALLBACK_SCSV repeatedly
# https://stackoverflow.com/questions/28010492/nginx-critical-error-with-ssl-handshaking/28010608#28010608
# Author: Stephan Orlowsky
  • Creamos la jail
#*********************************** 
#***** NGINX-HTTP-AUTH       ******* 
#***********************************
[nginx-http-auth]

enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/access.log
findtime = 3600
bantime = 172800
maxretry = 3   # Número máximo de intentos antes de bloquear

NOTA: Importante usar log de nginx o gitlab

La elección entre usar el archivo de registro de acceso de Nginx (/var/log/nginx/access.log) o el archivo de registro de acceso de GitLab (/var/log/gitlab/nginx/gitlab_error.log) depende de dónde desees aplicar la limitación de solicitudes HTTP y en qué parte de tu infraestructura deseas detectar y bloquear los intentos de abuso.

Aquí hay algunas consideraciones:

  1. Usar el archivo de registro de Nginx (/var/log/nginx/access.log): Si deseas aplicar la limitación de solicitudes HTTP en la capa de servidor web Nginx antes de que las solicitudes lleguen a GitLab, entonces debes utilizar el archivo de registro de Nginx. Esto protegerá tu servidor Nginx contra solicitudes excesivas o abusivas.
  2. Usar el archivo de registro de GitLab (/var/log/gitlab/nginx/gitlab_error.log): Si deseas aplicar la limitación de solicitudes HTTP después de que las solicitudes hayan pasado por Nginx y lleguen a GitLab, entonces debes utilizar el archivo de registro de GitLab. Esto protegerá tu instancia de GitLab y limitará el tráfico abusivo hacia GitLab específicamente.

En la mayoría de los casos, es una buena práctica aplicar esta limitación en la capa de servidor web (Nginx) antes de que las solicitudes lleguen a la aplicación web (GitLab) para evitar que el tráfico abusivo agote los recursos del servidor web y la aplicación web. Esto también puede reducir la carga en GitLab y proporcionar una protección más efectiva.

Por lo tanto, si deseas proteger tu servidor Nginx y limitar el tráfico antes de que llegue a GitLab, usa el archivo de registro de acceso de Nginx (/var/log/nginx/access.log) en la configuración de la jail nginx-limit-req en Fail2ban. Si deseas aplicar la limitación de solicitudes en GitLab, utiliza el archivo de registro de GitLab correspondiente.

nginx-limit-req

  • nginx-limit-req: Esta jail se utiliza para proteger contra ataques de inundación de solicitudes HTTP al limitar la cantidad de solicitudes permitidas desde una dirección IP en un período de tiempo determinado. Esto puede ser útil para prevenir ataques de fuerza bruta o escaneos.
  • NOTA: Igual a la configuración basica anterior

nginx-limit-conn

  • nginx-limit-conn: Ayuda a proteger tu servidor limitando el número máximo de conexiones simultáneas permitidas desde una dirección IP. Esto puede ayudar a mitigar ataques de saturación.
  • NOTA: Igual a la configuración basica anterior

nginx-botsearch

  • nginx-botsearch: Detecta bots que pueden buscar vulnerabilidades en tu sitio web. Esto puede ser relevante para GitLab si deseas protegerlo contra bots maliciosos.
  • NOTA: Igual a la configuración basica anterior

nginx-noscript

  • nginx-noscript: Detecta intentos de acceso a scripts o recursos que no existen en tu servidor web. Aunque GitLab no utiliza directamente esta funcionalidad, es posible que desees habilitarla para proteger otros recursos en tu servidor.
  • NOTA: Igual a la configuración basica anterior, sin embargo gitlab no esta en php por lo que se debe analizar si utilizar o no

nginx-overflows

  • La jail nginx-overflows en Fail2ban se utiliza para proteger tu servidor Nginx contra intentos de explotar vulnerabilidades relacionadas con desbordamientos de búfer u otros tipos de desbordamientos en solicitudes HTTP. Los desbordamientos de búfer son una clase común de vulnerabilidades que pueden ser explotadas por atacantes para ejecutar código malicioso o realizar otras acciones no autorizadas.
  • NOTA: esto se le debe aplicar a cualquier servidor nginx

nginx-nohome

  • La jail nginx-nohome en Fail2ban se utiliza para proteger tu servidor Nginx contra intentos de acceso a rutas o recursos que no están presentes en tu sitio web. Los atacantes a menudo intentan acceder a rutas o directorios que no existen en tu servidor web para buscar vulnerabilidades o realizar actividades maliciosas.
  • Al configurar la jail nginx-nohome, puedes monitorear el registro de acceso de Nginx en busca de patrones de actividad que indiquen intentos de acceso a rutas inexistentes y bloquear las direcciones IP que superen un cierto número de intentos en un período de tiempo especificado.
  • NOTA: esto se le debe aplicar a cualquier servidor nginx

nginx-badbots

  • La jail nginx-badbots en Fail2ban se utiliza para proteger tu servidor Nginx contra bots maliciosos conocidos que intentan realizar actividades maliciosas o que consumen recursos del servidor. Estos bots a menudo intentan realizar exploraciones en busca de vulnerabilidades, realizar spam o sobrecargar tu servidor con solicitudes inútiles.
  • NOTA: esto se le debe aplicar a cualquier servidor nginx

nginx-bad-request

  • La jail nginx-bad-request en Fail2ban se utiliza para proteger tu servidor Nginx contra solicitudes HTTP mal formadas o incorrectas que podrían ser indicativas de intentos de explotación o actividades maliciosas. Estas solicitudes pueden incluir parámetros inusuales o inválidos que podrían ser utilizados por atacantes para buscar vulnerabilidades en tu servidor.
  • NOTA: esto se le debe aplicar a cualquier servidor nginx

nginx-404

  • Si deseas configurar una jail para registrar y bloquear direcciones IP que realicen un número excesivo de solicitudes de este tipo, puedes seguir estos pasos:
  • NOTA: esto se le debe aplicar a cualquier servidor nginx

nginx-dos.conf

  • La jail nginx-dos en Fail2ban se utiliza para proteger tu servidor Nginx contra ataques de denegación de servicio (DoS) o ataques de inundación de solicitudes HTTP. Los ataques DoS intentan abrumar tu servidor con un gran volumen de solicitudes, lo que puede agotar los recursos del servidor y hacer que sea inaccesible para los usuarios legítimos.
  • Configurar la jail nginx-dos en Fail2ban te permite detectar y bloquear direcciones IP que realizan un número excesivo de solicitudes HTTP en un corto período de tiempo.
  • NOTA: esto se le debe aplicar a cualquier servidor nginx

MYSQL

mysqld-auth (No se ha podido configurar)

nano /etc/mysql/mysql.conf.d/mysqld.cnf
  • Modificamos
#bind-address            = 127.0.0.1
X
bind-address            = 0.0.0.0
  • Reiniciamos
sudo service mysql restart
sudo service mysql status
  • El filtro mysqld-auth.conf en Fail2Ban se utiliza para detectar intentos fallidos de inicio de sesión en el servidor MySQL (MariaDB o MySQL) y bloquear las direcciones IP que intentan autenticarse de manera incorrecta con el fin de proteger el servidor contra ataques de fuerza bruta y otros intentos de intrusión.
#*********************************** 
#*****   MYSQLD-AUTH         ******* 
#***********************************
[mysqld-auth]
enabled = true
filter = mysqld-auth
port = 3306  # Puerto de MySQL
logpath = /var/log/mysql/error.log  
maxretry = 3  
bantime = 172800
findtime = 600 
  • Le damos permisos a root de acceder al log
usermod -a -G adm root
usermod -a -G mysql root
  • Abrimos el archivo
nano /etc/fail2ban/filter.d/mysqld-auth.conf
  • Original
# Fail2Ban filter for unsuccesful MySQL authentication attempts
#
#
# To log wrong MySQL access attempts add to /etc/my.cnf in [mysqld]:
# log-error=/var/log/mysqld.log
# log-warnings = 2
#
# If using mysql syslog [mysql_safe] has syslog in /etc/my.cnf

[INCLUDES]

# Read common prefixes. If any customizations available -- read them from
# common.local
before = common.conf

[Definition]

_daemon = mysqld

failregex = ^%(__prefix_line)s(?:(?:\d{6}|\d{4}-\d{2}-\d{2})[ T]\s?\d{1,2}:\d{2}:\d{2} )?(?:\d+ )?\[\w+\] (?:\[[^\]]+\] )*Access denied for user '<F-USER>[^']+</F-USER>'@'<HOST>' (to database '[^']*'|\(using pa>

ignoreregex =

# DEV Notes:
#
# Technically __prefix_line can equate to an empty string hence it can support
# syslog and non-syslog at once.
# Example:
# 130322 11:26:54 [Warning] Access denied for user 'root'@'127.0.0.1' (using password: YES)
#
# Authors: Artur Penttinen
#          Yaroslav O. Halchenko
  • Agregamos
\[Warning\] Access denied for user .* from <HOST>
  • Resultado
# Fail2Ban filter for unsuccesful MySQL authentication attempts
#
#
# To log wrong MySQL access attempts add to /etc/my.cnf in [mysqld]:
# log-error=/var/log/mysqld.log
# log-warnings = 2
#
# If using mysql syslog [mysql_safe] has syslog in /etc/my.cnf

[INCLUDES]

# Read common prefixes. If any customizations available -- read them from
# common.local
before = common.conf

[Definition]

_daemon = mysqld

failregex = ^%(__prefix_line)s(?:(?:\d{6}|\d{4}-\d{2}-\d{2})[ T]\s?\d{1,2}:\d{2}:\d{2} )?(?:\d+ )?\[\w+\] (?:\[[^\]]+\] )*Access denied for user '<F-USER>[^']+</F-USER>'@'<HOST>' (to database '[^']*'|\(using pa>
            \[Warning\] Access denied for user .* from <HOST>
ignoreregex =

# DEV Notes:
#
# Technically __prefix_line can equate to an empty string hence it can support
# syslog and non-syslog at once.
# Example:
# 130322 11:26:54 [Warning] Access denied for user 'root'@'127.0.0.1' (using password: YES)
#
# Authors: Artur Penttinen
#          Yaroslav O. Halchenko
  • Probar el filtro
sudo fail2ban-regex /var/log/mysql/error.log /etc/fail2ban/filter.d/mysqld-auth.conf

mysql-dos

  • mysql-dos: Esta jail protege contra ataques de denegación de servicio (DoS) en MySQL que intentan sobrecargar el servidor con un gran número de solicitudes.
#*********************************** 
#*****     MYSQL-DOS         ******* 
#***********************************
[mysql-dos]
enabled = true
port = 3306
filter = mysql-dos
logpath = /var/log/mysql/error.log
maxretry = 100
findtime = 60
bantime = 172800
  • Creamos el archivo
nano /etc/fail2ban/filter.d/mysql-dos.conf
  • Agregamos
[Definition]
failregex = \[Warning\] Aborted connection <HOST> to db
            \[Warning\] Access denied for user .* from <HOST>
ignoreregex =

POSTFIX

postfix

  • postfix: Esta jail se utiliza para proteger el servicio de correo Postfix contra intentos de inicio de sesión fallidos, ataques de fuerza bruta y otros comportamientos maliciosos.
#*********************************** 
#*****     POSTFIX           ******* 
#***********************************
[postfix]
enabled = true
port = smtp,ssmtp
filter = postfix
logpath = /var/log/mail.log
maxretry = 5
findtime = 600
bantime = 172800
  • Abrimos el archivo
nano /etc/fail2ban/filter.d/postfix.conf
  • Original
# Fail2Ban filter for selected Postfix SMTP rejections
#
#

[INCLUDES]

# Read common prefixes. If any customizations available -- read them from
# common.local
before = common.conf

[Definition]

_daemon = postfix(-\w+)?/\w+(?:/smtp[ds])?
_port = (?::\d+)?
_pref = [A-Z]{4}

prefregex = ^%(__prefix_line)s<mdpr-<mode>> <F-CONTENT>.+</F-CONTENT>$

# Extended RE for normal mode to match reject by unknown users or undeliverable address, can be set to empty to avoid this:
exre-user = |[Uu](?:ser unknown|ndeliverable address)

mdpr-normal = (?:\w+: (?:milter-)?reject:|(?:improper command pipelining|too many errors) after \S+)
mdre-normal=^%(_pref)s from [^[]*\[<HOST>\]%(_port)s: [45][50][04] [45]\.\d\.\d+ (?:(?:<[^>]*>)?: )?(?:(?:Helo command|(?:Sender|Recipient) address) rejected: )?(?:Service unavailable|(?:Client host|Command|Dat>
            ^from [^[]*\[<HOST>\]%(_port)s:?

mdpr-auth = warning:
mdre-auth = ^[^[]*\[<HOST>\]%(_port)s: SASL ((?i)LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed:(?! Connection lost to authentication server| Invalid authentication mechanism)
mdre-auth2= ^[^[]*\[<HOST>\]%(_port)s: SASL ((?i)LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed:(?! Connection lost to authentication server)
# todo: check/remove "Invalid authentication mechanism" from ignore list, if gh-1243 will get finished (see gh-1297).

# Mode "rbl" currently included in mode "normal", but if needed for jail "postfix-rbl" only:
mdpr-rbl = %(mdpr-normal)s
mdre-rbl  = ^%(_pref)s from [^[]*\[<HOST>\]%(_port)s: [45]54 [45]\.7\.1 Service unavailable; Client host \[\S+\] blocked\b

# Mode "rbl" currently included in mode "normal" (within 1st rule)
mdpr-more = %(mdpr-normal)s
mdre-more = %(mdre-normal)s

# Includes some of the log messages described in
# <http://www.postfix.org/POSTSCREEN_README.html>.
mdpr-ddos = (?:lost connection after(?! DATA) [A-Z]+|disconnect(?= from \S+(?: \S+=\d+)* auth=0/(?:[1-9]|\d\d+))|(?:PREGREET \d+|HANGUP) after \S+|COMMAND (?:TIME|COUNT|LENGTH) LIMIT)
mdre-ddos = ^from [^[]*\[<HOST>\]%(_port)s:?

mdpr-extra = (?:%(mdpr-auth)s|%(mdpr-normal)s)
mdre-extra = %(mdre-auth)s
            %(mdre-normal)s

mdpr-aggressive = (?:%(mdpr-auth)s|%(mdpr-normal)s|%(mdpr-ddos)s)
mdre-aggressive = %(mdre-auth2)s

                  %(mdre-normal)s

mdpr-errors = too many errors after \S+
mdre-errors = ^from [^[]*\[<HOST>\]%(_port)s$


failregex = <mdre-<mode>>

# Parameter "mode": more (default combines normal and rbl), auth, normal, rbl, ddos, extra or aggressive (combines all)
# Usage example (for jail.local):
#   [postfix]
#   mode = aggressive
#
#   # or another jail (rewrite filter parameters of jail):
#   [postfix-rbl]
#   filter = postfix[mode=rbl]
#
#   # jail to match "too many errors", related postconf `smtpd_hard_error_limit`:
#   # (normally included in other modes (normal, more, extra, aggressive), but this jail'd allow to ban on the first message)
#   [postfix-many-errors]
#   filter = postfix[mode=errors]
#   maxretry = 1
#
mode = more

ignoreregex =

[Init]

journalmatch = _SYSTEMD_UNIT=postfix.service

# Author: Cyril Jaquier
  • Y le agregamos
^%(__prefix_line)slost connection after .+ from <HOST>\s*$
            ^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[<HOST>\]: 554 5\.7\.1 .*$
            ^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[<HOST>\]: 450 4\.7\.1 .*$
  • Resultado
# Fail2Ban filter for selected Postfix SMTP rejections
#
#

[INCLUDES]

# Read common prefixes. If any customizations available -- read them from
# common.local
before = common.conf

[Definition]

_daemon = postfix(-\w+)?/\w+(?:/smtp[ds])?
_port = (?::\d+)?
_pref = [A-Z]{4}

prefregex = ^%(__prefix_line)s<mdpr-<mode>> <F-CONTENT>.+</F-CONTENT>$

# Extended RE for normal mode to match reject by unknown users or undeliverable address, can be set to empty to avoid this:
exre-user = |[Uu](?:ser unknown|ndeliverable address)

mdpr-normal = (?:\w+: (?:milter-)?reject:|(?:improper command pipelining|too many errors) after \S+)
mdre-normal=^%(_pref)s from [^[]*\[<HOST>\]%(_port)s: [45][50][04] [45]\.\d\.\d+ (?:(?:<[^>]*>)?: )?(?:(?:Helo command|(?:Sender|Recipient) address) rejected: )?(?:Service unavailable|(?:Client host|Command|Data command) rejected|Relay access denied|(?:Host|Domain) not found|need fully-qualified hostname|match%(exre-user)s)\b
            ^from [^[]*\[<HOST>\]%(_port)s:?

mdpr-auth = warning:
mdre-auth = ^[^[]*\[<HOST>\]%(_port)s: SASL ((?i)LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed:(?! Connection lost to authentication server| Invalid authentication mechanism)
mdre-auth2= ^[^[]*\[<HOST>\]%(_port)s: SASL ((?i)LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed:(?! Connection lost to authentication server)
# todo: check/remove "Invalid authentication mechanism" from ignore list, if gh-1243 will get finished (see gh-1297).

# Mode "rbl" currently included in mode "normal", but if needed for jail "postfix-rbl" only:
mdpr-rbl = %(mdpr-normal)s
mdre-rbl  = ^%(_pref)s from [^[]*\[<HOST>\]%(_port)s: [45]54 [45]\.7\.1 Service unavailable; Client host \[\S+\] blocked\b

# Mode "rbl" currently included in mode "normal" (within 1st rule)
mdpr-more = %(mdpr-normal)s
mdre-more = %(mdre-normal)s

# Includes some of the log messages described in
# <http://www.postfix.org/POSTSCREEN_README.html>.
mdpr-ddos = (?:lost connection after(?! DATA) [A-Z]+|disconnect(?= from \S+(?: \S+=\d+)* auth=0/(?:[1-9]|\d\d+))|(?:PREGREET \d+|HANGUP) after \S+|COMMAND (?:TIME|COUNT|LENGTH) LIMIT)
mdre-ddos = ^from [^[]*\[<HOST>\]%(_port)s:?

mdpr-extra = (?:%(mdpr-auth)s|%(mdpr-normal)s)
mdre-extra = %(mdre-auth)s
            %(mdre-normal)s

mdpr-aggressive = (?:%(mdpr-auth)s|%(mdpr-normal)s|%(mdpr-ddos)s)
mdre-aggressive = %(mdre-auth2)s
                  %(mdre-normal)s

mdpr-errors = too many errors after \S+
mdre-errors = ^from [^[]*\[<HOST>\]%(_port)s$


failregex = <mdre-<mode>>

# Parameter "mode": more (default combines normal and rbl), auth, normal, rbl, ddos, extra or aggressive (combines all)
# Usage example (for jail.local):
#   [postfix]
#   mode = aggressive
#
#   # or another jail (rewrite filter parameters of jail):
#   [postfix-rbl]
#   filter = postfix[mode=rbl]
#
#   # jail to match "too many errors", related postconf `smtpd_hard_error_limit`:
#   # (normally included in other modes (normal, more, extra, aggressive), but this jail'd allow to ban on the first message)
#   [postfix-many-errors]
#   filter = postfix[mode=errors]
#   maxretry = 1
#
mode = more

ignoreregex = 

[Init]

journalmatch = _SYSTEMD_UNIT=postfix.service

# Author: Cyril Jaquier

PROXMOX

nano /etc/fail2ban/jail.d/defaults-debian.conf

Si es PROXMOX v7 o < menor

  • Agregamos al final
#*********************************** 
#*****        PROXMOX        ******* 
#***********************************
[proxmox]
enabled = true
port = https,http,8006
filter = proxmox
logpath = /var/log/daemon.log
maxretry = 3
bantime = 172800

Si es PROXMOX v8 o superior

  • Agregamos al final
[proxmox]
enabled = true
port = https,http,8006
filter = proxmox
backend = systemd
maxretry = 3
findtime = 2d
bantime = 1h
  • Ademas debemos instalar
apt update && apt install rsyslog

Continuamos

  • creamos el archivo
nano /etc/fail2ban/filter.d/proxmox.conf
  • Agregamos
[Definition]
failregex = pvedaemon\[.*authentication failure; rhost=<HOST> user=.* msg=.*
ignoreregex =
  • Reiniciamos el servicio
systemctl restart fail2ban
  • Ahora puede intentar ingresar en proxmox mas de 3 veces y correr el comando para ver el bloqueo
fail2ban-regex /var/log/daemon.log /etc/fail2ban/filter.d/proxmox.conf
  • Ademas debemos agregar las jaulas de
    • [sshd]
    • [sshd-ddos]
    • [apache-auth]
    • [apache-badbots]
    • [apache-common]
    • [apache-nohome]
    • [apache-noscript]
    • [apache-overflows]
    • [apache-modsecurity] NOTA: si esta instalado
    • [apache-404]
    • [apache-botsearch]
    • [apache-fakegooglebot]
    • [apache-shellshock]

RESUMEN PARA SERVIDOR PROXMOX

#***********************************
#*********** SSH  ******************
#***********************************
[sshd]
enabled = true
port = ssh,sftp,44
filter = sshd

logpath = %(sshd_log)s
backend = %(sshd_backend)s
bantime = 172800
maxretry = 3


#***********************************
#*********** SSH-DDOS  *************
#***********************************
[sshd-ddos]
enabled  = true
port     = ssh,sftp,44
filter   = sshd-ddos
logpath = %(sshd_log)s
backend = %(sshd_backend)s
bantime = 172800
maxretry = 3

#*********************************** 
#********** APACHE-AUTH   ********** 
#***********************************
[apache-auth]

enabled = true
filter = apache-auth
action = iptables-multiport[name=apache-auth, port="http,https"]
logpath = /var/log/apache2/*access.log
findtime = 600
bantime = 172800
maxretry = 3

#*********************************** 
#********** APACHE-BADBOTS  ******** 
#***********************************
[apache-badbots]

enabled = true
port = http,https
filter = apache-badbots
logpath = /var/log/apache2/*access.log
bantime = 172800
maxretry = 1   # El número máximo de intentos antes de bloquear


#*********************************** 
#********** APACHE-COMMON   ******** 
#***********************************
[apache-common]

enabled = true
port = http,https
filter = apache-common
logpath = /var/log/apache2/*access.log
bantime = 172800
maxretry = 3   # El número máximo de intentos antes de bloquear


#*********************************** 
#********** APACHE-NOHOME   ******** 
#***********************************
[apache-nohome]

enabled = true
port = http,https
filter = apache-nohome
logpath = /var/log/apache2/*access.log
bantime = 172800
maxretry = 3   # El número máximo de intentos antes de bloquear

#*********************************** 
#********** APACHE-NOSCRIPT ******** 
#***********************************
[apache-noscript]

enabled = true
port = http,https
filter = apache-noscript
logpath = /var/log/apache2/*access.log
bantime = 172800
maxretry = 3   # El número máximo de intentos antes de bloquear

#*********************************** 
#********** APACHE-OVERFLOWS ******* 
#***********************************
[apache-overflows]

enabled = true
port = http,https
filter = apache-overflows
logpath = /var/log/apache2/*access.log
bantime = 172800
maxretry = 2   # El número máximo de intentos antes de bloquear


#*********************************** 
#******      APACHE-404      ******* 
#***********************************
[apache-404]

enabled = true
port = http,https
filter = apache-404
logpath = /var/log/apache2/*access.log
findtime = 600  
bantime = 172800


#*********************************** 
#***** APACHE-BOTSEARCH      ******* 
#***********************************
[apache-botsearch]

enabled = true
port = http,https
filter = apache-botsearch
logpath = /var/log/apache2/*access.log
findtime = 3600 
bantime = 172800
maxretry = 3   # Número máximo de intentos antes de bloquear

#*********************************** 
#***** APACHE-FAKEGOOGLEBOT  ******* 
#***********************************
[apache-fakegooglebot]

enabled = true
port = http,https
filter = apache-fakegooglebot
logpath = /var/log/apache2/*access.log
findtime = 3600 
bantime = 172800
maxretry = 3   # Número máximo de intentos antes de bloquear


#*********************************** 
#***** APACHE-SHELLSHOCK     ******* 
#***********************************
[apache-shellshock]

enabled = true
port = http,https
filter = apache-shellshock
logpath = /var/log/apache2/*access.log
findtime = 3600
bantime = 172800
maxretry = 3   # Número máximo de intentos antes de bloquear


#*********************************** 
#***** NGINX-HTTP-AUTH       ******* 
#***********************************
[nginx-http-auth]

enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/access.log
findtime = 3600
bantime = 172800
maxretry = 3   # Número máximo de intentos antes de bloquear



#*********************************** 
#***** NGINX-LIMIT-REQ       ******* 
#***********************************
[nginx-limit-req]

enabled = true
port = http,https
filter = nginx-limit-req
logpath = /var/log/nginx/access.log  
findtime = 60 
maxretry = 100  # Número máximo de solicitudes permitidas en el período de tiempo
bantime = 172800


#*********************************** 
#***** NGINX-LIMIT-CONN      ******* 
#***********************************
[nginx-limit-conn]

enabled = true
port = http,https
filter = nginx-limit-conn
logpath = /var/log/nginx/access.log 
findtime = 60 
maxretry = 5 
bantime = 172800


#*********************************** 
#***** NGINX-BOTSEARCH       ******* 
#***********************************
[nginx-botsearch]

enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/access.log  
findtime = 3600 
bantime = 172800
maxretry = 3  

#*********************************** 
#***** NGINX-NOSCRIPT        ******* 
#***********************************
[nginx-noscript]

enabled = true
port = http,https
filter = nginx-noscript
logpath = /var/log/nginx/access.log 
findtime = 3600 
bantime = 172800
maxretry = 3  


#*********************************** 
#***** NGINX-OVERFLOWS       ******* 
#***********************************
[nginx-overflows]

enabled = true
port = http,https
filter = nginx-overflows
logpath = /var/log/nginx/access.log
findtime = 3600 
bantime = 172800
maxretry = 3  


#*********************************** 
#***** NGINX-NOHOME          ******* 
#***********************************
[nginx-nohome]

enabled = true
port = http,https
filter = nginx-nohome
logpath = /var/log/nginx/access.log
findtime = 3600 
bantime = 172800
maxretry = 3  



#*********************************** 
#***** NGINX-BADBOTS         ******* 
#***********************************
[nginx-badbots]

enabled = true
port = http,https
filter = nginx-badbots
logpath = /var/log/nginx/access.log
findtime = 3600 
bantime = 172800
maxretry = 3  


#*********************************** 
#***** NGINX-BAD-REQUEST     ******* 
#***********************************
[nginx-bad-request]

enabled = true
port = http,https
filter = nginx-bad-request
logpath = /var/log/nginx/access.log
findtime = 3600 
bantime = 172800
maxretry = 3  

#*********************************** 
#***** NGINX-404             ******* 
#***********************************
[nginx-404]

enabled = true
port = http,https
filter = nginx-404
logpath = /var/log/nginx/access.log
findtime = 3600 
bantime = 172800
maxretry = 5  


#*********************************** 
#***** NGINX-DOS             ******* 
#***********************************
[nginx-dos]

enabled = true
port = http,https
filter = nginx-dos
logpath = /var/log/nginx/access.log
findtime = 60 
bantime = 172800
maxretry = 100  


#*********************************** 
#*****   MYSQLD-AUTH         ******* 
#***********************************
[mysqld-auth]
enabled = true
filter = mysqld-auth
port = 3306  # Puerto de MySQL
logpath = /var/log/mysql/error.log  
maxretry = 3  
bantime = 172800
findtime = 600 


#*********************************** 
#*****     POSTFIX           ******* 
#***********************************
[postfix]
enabled = true
port = smtp,ssmtp
filter = postfix
logpath = /var/log/mail.log
maxretry = 5
findtime = 600
bantime = 172800

Samba

WordPress

WordPress-login

nano /etc/fail2ban/filter.d/wordpress-login.conf
  • Agregamos
# Fail2ban configuration file
#
# Author: Gustavo Matamoros Gonzalez
# Funtion: Block:
# /wp-login.php 


[Definition]
failregex = ^<HOST> .* "(GET|POST) /wp-login\.php HTTP/1.1"

ignoreregex =

  • Creamos la jail
#*********************************** 
#*****     WORDPRESS         ******* 
#*********************************** 
[wordpress-login]
enabled = true
port    = http,https
filter  = wordpress-login
logpath = /var/log/apache2/sada_services_80.casa-access.log 
maxretry = 2

WordPress-xmlrpc

  • Filtro
nano /etc/fail2ban/filter.d/wordpress-xmlrpc.conf
  • Agregamos
# Fail2ban configuration file
#
# Author: Gustavo Matamoros Gonzalez
# Funtion: Block:
# /xmlrpc.php

[Definition]
failregex = ^<HOST> .* "(GET|POST) /xmlrpc\.php HTTP/1.1"

ignoreregex =

  • Jail
[wordpress-xmlrpc]
enabled = true
port    = http,https
filter  = wordpress-xmlrpc
logpath = /var/log/apache2/sada_services_80.casa-access.log
maxretry = 2

WordPress-wlwmanifest

  • Filtro
nano /etc/fail2ban/filter.d/wordpress-wlwmanifest.conf
  • Agregamos
# Fail2ban configuration file
#
# Author: Gustavo Matamoros Gonzalez
# Funtion: Block:
# /wlwmanifest.xmlilregex


[Definition]
failregex = ^<HOST> .* "(GET|POST)*/wlwmanifest.xml
ignoreregex =
  • Reiniciamos
service fail2ban restart

RESUMEN SSH / POSTFIX / APACHE

#***********************************
#*********** SSH  ******************
#***********************************
[sshd]
enabled = true
port = ssh,sftp,44
filter = sshd
logpath = %(sshd_log)s
backend = %(sshd_backend)s
bantime = 172800
maxretry = 3

#***********************************
#*********** SSH-DDOS  *************
#***********************************
[sshd-ddos]
enabled  = true
port     = ssh,sftp,44
filter   = sshd-ddos
logpath = %(sshd_log)s
backend = %(sshd_backend)s
bantime = 172800
maxretry = 3

#*********************************** 
#********** APACHE-AUTH   ********** 
#***********************************
[apache-auth]

enabled = true
filter = apache-auth
action = iptables-multiport[name=apache-auth, port="http,https"]
logpath = /var/log/apache2/*access.log
findtime = 600
bantime = 172800
maxretry = 3

#*********************************** 
#********** APACHE-BADBOTS  ******** 
#***********************************
[apache-badbots]

enabled = true
port = http,https
filter = apache-badbots
logpath = /var/log/apache2/*access.log
bantime = 172800
maxretry = 1   # El número máximo de intentos antes de bloquear

#*********************************** 
#********** APACHE-COMMON   ******** 
#***********************************
[apache-common]
enabled = true
port = http,https
filter = apache-common
logpath = /var/log/apache2/*error.log
	  /var/log/apache2/*access.log
bantime = 172800
maxretry = 3

#*********************************** 
#********** APACHE-NOHOME   ******** 
#***********************************
[apache-nohome]

enabled = true
port = http,https
filter = apache-nohome
logpath = /var/log/apache2/*error.log
	  /var/log/apache2/*access.log
bantime = 172800
maxretry = 3   # El número máximo de intentos antes de bloquear

#*********************************** 
#********** APACHE-NOSCRIPT ******** 
#***********************************
[apache-noscript]

enabled = true
port = http,https
filter = apache-noscript
logpath = /var/log/apache2/*error.log
	  /var/log/apache2/*access.log
bantime = 172800

#*********************************** 
#********** APACHE-OVERFLOWS ******* 
#***********************************
[apache-overflows]

enabled = true
port = http,https
filter = apache-overflows
logpath = /var/log/apache2/*error.log
	  /var/log/apache2/*access.log
bantime = 172800
maxretry = 2   # El número máximo de intentos antes de bloquear


#*********************************** 
#******      APACHE-404      ******* 
#***********************************
[apache-404]

enabled = true
port = http,https
filter = apache-404
logpath = /var/log/apache2/*error.log
          /var/log/apache2/*access.log
findtime = 600  
bantime = 172800


#*********************************** 
#***** APACHE-BOTSEARCH      ******* 
#***********************************
[apache-botsearch]

enabled = true
port = http,https
filter = apache-botsearch
logpath = /var/log/apache2/*error.log
	  /var/log/apache2/*access.log
findtime = 3600 
bantime = 172800
maxretry = 3   # Número máximo de intentos antes de bloquear

#*********************************** 
#***** APACHE-FAKEGOOGLEBOT  ******* 
#***********************************
[apache-fakegooglebot]

enabled = true
port = http,https
filter = apache-fakegooglebot
logpath = /var/log/apache2/*error.log
	  /var/log/apache2/*access.log
findtime = 3600 
bantime = 172800
maxretry = 3   # Número máximo de intentos antes de bloquear


#*********************************** 
#***** APACHE-SHELLSHOCK     ******* 
#***********************************
[apache-shellshock]

enabled = true
port = http,https
filter = apache-shellshock
logpath = /var/log/apache2/*error.log
	  /var/log/apache2/*access.log
findtime = 3600
bantime = 172800
maxretry = 3   # Número máximo de intentos antes de bloquear




#*********************************** 
#*****     POSTFIX           ******* 
#***********************************
[postfix]
enabled = true
port = smtp,ssmtp
filter = postfix
logpath = /var/log/mail.log
maxretry = 5
findtime = 600
bantime = 172800


#*********************************** 
#*****     WORDPRESS         ******* 
#*********************************** 
[wordpress]
enabled = true
port    = http,https
filter  = wordpress
logpath = /var/log/apache2/*access.log
maxretry = 3


[wordpress-hard]
enabled = true
port    = http,https
filter  = wordpress-hard
logpath = /var/log/apache2/*error.log
          /var/log/apache2/*access.log
maxretry = 1

[wordpress-soft]
enabled = true
port    = http,https
filter = wordpress-soft
logpath = /var/log/apache2/*error.log
          /var/log/apache2/*access.log
maxretry = 1

WordPress:

nano /etc/fail2ban/jail.d/defaults-debian.conf
  • Agregamos
[wordpress-hard]
enabled = true
port    = http,https
filter  = wordpress-hard
logpath = /var/log/apache2/*error.log
          /var/log/apache2/*access.log
maxretry = 1

[wordpress-soft]
enabled = true
port    = http,https
filter = wordpress-soft
logpath = /var/log/apache2/*error.log
          /var/log/apache2/*access.log
maxretry = 3
  • Creamos el archivo
nano /etc/fail2ban/filter.d/wordpress-hard.conf
  • Agregamos
# Fail2Ban filter for WordPress hard failures
# Auto-generated: 2018-11-04T16:40:53+00:00
#

[INCLUDES]

before = common.conf

[Definition]

_daemon = (?:wordpress|wp)

failregex = ^%(__prefix_line)sBlocked authentication attempt for .* from <HOST>$
            ^%(__prefix_line)sBlocked user enumeration attempt from <HOST>$
            ^%(__prefix_line)sSpam comment \d+ from <HOST>$
            ^%(__prefix_line)sXML-RPC multicall authentication failure from <HOST>$
            ^%(__prefix_line)sPingback error .* generated from <HOST>$
            ^%(__prefix_line)sAuthentication attempt for unknown user .* from <HOST>$
            ^%(__prefix_line)sXML-RPC authentication attempt for unknown user .* from <HOST>$

ignoreregex =

# DEV Notes:
# Requires the 'WP fail2ban' plugin:
# https://github.com/invisnet/wp-fail2ban/
#
# Author: Charles Lecklider
  • Creamos el archivo
nano /etc/fail2ban/filter.d/wordpress-soft.conf
  • Agregamos
# Fail2Ban filter for WordPress soft failures
# Auto-generated: 2018-11-04T16:40:53+00:00
#

[INCLUDES]

before = common.conf

[Definition]

_daemon = (?:wordpress|wp)

failregex = ^%(__prefix_line)sAuthentication failure for .* from <HOST>$
            ^%(__prefix_line)sXML-RPC authentication failure for .* from <HOST>$

ignoreregex =

# DEV Notes:
# Requires the 'WP fail2ban' plugin:
# https://github.com/invisnet/wp-fail2ban/
#
# Author: Charles Lecklider

Demo-sada

  • Filtro
nano /etc/fail2ban/filter.d/demo-sada.conf
  • Agregamos
# Fail2ban configuration file
#
# Author: Gustavo Matamoros Gonzalez
# Funtion: Block:
# 120.0.52.214 - - [31/Oct/2023:00:05:32 -0600] "GET / HTTP/1.0" 302 366
# 117.62.218.192 - - [31/Oct/2023:13:50:18 -0600] "GET / HTTP/1.1" 302 486
# 45.79.181.223 - - [31/Oct/2023:00:10:15 -0600] "\x16\x03\x01" 400 392
# 138.68.208.44 - - [31/Oct/2023:00:54:19 -0600] "GET /portal/redlion HTTP/1.1" 404 341
# 66.240.236.119 - - [31/Oct/2023:00:56:53 -0600] "GET /sitemap.xml HTTP/1.1" 404 341
# 66.240.236.119 - - [31/Oct/2023:00:56:53 -0600] "GET /.well-known/security.txt HTTP/1.1" 404 341
# 167.94.146.55 - - [31/Oct/2023:01:10:40 -0600] "PRI * HTTP/2.0" 400 392
# 128.1.141.9 - - [31/Oct/2023:02:05:29 -0600] "GET /.env HTTP/1.1" 404 5138
# ::1 - - [31/Oct/2023:08:31:28 -0600] "OPTIONS * HTTP/1.0" 200 110
# 45.129.14.100 - - [31/Oct/2023:11:46:33 -0600] "GET /local.env HTTP/1.1" 404 5070
# 192.241.214.21 - - [31/Oct/2023:12:12:18 -0600] "GET /manager/text/list HTTP/1.1" 404 341
# 103.241.67.54 - - [31/Oct/2023:13:43:34 -0600] "GET /.git/HEAD HTTP/1.1" 200 244 
# 103.241.67.54 - - [31/Oct/2023:13:43:37 -0600] "GET /.git/ORIG_HEAD HTTP/1.1" 200 264
# 103.241.67.54 - - [31/Oct/2023:13:43:40 -0600] "GET /.git/objects/4d/ HTTP/1.1" 200 5518
# 89.190.156.174 - - [31/Oct/2023:15:24:38 -0600] "GET /cgi/conf.bin HTTP/1.1" 404 397


[Definition]
failregex = ^<HOST> - - \[.*\] "(GET|POST) / HTTP/1\.0" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) / HTTP/1\.1" \d+ \d+$
            ^<HOST> - - \[.*\] "\\x16\\x03\\x01" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /portal/redlion HTTP/1\.1" \d+ \d+$
	    ^<HOST> - - \[.*\] "(GET|POST) /robots.txt HTTP/1\.1" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /sitemap\.xml HTTP/1\.1" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /.well-known/security\.txt HTTP/1\.1" \d+ \d+$
            ^<HOST> - - \[.*\] "PRI \* HTTP/2\.0" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /.env HTTP/1\.1" \d+ \d+
            ^<HOST> - - \[.*\] "(GET|POST) /boaform/admin/formLogin HTTP/1\.1" \d+ \d+$
            ^<HOST> - - \[.*\] "OPTIONS \* HTTP/1\.0" \d+ \d+$
            ^<HOST> - - \[.*\] "GET /local\.env HTTP/1\.1" \d+ \d+$
            ^<HOST> - - \[.*\] "GET /manager/text/list HTTP/1\.1" \d+ \d+$
            ^<HOST> - - \[.*\] "GET /.git/.* HTTP/1\.1" \d+ \d+$
            ^<HOST> - - \[.*\] "POST /boaform/admin/formLogin HTTP/1\.1" \d+ \d+$
            ^<HOST> - - \[.*\] "GET /cgi/conf\.bin HTTP/1\.1" \d+ \d+$


ignoreregex =
  • Jail
#*********************************** 
#*****     DEMO-SADA         ******* 
#*********************************** 
[demo-sada]
enabled = true
port    = http,https
filter  = demo-sada
logpath = /var/log/apache2/demo_sada_services_80.casa-access.log
maxretry = 1

activos-conare

  • Filtro
nano /etc/fail2ban/filter.d/activos-conare.conf
  • Agregamos
# Fail2ban configuration file
#
# Author: Gustavo Matamoros Gonzalez

[Definition]
failregex = 

            #^<HOST> - - \[.*\] "(GET|POST) / HTTP/1\.\d" \d+ \d+$

            ^<HOST> - - \[.*\] "-" \d+ \d+$

            
            # ARCHIVOS DIRECTOS
            ^<HOST> - - \[.*\] "(GET|POST) /0bb8de035fc6\.php HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /about HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /blog HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /config.json HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /core HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /css/circlemenu\.css HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /favicon\.ico HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /home HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /hudson HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /index\.php?lang.* HTTP/1\.\d" \d+ \d+$


            ^<HOST> - - \[.*\] "(GET|POST) /local\.env HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /login.action HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /new HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /newsite HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /old HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /server-status HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /showLogin\.cc HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /style\.php HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /test HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /testing HTTP/1\.\d" \d+ \d+$


            # RUTAS GENERICAS
            ^<HOST> - - \[.*\] "(GET|POST) /administrator/.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /actuator.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /blog/.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /boaform.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /cgi.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /db/.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /debug.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /druid/.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /ecp/.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /fonts/font-awesome.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /fonts.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) http://.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /js/snap.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /manager.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /myadmin/.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /mysql.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /phpMyAdmin.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /portal.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /prograweb.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /robots.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /shopdb/.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /sitemap.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /s/.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /telescope.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /v2.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /vendor.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /wp-content.* HTTP/1\.\d" \d+ \d+$

            # CARACTERES
            ^<HOST> - - \[.*\] "(GET|POST) /_all_dbs HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /_ignition.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /?XDEBUG_SESSION_START.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /?rest_route.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /.DS_Store HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /.env HTTP/1\.\d" \d+ \d+
            ^<HOST> - - \[.*\] "(GET|POST) /.git/.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /.vscode/.* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "(GET|POST) /.well-known.* HTTP/1\.\d" \d+ \d+$

            # WORDPRESS
            ^<HOST> .* "(GET|POST) /wp-login\.php HTTP/1.\d"  \d+ \d+$
            ^<HOST> .* "(GET|POST) /wordpress HTTP/1.\d"  \d+ \d+$
            ^<HOST> .* "(GET|POST) /wordpress/.* HTTP/1.\d"  \d+ \d+$
            ^<HOST> .* "(GET|POST) /wp HTTP/1.\d"  \d+ \d+$
            ^<HOST> .* "(GET|POST) /wp/.* HTTP/1.\d"  \d+ \d+$
            ^<HOST> .* "(GET|POST) /wp-admin/.* HTTP/1.\d"  \d+ \d+$
            ^<HOST> .* "(GET|POST) /wp-content/.* HTTP/1.\d"  \d+ \d+$


            #X
            ^<HOST> - - \[.*\] "\\x16\\x03\\x01" \d+ \d+$
            ^<HOST> - - \[.*\] "\\x03" \d+ \d+$

            # HEADS
            ^<HOST> - - \[.*\] "CONNECT .* HTTP/1\.\d" \d+ \d+$
	        ^<HOST> - - \[.*\] "OPTIONS \* HTTP/1\.\d" \d+ \d+$
            ^<HOST> - - \[.*\] "PRI \* HTTP/2\.0" \d+ \d+$
            ^<HOST> - - \[.*\] "HEAD / HTTP/1\.\d" \d+ \d+$
            

ignoreregex =
  • Jail
#*********************************** 
#*****     DEMO-SADA         ******* 
#*********************************** 
[demo-sada]
enabled = true
port    = http,https
filter  = demo-sada
logpath = /var/log/apache2/demo_sada_services_80.casa-access.log
maxretry = 1