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

Ciao colleghi! Oggi, mentre l'intensità del dibattito sulla "remotizzazione" si è un po' attenuata, la maggior parte degli amministratori ha risolto la questione dell'accesso remoto degli impiegati alla rete aziendale. È il momento di condividere un mio vecchio progetto volto a migliorare la sicurezza del VPN. In questo articolo non parlerò delle attuali mode come IPSec IKEv2 e xAuth. Discuteremo della costruzione di un sistema di autenticazione a due fattori (2FA) per gli utenti VPN, utilizzando MikroTik come server VPN. In particolare, utilizzeremo i protocolli "classici" come PPP.

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

Oggi spiegherò come proteggere MikroTik PPP-VPN anche in caso di "accesso non autorizzato" all'account utente. Quando questo schema fu implementato per uno dei miei clienti, lui lo ha descritto brevemente dicendo "ora è proprio come in banca!".

Il metodo non utilizza servizi di autenticazione esterni. Le funzioni sono eseguite tramite le risorse interne del router stesso. Senza costi per il cliente connesso. Il metodo funziona sia per client PC che per dispositivi mobili.

Lo schema di protezione generale appare come segue:

  1. L'indirizzo IP interno dell'utente che si è connesso con successo al server VPN finisce automaticamente nella "lista grigia".
  2. L'evento di connessione genera automaticamente un codice monouso, che viene inviato all'utente in uno dei modi disponibili.
  3. Gli indirizzi presenti in questo elenco hanno accesso limitato alle risorse della rete locale, ad eccezione del servizio 'autenticatore', che attende di ricevere il codice monouso.
  4. Dopo aver presentato il codice, l'utente ottiene accesso alle risorse interne della rete.

Primo Il problema più piccolo con cui ci si è dovuti confrontare è stato memorizzare le informazioni di contatto dell'utente per inviare il codice 2FA. Poiché non è possibile creare campi dati arbitrari corrispondenti agli utenti in Mikrotik, è stato utilizzato il campo esistente 'commento':

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

La seconda Il problema si è rivelato più serio: la scelta del percorso e del metodo di consegna del codice. Attualmente sono state implementate tre schemi: a) SMS tramite modem USB b) e-mail c) SMS tramite e-mail disponibile per i clienti aziendali del operatore mobile rosso.

Sì, gli schemi con SMS comportano dei costi. Ma se ci si pensa, 'la sicurezza è sempre una questione di soldi' (c).
Lo schema email non mi piace. Non perché richieda l'accesso al server di posta per il cliente autenticato — non è un problema separare il traffico. Tuttavia, se il cliente ha imprudentemente salvato le password per il VPN e per la posta nel browser e poi ha perso il laptop, un malintenzionato avrà accesso completo alla rete aziendale.

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

Terzo Il problema era in che punto e come generare un codice casuale in MikroTik per il 2FA.Nel linguaggio di scripting di RouterOS non esiste un'analoga funzione random() e in passato ho visto alcuni script di generazione di numeri pseudocasuali. Nessuno di essi mi è piaciuto per vari motivi.

In realtà, esiste un generatore di sequenze pseudocasuali in MikroTik! È nascosto alla vista superficiale nel contesto /certificates scep-server. Primo metodo Ottenere una password usa e getta è 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 potrà essere utilizzato in seguito negli script.

Secondo metodo ricevere una password temporanea che è anche facile da usare — utilizzo di un servizio esterno random.org per generare la sequenza desiderata di numeri pseudo-casuali. Ecco un esempio semplificato interfaccia console di come ottenere i 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» mostra 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 temporaneo nella seconda fase di autenticazione.

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

Nel router MikroTik deve esistere un servizio in grado di accettare il codice e associarlo a un client specifico. In caso di corrispondenza del codice fornito con quello atteso, l'indirizzo del client deve essere inserito in un qualche «lista bianca», gli indirizzi della quale hanno accesso alla rete interna dell'azienda.

Data la scarsa disponibilità di servizi, è stata presa la decisione di accettare i codici tramite http utilizzando il webproxy integrato in MikroTik. 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 lista "bianca" viene effettuata proprio dal firewall tramite Layer7 regexp. Al router è stato assegnato un nome DNS convenzionale "gw.local", ed è stata creata una registrazione A statica per fornire ai client PPP:

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

Cattura del traffico proxy di 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 a un'immagine che comunica il superamento della fase di autenticazione:

Configurazione Proxy
/ip proxy
imposta abilitato=sì porta=3128
/ip proxy access
aggiungi azione=nega disabilitato=no reindirizza-a=gw.local/mikrotik_logo.png src-indirizzo=0.0.0.0/0

Elencherò gli elementi importanti della configurazione:

  1. interface-list "2fa" — lista dinamica delle interfacce dei clienti 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. la catena del firewall «input_2fa» verifica i pacchetti tcp per la presenza di un codice di autorizzazione e la corrispondenza dell'indirizzo IP del mittente del codice con quello richiesto. Le regole vengono aggiunte e rimosse dinamicamente dalla catena.

Uno schema di flusso semplificato per l'elaborazione del pacchetto appare così:

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

Per rientrare nella verifica Layer 7 del traffico dai clienti nella lista «grigia» che non hanno ancora superato il secondo stadio di autenticazione, è stata creata una regola nella catena standard «input»:

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

Iniziamo ora ad integrare tutto questo nel servizio PPP. MikroTik consente di utilizzare script nei profili (ppp-profile) e di assegnarli ad eventi di connessione e disconnessione PPP. Le impostazioni del ppp-profile possono essere applicate sia al server PPP nel suo insieme, sia a singoli utenti. In questo caso, il profilo assegnato all'utente ha la priorità, sovrascrivendo i parametri di profilo definiti per il server nel suo complesso.

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

Nel nuovo profilo speciale utilizziamo l'aggiunta dinamica dell'indirizzo e dell'interfaccia dell'utente connesso nelle liste 'grigie' degli indirizzi e delle interfacce:

winbox
Autenticazione a due fattori per gli 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 proveniente da clienti VPN che non hanno superato l'autenticazione secondaria nella catena dstnat (prerouting).

Una volta completata la preparazione, creiamo catene aggiuntive del firewall e il profilo, scriviamo uno script responsabile della generazione automatica del codice 2FA e di regole firewall specifiche.

Documentazione wiki.mikrotik.com il PPP-Profile ci arricchisce con informazioni sulle variabili relative agli eventi di connessione e disconnessione dei clienti PPP. «Esegui script all'evento di accesso dell'utente. Queste sono le variabili disponibili accessibili per lo script dell'evento: utente, indirizzo-locale, indirizzo-remoto, id-chiamante, id-chiamato, interfaccia». Alcune di esse ci saranno molto utili.

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

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

"indirizzo locale")
:log info (

"indirizzo remoto")
:log info (

"id chiamante")
:log info (

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

"interfaccia") name])
#Объявляем свои локальные переменные
:local nome_lista "2fa_recluso"
:local viamodem false
:local porta_modem "usb2"
#ищем автоматически созданную запись в адрес-листе "2fa_jailed"
:local recnum1 [/ip fi indirizzo-lista trova indirizzo=(

"indirizzo remoto") lista=$nome_lista]

#получаем псевдослучайный код через 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
:local vtelefono [/ppp segreto ottieni [trova nome=$utente] commento]

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

# Отправляем SMS по выбранному каналу - USB-модем или email-to-sms
se $viamodem fare={
/tool sms send phone-number=$vphone message=$msgboby port=$modemport }
altrimenti={
/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)
:local vcommento ("2fa_".(

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

"vcommento") comment=(

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

"vcommento") protocollo=tcp src-address=(

"indirizzo remoto") dst-limit=1,1,src-address/1m40s


Specificamente per coloro che amano copiare e incollare senza pensare, avverto che il codice proviene da una versione di test e potrebbe contenere piccole imprecisioni. Un professionista sarà in grado di capire dove esattamente senza problemi.

Quando un utente viene disconnesso, viene generato un evento «On-Down» e viene chiamato lo script corrispondente con i parametri. Il compito di questo script è ripulire le regole del firewall create per l'utente disconnesso.

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

:local vcommento ("2fa_".(

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

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

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


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

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

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

Come appare dalla parte del cliente.

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

SMS
Autenticazione a due fattori per gli 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.

Quando una connessione VPN viene stabilita con un PC, l'utente avrà bisogno di un modulo di immissione della password minimale. Un piccolo modulo in formato HTML viene inviato all'utente durante la configurazione della VPN. Il file può anche essere inviato via email, consentendo all'utente di salvarlo e creare un collegamento in un luogo comodo. Ecco come appare:

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

L'utente clicca sul collegamento, si apre un semplice modulo per l'immissione del codice, che inserirà il codice nell'URL aperto:

Screenshot del modulo
Autenticazione a due fattori per gli utenti VPN tramite MikroTik e SMS

Il modulo è il più primitivo, fornito a titolo di esempio. Chi desidera può modificarlo secondo le proprie esigenze.

2fa_login_mini.html

<html>
<head> <title>Accesso tramite SMS OTP</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 di MikroTik, il che dovrebbe servire da segnale di avvenuta autenticazione:

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

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

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

Si prega di non tentare di sostituire un router da $500 con un microtik 'giocattolo' da $20. Dispositivi come 'hAP Lite'/'hAP mini' (home access point) hanno un processore molto debole (smips) e potrebbero non gestire il carico nel segmento business.

Attenzione! Questo approccio ha un inconveniente: quando i clienti si connettono e disconnettono, ci sono cambiamenti nella configurazione che il router cerca di salvare nella sua memoria non volatile. Con un gran numero di clienti e frequenti riconnessioni, ciò può portare a una degradazione della memoria interna del router.

P.S.: i metodi di consegna del codice ai clienti possono essere ampliati e arricchiti in base alle vostre capacità di programmazione. Ad esempio, è possibile inviare messaggi su telegram o... suggerite le vostre idee!

Spero che questo articolo sia utile e contribuisca 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