Двухфактарная аўтэнтыфікацыя карыстальнікаў VPN з дапамогай MikroTik і SMS

Добры дзень калегі! Сёння, калі напал запалу вакол «выдалёнкі» трохі спаў, большасць адмінаў перамагло задачу выдаленага доступу супрацоўнікаў да карпаратыўнай сеткі, прыйшоў час падзяліцца маёй даўняй напрацоўкай па павышэнні бяспекі VPN. У гэтым артыкуле не будзе модных зараз IPSec IKEv2 і xAuth. Размова пойдзе аб пабудове сістэмы двухфактарнай аўтэнтыфікацыі (2FA) карыстальнікаў VPN, калі MikroTik выступае ў якасці VPN-сервера. А менавіта, калі выкарыстоўваюцца "класічныя" пратаколы тыпу PPP.

Двухфактарная аўтэнтыфікацыя карыстальнікаў VPN з дапамогай MikroTik і SMS

Сёння я распавяду як абараніць MikroTik PPP-VPN нават у выпадку «згону» карыстацкай улікоўкі. Калі гэтая схема была ўкаранёна аднаму з маіх заказчыкаў, ён ахарактарызаваў яго коратка "ну, зараз прама як у банку!".

Метад не выкарыстоўвае знешніх сэрвісаў-аўтэнтыфікатараў. Задачы выконваюцца ўнутранымі сродкамі самога маршрутызатара. Без выдаткаў для падключанага кліента. Спосаб працуе як для кліентаў PC, так і для мабільных прылад.

Агульная схема абароны выглядае наступным чынам:

  1. Унутраны IP-адрас карыстача паспяхова які падлучыўся да ў VPN-серверу, аўтаматычна пападае ў «шэры» спіс.
  2. Падзея падлучэння аўтаматычна генеруе аднаразовы код, які перасылаецца карыстачу адным з даступных спосабаў.
  3. Адрасам, якія знаходзяцца ў гэтым спісе абмежаваны доступ да рэсурсаў лакальнай сеткі, за выключэннем сэрвісу "аўтэнтыфікатара", які чакае атрыманне аднаразовага кода-пароля.
  4. Пасля прад'яўлення кода, карыстачу адчыняецца доступ да ўнутраных рэсурсаў сеткі.

Першая самая маленькая праблема з якой прыйшлося сутыкнуцца, гэта захоўванне кантактнай інфармацыі аб карыстачу для перасылкі яму кода 2FA. Паколькі, адвольных палёў дадзеных, якія адпавядаюць карыстачам у мікратыцы стварыць нельга, было скарыстана існае поле «comment»:

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

Другая праблема апынулася больш сур'ёзны - выбар шляху і спосабу дастаўкі кода. У дадзены момант рэалізаваны тры схемы: а) SMS праз USB-мадэм б) e-mail у) SMS via e-mail даступны для карпаратыўных кліентаў чырвонага сотавага аператара.

Так, схемы з SMS прыносяць выдаткі. Але калі разабрацца, "бяспека гэта заўсёды пра грошы" (з).
Схема з e-mail асабіста мне не падабаецца. Не таму, што патрабуе даступнасці паштовага сервера для аўтэнтыфікаванага кліента - гэта не праблема падзяліць трафік. Аднак, калі кліент бестурботна захоўваў паролі на і на vpn і на пошту ў браўзэры, а затым страціў свой наўтбук, зламыснік атрымае з яго поўны доступ да карпаратыўнай сеткі.

Такім чынам, вырашана - дастаўляем аднаразовы код пры дапамозе SMS-паведамленняў.

трэцяя праблема была ў тым, дзе і як у MikroTik згенераваць псеўдавыпадковы код для 2FA. У скрыптовай мове RouterOS няма аналогу функцыі random() і перш я бачыў некалькі мыліцавых скрыптовых генератараў псеўдавыпадковых лікаў. Ніводны з іх мне не спадабаўся па розных прычынах.

На самай справе, генератар псеўдавыпадковых паслядоўнасцяў у MikroTik ЁСЦЬ! Прыхаваны ён ад павярхоўнага погляду ў кантэксце /certificates scep-server. першы спосаб атрымаць аднаразовы пароль лёгкі і просты - камандай /certificates scep-server otp generate. Калі выканаць простую аперацыю прысваення зменнай, то мы атрымаем значэнне тыпу array, якое можна выкарыстоўваць у далейшым у скрыптах.

другі спосаб атрымання аднаразовага пароля які таксама лёгка прымяніць — выкарыстанне знешняга сэрвісу random.org для генерацыі жаданага віду паслядоўнасці псеўдавыпадковых лікаў. Вось спрошчаны кансольны прыклад атрымання дадзеных у зменную:

Код
: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

Запыт сфарматаваны для кансолі (у целе скрыпту запатрабуецца экранаванне спецзнакаў) атрымлівае радок з шасці знакаў-лічбаў у зменную $rnd1. Наступная каманда "put" проста адлюстроўвае зменную ў кансолі MikroTik.

Чацвёртая праблема, якую прыйшлося аператыўна вырашаць - гэта якім чынам і куды падлучаны кліент будзе перадаваць свой аднаразовы код на другой стадыі аўтэнтыфікацыі.

Двухфактарная аўтэнтыфікацыя карыстальнікаў VPN з дапамогай MikroTik і SMS

На роўтары MikroTik павінна існаваць служба здольная прыняць код і супаставіць яго з пэўным кліентам. Пры супадзенні прадстаўленага кода з чаканым адрас кліента павінен патрапіць у нейкі "белы" спіс, адрасам з якога дазволены доступ да ўнутранай сеткі кампаніі.

З прычыны небагатага выбару службаў, было прынятае рашэнне прымаць коды па http пры дапамозе ўбудаванага ў мікрацік webproxy. А паколькі фаервол умее працаваць з дынамічнымі спісамі IP-адрасоў, то пошук кода, супастаўленне яго з кліенцкім IP і занясенне ў "белы" спіс выконвае менавіта фаервол пасродкам Layer7 regexp. Самому маршрутызатару прысвоена ўмоўнае DNS-імя "gw.local", на ім створаны статычны А-запіс для выдачы PPP-кліентам:

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

Захоп на проксі трафіку неправераных кліентаў:
/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

У дадзеным выпадку ў проксі дзве функцыі.

1. Адкрываць tcp-злучэнні з кліентамі;

2. У выпадку паспяховай аўтарызацыі пераадрасаваць кліенцкі браўзэр на старонку або карцінку, якая паведамляе аб паспяховым праходжанні аўтэнтыфікацыі:

Proxy config
/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

Пералічу важныя элементы канфігурацыі:

  1. interface-list "2fa" – дынамічны спіс кліенцкіх інтэрфейсаў, трафік з якіх патрабуе апрацоўкі ў рамках 2FA;
  2. address-list "2fa_jailed" — "шэры" спіс тунэльных IP-адрасоў кліентаў VPN;
  3. address_list "2fa_approved" — "белы" спіс тунэльных IP-адрасоў кліентаў VPN, якія паспяхова прайшлі двухфактарную аўтэнтыфікацыю.
  4. ланцужок фаервала "input_2fa" - у ёй адбываецца праверка tcp-пакетаў на наяўнасць кода аўтарызацыі і супадзенне IP-адрасы адпраўніка кода з патрабаваным. Правілы ў ланцужок дадаюцца і выдаляюцца дынамічна.

Спрошчаная блок-схема апрацоўкі пакета выглядае так:

Двухфактарная аўтэнтыфікацыя карыстальнікаў VPN з дапамогай MikroTik і SMS

Для траплення ў праверку па Layer7 трафіку ад кліентаў з "шэрага" спісу яшчэ не прайшлі другі этап аўтэнтыфікацыі, у стандартным ланцужку "input" створана правіла:

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

Зараз пачнем прыкручваць усё гэтае багацце да сэрвісу PPP. MikroTik дазваляе выкарыстоўваць скрыпты ў профілях (ppp-profile) і прызначаць іх на падзеі ўсталёўкі і парыву ppp-злучэнні. Настройкі ppp-profile могуць прымяняцца як для PPP-сервера ў цэлым, так і для асобных карыстальнікаў. Пры гэтым прызначаны карыстачу profile мае прыярытэт перакрываючы сваімі зададзенымі параметрамі параметры profile абранага для сервера ў цэлым.

У выніку такога падыходу, мы можам стварыць спецыяльны профіль для двухфактарнай аўтэнтыфікацыі і прызначыць яго не ўсім карыстальнікам, а толькі тым, каму лічым патрэбным гэта зрабіць. Гэта можа быць актуальна ў выпадку, калі службы PPP у вас выкарыстоўваюцца не толькі для падлучэння канчатковых карыстачоў, але адначасова і для пабудовы site-to-site злучэнняў.

У ізноў створаным адмысловым профілі выкарыстаем дынамічнае даданне адрасу і інтэрфейсу які падлучыўся карыстача ў «шэрыя» спісы адрасоў і інтэрфейсаў:

winbox
Двухфактарная аўтэнтыфікацыя карыстальнікаў VPN з дапамогай MikroTik і SMS

Код
/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

Выкарыстоўваць сумесна спісы "address-list" і "interface-list" неабходна, каб вызначаць і захопліваць трафік ад якія не прайшлі другасную аўтарызацыю VPN-кліентаў у ланцужку dstnat (prerouting).

Калі падрыхтоўка скончана, дадатковыя ланцужкі фаервала і профіль створаны, напішам скрыпт які адказвае за аўтагенерацыю кода 2FA і асобных правіл фаервала.

Дакументацыя wiki.mikrotik.com на PPP-Profile ўзбагачае нас інфармацыяй аб зменных, звязаных з падзеямі падключэння-адключэння PPP-кліента «Execute script on user login-event. Ці існуюць variables, якія accessible для event script: user, local-address, remote-address, caller-id, called-id, interface». Некаторыя з іх нам вельмі спатрэбяцца.

Код, які выкарыстоўваецца ў профілі для падзеі падлучэння PPP on-up

#Логируем для отладки полученные переменные 
: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

Спецыяльна для аматараў бяздумна капіпасціць папярэджваю - код узяты з тэставай версіі і можа змяшчаць нязначныя ачапяткі. Разабрацца дзе менавіта які разумее чалавеку працы не складзе.

Пры адключэнні карыстальніка генеруецца падзея "On-Down" і выклікаецца адпаведны скрыпт з параметрамі. Задача гэтага скрыпту - пачысціць за сабой правілы фаервала, створаныя для які адключыўся карыстача.

Код, які выкарыстоўваецца ў профілі для падзеі падлучэння PPP on-down

: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]
Пасля гэтага можна ствараць карыстачоў і прызначаць усім ці некаторым з іх профіль з двухфактарнай аўтэнтыфікацыяй.

winbox
Двухфактарная аўтэнтыфікацыя карыстальнікаў VPN з дапамогай MikroTik і SMS

Код
/ppp secrets set [find name=Petrov] profile=2FA

Як гэта выглядае на баку кліента.

Пры ўсталёўцы VPN-злучэнні, на тэлефон/планшэт на андроід/iOS з сім-картай прыходзіць SMS прыкладна такога выгляду:

SMSка
Двухфактарная аўтэнтыфікацыя карыстальнікаў VPN з дапамогай MikroTik і SMS

Калі злучэнне ўсталявана непасрэдна з тэлефона/планшэта, то можна прайсці 2FA проста клікнуўшы па спасылцы з паведамлення. Гэта зручна.

Калі VPN-злучэнне усталёўваецца з PC, то для карыстача запатрабуецца мінімальная форма ўводу пароля. Невялікая форма ў выглядзе файла HTML перадаецца карыстачу пры наладзе VPN. Файлік можна нават па пошце пераслаць, каб карыстач захаваў яго ў сябе і стварыў цэтлік у зручным месцы. Прыкладна так гэта выглядае:

Цэтлік на стале
Двухфактарная аўтэнтыфікацыя карыстальнікаў VPN з дапамогай MikroTik і SMS

Карыстальнік пстрыкае мышкай па цэтліку, адчыняецца простая форма ўводу кода, якая ўставіць код у адчыняны URL:

Скрын формы
Двухфактарная аўтэнтыфікацыя карыстальнікаў VPN з дапамогай MikroTik і SMS

Форма самая прымітыўная, дадзеная для прыкладу. Жадаючыя могуць дапрацаваць пад сябе.

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>

Калі аўтарызацыя прайшла паспяхова, карыстач у браўзэры ўбачыць лога MikroTik, што павінна паслужыць сігналам аб паспяховай аўтэнтыфікацыі:

Двухфактарная аўтэнтыфікацыя карыстальнікаў VPN з дапамогай MikroTik і SMS

Заўважу, што карцінка вяртаецца з убудаванага web-сервера MikroTik з дапамогай WebProxy Deny Redirect.

Мяркую, карцінку можна кастамізаваць, выкарыстоўваючы прыладу «hotspot», загрузіўшы туды свой варыянт і задаўшы на яго Deny Redirect URL з WebProxy.

Вялікая просьба да тых, хто спрабуе купіўшы самы танны «цацачны» мікрацік за $20, замяніць ім маршрутызатар за $500 – не трэба так паступаць. Прылады тыпу "hAP Lite" / "hAP mini" (home access point) маюць вельмі слабы CPU (smips), і цалкам верагодна не справяцца з нагрузкай у бізнес-сегменце.

Увага! У дадзенага рашэння ёсць адзін мінус: пры падлучэнні-адключэнні кліентаў адбываюцца змены канфігурацыі, якую маршрутызатар спрабуе захоўваць у сваёй энерганезалежнай памяці. Пры вялікай колькасці кліентаў і частых падлучэннях-адключэннях, гэта можа прывесці да дэградацыі ўнутранага назапашвальніка ў маршрутызатары.

PS: метады дастаўкі кода кліенту могуць быць пашыраны і дапоўнены наколькі хопіць вашых магчымасцяў у праграмаванні. Напрыклад, можна адпраўляць паведамленні ў telegram ці… прапануйце варыянты!

Спадзяюся артыкул апынецца вам карысным і дапаможа зрабіць сеткі малога і сярэдняга бізнэсу яшчэ крыху бяспечней.

Крыніца: habr.com