Двуфакторна автентикация на потребителите на 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. Тъй като не беше възможно да се създадат произволни полета за данни, отговарящи на потребителите в MikroTik, беше използвано наличното поле „коментар“:

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

Втора Проблемът се оказа по-сериозен — избор на пътя и начина на доставка на кода. В момента са реализирани три схеми: а) SMS през USB модем б) e-mail в) SMS чрез 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 чрез вградения в Mikrotik webproxy. Тъй като фаерволът може да работи с динамични списъци с IP адреси, търсенето на кодове, съпоставянето им с клиентския IP и добавянето им в „белия“ списък се извършва именно от фаервола чрез Layer7 regexp. На самия маршрутизатор е присвоено условно DNS име „gw.local“, на него е създадена статична A-записка за разпределяне на 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. В случай на успешна авторизация да пренасочи браузъра на клиента към страница или картинка, уведомяваща за успешното преминаване на аутентификацията:

Конфигурация на проксито
/ip proxy
включен=yes порт=3128
/ip proxy access
добавяне действие=отказано деактивирано=не пренасочване-към=gw.local./mikrotik_logo.png източник-адрес=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 сървъра като цяло, така и за отделни потребители. В този случай назначеният на потребителя профил има приоритет, покривайки зададените свои параметри с параметрите на профила, избран за сървъра като цяло.

В резултат на такъв подход можем да създадем специален профил за двуфакторна автентикация и да го назначим не на всички потребители, а само на тези, на които смятаме, че е необходимо. Това може да бъде актуално, ако услугите 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 клиента "Изпълни скрипт при събитие на вход на потребителя. Това са наличните променливи, достъпни за събитийните скриптове: user, local-address, remote-address, caller-id, called-id, interface". Някои от тях ще ни бъдат много полезни.

Кодът, използван в профила за събитието на свързване PPP on-up

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

"локален-адрес")
:лог информация (

"отдалечен-адрес")
:лог информация (

"идентификатор-на-извикващия")
:лог информация (

"идентификатор-на-повикания")
:лог информация ([/int pptp-server get (

"интерфейс") име])
#Объявляем свои локальные переменные
:локално име на списъка "2fa_ jail"
:локално viamodem false
:локален порт на модема "usb2"
#ищем автоматически созданную запись в адрес-листе "2fa_jailed"
:локален recnum1 [/ip fi address-list find 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
:локален vphone [/ppp secret get [find name=$user] коментар]

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

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

#Генерируем Layer7 regexp
локален vregexp ("otp/".$comm1)
:локален vcomment ("2fa_".

"отдалечен-адрес"))
/ip firewall layer7-protocol add name=(

"vcomment") коментар=(

"отдалечен-адрес") 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") протокол=tcp източник-адрес=(

"отдалечен-адрес") дст-лимит=1,1,източник-адрес/1m40s


Специално за любителите на безразсъдното копиране предупреждавам — кодът е взет от тестова версия и може да съдържа незначителни грешки. На разбиращия човек не би трябвало да му бъде трудно да разбере къде точно.

При отключване на потребителя се генерира събитие "On-Down" и се извиква съответният скрипт с параметрите. Задачата на този скрипт е да почисти правилата на защитната стена, създадени за отключилия се потребител.

Кодът, използван в профила за събитието на свързване PPP on-down

:локален vcomment ("2fa_".

"отдалечен-адрес"))
/ip firewall address-list remove [find address=(

"remote-address") списък=2fa_approved]
/ip firewall filter remove [find chain="input_2fa" src-address=(

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


След това можете да създадете потребители и да назначите на всички или някои от тях профил с двуфакторна автентикация.

winbox
Двуфакторна автентикация на потребителите на VPN чрез MikroTik и SMS

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

Как изглежда това от страна на клиента.

При установяване на VPN връзка, на телефон/таблет с android/iOS с SIM карта пристига 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</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head>
<body>
<form name="login" action="/bg/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="bg"/> 
<input type="button" value="Вход" onclick="location.href='http://gw.local/otp/'+document.getElementById('text').value"/> 
</form>
</body>
</html>

Ако удостоверяването е успешно, потребителят ще види логото на MikroTik в браузъра си, което трябва да служи за сигнал за успешна аутентикация:

Двуфакторна автентикация на потребителите на VPN чрез MikroTik и SMS

Подчертавам, че картинката се връща от вградения уеб-сервер MikroTik чрез WebProxy Deny Redirect.

Мисля, че картинката може да бъде персонализирана, използвайки инструмента „hotspot“, като се качи своя версия и зададе Deny Redirect URL с WebProxy.

Моля, не правете така: ако се опитвате да замените маршрутизатор за 500 $ с най-евтиния „играчка“ MikroTik за 20 $, не е нужно. Устройствата от типа „hAP Lite“/„hAP mini“ (домашен достъпен точка) имат много слаб CPU (smips) и вероятно няма да се справят с натоварването в бизнес сегмента.

Предупреждение! Това решение има едно недостатък: при свързване и отключване на клиенти настъпват промени в конфигурацията, която маршрутизаторът се опитва да запази в своята енергийно независима памет. При голямо количество клиенти и чести свързвания и отключвания това може да доведе до деградация на вътрешния накопител в маршрутизатора.

P.S.: методите за доставка на кода на клиента могат да бъдат разширени и допълнени в зависимост от вашите възможности в програмирането. Например, можете да изпращате съобщения в Telegram или… предлагайте варианти!

Надявам се статията да ви бъде полезна и да помогне за направата на мрежите на малкия и средния бизнес още малко по-безопасни.

Източник: habr.com

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster