Autenticazione a due fattori per utenti VPN tramite MikroTik e SMS

Ciao colleghi! Oggi, quando la tensione attorno al lavoro da remoto si è un po' allentata, la maggior parte degli amministratori ha risolto il problema dell'accesso remoto dei dipendenti alla rete aziendale. È giunto il momento di condividere il mio lungo sviluppo per migliorare la sicurezza della VPN. In questo articolo non parlerò dei trendy IPSec IKEv2 e xAuth. Tratteremo della creazione di un sistema di autenticazione a due fattori (2FA) per gli utenti VPN, quando MikroTik funge da server VPN. In particolare, quando si utilizzano protocolli "classici" come PPP.

Autenticazione a due fattori per utenti VPN tramite MikroTik e SMS

Oggi vi dirò come proteggere MikroTik PPP-VPN anche in caso di "furto" dell'account utente. Quando questo schema è stato implementato per uno dei miei clienti, lo ha descritto brevemente come "ora è proprio come in banca!".

Il metodo non utilizza servizi di autenticazione esterni. I compiti vengono eseguiti con gli strumenti interni del router stesso. Senza costi per il cliente connesso. Il metodo funziona sia per i client PC che per i dispositivi mobili.

Lo schema generale di protezione è il seguente:

  1. L'indirizzo IP interno dell'utente che si è connesso con successo al server VPN finisce automaticamente in una "lista grigia".
  2. L'evento di connessione genera automaticamente un codice usa e getta, che viene inviato all'utente con uno dei metodi disponibili.
  3. Gli indirizzi in questa lista hanno accesso limitato alle risorse della rete locale, ad eccezione del servizio "autenticatore", che attende il ricevimento del codice usa e getta.
  4. Dopo aver presentato il codice, all'utente viene concessa l'accesso alle risorse interne della rete.

La prima Il problema più piccolo che ho dovuto affrontare è stato conservare le informazioni di contatto dell'utente per inviare il codice 2FA. Poiché non è possibile creare campi dati arbitrari per gli utenti in MikroTik, è stato utilizzato il campo esistente "commento":

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

Secondo il problema si è rivelato più serio: la scelta del percorso e del metodo di consegna del codice. Al momento sono state realizzate tre modalità: a) SMS tramite modem USB b) e-mail c) SMS tramite e-mail disponibile per i clienti aziendali dell'operatore mobile rosso.

Sì, le modalità SMS comportano dei costi. Ma se ci pensiamo, "la sicurezza è sempre una questione di soldi" (c).
Lo schema con l'e-mail non mi piace affatto. Non perché richieda l'accessibilità del server di posta per il client autenticato, questo non è un problema per separare il traffico. Tuttavia, se il client ha inconsapevolmente salvato le password sia per la VPN che per la posta nel browser e poi ha perso il proprio laptop, l'attaccante avrà accesso completo alla rete aziendale.

Quindi, è deciso: invieremo un codice monouso tramite SMS.

Terzo il problema era dove e come generare in MikroTik un codice pseudo-casuale per 2FA. Nel linguaggio di scripting di RouterOS non esiste una funzione equivalente a random() e in precedenza ho visto diversi script di generatori di numeri pseudo-casuali, ma nessuno di essi mi è piaciuto per vari motivi.

In realtà, c'è un generatore di sequenze pseudo-casuali in MikroTik! È nascosto da uno sguardo distratto nel contesto /certificates scep-server. Primo modo ottenere una password monouso è facile e semplice — con il comando /certificates scep-server otp generate. Se eseguiamo una semplice operazione di assegnazione a una variabile, otterremo un valore di tipo array, che può essere utilizzato successivamente negli script.

Secondo modo ottenere una password monouso che è anche facile da applicare — utilizzando un servizio esterno random.org per generare la sequenza di numeri pseudo-casuali desiderata. Ecco un esempio semplificato console di come ottenere dati in una variabile:

Codice
: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 richiesta formattata per la console (nel corpo dello script sarà necessario eseguire l'escaping dei caratteri speciali) ottiene una stringa di sei cifre nella variabile $rnd1. Il comando successivo 'put' visualizza semplicemente la variabile nella console di MikroTik.

Il quarto problema, che ha dovuto essere risolto rapidamente è come e dove il client connesso trasmetterà il proprio codice monouso nella seconda fase dell'autenticazione.

Autenticazione a due fattori per utenti VPN tramite MikroTik e SMS

Sul router MikroTik deve esistere un servizio capace di ricevere il codice e associarlo a un cliente specifico. Se il codice fornito corrisponde a quello atteso, l'indirizzo del cliente deve essere inserito in una sorta di "lista bianca", dai cui indirizzi è consentito l'accesso alla rete interna dell'azienda.

A causa della limitata scelta di servizi, è stata presa la decisione di accettare i codici tramite http utilizzando il webproxy integrato nel MikroTik. E poiché il firewall è in grado di lavorare con liste dinamiche di indirizzi IP, la ricerca del codice, il suo confronto con l'IP del cliente e l'inserimento nella whitelist vengono eseguiti dal firewall mediante Layer7 regexp. Al router è stato assegnato un nome DNS convenzionale "gw.local", su di esso è stata creata una registrazione A statica per la distribuzione ai client PPP:

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

Cattura del traffico proxy dei clienti non verificati:
/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

In questo caso, il proxy ha due funzioni.

1. Stabilire connessioni tcp con i clienti;

2. In caso di autorizzazione riuscita, reindirizzare il browser del cliente a una pagina o un'immagine che informa del superamento dell'autenticazione:

Configurazione Proxy
/ip proxy
set enabled=yes port=3128
/ip proxy access
add action=deny disabled=no redirect-to=gw.local./mikrotik_logo.png src-address=0.0.0.0/0

Elencherò gli elementi importanti della configurazione:

  1. interface-list "2fa" — lista dinamica delle interfacce client il cui traffico richiede elaborazione nell'ambito della 2FA;
  2. address-list "2fa_jailed" — lista "grigia" degli indirizzi IP tunnel dei clienti VPN;
  3. address_list "2fa_approved" — lista "bianca" degli indirizzi IP tunnel dei clienti VPN che hanno superato con successo l'autenticazione a due fattori.
  4. catena del firewall "input_2fa" — qui avviene il controllo dei pacchetti tcp per verificare la presenza del codice di autorizzazione e il confronto dell'indirizzo IP del mittente del codice con quello richiesto. Le regole vengono aggiunte e rimosse dalla catena in modo dinamico.

Uno schema semplificato della lavorazione del pacchetto appare così:

Autenticazione a due fattori per utenti VPN tramite MikroTik e SMS

Per consentire il controllo del traffico Layer7 dai clienti nella lista "grigia" che non hanno ancora superato la seconda fase di autenticazione, è stata creata una regola nella catena standard "input":

Codice
/ip firewall filter add chain=input !src-address-list=2fa_approved action=jump jump-target=input_2fa

Ora iniziamo ad integrare tutto questo nella service PPP. MikroTik consente di utilizzare script nei profili (ppp-profile) e di assegnarli a eventi di creazione e disconnessione delle connessioni ppp. Le impostazioni del ppp-profile possono essere applicate sia al server PPP in generale, sia a singoli utenti. In questo caso, il profilo assegnato all'utente ha la priorità, sovrapponendo i suoi parametri a quelli del profilo scelto per il server nel complesso.

Grazie a questo approccio, possiamo creare un profilo specifico per l'autenticazione a due fattori e assegnarlo non a tutti gli utenti, ma solo a coloro che riteniamo necessario. Questo può essere rilevante nel caso in cui i servizi PPP vengano utilizzati non solo per connettere utenti finali, ma anche per costruire connessioni site-to-site.

Nel nuovo profilo creato, utilizziamo l'aggiunta dinamica di indirizzi e interfacce dell'utente connesso nelle liste "grigie" di indirizzi e interfacce:

winbox
Autenticazione a due fattori per utenti VPN tramite MikroTik e SMS

Codice
/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

È necessario utilizzare insieme le liste "address-list" e "interface-list" per identificare e catturare il traffico degli utenti VPN che non hanno superato l'autenticazione secondaria nella catena dstnat (prerouting).

Quando la preparazione è completa, le catene aggiuntive del firewall e il profilo sono stati creati, scriveremo uno script responsabile dell'autogenerazione del codice 2FA e di regole specifiche del firewall.

Documentazione wiki.mikrotik.com sul PPP-Profile ci fornisce informazioni sulle variabili relative agli eventi di connessione e disconnessione del client PPP "Esegui lo script all'evento di accesso dell'utente. Queste sono le variabili disponibili accessibili per lo script dell'evento: user, local-address, remote-address, caller-id, called-id, interface". Alcune di esse ci saranno molto utili.

Codice utilizzato nel profilo per l'evento di connessione PPP on-up

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

("indirizzo locale")
:informazioni di log (

("indirizzo remoto")
:informazioni di log (

("id chiamante")
:informazioni di log (

("id chiamato")
:informazioni di log ([/int pptp-server get (

("interfaccia") nome])
#Объявляем свои локальные переменные
:nome lista locale "2fa_jailed"
:locale viamodem falso
:portamodem locale "usb2"
#ищем автоматически созданную запись в адрес-листе "2fa_jailed"
:recnum1 locale [/ip fi address-list trova indirizzo=(

("indirizzo remoto") 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
:telefono locale [/ppp segreto ottieni [trova nome=$user] commento]

#Готовим тело сообщения. Если клиент подключается к VPN прямо с телефона ему достаточно
#будет перейти прямо по ссылке из полученного сообщения
:msgboby locale ("Il tuo codice: ".$comm1."n Oppure apri il link http://gw.local/otp/".$comm1."/")

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

#Генерируем Layer7 regexp
vregexp locale ("otp/".$comm1)
:commento locale ("2fa_".(

("indirizzo remoto"))
/ip firewall layer7-protocol add name=(

("vcomment") commento=(

("indirizzo remoto") regexp=(

("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=(

("vcomment") protocollo=tcp indirizzo-sorgente=(

("indirizzo remoto") limite-dst=1,1,indirizzo-sorgente/1m40s


Specificamente per coloro che amano copiare e incollare senza riflessione, avviso che il codice è preso da una versione di prova e potrebbe contenere piccole imprecisioni. Per una persona che capisce, non sarà difficile capire esattamente dove.

Quando un utente si disconnette, viene generato un evento "On-Down" e viene chiamato il corrispondente script con i parametri. L'obiettivo di questo script è pulire le regole del firewall create per l'utente disconnesso.

Codice utilizzato nel profilo per l'evento di connessione PPP on-down

:commento locale ("2fa_".(

("indirizzo remoto"))
/ip firewall address-list remove [find address=(

"remote-address") list=2fa_approved]
/ip firewall filter remove [find chain="input_2fa" src-address=(

"remote-address") ]
/ip firewall layer7-protocol remove [find name=$vcomment]


Dopo ciò è possibile creare utenti e assegnare a tutti o ad alcuni di essi un profilo con autenticazione a due fattori.

winbox
Autenticazione a due fattori per utenti VPN tramite MikroTik e SMS

Codice
/ppp secrets set [find name=Petrov] profile=2FA

Come appare dal lato client.

Quando si stabilisce una connessione VPN, sul telefono/tablet Android/iOS con scheda SIM arriva un SMS di questo tipo:

SMS
Autenticazione a due fattori per utenti VPN tramite MikroTik e SMS

Se la connessione è stabilita direttamente dal telefono/tablet, è possibile completare il 2FA semplicemente cliccando sul link del messaggio. È comodo.

Se la connessione VPN viene stabilita con il PC, per l'utente sarà necessaria una forma minima di inserimento della password. Una piccola forma sotto forma di file HTML viene inviata all'utente durante la configurazione della VPN. Il file può anche essere inviato via email, affinché l'utente lo salvi e crei un collegamento in un luogo comodo. Ecco come appare:

Collegamento sul desktop
Autenticazione a due fattori per utenti VPN tramite MikroTik e SMS

L'utente clicca sul collegamento, si apre una semplice forma di inserimento del codice che incollerà il codice nell'URL aperto:

Screenshot della forma
Autenticazione a due fattori per utenti VPN tramite MikroTik e SMS

La forma è molto primitiva ed è fornita solo come esempio. Chi desidera può modificarla a proprio piacimento.

2fa_login_mini.html

<html>
<head> <title>Accesso OTP SMS</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head>
<body>
<form name="login" action="/it/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="it"/> 
<input type="button" value="Accesso" onclick="location.href='http://gw.local/otp/'+document.getElementById('text').value"/> 
</form>
</body>
</html>

Se l'autenticazione ha avuto successo, l'utente vedrà nel browser il logo MikroTik, il che dovrebbe servire come segnale di autenticazione avvenuta con successo:

Autenticazione a due fattori per utenti VPN tramite MikroTik e SMS

Nota che l'immagine viene restituita dal server web integrato di MikroTik tramite il WebProxy Deny Redirect.

Credo che l'immagine possa essere personalizzata utilizzando lo strumento "hotspot", caricando la propria versione e impostando su di essa l'URL Deny Redirect con WebProxy.

Un grande favore a coloro che cercano di sostituire un router da $500 con il più economico "giocattolo" MikroTik da $20 — non fatelo. Dispositivi come "hAP Lite"/"hAP mini" (home access point) hanno una CPU molto debole (smips) e potrebbero non essere in grado di gestire il carico nel settore aziendale.

Attenzione! Questa soluzione ha un piccolo svantaggio: quando i client si connettono e disconnettono, ci sono cambiamenti nella configurazione, che il router cerca di conservare nella propria memoria non volatile. Con un grande numero di client e connessioni/disconnessioni frequenti, questo può portare a una degradazione del supporto interno nel router.

P.S.: I metodi di consegna del codice ai clienti possono essere ampliati e arricchiti quanto basta con le vostre capacità di programmazione. Ad esempio, è possibile inviare messaggi su telegram o... suggerite varianti!

Spero che questo articolo possa esservi utile e contribuire a rendere le reti delle piccole e medie imprese un po' più sicure.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster