Autenticación de dos factores para usuarios de VPN mediante MikroTik y SMS

¡Hola colegas! Hoy, cuando la tensión en torno al trabajo remoto ha disminuido un poco, la mayoría de los administradores han superado el desafío del acceso remoto de los empleados a la red corporativa. Es hora de compartir mi antiguo trabajo sobre cómo aumentar la seguridad de la VPN. En este artículo no se hablará de las modas actuales como IPSec IKEv2 y xAuth. Se tratará de construir un sistema. de autenticación de dos factores (2FA) para usuarios de VPN, cuando MikroTik actúa como servidor VPN. Específicamente, cuando se utilizan protocolos "clásicos" como PPP.

Autenticación de dos factores para usuarios de VPN mediante MikroTik y SMS

Hoy les contaré cómo proteger MikroTik PPP-VPN incluso en el caso de un "robo" de la cuenta de usuario. Cuando se implementó este esquema para uno de mis clientes, lo describió brevemente como "bueno, ahora es como en el banco!".

El método no utiliza servicios de autenticación externos. Las tareas se llevan a cabo utilizando los recursos internos del propio enrutador. Sin costos para el cliente conectado. El método funciona tanto para clientes de PC como para dispositivos móviles.

El esquema general de protección es el siguiente:

  1. La dirección IP interna del usuario que se conectó exitosamente al servidor VPN se agrega automáticamente a la "lista gris".
  2. El evento de conexión genera automáticamente un código de un solo uso, que se envía al usuario de una de las formas disponibles.
  3. Las direcciones en esta lista tienen acceso limitado a los recursos de la red local, a excepción del servicio de "autenticador", que espera recibir el código de un solo uso.
  4. Después de presentar el código, se abre el acceso al usuario a los recursos internos de la red.

Primero El problema más pequeño que se presentó fue almacenar la información de contacto del usuario para enviarle el código 2FA. Dado que no se pueden crear campos de datos arbitrarios asociados con los usuarios en MikroTik, se utilizó el campo existente "comentario":

/ppp secrets add name=Petrov password=4M@ngr! comment=«89876543210»

Segundo el problema resultó ser más serio: elegir el camino y la forma de entrega del código. En este momento, se han implementado tres esquemas: a) SMS a través de un módem USB b) correo electrónico c) SMS a través de correo electrónico disponible para clientes corporativos del operador de telefonía móvil rojo.

Sí, los esquemas con SMS conllevan costos. Pero si se analiza, "la seguridad siempre se trata de dinero" (c).
No me gusta el esquema de e-mail. No porque requiera la disponibilidad del servidor de correo para un cliente autenticado — no es un problema dividir el tráfico. Sin embargo, si el cliente guardó descuidadamente las contraseñas tanto en el VPN como en el correo en el navegador, y luego perdió su computadora portátil, el atacante obtendrá acceso completo a la red corporativa.

Así que se decidió — entregaremos un código de un solo uso a través de mensajes SMS.

Tercero El problema estaba en dónde y cómo generar un código pseudorandom para 2FA en MikroTik.En el lenguaje de script de RouterOS no hay un equivalente a la función random() y antes había visto varios generadores de números pseudorandom en scripts improvisados. Ninguno de ellos me gustó por diversas razones.

¡De hecho, hay un generador de secuencias pseudorandom en MikroTik! Está oculto a la vista superficial en el contexto de /certificates scep-server. Primer método Obtener una contraseña de un solo uso es fácil y simple — con el comando /certificates scep-server otp generate. Si realizamos una sencilla operación de asignación de variable, obtendremos un valor del tipo array, que podemos utilizar más adelante en los scripts.

Segundo método La obtención de una contraseña de un solo uso que también es fácil de aplicar — el uso de un servicio externo random.org para generar la secuencia deseada de números pseudorandom. Aquí hay un ejemplo simplificado consola de cómo obtener datos en una variable:

Código
:global rnd1 [:pick ([/tool fetch url="https://www.random.org/strings/?num=1&len=7&digits=on&unique=on&format=plain&rnd=new" as-value output=user ]->"da
ta") 1 6]
:put $rnd1

La consulta formateada para la consola (en el cuerpo del script será necesario escapar caracteres especiales) obtiene una cadena de seis caracteres-números en la variable $rnd1. El siguiente comando «put» simplemente muestra la variable en la consola MikroTik.

El cuarto problema, que hubo que resolver rápidamente — es cómo y dónde el cliente conectado transmitirá su código de un solo uso en la segunda etapa de autenticación.

Autenticación de dos factores para usuarios de VPN mediante MikroTik y SMS

En el router MikroTik debe existir un servicio capaz de recibir el código y compararlo con un cliente específico. Si el código proporcionado coincide con el esperado, la dirección del cliente debe entrar en una especie de «lista blanca», desde la cual se permite el acceso a la red interna de la empresa.

Dado el escaso número de servicios disponibles, se decidió recibir códigos a través de http utilizando el webproxy incorporado en Mikrotik. Y dado que el firewall puede trabajar con listas dinámicas de direcciones IP, la búsqueda del código, su comparación con la IP del cliente y la inclusión en la lista blanca son realizadas precisamente por el firewall a través de Layer7 regexp. Al router se le asignó el nombre DNS condicional «gw.local», y se creó un registro A estático para la asignación a los clientes PPP:

DNS
/ip dns static add name=gw.local address=172.31.1.1

Captura en proxy del tráfico de clientes no verificados:
/ip firewall nat add chain=dstnat dst-port=80,443 in-interface=2fa protocol=tcp !src-address-list=2fa_approved action=redirect to-ports=3128

En este caso, el proxy tiene dos funciones.

1. Abrir conexiones TCP con los clientes;

2. En caso de autorización exitosa, redirigir el navegador del cliente a una página o imagen que notifique sobre la autenticación exitosa:

Configuración del proxy
/ip proxy
configurar habilitado=sí puerto=3128
/ip proxy access
agregar acción=denegar deshabilitado=no redirigir-a=gw.local./mikrotik_logo.png src-dirección=0.0.0.0/0

Enumeraré los elementos importantes de la configuración:

  1. interface-list «2fa» — lista dinámica de interfaces de cliente, cuyo tráfico requiere procesamiento en el contexto de 2FA;
  2. address-list «2fa_jailed» — lista gris de direcciones IP de túneles de clientes VPN;
  3. address_list «2fa_approved» — lista blanca de direcciones IP de túneles de clientes VPN que han pasado exitosamente la autenticación de dos factores.
  4. cadena de firewall «input_2fa» — en ella se realiza la verificación de los paquetes TCP para comprobar la existencia del código de autorización y la coincidencia de la dirección IP del remitente del código con la requerida. Las reglas en la cadena se añaden y eliminan dinámicamente.

Un diagrama de flujo simplificado para el procesamiento del paquete se ve así:

Autenticación de dos factores para usuarios de VPN mediante MikroTik y SMS

Para permitir la verificación del tráfico de Layer7 de los clientes en la lista gris que aún no han pasado la segunda fase de autenticación, se creó una regla en la cadena estándar «input»:

Código
/ip firewall filter add chain=input !src-address-list=2fa_aprobado action=saltar jump-target=input_2fa

Ahora comenzaremos a integrar toda esta riqueza al servicio PPP. MikroTik permite usar scripts en los perfiles (ppp-profile) y asignarlos a eventos de establecimiento y ruptura de la conexión PPP. La configuración del ppp-profile puede aplicarse tanto para el servidor PPP en general como para usuarios individuales. En este caso, el perfil asignado a un usuario tiene prioridad, sobrescribiendo los parámetros del perfil elegido para el servidor en general.

Como resultado de este enfoque, podemos crear un perfil especial para la autenticación de dos factores y asignarlo no a todos los usuarios, sino solo a aquellos a quienes consideramos necesario hacerlo. Esto puede ser relevante si los servicios PPP se utilizan no solo para conectar usuarios finales, sino también para establecer conexiones site-to-site.

En el nuevo perfil especial, utilizamos la adición dinámica de la dirección y la interfaz del usuario conectado en las listas «grises» de direcciones e interfaces:

winbox
Autenticación de dos factores para usuarios de VPN mediante MikroTik y SMS

Código
/ppp profile add address-list=2fa_jailed change-tcp-mss=no local-address=192.0.2.254 name=2FA interface-list=2fa only-one=yes remote-address=dhcp_pool1 use-compression=no use-encryption= required use-mpls=no use-upnp=no dns-server=172.31.1.1

Es necesario utilizar conjuntamente las listas «address-list» y «interface-list» para identificar y capturar el tráfico de los clientes VPN que no han pasado la segunda autenticación en la cadena dstnat (prerouting).

Cuando la preparación esté lista, se crearán cadenas adicionales del firewall y un perfil, escribiremos un script responsable de la autogeneración del código 2FA y de las reglas del firewall.

Documentación wiki.mikrotik.com El PPP-Profile nos enriquece con información sobre las variables relacionadas con los eventos de conexión y desconexión del cliente PPP «Ejecutar script en el evento de inicio de sesión del usuario. Estas son las variables disponibles que son accesibles para el script del evento: user, local-address, remote-address, caller-id, called-id, interface». Algunas de ellas nos serán muy útiles.

Código utilizado en el perfil para el evento de conexión PPP on-up

#Логируем для отладки полученные переменные 
:log info (

quot;dirección-local")
:registro info (

quot;dirección-remota")
:registro info (

quot;id-del-llamador")
:registro info (

quot;id-llamado")
:registro info ([/int pptp-server get (

quot;interfaz") nombre])
#Объявляем свои локальные переменные
:lista-local "2fa_jailed"
:local viamodem false
:puerto-modem local "usb2"
#ищем автоматически созданную запись в адрес-листе "2fa_jailed"
:número-recipient1 [ /ip fi address-list find address=(

quot;dirección-remota") lista=$listname]

#получаем псевдослучайный код через random.org
#:local rnd1 [:pick ([/tool fetch url="https://www.random.org/strings/?num=1&len=7&digits=on&unique=on&format=plain&rnd=new" as-value output=user]->"data") 0 4]
#либо получаем псевдослучайный код через локальный генератор
#:local rnd1 [pick ([/cert scep-server otp generate as-value minutes-valid=1]->"password") 0 4 ]

#Ищем и обновляем коммент к записи в адрес-листе. Вносим искомый код для отладки
/ip fir address-list set $recnum1 comment=$rnd1
#получаем номер телефона куда слать SMS
:teléfono-local [ /ppp secret get [find name=$user] comentario]

#Готовим тело сообщения. Если клиент подключается к VPN прямо с телефона ему достаточно
#будет перейти прямо по ссылке из полученного сообщения
:local msgboby ("Tu código: ".$comm1."n O abre el enlace http://gw.local/otp/".$comm1."/")

# Отправляем SMS по выбранному каналу - USB-модем или email-to-sms
si $viamodem do={
/tool sms send phone-number=$vphone message=$msgboby port=$modemport }
sino={
/tool e-mail send server=a.b.c.d from=admin@mydomain.example to=mail2sms@mcommunicator.ru subject="@".$vphone body=$msgboby }

#Генерируем Layer7 regexp
local vregexp ("otp\".$comm1)
:comentario-local ("2fa_".(

quot;dirección-remota"))
/ip firewall layer7-protocol add name=(

quot;vcomment") comentario=(

quot;dirección-remota") regexp=(

quot;vregexp")

#Генерируем правило проверяющее по Layer7 трафик клиента в поисках нужного кода
#и небольшой защитой от брутфорса кодов с помощью dst-limit
/ip firewall filter add action=add-src-to-address-list address-list=2fa_approved address-list-timeout=none-dynamic chain=input_2fa dst-port=80,443,3128 layer7-protocol=(

quot;vcomment") protocolo=tcp src-address=(

quot;dirección-remota") dst-limit=1,1,src-address/1m40s


Especialmente para los entusiastas de copiar y pegar sin pensar, advierto: el código se ha tomado de una versión de prueba y puede contener errores tipográficos menores. Comprender dónde están exactamente no será difícil para una persona que lo entienda.

Al desconectar al usuario, se genera el evento «On-Down» y se invoca el script correspondiente con los parámetros. La tarea de este script es limpiar las reglas del firewall creadas para el usuario desconectado.

Código utilizado en el perfil para el evento de conexión PPP on-down

:comentario-local ("2fa_".(

quot;dirección-remota"))
/ip firewall address-list remove [find address=(

"dirección-remota") lista=2fa_aprobada]
/ip firewall filter remove [find chain="input_2fa" src-address=(

"dirección-remota") ]
/ip firewall layer7-protocol remove [find name=$vcomment]


Después de esto, se pueden crear usuarios y asignar a todos o a algunos de ellos un perfil con autenticación de dos factores.

winbox
Autenticación de dos factores para usuarios de VPN mediante MikroTik y SMS

Código
/ppp secrets set [find name=Petrov] profile=2FA

Así es como se ve del lado del cliente.

Al establecer una conexión VPN, el teléfono/tableta Android/iOS con la tarjeta SIM recibe un SMS de este tipo:

SMS
Autenticación de dos factores para usuarios de VPN mediante MikroTik y SMS

Si la conexión se establece directamente desde el teléfono/tableta, se puede completar el 2FA simplemente haciendo clic en el enlace del mensaje. Es conveniente.

Si se establece una conexión VPN con una PC, el usuario necesitará un formulario mínimo para ingresar la contraseña. Se envía un pequeño formulario en forma de archivo HTML al usuario al configurar la VPN. El archivo se puede enviar incluso por correo, para que el usuario lo guarde y cree un acceso directo en un lugar conveniente. Así es como se ve:

Acceso directo en el escritorio
Autenticación de dos factores para usuarios de VPN mediante MikroTik y SMS

El usuario hace clic en el acceso directo, se abre un simple formulario de entrada de código que insertará el código en la URL abierta:

Captura de pantalla del formulario
Autenticación de dos factores para usuarios de VPN mediante MikroTik y SMS

El formulario es muy básico, proporcionado solo como ejemplo. Los interesados pueden personalizarlo a su gusto.

2fa_login_mini.html

<html>
<head> <title>Inicio de sesión con OTP SMS</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head>
<body>
<form name="login" action="/es/location.href=&#039;http://gw.local/otp/&#039;+document.getElementById(‘text&#039;).value/"  method="post"
 <input id="text" type="text" data-trp-original-action="location.href='http://gw.local/otp/'+document.getElementById(‘text').value"/><input type="hidden" name="trp-form-language" value="es"/> 
<input type="button" value="Iniciar sesión" onclick="location.href='http://gw.local/otp/'+document.getElementById('text').value"/> 
</form>
</body>
</html>

Si la autenticación fue exitosa, el usuario verá el logo de MikroTik en el navegador, lo que debería servir como señal de una autenticación exitosa:

Autenticación de dos factores para usuarios de VPN mediante MikroTik y SMS

Cabe mencionar que la imagen se devuelve desde el servidor web integrado de MikroTik a través de WebProxy Deny Redirect.

Supongo que la imagen se puede personalizar utilizando la herramienta 'hotspot', subiendo su propia versión y configurando la URL Deny Redirect con WebProxy.

Una gran solicitud a aquellos que intentan reemplazar un enrutador de $500 por el más barato 'juguete' MikroTik de $20: no lo hagan. Dispositivos como 'hAP Lite'/ 'hAP mini' (punto de acceso doméstico) tienen una CPU muy débil (smips) y probablemente no soporten la carga en el segmento empresarial.

¡Advertencia! Este enfoque tiene una desventaja: al conectar y desconectar clientes, se producen cambios en la configuración que el enrutador intenta guardar en su memoria no volátil. Con un gran número de clientes y desconexiones frecuentes, esto puede llevar a la degradación del almacenamiento interno en el enrutador.

P.D.: los métodos de entrega del código al cliente pueden ampliarse y complementarse tanto como lo permitan sus capacidades de programación. Por ejemplo, se pueden enviar mensajes en Telegram o... ¡propongan otras opciones!

Espero que este artículo les resulte útil y ayude a hacer las redes de pequeñas y medianas empresas un poco más seguras.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster