Tvåfaktorsautentisering för VPN-användare via MikroTik och SMS

Hej kollegor! Idag, när intensiteten kring "distansarbete" har avtagit något och de flesta administratörer har löst problemet med fjärråtkomst för anställda till det interna nätverket, är det dags att dela med mig av en långvarig lösning för att förbättra säkerheten i VPN. I den här artikeln kommer vi inte att fokusera på de modiga IPSec IKEv2 och xAuth. Vi kommer att diskutera hur man bygger ett system för tvåfaktorsautentisering (2FA) av VPN-användare, när MikroTik fungerar som VPN-server. Specifikt när "klassiska" protokoll som PPP används.

Tvåfaktorsautentisering för VPN-användare via MikroTik och SMS

Idag ska jag berätta hur man skyddar MikroTik PPP-VPN även vid "kapning" av en användarkonto. När detta system implementerades för en av mina kunder, beskrev han det kortfattat med "nu känns det verkligen som i en bank!".

Metoden använder inga externa autentiseringstjänster. Uppgifterna hanteras av routerens interna funktioner. Utan kostnader för den anslutna klienten. Metoden fungerar både för PC-kunder och mobilanvändare.

Den övergripande skyddsstrukturen ser ut som följande:

  1. Den interna IP-adressen för användaren som framgångsrikt kopplar upp sig mot VPN-servern hamnar automatiskt på en "grålista".
  2. Anslutningseventet genererar automatiskt en engångskod som skickas till användaren på ett av de tillgängliga sätten.
  3. IP-adresser som finns på denna lista får begränsad åtkomst till resurser i det lokala nätverket, med undantag för "autentiseringstjänsten" som väntar på att få ett engångskod-lösenord.
  4. Efter att koden har presenterats får användaren tillgång till interna nätverksresurser.

Första Det minsta problemet jag stötte på var att lagra kontaktinformationen om användaren för att kunna skicka koden för 2FA. Eftersom det inte går att skapa godtyckliga fält som motsvarar användarna i MikroTik, användes det befintliga fältet "kommentar":

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

Andra Problemet var faktiskt mer allvarligt - att välja metod och sätt för att leverera koden. För närvarande har tre scheman implementerats: a) SMS via USB-modem b) e-post c) SMS via e-post, tillgängligt för företagets kunder hos den röda mobiloperatören.

Ja, SMS-scheman medför kostnader. Men om man tänker efter är "säkerhet alltid en fråga om pengar".
Jag gillar inte schemat med e-post. Inte för att det kräver tillgång till e-postservern för den autentiserade klienten — det är inte ett problem att separera trafiken. Men om klienten vårdslöst har sparat lösenord på både VPN och e-post i webbläsaren och sedan förlorat sin bärbara dator får en illasinnad person full tillgång till det företagsnätverket.

Så, det är beslutat - vi skickar en engångskod via SMS.

Tredje Problemet var att var och hur man i MikroTik genererar en pseudorandom kod för 2FA.Det finns ingen motsvarighet till funktionen random() i skriptspråket RouterOS, och jag har tidigare sett flera klumpiga skriptgeneratorer för pseudorandomnummer. Ingen av dem tilltalade mig av olika anledningar.

Faktum är att det finns en pseudorandom sekvensgenerator i MikroTik! Den är gömd för den ytliga blicken inom kontexten /certificates scep-server. Den första metoden Att få en engångskod är enkelt — med kommandot /certificates scep-server otp generate. Genom att utföra en enkel tilldelningsoperation av en variabel får vi ett värde av typen array, som kan användas vidare i skripten.

Den andra metoden Att få en engångskod som också är lätt att använda — genom en extern tjänst random.org för att generera den önskade typen av sekvens av pseudorandomnummer. Här är ett förenklat konsol exempel för att få 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

Förfrågan formaterad för konsolen (i skriptets kropp krävs att specialtecken rymmas in) får en sträng av sex siffror i variabeln $rnd1. följande "put"-kommando visar helt enkelt variabeln i MikroTik-konsolen.

Det fjärde problemet, som fick lösas snabbt — är hur och dit den anslutna klienten kommer att skicka sin engångskod i det andra autentiseringsteget.

Tvåfaktorsautentisering för VPN-användare via MikroTik och SMS

Det måste finnas en tjänst på MikroTik-router som kan ta emot koden och matcha den med den specifika klienten. Om den angivna koden matchar den förväntade ska klientens adress hamna på en slags "vit" lista, adresser därifrån tillåts åtkomst till företagets interna nätverk.

På grund av det begränsade utbudet av tjänster, beslutades det att ta emot koder via http med hjälp av den inbyggda webproxy-funktionen i MikroTik. Eftersom brandväggen kan arbeta med dynamiska listor över IP-adresser, så utför brandväggen sökningen av koden, matchningen med klientens IP och inskrivning i "vita" listor genom Layer7 regexp. Routern har tilldelats det vilseledande DNS-namnet "gw.local", och en statisk A-post har skapats för att tilldela PPP-klienter:

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

Proxy-inspelning av trafik från obekräftade kunder:
/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 proxy:n två funktioner.

1. Öppna tcp-anslutningar med kunder;

2. Vid lyckad autentisering omdirigera klientens webbläsare till en sida eller bild som informerar om att autentiseringen har lyckats:

Proxy-konfiguration
/ip proxy
ställ in enabled=yes port=3128
/ip proxy access
lägg till action=deny disabled=no redirect-to=gw.local/mikrotik_logo.png src-address=0.0.0.0/0

Jag kommer att nämna viktiga konfigurationselement:

  1. interface-list "2fa" — en dynamisk lista över klienternas gränssnitt vars trafik behöver bearbetas inom ramen för 2FA;
  2. address-list "2fa_jailed" — en "grå" lista över tunnelerade IP-adresser från VPN-kunder;
  3. address_list "2fa_approved" — en "vit" lista över tunnelerade IP-adresser från VPN-kunder som framgångsrikt har genomgått tvåfaktorsautentisering.
  4. brandvägskedjan "input_2fa" — här kontrolleras tcp-paket för förekomst av autentiseringskod och att avsändarens IP-adress överensstämmer med den som krävs. Regler i kedjan läggs till och tas bort dynamiskt.

Det förenklade blockdiagrammet för paketbearbetning ser ut så här:

Tvåfaktorsautentisering för VPN-användare via MikroTik och SMS

För att trafik från kunder i den "grå" listan som ännu inte genomgått andra autentiseringsteget ska kontrolleras med Layer7, skapades en regel i den standardiserade kedjan "input":

Kod
/ip firewall filter add chain=input !src-address-list=2fa_godkänd action=hoppa hoppa-mål=input_2fa

Nu börjar vi koppla allt detta till PPP-tjänsten. MikroTik tillåter användning av skript i profiler (ppp-profile) och tilldelning av dem till händelser för etablering och avbrott av PPP-anslutningar. Inställningar för ppp-profile kan tillämpas både för hela PPP-servern och för enskilda användare. Den tilldelade profilen för en användare har prioritet och övertrumfar parametrarna för den profil som valts för servern i stort.

Genom den här metoden kan vi skapa en speciell profil för tvåfaktorsautentisering och tilldela den inte till alla användare, utan bara till dem vi anser behöver det. Detta kan vara relevant om PPP-tjänster används inte bara för att koppla upp slutanvändare, utan även för att bygga site-to-site-anslutningar.

I den nyligen skapade specialprofilen använder vi dynamisk tillägg av adress och gränssnitt för den anslutna användaren i "grå" listor av adresser och gränssnitt:

winbox
Tvåfaktorsautentisering för 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

Att använda både "address-list" och "interface-list" tillsammans är nödvändigt för att identifiera och fånga trafik från VPN-klienter som inte har genomgått sekundär autentisering i dstnat-kedjan (prerouting).

När förberedelserna är klara och ytterligare brandväggskedjor och profiler har skapats, skriver vi ett skript som ansvarar för autogenerering av 2FA-kod och specifika brandväggsregler.

Dokumentationen wiki.mikrotik.com om PPP-Profile berikar oss med information om variabler relaterade till händelser vid inloggning och utloggning av PPP-klienter "Kör skript vid användarinloggningshändelse. Dessa är tillgängliga variabler som är tillgängliga för händelseskryptet: användare, lokal-adress, fjärr-adress, caller-id, called-id, gränssnitt". Några av dem kommer att vara mycket användbara för oss.

Koden som används i profilen för PPP inloggningshändelsen on-up

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

"lokal-adress")
:logginfo (

"avlägsen-adress")
:logginfo (

"uppringar-id")
:logginfo (

"uppringd-id")
:logginfo ([/int pptp-server get (

"gränssnitt") namn])
#Объявляем свои локальные переменные
:lokal listnamn "2fa_fängslad"
:lokal viamodem falsk
:lokal modemport "usb2"
#ищем автоматически созданную запись в адрес-листе "2fa_jailed"
:lokal recnum1 [/ip fi address-list find address=(

"avlägsen-adress") lista=$listnamn]

#получаем псевдослучайный код через 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
:lokal vtelefon [/ppp hemlighet hämta [finna namn=$användare] kommentar]

#Готовим тело сообщения. Если клиент подключается к VPN прямо с телефона ему достаточно
#будет перейти прямо по ссылке из полученного сообщения
:lokal meddelande ("Din kod: " . $comm1 . "n Eller öppna länk http://gw.local/otp/" . $comm1 . " /")

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

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

"avlägsen-adress"))
/ip firewall layer7-protocol add name=(

"vkommentar") kommentar=(

"avlägsen-adress") 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=(

"vkommentar") protokoll=tcp src-adress=(

"avlägsen-adress") dst-limit=1,1,src-adress/1m40s


Speciellt för dem som hastigt kopierar och klistrar in, varnas — koden är hämtad från testversionen och kan innehålla mindre tryckfel. Att förstå var exakt kommer inte att vara en svårighet för den som är insatt.

Vid användarens avstängning genereras händelsen "On-Down" och det motsvarande skriptet anropas med parametrar. Uppgiften för detta skript är att rensa upp brandväggsregler som skapades för den avstängda användaren.

Koden som används i profilen för PPP avstängningshändelsen on-down

:lokal vkommentar ("2fa_" . (

"avlägsen-adress"))
/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]


Efter detta kan användare skapas och tilldelas en profil med tvåfaktorsautentisering, antingen till alla eller vissa av dem.

winbox
Tvåfaktorsautentisering för VPN-användare via MikroTik och SMS

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

Hur detta ser ut på klientens sida.

Vid upprättande av VPN-anslutning, på en telefon/tablet med Android/iOS med SIM-kort, kommer ett SMS av ungefär följande typ:

SMS:et
Tvåfaktorsautentisering för VPN-användare via MikroTik och SMS

Om anslutningen upprättas direkt från telefonen/tableten kan man enkelt genomföra 2FA genom att klicka på länken i meddelandet. Det är bekvämt.

Om VPN-anslutningen upprättas med en PC, kommer användaren att behöva ett minimum av inmatningsformuläret för lösenord. En liten HTML-form överförs till användaren vid inställningen av VPN. Filen kan till och med skickas via e-post så att användaren kan spara den och skapa en genväg på en bekväm plats. Så här ser det ut:

Genväg på skrivbordet
Tvåfaktorsautentisering för VPN-användare via MikroTik och SMS

Användaren klickar på genvägen, en enkel inmatningsform öppnas där koden ska klistras in i den öppnade URL:en:

Skärm av formuläret
Tvåfaktorsautentisering för VPN-användare via MikroTik och SMS

Formuläret är mycket primitivt och ges bara som exempel. Den som önskar kan anpassa det för sig själv.

2fa_login_mini.html

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

Om inloggningen lyckas kommer användaren att se MikroTik-logotypen i webbläsaren, vilket bör signalera att autentiseringen har lyckats:

Tvåfaktorsautentisering för VPN-användare via MikroTik och SMS

Jag påpekar att bilden returneras från MikroTiks inbyggda webserver via WebProxy Deny Redirect.

Jag tror att bilden kan anpassas genom att använda verktyget "hotspot", ladda upp sin egen version och ställa in Deny Redirect URL med WebProxy.

En stor vänlig begäran till dem som försöker byta ut den billigaste "leksak" MikroTik för $20 mot en router för $500 — gör inte så. Enheter som "hAP Lite"/"hAP mini" (home access point) har en mycket svag CPU (smips) och kommer sannolikt inte att klara av belastningen i företagssektorn.

Varning! Det finns en nackdel med denna lösning: vid anslutning och frånkoppling av klienter sker förändringar i konfigurationen 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 nedbrytning av den interna lagringsenheten i routern.

P.S.: metoder för att leverera koden till kunden kan utvidgas och kompletteras så långt era programmeringsmöjligheter räcker. Till exempel kan man skicka meddelanden till telegram eller... kom gärna med förslag!

Jag hoppas att artikeln blir till nytta och hjälper till att göra nätverken för små och medelstora företag lite säkrare.

Källa: habr.com

Köp pålitlig webbhotell med DDoS-skydd, VPS VDS-servrar 🔥 Köp pålitlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster