Protegiendo a nuestro Redmine

Israel Santana
Edosoft
Published in
2 min readMay 21, 2018

--

Hace unos días en un análisis rutinario de seguridad, detectamos que en nuestro redmine estábamos recibiendo peticiones bastante extrañas, parecía un escaneo inicial y/o esporádico, pero decidimos actuar lo antes posible antes de que la cosa fuese a más. Necesitábamos una solución rápida y efectiva.

Análisis

Nuestra infraestructura está montada sobre Google Cloud Platform (GCP), es muy sencilla y se puede ver en el siguiente diagrama.

Esquema de Redmine en GCP

Las peticiones raras que veíamos en NGiNX eran como las siguientes:

195.22.127.231 — — [04/May/2018:18:32:33 +0100] “GET /msd1.24.3/sql.php HTTP/1.1” 301 185 “-” “Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36”

195.22.127.231 — — [04/May/2018:18:32:33 +0100] “GET /msd1.24stable/sql.php HTTP/1.1” 301 185 “-” “Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36”

Como medida rápida, queríamos implementar fail2ban para proteger a nuestra máquina de forma rápida, entendemos que la parte correcta sería llevar los logs a stackdriver, pero no queríamos hacer muchos cambios, queríamos obtener valor con poco esfuerzo.

Fail2ban, es un pequeño demonio en Linux, que nos permite analizar los logs en tiempo real y tomar acciones.

Nuestro NGiNX, envía todas las peticiones a unicorn, y como nos estaba mostrando un 301 como respuesta de http. Por eso, no podemos saber en nuestro NGiNX lo que es correcto o no. Por este motivo, deberíamos utilizar el log de unicorn. Inicialmente dicho log, no nos daba demasiada información:

ActionController::RoutingError (No route matches [GET] “/msd1.24.3/sql.php”):

ActionController::RoutingError (No route matches [GET] “/msd1.24stable/sql.php”):

Necesitábamos una solución rápida, una reunión rápida y todos a trabajar :-)

Implementación

Estaba claro que necesitábamos cambiar un poco el log de nuestro redmine para que provea de una información que el fail2ban pueda entender. Fail2ban, sería el encargado de bloquear a esas ip sospechosas de forma temporal e informarnos por correo electrónico.

Nuestro equipo de desarrollo, rápidamente encontró la solución, básicamente, comprobaban que si ningún controlador gestiona la petición, nos devolviese una línea de log como esta:

I, [2018–05–04T18:32:33.534877 #1519] INFO — : ILLEGAL_ACCESS_ATTEMPT 195.22.127.231 GET 404 /msd1.24.4/sql.php

Bingo !! Ya tenemos algo sobre lo que podemos crear básicamente una regla de fail2ban, nuestra regla de filtrado es:

failregex = ILLEGAL_ACCESS_ATTEMPT <HOST> (GET|POST) (404|444|403|400) .*$

Ahora, sólo nos quedaba crear una jaula específica para nuestro redmine:

banaction = iptables-multiport

port = http,https

filter = redmine-404

logpath = /home/redmine/redmine/log/production.log

maxretry = 4

action = %(action_mwl)s

Con esto, ya tenemos protegida a nuestro redmine, aunque dentro de poco, pasaremos los logs a StrackDriver para obtener mayor información y control.

--

--