Tere kolleegid! Täna, kui emotsioonid 'kaugtöö' ümber on veidi rahunenud, on enamik administraatoreid lahendanud töötajate kaugnägemise juurdepääsu ettevõtte võrgule ja on aeg jagada minu pikka aega arendatud lahendust VPN-i turvalisuse tõstmiseks. Käesolevas artiklis ei käsitleta moes olevaid IPSec IKEv2 ja xAuth. Jutt käib süsteemi loomisest VPN-i kasutajate jaoks, kui MikroTik toimib VPN-serverina. Nimelt, kui kasutatakse 'klassikalisi' protokolle nagu PPP.

Täna räägin, kuidas kaitsta MikroTik PPP-VPN-i isegi juhul, kui kasutajakonto 'varastatakse'. Kui see skeem rakendati ühe minu kliendi juurde, iseloomustas ta seda lühidalt: 'nüüd on see nagu pangas!'.
Meetod ei kasuta väliseid autentimisservise. Ülesanded täidetakse marsruuteri enda sisemiste vahenditega. Ilma kuludeta ühendatud kliendile. See meetod töötab nii PC-kliendi kui ka mobiilseadmete jaoks.
Üldine kaitse skeem näeb välja järgmine:
- Kasutaja, kes eduka ühenduse loob VPN-serveriga, sise-IP aadress põhimõtteliselt satub 'hallidesse' nimekirja.
- Ühenduse loomise sündmus genereerib automaatselt ühekordse koodi, mis saadetakse kasutajale ühe olemasoleva meetodi kaudu.
- Nendele aadressidele, mis on selles nimekirjas, on juurdepääs kohaliku võrgu ressurssidele piiratud, välja arvatud 'autentimisservise', mis ootab ühekordse koodi-kunni saamist.
- Koodi esitlemisel avatakse kasutajale juurdepääs võrgu siseressurssidele.
Esimene Väikseim probleem, millega tuli silmitsi seista, oli kasutaja kontaktandmete hoidmine 2FA koodi saatmiseks. Kuna MikroTik'is ei saa seonduda kasutajatega suvalisi andmevälju luua, kasutati olemasolevat välja 'comment':
/ppp secrets add name=Petrov password=4M@ngr! comment=«89876543210»
Teine Probleem osutus tõsiseks — koodi edastamise tee ja meetodi valideerimine. Hetkel on rakendatud kolm skeemi: a) SMS läbi USB-modemi b) e-post c) SMS e-posti kaudu, mis on ettevõtte klientide jaoks kergesti kättesaadav punase mobiilsideoperaatori poolt.
Jah, SMS-i skeemid toovad kaasa kulud. Kuid kui süveneda, 'turvalisus on alati rahast kinni' (c).
E-posti skeem mulle isiklikult ei meeldi. Mitte sellepärast, et see nõuab postiserveri kättesaadavust autentitava kliendi jaoks — see ei ole probleem liikluse jagamisel. Kuid kui klient on hooletult salvestanud paroolid nii VPN-is kui ka e-postis brauseris ja kaotab oma sülearvuti, pääseb kurjategija tema kaudu täielikult ettevõtte võrku.
Nii et on otsustatud — saadame ühekordse koodi SMS-sõnumite kaudu.
Kolmas Probleem oli selles, kus ja kuidas genereerida MikroTikis pseudojuhuslik kood 2FA jaoks. RouterOS-i skriptikeeles ei ole analooge funktsioonile random() ja olen varem näinud mitmeid häkkimisega skripte pseudojuhuslike arvude genereerimiseks. Ükski neist ei meeldinud mulle erinevatel põhjustel.
Tegelikult on MikroTikis pseudojuhuslike järjendite generaator! See on peidetud pinnapealselt vaadates kontekstis /certificates scep-server. Esimene viis Ühekordse parooli saamine on lihtne ja kerge — käsuga /certificates scep-server otp generate. Kui teeme lihtsa muutuja omistamise operatsiooni, saame massiivi tüüpi väärtuse, mida saab hiljem skriptides kasutada.
Teine meetod ükskordse parooli hankimine, mis on samuti lihtne rakendada — kasutada välist teenust soovitud tüüpi pseudojuhuslike arvude järjendi genereerimiseks. Siin on lihtsustatud konsoli näide andmete saamiseks muutujasse:
Kood
: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
Konsolile vormindatud päring (skripti kehas tuleb spetsiaalsete märkide eskaleerimine) saab kuue märgiga-nummerdatud stringi muutujasse $rnd1. Järgnev käsk «put» lihtsalt kuvab muutuja MikroTiki konsoolis.
Neljas probleem, mida tuli kiiresti lahendada — kuidas ja kuhu ühendatud klient edastab oma ühekordse koodi teise autentimise etapi jooksul.

MikroTiki ruuteris peab olema teenus, mis suudab vastu võtta koodi ja siduda selle konkreetse kliendiga. Kui antud kood ühtib oodatava koodiga, peab kliendi aadress minema mingisse «valgesse» nimekirja, mille aadressidele on lubatud juurdepääs ettevõtte sisevõrku.
Arvestades teenuste vähest valikut, otsustati võtta koodid http kaudu MikroTiki sisseehitatud webproxy abil. Kuna tulemüür suudab töötada dünaamiliste IP-aadresside loenditega, siis koodi otsimine, selle seostamine kliendi IP-ga ja lisamine "valgesse" nimekirja toimub just tulemüüri kaudu Layer7 regexp abil. Maršrutizaatorile on määratud tinglik DNS-nimi "gw.local", millele on loodud statiline A-kirje PPP-klientide väljastamiseks:
DNS
/ip dns static add name=gw.local address=172.31.1.1
Proksi kontrollimata klientide liikluse püüdmine:
/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
Antud juhul on proksil kaks funktsiooni.
1. Avada tcp-ühendused klientidega;
2. Edastada kliendi brauser pärast edukat autentimist leheküljele või pildile, mis teavitab edukast autentimisest:
Proksi konfiguratsioon
/ip proxy
sead lubatud=jah port=3128
/ip proxy access
lisage tegevus=keela keelatud=ei suuna=gateway.local./mikrotik_logo.png allika-aadress=0.0.0.0/0
Loetlen olulised konfiguratsiooni elemendid:
- interface-list "2fa" — dünaamiline nimekiri klientide liidestest, mille liiklus vajab töötlemist 2FA raames;
- address-list "2fa_jailed" — "hall" nimekiri VPN-klientide tunnelite IP-aadressidest;
- address_list "2fa_approved" — "valge" nimekiri VPN-klientide tunnelite IP-aadressidest, kes on edukalt läbinud kahefaktorilise autentimise.
- tulemüüri ketti "input_2fa" — selles toimub tcp-pakettide kontrollimine autoriseerimiskoodi olemasolu ja saatja koodi IP-aadressi sobivuse osas. Reeglid lisatakse ja eemaldatakse ketti dünaamiliselt.
Lihtsustatud paketi töötlemise plaan on järgmine:
Kuna klientide halli nimekirja liikluse kontrollimiseks Layer7 ei ole teist autentimise etappi läbitud, on standardse "input" ketti loodud reegel:
Kood
/ip firewall filter add chain=input !src-address-list=2fa_kinnitatud action=jump jump-target=input_2fa
Nüüd hakkame kogu seda rikkust PPP teenusele külge keerama. MikroTik võimaldab kasutada skripte profiilides (ppp-profile) ja määrata neid PPP-ühenduse loomise ja katkestamise sündmustele. PPP-profiili seadeid saab rakendada nii PPP-serverile tervikuna kui ka üksikutele kasutajatele. Määratud kasutaja profiil omab prioriteeti, ületades oma määratud parameetritega serveri jaoks valitud profiili parameetreid.
Selle lähenemise tulemuseks on see, et saame luua spetsiaalse profiili kahefaktorilise autentimise jaoks ja määrata selle mitte kõigile kasutajatele, vaid ainult neile, kellele me seda vajalikuks peame. See võib olla aktuaalne juhul, kui PPP teenuseid kasutatakse mitte ainult lõppkasutajate ühendamiseks, vaid ka site-to-site ühenduste loomiseks.
Uues loodud spetsiaalses profiilis kasutame dünaamilist aadressi ja ühendatud kasutaja liidese lisamist „hallidesse“ aadresside ja liideste nimekirjadesse:
winbox
Kood
/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
Peame koos kasutama nimekirju „address-list“ ja „interface-list“, et määratleda ja haarata VPN-klientide autoriseerimata liiklust dstnat ahelas (prerouting).
Kui ettevalmistus on lõppenud, ja täiendavad tulemüüriahelad ning profiil on loodud, kirjutame skripti, mis vastutab 2FA koodi ja eraldi tulemüürireeglite automaatse genereerimise eest.
PPP-profiili kohta saadud teave rikastab meid ühendamise ja katkestamise sündmustega seotud muutujate kohta „Käivita skript kasutaja sisenemise sündmuses. Need on saadaval olevad muutuja, mis on sündmuse skripti jaoks kergesti kätte saadavad: kasutaja, lokaal-aadress, kaug-aadress, caller-id, called-id, liides“. Mõned neist tulevad meile väga kasuks.
Kood, mis kasutatakse profiilis PPP ühendamise sündmuse puhul on "on-up".
#Логируем для отладки полученные переменные :log info (local-address")
:log info (remote-address")
:log info (caller-id")
:log info (called-id")
:log info ([/int pptp-server get (interface") name])
#Объявляем свои локальные переменные
:local listname "2fa_jailed"
:local viamodem false
:local modemport "usb2"
#ищем автоматически созданную запись в адрес-листе "2fa_jailed"
:local recnum1 [/ip fi address-list find address=(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 from=admin@mydomain.example to=mail2sms@mcommunicator.ru subject="@".$vphone body=$msgboby }#Генерируем Layer7 regexp
local vregexp ("otp\/" . $comm1)
:local vcomment ("2fa_" . (remote-address"))
/ip firewall layer7-protocol add name=(vcomment") comment=(
remote-address") 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") protocol=tcp src-address=(
remote-address") dst-limit=1,1,src-address/1m40s
Eriliselt neile, kes armastavad mõtlemata kopeerida, hoiatame — kood on võetud testversioonist ja võib sisaldada ebaolusid. Arusaamine, kus täpselt, ei valmista arusaajale raskusi.Kasutaja väljalülitamisel genereeritakse sündmus „On-Down“ ja kutsutakse vastav skript parameetritega. Selle skripti ülesanne on puhastada oma reeglid tulemüüris, mis on loodud väljunud kasutaja jaoks.
Kood, mis kasutatakse profiilis PPP ühendamise sündmuse puhul on "on-down".
:local vcomment ("2fa_" . (remote-address"))
/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]
Pärast seda saab luua kasutajaid ja määrata kõigile või osadele neist profiil kahefaktorilise autentimisega.winbox
Kood
/ppp secrets set [find name=Petrov] profile=2FAKuidas see kliendi poolel välja näeb.
VPN-ühenduse loomisel tuleb Android/iOS nutitelefoni või tahvelarvutisse sim-kaardiga SMS, mis on ligikaudu sellise sisuga:
SMS
Kui ühendus on loodud otse telefonist/tahvelarvutist, saab 2FA läbida lihtsalt, klõpsates sõnumis oleval lingil. See on mugav.
Kui VPN-ühendust luuakse PC-ga, vajab kasutaja minimaalset parooli sisestamise vormi. Väike HTML-fail edastatakse kasutajale VPN-i seadistamisel. Faili saab isegi e-posti teel saata, et kasutaja saaks selle endale salvestada ja mugavasse kohta otsetee luua. Umbes nii see välja näeb:
Otseteelaual
Kasutaja klõpsab otseteel, avaneb lihtne koodi sisestamise vorm, mis sisestab koodi avatud URL-i:
Vormi ekraanipilt
Vorm on kõige primitiivsem, antud näitena. Soovijad saavad seda enda vajadustele kohandada.
2fa_login_mini.html
<html> <head> <title>SMS OTP sisselogimine</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <form name="login" action="/et/location.href='http://gw.local/otp/'+document.getElementById(‘text').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="et"/> <input type="button" value="Logi sisse" onclick="location.href='http://gw.local/otp/'+document.getElementById('text').value"/> </form> </body> </html>Kui autentimine on edukalt läinud, näeb kasutaja brauseris MikroTiki logo, mis peaks olema signaaliks eduka autentimise kohta:
Mainin, et pilt saadetakse MikroTiki sisseehitatud veebiserverist koos WebProxy Deny Redirectiga.
Usun, et pilti on võimalik kohandada kasutades tööriista „hotspot”, laetud sinna oma versioon ja seadistades sellele Deny Redirect URL koos WebProxyga.
Suur palve neile, kes püüavad osta kõige odavamat „mänguasi” MikroTiki $20 eest, et asendada sellega $500 marsruutija — ärge nii käituda. Seadmed nagu „hAP Lite”/„hAP mini” (kodune juurdepunkt) omavad väga nõrka CPU-d (smips) ja ei pruugi äri-segmendis koormusega toime tulla.
Hoiatus! Selle lahenduse üks puudus: kliendid ühendudes ja lahti ühendudes toimub konfiguratsioonimuudatus, mida marsruutija püüab salvestada oma energiat säästvasse mällu. Suure arvu klientide ja sagedaste ühenduste-lahtiühenduste korral võib see põhjustada marsruutija sisemälu halvenemist.
P.S.: koodi edastamise meetodeid klientidele saab laiendada ja täiendada nii palju, kui teie programmeerimisvõimalused võimaldavad. Näiteks saab saata sõnumeid Telegramis või… pakkuda välja variante!
Loodan, et artikkel on teile kasulik ja aitab muuta väikeste ja keskmise suurusega ettevõtete võrgud veelgi turvalisemaks.
Allikas: habr.com




