Здравейте, колеги! Днес, когато страстите около "удаленката" малко поутихнаха, повечето администратори решиха задачата за отдален достъп на служителите до корпоративната мрежа. Време е да споделя моята стара разработка за повишаване на сигурността на VPN. В тази статия няма да става дума за модните в момента IPSec IKEv2 и xAuth. Реч ще е за изграждане на система на потребителите на VPN, когато MikroTik функционира като VPN сървър. По-специално, когато се използват "класическите" протоколи от типа PPP.

Днес ще ви разкажа как да защитите MikroTik PPP-VPN дори в случай на "угание" на потребителския акаунт. Когато тази схема беше внедрена при един от моите клиенти, той я описа с една дума: "Е, сега е точно като в банката!".
Методът не използва външни услуги за автентикация. Задачите се изпълняват от вътрешните средства на самия маршрутизатор. Без разходи за клиента, който се свързва. Методът работи както за PC клиенти, така и за мобилни устройства.
Общата схема за защита изглежда по следния начин:
- Вътрешният IP адрес на успешно свързания потребител с VPN сървъра автоматично попада в "сивия" списък.
- Събитието на свързване автоматично генерира еднократен код, който се изпраща на потребителя по един от наличните начини.
- На адресите, които са в този списък, е ограничен достъпът до ресурсите на локалната мрежа, освен до услугата "автентификатор", която очаква получаване на еднократния код-парола.
- След представянето на кода, на потребителя се открива достъп до вътрешните ресурси на мрежата.
Първа най-малкия проблем, с който се наложи да се сблъскам, беше съхранението на контактна информация за потребителя за изпращането на кода 2FA. Тъй като не могат да се създават произволни полета данни, които да отговарят на потребителите в MikroTik, беше използвано съществуващото поле "comment":
/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. Ако извършим проста операция за присвояване на променлива, ще получим стойност от тип масив, която може да се използва по-нататък в скриптовете.
Вторият метод получаване на еднократна парола, която също е лесна за прилагане — използването на външна услуга за генериране на желаната последователност от псевдослучайни числа. Ето опростен конзолен пример за получаване на данни в променлива:
Код
: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.
Четвъртият проблем, който трябваше бързо да решим — е как и къде свързаният клиент ще предава своя еднократен код на втория етап на аутентификация.

На рутера 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. В случай на успешно удостоверяване, да пренасочи клиентския браузър към страница или изображение, известяващо за успешното преминаване на аутентификацията:
Proxy конфигурация
/ip proxy
поставете включено=yes порт=3128
/ip proxy access
добавете действие=отказано деактивирано=не пренасочване-към=gw.local./mikrotik_logo.png src-адрес=0.0.0.0/0
Ще изброя важните елементи на конфигурацията:
- interface-list „2fa“ — динамичен списък на клиентските интерфейси, чийто трафик изисква обработка в рамките на 2FA;
- address-list „2fa_jailed“ — „сив“ списък на тунелни IP адреси на VPN клиенти;
- address_list „2fa_approved“ — „бял“ списък на тунелни IP адреси на VPN клиенти, успешно преминали двуфакторна аутентификация.
- верига на защитната стена „input_2fa“ — в нея се извършва проверка на tcp-пакети за наличие на код за удостоверяване и съвпадение на IP адреса на подателя на кода с изискваното. Правилата в веригата се добавят и премахват динамично.
Определената блок-схема за обработка на пакети изглежда така:
За да влезе в проверката по 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
Код
/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 и отделните правила на защитната стена.
на PPP-Profile ни обогатява с информация за променливи, свързани със събитията на свързване-изключване на PPP-клиента „Изпълни скрипт при събитието на влизане на потребителя. Това са наличните променливи, достъпни за скрипта на събитието: user, local-address, remote-address, caller-id, called-id, interface“. Някои от тях ще ни бъдат изключително полезни.
Кодът, използван в профила за събитието на свързване PPP on-up
#Логируем для отладки полученные переменные :log info (quot;локален-адрес")
:лог информация (quot;отдалечен-адрес")
:лог информация (quot;идентификатор-на-обаждащия")
:лог информация (quot;идентификатор-на-приемащия")
:лог информация ([/интерфейс pptp-сървър получи (quot;интерфейс") име])
#Объявляем свои локальные переменные
:локален списък "2fa_занят"
:локален viamodem фалшив
:локален modemport "usb2"
#ищем автоматически созданную запись в адрес-листе "2fa_jailed"
:локален recnum1 [/ip fi адрес-списък намери адрес=(quot;отдалечен-адрес") списък=$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 тайна получи [намери име=$user] коментар]#Готовим тело сообщения. Если клиент подключается к VPN прямо с телефона ему достаточно
#будет перейти прямо по ссылке из полученного сообщения
:локален msgboby ("Вашият код: ".$comm1."n Или отворете линк http://gw.local/otp/".$comm1."/")# Отправляем SMS по выбранному каналу - USB-модем или email-to-sms
ако $viamodem направи={
/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_".(quot;отдалечен-адрес"))
/ip firewall layer7-protocol add name=(quot;vcomment") коментар=(
quot;отдалечен-адрес") 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") протокол=tcp src-адрес=(
quot;отдалечен-адрес") dst-лимит=1,1,src-адрес/1m40s
Специално за любителите на безмислено копиране и поставяне, предупреждавам — кодът е взет от тестовата версия и може да съдържа незначителни грешки. На разбирането на опитен човек няма да му е трудно да разбере къде точно.При изключване на потребителя се генерира събитие „On-Down“ и се извиква съответният скрипт с параметри. Задачата на този скрипт е да почисти правилата на защитната стена, създадени за изключения потребители.
Кодът, използван в профила за събитието на свързване PPP on-down
:локален vcomment ("2fa_".(quot;отдалечен-адрес"))
/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]
След това можем да създадем потребители и да назначим профил с двуфакторна автентикация на всички или на някои от тях.winbox
Код
/ppp secrets set [find name=Petrov] profile=2FAКак изглежда от страната на клиента.
При установяване на VPN-съединение, на телефона/таблета с Android/iOS и SIM карта идва SMS от такъв вид:
SMS
Ако връзката е установена директно от телефона/таблета, може да преминеш през 2FA просто като кликнеш на линка от съобщението. Това е удобно.
Ако VPN връзката се установява с PC, на потребителя ще му е необходим минимален формуляр за въвеждане на парола. Малкият формуляр под формата на HTML файл се предава на потребителя при настройката на VPN. Файлът може даже да се изпрати по пощата, за да го съхрани и да създаде ярлык на удобно място. Примерно така изглежда:
Ярлык на работния плот
Потребителят кликва с мишката върху ярлыка, отваря се прост формуляр за въвеждане на код, който ще постави кода в отворения URL:
Скриншот на формата
Формата е най-примитивна и е дадена за пример. Желаещите могат да я доработят по свой вкус.
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='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="bg"/> <input type="button" value="Вход" onclick="location.href='http://gw.local/otp/'+document.getElementById('text').value"/> </form> </body> </html>Ако авторизацията е успешна, потребителят в браузъра ще види логото на MikroTik, което трябва да служи като знак за успешна аутентикация:
Забелязвам, че изображението се връща от вградения уеб сървър MikroTik с помощта на WebProxy Deny Redirect.
Сигурен съм, че изображението може да се персонализира, използвайки инструмента "hotspot", качвайки собствена версия и задавайки нейния Deny Redirect URL с WebProxy.
Моля, към онези, които се опитват да заменят маршрутизатор за $500 с най-евтиния "играчка" MikroTik за $20 — не правете това. Устройствата от типа "hAP Lite"/"hAP mini" (home access point) имат много слаб CPU (smips) и вероятно няма да се справят с натоварването в бизнес сегмента.
Внимание! Тази настройка има един недостатък: при свързване и разкачане на клиенти имат промени в конфигурацията, която маршрутизаторът се опитва да запази в своята енергонезависима памет. При голям брой клиенти и чести свързвания и разкачвания, това може да доведе до деградация на вътрешния памет на маршрутизатора.
P.S.: Методите за доставка на кода на клиента могат да бъдат разширени и допълнени, колкото е необходимо от вашите програмни умения. Например, можете да изпращате съобщения в Telegram или… предлагайте варианти!
Надявам се статията да бъде полезна за вас и да помогне да направите мрежите на малкия и средния бизнес още малко по-безопасни.
Източник: habr.com




