Questa guida vi porta da una semplice VPN MikroTik a una in cui ogni accesso deve essere approvato con un tap nell’app Notakey Authenticator, usando nient’altro che lo scripting di RouterOS. In questa configurazione non c’è alcun server RADIUS, nessun auth proxy e niente da distribuire nella vostra rete oltre al router che avete già.
Tutti gli script provengono dal repository ufficiale
notakey/mikrotik-2fa-vpn.
Come funziona
Comprendere il flusso rende ovvio ogni passaggio successivo:
- L’utente compone la VPN e si autentica con nome utente e password come al
solito. La sessione PPP si attiva, ma il firewall blocca immediatamente tutto
il suo traffico, perché il suo indirizzo finisce in un elenco di indirizzi
vpn_pending. - Scatta lo script up del profilo PPP. Chiama il vostro Notakey Authentication Server, che invia una richiesta di approvazione al telefono dell’utente: «Effettuare l’accesso come <user> da <caller IP>?»
- Se l’utente approva entro il timeout (60 secondi), lo script rimuove il suo
indirizzo da
vpn_pending: il blocco del firewall si toglie e il traffico scorre. - Se l’utente rifiuta o la richiesta scade, lo script termina la sessione PPP. La sola password non è mai stata sufficiente.
Prerequisiti
- RouterOS 6.46.4 o più recente (gli script funzionano anche su RouterOS 7.x).
- Una VPN basata su PPP funzionante sul router (L2TP/IPsec, PPTP o SSTP) a cui gli utenti possono già connettersi con nome utente e password.
- Un Notakey Authentication Server raggiungibile dal router. È sufficiente il piano cloud gratuito su signup.notakey.com (primi 6 utenti gratuiti), oppure l’ appliance on-premise (primi 10 utenti gratuiti).
- Un telefono iOS o Android con l’app Notakey Authenticator.
Passaggio 1 – Preparate il lato Notakey
- Nella vostra dashboard Notakey, create una nuova applicazione (servizio) per la VPN: assegnatele un nome riconoscibile, ad esempio «Office VPN»; è questo nome che gli utenti vedono sul telefono.
- Copiate l’Access ID dell’applicazione (un UUID): lo incollerete nello script del router al passaggio 4.
- Create l’utente (o collegate la vostra sorgente utenti) e configurate un requisito di registrazione, poi registrate il telefono: installate Notakey Authenticator, aggiungete il vostro servizio e completate la registrazione.
Il nome utente in Notakey deve corrispondere esattamente al nome utente della
VPN: lo script del router usa il nome utente PPP per indirizzare la notifica
push. john sul router e john.doe in Notakey falliranno silenziosamente.
Passaggio 2 – Installate la libreria JParseFunctions
Gli script di RouterOS non sanno analizzare il JSON in modo nativo; questa libreria (dal progetto mikrotik-json-parser) colma la lacuna.
In WinBox o WebFig, andate su System → Scripts, create un nuovo script
denominato esattamente JParseFunctions, lasciate le caselle dei criteri sui
valori predefiniti (non serve alcun privilegio speciale) e incollate l’intero
contenuto del
file JParseFunctions
di quel progetto.
Passaggio 3 – Installate la libreria NotakeyFunctions
Stessa procedura: create un secondo script denominato esattamente
NotakeyFunctions e incollate il contenuto di
NotakeyFunctions.lua
dal repository Notakey. È il client che dialoga con l’API Notakey: crea la
richiesta di autenticazione e interroga in attesa della risposta dell’utente.
I nomi degli script contano: lo script del profilo, nel passaggio successivo, carica entrambe le librerie per nome.
Passaggio 4 – Collegate gli script up/down a un profilo PPP
Aprite il profilo PPP della vostra VPN (PPP → Profiles), oppure createne uno dedicato in modo che la 2FA si applichi solo agli utenti selezionati durante i test.
- Nella scheda General, impostate Address List su
vpn_pending. Ogni nuova connessione che usa questo profilo vede ora il proprio indirizzo aggiunto a quell’elenco nel momento in cui la sessione si attiva. - Nella scheda Scripts, incollate lo script On Up qui sotto (da
PppProfileScript.lua) nel riquadro On Up, modificando due valori per il vostro ambiente:ntkHost, l’hostname del vostro server Notakey (senzahttps://), entkAccessId, l’Access ID dell’applicazione copiato al passaggio 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
}
Lo script On Down dello stesso file si limita a registrare la disconnessione: incollatelo nel riquadro On Down per avere log puliti, oppure omettetelo.
Il timeout di approvazione (authTtl) è di 60 secondi: abbastanza da tirare
fuori il telefono dalla tasca, abbastanza breve perché un accesso bloccato non
tenga aperta una sessione a metà per sempre.
Passaggio 5 – Aggiungete le regole del firewall
La regola di drop è ciò che dà un senso concreto all’elenco pending:
/ip firewall filter
add chain=forward src-address-list=vpn_pending action=drop \
comment="Block VPN clients pending 2FA approval"
Collocatela sopra le vostre regole generali di autorizzazione VPN, in modo che
prevalga finché l’approvazione è pendente. Se i client VPN devono essere bloccati
anche nell’accesso al router stesso, replicate la regola nella catena input.
Un caso particolare: se l’approvazione avviene sullo stesso dispositivo che compone la VPN (il telefono stesso è il client VPN), il traffico di approvazione deve poter raggiungere il server Notakey mentre tutto il resto è ancora bloccato. Aggiungete una regola di accept sopra il drop:
/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"
(Approvare da un secondo dispositivo, con il telefono che approva mentre un
portatile compone la connessione, non richiede alcuna regola aggiuntiva: il router
interroga da sé l’API Notakey, e il proprio traffico non è soggetto alla catena
forward.)
Passaggio 6 – Assegnate il profilo e collaudate
Puntate il vostro utente VPN (PPP → Secrets) al profilo del passaggio 4, poi componete la VPN da un client:
- Il tunnel si connette, ma non instrada nulla: siete in
vpn_pending. - Entro un secondo o due, la notifica push arriva sul telefono.
- Approvate → il traffico inizia a scorrere. Rifiutate o ignorate → allo scadere del timeout la sessione cade.
Osservate quanto accade in Log (gli script registrano ogni richiesta ed
esito) e in IP → Firewall → Address Lists, dove l’indirizzo del client compare
in vpn_pending e scompare all’approvazione.
Risoluzione dei problemi
- Non arriva alcuna push: quasi sempre un nome utente non corrispondente tra PPP Secrets e il servizio Notakey, oppure il telefono non è mai stato registrato a questa specifica applicazione.
- La push arriva ma non riuscite ad approvarla: probabilmente state approvando dallo stesso dispositivo che compone la VPN, e la regola di drop dell’elenco pending sta bloccando il traffico di approvazione. Aggiungete la regola di accept del passaggio 5, oppure approvate da un dispositivo che non sia dentro il tunnel.
- Il testo della richiesta appare corrotto o la richiesta fallisce: la libreria di parsing JSON non gestisce le parentesi (ed eventualmente altri segni di punteggiatura speciali) nel messaggio di autenticazione. Mantenete il testo del messaggio semplice.
- Funziona per un utente ma non per un altro: verificate l’assegnazione del profilo del secondo utente; solo i secret che puntano al profilo 2FA ricevono il trattamento.
Dove si colloca
Questo approccio basato su script è la via più rapida per la 2FA su VPN MikroTik e non richiede alcuna infrastruttura aggiuntiva. Se in seguito ne uscirete (molti router, altri fornitori di VPN o una policy centralizzata), lo stesso server Notakey consente una configurazione basata su RADIUS in cui un auth proxy gestisce il flusso di approvazione al posto degli script del router.