Tvåfaktorsautentisering av VPN-användare via MikroTik och SMS

Hallå kollegor! Idag, när intensiteten av passioner kring "fjärrarbete" avtog lite, majoriteten av administratörerna vann uppgiften att fjärråtkomst för anställda till företagsnätverket, det är dags att dela med mig av min långvariga erfarenhet av att förbättra VPN-säkerheten. Den här artikeln kommer inte att vara på modet nu IPSec IKEv2 och xAuth. Det handlar om att bygga ett system. tvåfaktorsautentisering (2FA) VPN-användare när MikroTik fungerar som en VPN-server. Nämligen när "klassiska" protokoll som PPP används.

Tvåfaktorsautentisering av VPN-användare via MikroTik och SMS

Idag ska jag berätta hur du skyddar MikroTik PPP-VPN även om användarkontot är "kapat". När detta system introducerades för en av mina kunder beskrev han kortfattat det som "ja, nu är det precis som på en bank!".

Metoden använder inte externa autentiseringstjänster. Uppgifterna utförs internt av routern själv. Ingen kostnad för den anslutande klienten. Metoden fungerar för både PC-klienter och mobila enheter.

Det allmänna skyddssystemet är som följer:

  1. Den interna IP-adressen för en användare som framgångsrikt har anslutit till VPN-servern är automatiskt grålistad.
  2. Anslutningshändelsen genererar automatiskt en engångskod som skickas till användaren med någon av de tillgängliga metoderna.
  3. Adresserna i den här listan har begränsad tillgång till lokala nätverksresurser, med undantag för tjänsten "autentisering", som väntar på att få ett engångslösenord.
  4. Efter att ha presenterat koden har användaren tillgång till nätverkets interna resurser.

första det minsta problemet jag hade att möta var att lagra kontaktinformation om användaren för att skicka honom 2FA-koden. Eftersom det är omöjligt att skapa godtyckliga datafält som motsvarar användare i Mikrotik, användes det befintliga "kommentar"-fältet:

/ppp-hemligheter lägg till namn=Petrov-lösenord=4M@ngr! comment="89876543210"

andra problemet visade sig vara allvarligare - valet av väg och metod för att leverera koden. Tre system är för närvarande implementerade: a) SMS via USB-modem b) e-post c) SMS via e-post tillgängligt för företagskunder hos den röda mobiloperatören.

Ja, SMS-system medför kostnader. Men om du tittar, "säkerhet handlar alltid om pengar" (c).
Jag personligen gillar inte upplägget med e-post. Inte för att det kräver att e-postservern är tillgänglig för klienten som autentiseras – det är inga problem att dela upp trafiken. Men om en klient slarvigt sparade både vpn- och e-postlösenord i en webbläsare och sedan förlorade sin bärbara dator, skulle angriparen få full tillgång till företagets nätverk från den.

Så det är bestämt - vi levererar en engångskod med hjälp av SMS.

tredje Problemet var var hur man genererar en pseudo-slumpmässig kod för 2FA i MikroTik. Det finns ingen analog till random()-funktionen i RouterOS-skriptspråket, och jag har sett flera kryckskript-pseudo-slumptalsgeneratorer tidigare. Jag gillade inte någon av dem av olika anledningar.

Faktum är att det finns en pseudo-slumpmässig sekvensgenerator i MikroTik! Den är dold från en ytlig blick i sammanhanget av /certificates scep-server. Det första sättet att få ett engångslösenord är enkelt och enkelt - med kommandot /certificates scep-server otp generera. Om vi ​​utför en enkel variabeltilldelningsoperation får vi ett arrayvärde som kan användas senare i skript.

Det andra sättet skaffa ett engångslösenord som också är enkelt att applicera - med hjälp av en extern tjänst random.org för att generera önskad typ av sekvens av pseudoslumptal. Här är en förenklad fribärande exempel på att få in data i en variabel:

Kod
: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

En begäran formaterad för konsolen (escapende specialtecken kommer att krävas i skriptets brödtext) får en sträng med sex siffror i variabeln $rnd1. Följande "put"-kommando visar helt enkelt variabeln i MikroTik-konsolen.

Det fjärde problemet som måste lösas snabbt - det är hur och var den anslutna klienten kommer att överföra sin engångskod i det andra steget av autentisering.

Tvåfaktorsautentisering av VPN-användare via MikroTik och SMS

Det måste finnas en tjänst på MikroTik-routern som kan acceptera koden och matcha den med en specifik klient. Om den angivna koden stämmer överens med den förväntade, bör kundens adress ingå i en viss "vit" lista, varifrån adresser tillåts åtkomst till företagets interna nätverk.

På grund av det dåliga utbudet av tjänster beslutades det att acceptera koder via http med hjälp av den inbyggda webproxyn i Mikrotik. Och eftersom brandväggen kan arbeta med dynamiska listor med IP-adresser, är det brandväggen som utför sökningen efter koden, matchar den med klientens IP och lägger till den i den "vita" listan med Layer7 regexp. Själva routern har tilldelats ett villkorligt DNS-namn "gw.local", en statisk A-post har skapats på den för utfärdande till PPP-klienter:

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

Fånga trafik från overifierade klienter på proxyn:
/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

I det här fallet har proxyn två funktioner.

1. Öppna tcp-anslutningar med klienter;

2. Om auktoriseringen lyckas, omdirigera klientens webbläsare till en sida eller bild som meddelar om framgångsrik autentisering:

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

Jag kommer att lista de viktiga konfigurationselementen:

  1. gränssnittslista "2fa" - en dynamisk lista över klientgränssnitt, från vilken trafik kräver bearbetning inom 2FA;
  2. adresslista "2fa_jailed" - "grå" lista över tunnel-IP-adresser för VPN-klienter;
  3. adresslista "2fa_approved" - "vit" lista över tunnel-IP-adresser för VPN-klienter som har klarat tvåfaktorsautentisering.
  4. brandväggskedja "input_2fa" - den kontrollerar tcp-paket för närvaron av en auktoriseringskod och matchar IP-adressen för kodavsändaren med den nödvändiga. Regler i kedjan läggs till och tas bort dynamiskt.

Ett förenklat flödesschema över paketbearbetning ser ut så här:

Tvåfaktorsautentisering av VPN-användare via MikroTik och SMS

För att komma in i Layer7-kontrollen av trafik från klienter från den "grå" listan som ännu inte har passerat det andra steget av autentisering, har en regel skapats i standardkedjan "input":

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

Låt oss nu börja fästa all denna rikedom till PPP-tjänsten. MikroTik låter dig använda skript i profiler (ppp-profil) och tilldela dem till händelserna med att upprätta och bryta en ppp-anslutning. PPP-profilinställningarna kan tillämpas på PPP-servern som helhet eller på enskilda användare. Samtidigt har profilen som tilldelats användaren prioritet och åsidosätter parametrarna för profilen som valts för servern som helhet med dess specificerade parametrar.

Som ett resultat av detta tillvägagångssätt kan vi skapa en speciell profil för tvåfaktorsautentisering och tilldela den inte till alla användare, utan bara till de som anser det nödvändigt att göra det. Detta kan vara relevant om du använder PPP-tjänster inte bara för att ansluta slutanvändare, utan samtidigt för att bygga plats-till-plats-anslutningar.

I den nyskapade specialprofilen använder vi det dynamiska tillägget av adressen och gränssnittet för den anslutna användaren till de "grå" listorna med adresser och gränssnitt:

winbox
Tvåfaktorsautentisering av VPN-användare via MikroTik och SMS

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

Det är nödvändigt att använda både "adresslista" och "gränssnittslista"-listor för att upptäcka och fånga upp trafik från icke-sekundära VPN-klienter i dstnat-kedjan (prerouting).

När förberedelserna är klara, ytterligare brandväggskedjor och en profil skapas, kommer vi att skriva ett script som ansvarar för autogenerering av 2FA-koden och individuella brandväggsregler.

Dokumentation wiki.mikrotik.com on PPP-Profile berikar oss med information om variabler som är associerade med PPP-klient connect-disconnect-händelser "Kör skript på användarinloggningshändelse. Dessa är tillgängliga variabler som är tillgängliga för händelseskriptet: user, local-address, remote-address, caller-id, called-id, interface". Några av dem är mycket användbara för oss.

Kod som används i profilen för PPP on-up anslutningshändelse

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

quot;local-address")
:log info (


quot;remote-address")
:log info (


quot;caller-id")
:log info (


quot;called-id")
:log info ([/int pptp-server get (


quot;interface") name])
#Объявляем свои локальные переменные
:local listname "2fa_jailed"
:local viamodem false
:local modemport "usb2"
#ищем автоматически созданную запись в адрес-листе "2fa_jailed"
:local recnum1 [/ip fi address-list find address=(


quot;remote-address") list=$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
:local vphone [/ppp secret get [find name=$user] comment]

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

# Отправляем SMS по выбранному каналу - USB-модем или email-to-sms
if $viamodem do={
/tool sms send phone-number=$vphone message=$msgboby port=$modemport }
else={
/tool e-mail send server=a.b.c.d [email protected] [email protected] subject="@".$vphone body=$msgboby }

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


quot;remote-address"))
/ip firewall layer7-protocol add name=(


quot;vcomment") comment=(


quot;remote-address") 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") protocol=tcp src-address=(


quot;remote-address") dst-limit=1,1,src-address/1m40s

Speciellt för dem som gillar att kopiera och klistra in utan att tänka på, varnar jag - koden är hämtad från testversionen och kan innehålla mindre stavfel. Det kommer inte att vara svårt för en förstående person att ta reda på exakt var.

När en användare kopplar från genereras en "On-Down"-händelse och motsvarande skript med parametrar anropas. Syftet med det här skriptet är att rensa upp brandväggsreglerna som skapats för den frånkopplade användaren.

Kod som används i profilen för PPP on-down anslutningshändelse

:local vcomment ("2fa_".(

quot;remote-address"))
/ip firewall address-list remove [find address=(


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


quot;remote-address") ] /ip firewall layer7-protocol remove [find name=$vcomment]
Du kan sedan skapa användare och tilldela alla eller några av dem till en tvåfaktorsautentiseringsprofil.

winbox
Tvåfaktorsautentisering av VPN-användare via MikroTik och SMS

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

Hur det ser ut på kundsidan.

När en VPN-anslutning upprättas får en Android/iOS-telefon/surfplatta med ett SIM-kort ett SMS så här:

SMS
Tvåfaktorsautentisering av VPN-användare via MikroTik och SMS

Om anslutningen upprättas direkt från telefonen/surfplattan kan du gå igenom 2FA helt enkelt genom att klicka på länken från meddelandet. Det är bekvämt.

Om VPN-anslutningen upprättas från en PC kommer användaren att behöva ange ett minimalt lösenordsformulär. En liten blankett i form av en HTML-fil ges till användaren när VPN konfigureras. Filen kan till och med skickas med post så att användaren sparar den och skapar en genväg på ett bekvämt ställe. Det ser ut så här:

Etikett på bordet
Tvåfaktorsautentisering av VPN-användare via MikroTik och SMS

Användaren klickar på genvägen, ett enkelt formulär för kodinmatning öppnas, som klistrar in koden i den öppnade URL:en:

Skärmformulär
Tvåfaktorsautentisering av VPN-användare via MikroTik och SMS

Den mest primitiva formen ges som exempel. De som vill kan modifiera själva.

2fa_login_mini.html

<html>
<head> <title>SMS OTP login</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head>
<body>
<form name="login" action="location.href='http://gw.local/otp/'+document.getElementById(‘text').value"  method="post"
 <input id="text" type="text"/> 
<input type="button" value="Login" onclick="location.href='http://gw.local/otp/'+document.getElementById('text').value"/> 
</form>
</body>
</html>

Om auktoriseringen lyckades kommer användaren att se MikroTik-logotypen i webbläsaren, vilket bör signalera framgångsrik autentisering:

Tvåfaktorsautentisering av VPN-användare via MikroTik och SMS

Observera att bilden returneras från den inbyggda MikroTik-webbservern med WebProxy Deny Redirect.

Jag antar att bilden kan anpassas med hjälp av "hotspot"-verktyget, ladda upp din egen version där och ställa in Deny Redirect URL till den med WebProxy.

En stor förfrågan till dem som försöker köpa den billigaste "leksaken" Mikrotik för 20 $ och ersätta en router på 500 $ med den - gör inte det. Enheter som "hAP Lite" / "hAP mini" (hemåtkomstpunkt) har en mycket svag CPU (smips), och det är troligt att de inte kommer att klara belastningen i affärssegmentet.

Varning! Denna lösning har en nackdel: när klienter ansluter eller kopplar från sker konfigurationsändringar, som routern försöker spara i sitt icke-flyktiga minne. Med ett stort antal klienter och frekventa anslutningar och frånkopplingar kan detta leda till försämring av det interna minnet i routern.

PS: Metoder för att leverera kod till klienten kan utökas och kompletteras så långt som dina programmeringsmöjligheter är tillräckliga. Du kan till exempel skicka meddelanden till telegram eller ... föreslå alternativ!

Jag hoppas att artikeln kommer att vara användbar för dig och kommer att bidra till att göra nätverken för små och medelstora företag lite säkrare.

Källa: will.com