Buenas tardes
En una
publicación anterior
, hablé sobre cómo, de manera fácil y natural, puede configurar la recopilación de metadatos de tráfico de red en los enrutadores Mikrotik en una base de datos.
Ahora es el momento de enseñarle a nuestro servidor a hacer un análisis elemental de los datos recibidos y enviar comandos de regreso.
Propósito: Control dinámico de las reglas de firewall de Mikrotik para suprimir los ataques de red con adivinar contraseñas.
Medios: distribución fresca de Linux con rsyslogd v8, crond, mariadb DBMS y el enrutador Mikrotik.
Mecánica: Al usar la tarea asignada, se ejecuta una consulta SQL en la base de datos con datos de tráfico acumulados y actualizados y devuelve una lista de direcciones IP salientes, el script bash lanzado por la corona genera comandos Mikrotik y, utilizando una conexión ssh, repone la lista de direcciones para las reglas de bloqueo existentes.
Se tratará de proteger los puertos TCP abiertos. Estos pueden ser puertos que ingresan a Mikrotik y se reenvían a la red local.
Para comenzar, indicamos dónde puede haber debilidades:
- Protocolos de control de ssh, telnet, web, enrutador winbox
- Servicios de correo smtp, pop, imap
- Cualquier servicio web proporcionado fuera
- Escritorio remoto MS RDP, VNC, etc.
- Cualquier otra cosa a su discreción.
Escribir una consulta SQL para buscar fuerza brutaNuestra organización tiene servidores de terminal abiertos al exterior a través de puertos no prioritarios.
En DNAT Mikrotik, activé el registro de las reglas necesarias agregando el prefijo RDP_DNAT. Por este prefijo buscaremos:
MariaDB [traflog]> select src,dport,count(dport) as ' ' from traffic where datetime>now() - interval 1 day and logpref='RDP_DNAT' group by src having count(dport)>50; +
Esta solicitud muestra la dirección IP (de donde proviene el ataque), el puerto al que se realiza la conexión (se cambia el número de puerto) y el número de intentos de conexión, con agrupación preliminar por src y selección de líneas, con el número de intentos más de 50 en el pasado, desde el momento actual, día.
En mi caso, estas direcciones se pueden prohibir de forma segura, ya que el número de conexiones con clientes "buenos" es menor, no más de 5-10 por día desde una ip.
La solicitud funciona bien, rápido, pero es un poco larga. Para un uso posterior, propongo hacer una vista, que copiaría menos en el futuro:
MariaDB [traflog]> create or replace view rdp_brute_day as select src, dport, count(dport) from traffic where datetime>now() - interval 1 day and logpref='RDP_DNAT' group by src having count(dport)>50; Query OK, 0 rows affected (0.23 sec)
Veamos cómo funciona la vista:
MariaDB [traflog]> select src,count(dport) from rdp_brute_day; +
Genial
Añadimos al usuario Mikrotik con autorización por clave dsaEn la consola de Linux, generamos la clave dsa, bajo el usuario en nombre de quién se lanzará la tarea programada, que hice desde la raíz:
root@monix:~
La frase de contraseña no es necesaria. Copiamos la clave pública /root/.ssh/id_dsa.pub a Mikrotik de cualquier manera posible. Lo saqué con el comando cat, copié el texto de la ventana de masilla en un archivo de texto, lo guardé y lo arrastré a la ventana de archivos de winbox.
No sé por qué, pero durante las siguientes operaciones a través de la interfaz de winbox, algo salió mal. Al conectarse desde el servidor a través de ssh, Mikrotik también me solicitó una contraseña. Después de eliminar al usuario creado y realizar todas las operaciones a través de la consola, la conexión dsa funcionó. Hizo aproximadamente como se describe
aquí .
En general, recibí la entrada de bienvenida sin contraseña usando la clave dsa y ejecuté el comando de verificación:
root@monix:/
Bueno
Escribir un script bashEl guión no fue complicado:
mikrotik_cmd_list(){ brute_src_list=$(mysql --skip-column-names traflog -e 'select src from rdp_brute_day') for src in $brute_src_list do echo "ip firewall address-list add address=$src list=rdp_banlist timeout=1d" done } mikrotik_cmd_list | ssh -T rsyslogger@192.168.0.230
Para transferir todos los comandos dentro de la misma conexión ssh, necesitaba describir la función mikrotik_cmd_list (), en la que primero se realiza una solicitud guardando direcciones IP en la variable brute_src_list, luego en el bucle esta variable genera secuencialmente comandos para Mikrotik. Después de llamar a la función, la salida se enruta a través de la tubería a ssh.
No olvide cerrar los derechos de acceso de script para todos, excepto root, y hacer que el archivo sea ejecutable.
El comando que genera el script agregará la dirección IP a rdp_banlist durante 1 día, después de este tiempo se eliminará de la lista misma. Si desea dejarlo para siempre, elimine la opción de tiempo de espera.
Agregar una regla al firewallSe me ocurrieron dos opciones sobre cómo usar rdp_banlist:
Opción uno: agregue rdp_banlist con un signo de exclamación a las reglas NAT con el prefijo RDP_DNAT.
add action=dst-nat chain=dstnat comment="..." dst-address=1.2.3.4 dst-port=12345 log=yes log-prefix=RDP_DNAT protocol=tcp src-address-list=\ !rdp_banlist to-addresses=192.168.200.181 to-ports=3389
Algo asi. Es decir, lo hacemos todo, excepto lo que está en rdp_banlist.
En esta opción, hay un más y un menos.
La ventaja es que las conexiones se detendrán de inmediato.
La desventaja es que esta IP ya no entrará en la base de datos de traflog y después de un día, cuando haya pasado el tiempo de espera de almacenamiento en la lista negra, comenzará a fallar nuevamente.
Opción dos: agregue rdp_banlist con un signo de exclamación a la regla del cortafuegos de la cadena de reenvío, donde permitimos que el tráfico pase a través de TCP 3389, de forma similar al primer método.
add action=accept chain=forward comment="..." dst-port=3389 log=yes log-prefix=ACCEPT_RDP protocol=tcp src-address-list=\ !rdp_banlist to-ports=3389
Algo asi. Permitimos todo excepto eso en la lista de prohibición.
También hay un más y menos.
Más. Los registros con el prefijo RDP_DNAT continuarán transmitiéndose en la base de datos de traflog, por lo que determinaremos el signo de ataque. Como resultado, cuando expire el tiempo de espera de prohibición para un host específico que continúa con los intentos de fuerza bruta, se agregará nuevamente a la lista de prohibición después del próximo lanzamiento de la tarea programada.
La desventaja es que continúa en la tabla DSTNAT, creando un nuevo registro con cada conexión, aunque sea temporal.
En general, la decisión es suya, elegí ambos :) (de hecho, solo el primero funciona en este caso), ya que el segundo se activó antes y la mecánica era diferente allí, según las entradas secuenciales en las listas etapa1, etapa2, etapa3, banlist ... bueno, entiendes el punto. Un truco antiguo y poco confiable, puede prohibir fácilmente a los clientes "buenos" y al mismo tiempo omitir a los "malos" que calcularon cortésmente la etapa de tiempo de espera1.
Trabajo programado crontabQueda por agregar la tarea asignada al crontab:
root@monix:/root
Tal registro ejecutará el script cada hora en 12 minutos.
Debo admitir que hoy terminé de trabajar en esta mecánica y con un alto grado de probabilidad, algo podría salir mal. Según las circunstancias, completaré y corregiré los errores. Quiero
beber para dormir profundamente en las vacaciones de Año Nuevo, es por eso que tengo prisa por terminar.
Eso es probablemente todo.
¡Gracias a todos por su atención y feliz año nuevo!
Referencias
Documentación de MySQLDocumentación del cortafuegos MikrotikGracias a Andrey Smirnov por el
artículo sobre la conexión dsa.