Esta guía lo lleva desde una VPN de MikroTik corriente hasta otra en la que cada inicio de sesión debe aprobarse con un toque en la app Notakey Authenticator, usando únicamente scripts de RouterOS. En esta configuración no hay servidor RADIUS, ni auth-proxy, ni nada que desplegar dentro de su red más allá del router que ya tiene.
Todos los scripts proceden del repositorio oficial
notakey/mikrotik-2fa-vpn.
Cómo funciona
Entender el flujo hace que cada paso de más abajo resulte evidente:
- El usuario marca la VPN y se autentica con su nombre de usuario y contraseña
como siempre. La sesión PPP se levanta, pero el firewall bloquea de
inmediato todo su tráfico, porque su dirección va a parar a una lista de
direcciones
vpn_pending. - Se dispara el script up del perfil PPP. Llama a su Notakey Authentication Server, que envía una solicitud de aprobación al teléfono del usuario: «Log in as <user> from <caller IP>?»
- Si el usuario aprueba dentro del tiempo de espera (60 segundos), el
script elimina su dirección de
vpn_pending: el bloqueo del firewall se levanta y el tráfico fluye. - Si el usuario rechaza o la solicitud caduca, el script cierra la sesión PPP. La contraseña por sí sola nunca fue suficiente.
Requisitos
- RouterOS 6.46.4 o posterior (los scripts también funcionan en RouterOS 7.x).
- Una VPN basada en PPP en funcionamiento en el router —L2TP/IPsec, PPTP o SSTP— a la que los usuarios ya se puedan conectar con nombre de usuario y contraseña.
- Un Notakey Authentication Server alcanzable desde el router. Basta con el plan gratuito en la nube en signup.notakey.com (los primeros 6 usuarios gratis) o con ejecutar el appliance on-premise (los primeros 10 usuarios gratis).
- Un teléfono iOS o Android con la app Notakey Authenticator.
Paso 1: prepare el lado de Notakey
- En su panel de Notakey, cree una nueva aplicación (servicio) para la VPN; póngale un nombre reconocible, p. ej. «Office VPN»; este nombre es el que los usuarios ven en su teléfono.
- Copie el Access ID de la aplicación (un UUID): lo pegará en el script del router en el paso 4.
- Cree el usuario (o conecte su fuente de usuarios) y configure un requisito de registro; después registre el teléfono: instale Notakey Authenticator, añada su servicio y complete el registro.
El nombre de usuario en Notakey debe coincidir exactamente con el nombre de
usuario de la VPN: el script del router usa el nombre de usuario PPP para
dirigir la notificación push. john en el router y john.doe en Notakey
fallará sin dar ningún aviso.
Paso 2: instale la biblioteca JParseFunctions
Los scripts de RouterOS no saben analizar JSON de forma nativa; esta biblioteca (del proyecto mikrotik-json-parser) cubre ese hueco.
En WinBox o WebFig, vaya a System → Scripts, cree un nuevo script llamado
exactamente JParseFunctions, deje las casillas de política en sus valores por
defecto (no requiere privilegios especiales) y pegue el contenido íntegro del
archivo JParseFunctions
de ese proyecto.
Paso 3: instale la biblioteca NotakeyFunctions
El mismo procedimiento: cree un segundo script llamado exactamente
NotakeyFunctions y pegue el contenido de
NotakeyFunctions.lua
del repositorio de Notakey. Este es el cliente que se comunica con la API de
Notakey: crea la solicitud de autenticación y sondea la respuesta del usuario.
Los nombres de los scripts importan: el script de perfil del paso siguiente carga ambas bibliotecas por su nombre.
Paso 4: asocie los scripts up/down a un perfil PPP
Abra el perfil PPP de su VPN (PPP → Profiles), o cree uno dedicado para que el 2FA se aplique solo a usuarios seleccionados mientras hace pruebas.
- En la pestaña General, ponga Address List en
vpn_pending. Cada nueva conexión que use este perfil verá ahora su dirección añadida a esa lista en el momento en que la sesión se levante. - En la pestaña Scripts, pegue el script On Up de más abajo (de
PppProfileScript.lua) en la casilla On Up, cambiando dos valores para su entorno:ntkHost—el nombre de host de su servidor Notakey (sinhttps://)— yntkAccessId—el Access ID de la aplicación que copió en el paso 1—.
{
:local localAddr $"local-address";
:local remoteAddr $"remote-address";
:local callerId $"caller-id";
:local calledId $"called-id";
:log info "$user (srcIp=$callerId, dstIp=$calledId) connected: was given $remoteAddr IP (GW $localAddr)";
/system script run "JParseFunctions";
:global JSONUnload;
/system script run "NotakeyFunctions";
:global NtkAuthRequest;
:global NtkWaitFor;
:global NtkUnload;
# Change values below to match your Notakey installation
:local ntkHost "demo.notakey.com";
:local ntkAccessId "12345645-b32b-4788-a00d-251cd7dc9a03";
# Custom message in authentication request
:local authDescMsg "Log in as $user from $callerId\?";
:local ntkAuthUuid ([$NtkAuthRequest host=$ntkHost accessId=$ntkAccessId authUser=$user authTitle="VPN connection" authDesc=$authDescMsg authTtl=60]);
:if ([$NtkWaitFor uuid=$ntkAuthUuid host=$ntkHost accessId=$ntkAccessId]) do={
# Remove blocking rule after successful 2FA authentication
/ip firewall address-list remove [/ip firewall address-list find where list=vpn_pending address=$remoteAddr]
} else={
:log info "VPN 2FA authentication failure for user $user from IP $callerId";
# Disconnect active session with this IP and user
/ppp active remove [/ppp active find name="$user" address="$remoteAddr"]
}
$NtkUnload
$JSONUnload
}
El script On Down del mismo archivo solo registra la desconexión; péguelo en la casilla On Down para tener registros ordenados, u omítalo.
El tiempo de espera de aprobación (authTtl) es de 60 segundos: suficiente
para sacar el teléfono del bolsillo, y lo bastante corto como para que un inicio
de sesión atascado no mantenga una sesión a medio abrir de forma indefinida.
Paso 5: añada las reglas de firewall
La regla de descarte es lo que hace que la lista de pendientes signifique algo de verdad:
/ip firewall filter
add chain=forward src-address-list=vpn_pending action=drop \
comment="Block VPN clients pending 2FA approval"
Colóquela por encima de sus reglas generales de permitir la VPN, para que
prevalezca mientras la aprobación está pendiente. Si los clientes de la VPN
también deben quedar bloqueados para alcanzar el propio router, replique la
regla en la cadena input.
Un caso especial: si la aprobación se va a producir en el mismo dispositivo que marca la VPN —el propio teléfono es el cliente de la VPN—, el tráfico de aprobación debe poder alcanzar el servidor Notakey mientras todo lo demás sigue bloqueado. Añada una regla de aceptar por encima de la de descarte:
/ip firewall filter
add chain=forward src-address-list=vpn_pending dst-address=<notakey-server-ip> \
action=accept comment="Let pending clients reach Notakey for approval"
(Aprobar desde un segundo dispositivo —el teléfono aprueba mientras un portátil
marca la VPN— no necesita ninguna regla adicional: el router sondea por sí mismo
la API de Notakey, y su propio tráfico no está sujeto a la cadena forward.)
Paso 6: asigne el perfil y pruebe
Apunte su usuario de VPN (PPP → Secrets) al perfil del paso 4 y, después, marque la VPN desde un cliente:
- El túnel se conecta, pero nada se enruta: está en
vpn_pending. - En uno o dos segundos, la notificación push llega al teléfono.
- Apruebe → el tráfico empieza a fluir. Rechace o ignore → tras el tiempo de espera la sesión se cae.
Véalo ocurrir en Log (los scripts registran cada solicitud y su resultado)
y en IP → Firewall → Address Lists, donde la dirección del cliente aparece
en vpn_pending y desaparece al aprobar.
Resolución de problemas
- No llega ninguna push: casi siempre es una falta de coincidencia del nombre de usuario entre PPP Secrets y el servicio de Notakey, o el teléfono nunca se registró en esta aplicación concreta.
- Llega la push pero no puede aprobarla: probablemente esté aprobando desde el mismo dispositivo que marca la VPN, y la regla de descarte de la lista de pendientes está bloqueando el tráfico de aprobación. Añada la regla de aceptar del paso 5, o apruebe desde un dispositivo que no esté dentro del túnel.
- El texto de la solicitud sale ilegible o la solicitud falla: la biblioteca que analiza el JSON no admite paréntesis (y posiblemente otros signos de puntuación especiales) en el mensaje de autenticación. Mantenga el texto del mensaje sencillo.
- Funciona para un usuario pero no para otro: confirme la asignación de perfil del segundo usuario; solo los secrets que apuntan al perfil de 2FA reciben el tratamiento.
Dónde encaja esto
Este enfoque basado en scripts es la vía más rápida al 2FA en una VPN de MikroTik y no requiere infraestructura adicional. Si más adelante se le queda pequeño —muchos routers, otros proveedores de VPN o una política centralizada—, el mismo servidor Notakey admite una configuración basada en RADIUS en la que un auth proxy se encarga del flujo de aprobación en lugar de los scripts del router.