Двухфакторная аутентификация пользователей VPN посредством MikroTik и SMS | ProHoster

Описание

Компонент для авторизации на портале “Госуслуги”.

Введение

Стоит упомянуть, что есть компании, которые имеют готовые решения для интеграции с ЕСИА, например эта или вот эта — если вам лень во всем этом разбираться, можно воспользоваться их услугами. Сами не пользовались, советовать не можем.

Подробное описание общего механизма интеграции представлено на сайте Министерства цифрового развития… Методичка довольно увесистая, но даже из нее не все детали очевидны при реализации. Если в кратце, то основные шаги выглядят следующим образом:

  1. Регистрация ИС в регистре информационных систем ЕСИА
  2. Регистрация ИС в тестовой среде
  3. Выполнение доработки системы для взаимодействия с ЕСИА

В данной статье будет описан только 3 пункт, предыдущие 2 – бюрократия, оставим ее за рамками Хабра. В методичке предлагают реализовать интеграцию 2 способами: SAML или OpenID Connect. Говорят,

с 01.01.2022 г. взаимодействие по протоколу SAML 2.0 больше не будет разрешено (только для действующих систем). Для подключения к ЕСИА необходимо будет использовать протокол OAuth 2.0 / OpenID Connect (сейчас доступны оба варианта).

Поэтому мы выбрали красную таблетку второй вариант. Согласно методичке, базовый сценарий аутентификации представляет собой примерно следующие шаги:

Авторизация через network policy server (nps) для mikrotik

Как быстро и просто настроить авторизацию через RADIUS от Microsoft? Думаю, это поможет тем, кто захочет иметь возможность заходить на устройства MikroTik через дружелюбный WinBox и простой SSH.

Базовая информация

Мы реализовали сервис интеграции с ЕСИА под Windows, используя КриптоПро CSP. В теории скорее всего можно это все аккуратно упаковать в docker и положить в Linux-образные системы, оставим это на откуп читателю. Для нас же актуальным стеком был следующий:

Каждый запрос в ЕСИА по соображениям безопасности дополняется полем client_secret, которое формируется как открепленная подпись 4 полей запроса в формате UTF-8:

private string GetClientSecret(
	X509Certificate2 certificate, 
	string scope, 
	string timestamp, 
	string clientId, 
	string state)
{
	var signMessage = Encoding.UTF8.GetBytes($"{scope}{timestamp}{clientId}{state}");

	byte[] encodedSignature = SignatureProvider.Sign(signMessage, certificate);
 
	return Base64UrlEncoder.Encode(encodedSignature);
}

Тут SignatureProvider – класс для реализации работы с сертификатами, он довольно просто реализуется. Для подписи использовался алгоритм ГОСТ – импортозамещение и все такое.

Благодарим за внимание

Пакет заоперсорсен финтех-компанией в которой я работаю. Не тестировалось на животных.

Внимание!

Получив токен вы можете выполнять любые API запросы. Библиотека не поддерживает все существующие методы в API, а предоставляет только самые базовые. Основная цель библиотеки – получение токена.

Дальнейшая настройка политики.

Дальнейшая настройка политики

На этапе выбора протокола аутентификации достаточно выбрать нешифрованный (о чем получите предупреждение) PAP для SSH или шифрованный CHAP для WinBox. Я выбрал оба. Если есть необходимость использовать web версию, то достаточно включить MS-CHAPv2, в остальном всё аналогично.

PAP для SSH или шифрованный CHAP для WinBox

Собственно, предупреждение о выборе небезопасного способа. Предлагают почитать пошаговый справочный материал.

предупреждение о выборе небезопасного способа

На данном этапе я не стал ничего трогать.

PAP для SSH или шифрованный CHAP для WinBox

Двухфакторная аутентификация пользователей vpn посредством mikrotik и sms | prohoster

Здравствуйте коллеги! Сегодня, когда накал страстей вокруг «удалёнки» немного спал, большинство админов победило задачу удаленного доступа сотрудников к корпоративной сети, пришло время поделиться моей давней наработкой по повышению безопасности VPN. В этой статье не будет модных ныне IPSec IKEv2 и xAuth. Речь пойдет о построении системы пользователей VPN, когда MikroTik выступает в качестве VPN-сервера. А именно, когда используются «классические» протоколы типа PPP.

Двухфакторная аутентификация пользователей VPN посредством MikroTik и SMS

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

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

Общая схема защиты выглядит следующим образом:

  1. Внутренний IP-адрес пользователя успешно подключившегося к в VPN-серверу, автоматически попадает в «серый» список.
  2. Событие подключения автоматически генерирует одноразовый код, который пересылается пользователю одним из доступных способов.
  3. Адресам, находящимся в этом списке ограничен доступ к ресурсам локальной сети, за исключением сервиса «аутентификатора», ожидающего получение одноразового кода-пароля.
  4. После предъявления кода, пользователю открывается доступ к внутренним ресурсам сети.

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

/ppp secrets add name=Petrov [email protected]! 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, которое можно использовать в дальнейшем в скриптах.

Второй способ получения одноразового пароля который тоже легко применить — использование внешнего сервиса для генерации желаемого вида последовательности псевдослучайных чисел. Вот упрощенный консольный пример получения данных в переменную:

Код
: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-адреса отправителя кода с требуемым. Правила в цепочку добавляются и удаляются динамически.

Упрощенная блок-схема обработки пакета выглядит так:

Для попадания в проверку по 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

Код
/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-клиента «Execute script on user login-event. These are available variables that are accessible for the 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), и вполне вероятно не справятся с нагрузкой в бизнес-сегменте.

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

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

Надеюсь статья окажется вам полезной и поможет сделать сети малого и среднего бизнеса еще чуть безопаснее.

Источник: vhod-v-lichnyj-kabinet.ru

Добавление radius клиента

Для того, чтобы сервер знал с какими устройствами налаживать общение нужно добавить их в RADIUS Clients.

RADIUS Clients

Для примера, добавляю свой MikroTik wAP. Friendly name установил как Identity на устройстве и IP заданный на его единственном проводном интерфейсе. Для того, чтобы устройство смогло авторизоваться на сервере нужно ввести ключ. Он создается на сервере либо вручную, либо генерируется автоматически. Я предпочел второй вариант.

New-NpsRadiusClient –Address “10.1.1.21” –Name “router01” –SharedSecret “egEcM4myJCptphGlZ1UymS#qLh^urp@fJ1hF8dE6dwb27NI^oIJtTWKKp^MEsU6p”

New Radius Client

Vendor name остановим на стандартном RADIUS.

Vendor name

Устройство добавлено.

Добавление сервера авторизации на mikrotik

Первым делом присвоим System/Identity равным router01 и IP с маской для интерфейса.

/system identity set name=router01 /ip address add address=10.1.1.21/24interface=ether1network=10.1.1.0

System/Identity

Как обновить токен?

Стандартно, как описано в документации к oauth2-client

Как получить oid?

Если 2 способа:

  1. oid содержится в jwt токене, расшифровав его
  2. После получения токена oid сохраняется в config и получить можно так

Конфиг

clientId – ID вашего приложения.

redirectUrl – URL куда будет перенаправлен ответ с кодом.

Настройка системы sms авторизации igofree на mikrotik

Настройка системы SMS авторизации iGoFree на MikroTik

Настройка начинается с подключения маршрутизатора к интернету. В самом простом случае следует вставить Ethernet кабель от провайдера в первый порт MikroTik и роутер получает IP через DHCP client. Кроме того по умолчанию на первом порту сделан scr-nat masqurade.

Если необходима постоянная достоступность интернета, можно настроить резервирование через 3G модем. С модемами Huawei поддерживающими Hi-Link нужно создать DHCP client на интерфейсе lte2 указав в поле Default Route Distance (метрика или цена маршрута) значение большее чем на основном канале.

Настройка маршрутизатора

Настроим OpenVPN client на MikroTik. Для этого откроем окно с интерфейсами и плюсиком добавим новый интерфейс:

OpenVPN client на MikroTik

Переиспользование токена

Дополнительно укажите токен и идентификатор в конфиге

Получаем данные пользователя

Проверяя стейт и меняя код на аутентификационный токен.

Получение данных организации

Полученный токен доступа для запроса данных по организации мы использовать не можем, т.к. он завязан на определенный scope. Поэтому нужно получить отдельный токен. По сути методы получения токена доступа для организации и информации по ней не сильно отличаются от рассмотренных ранее.

Получение токена доступа

Для получение каких-либо данных в ЕСИА нам нужно получить токен доступа. Для этого формируем POST запрос в ЕСИА (для тестовой среды базовый url такой:

Предисловие

Однажды в далекой-далекой галактике… потребовалось нам реализовать аутентификацию пользователей с помощью учетной записи ЕСИА на ГосУслугах. Т.к. обитаем мы в галактике .Net, первым делом был изучен весь гугол на предмет готового космолета дабы не костылить все самим, но поиски ни к чему путному не привели. Поэтому решено было изучить тему и реализовать-таки космолет своими силами.

Проверка через ssh и winbox

Проверка подключения через SSH и экспорт конфигурации.

Проверка через SSH и WinBox

И проверяем авторизацию в Winbox.

Проверяем авторизацию в Winbox

Редиректим посетителя на есиа

Одновременно сохраняя стейт для последующей проверки.

Создание политики подключения

Создание политики подключения

Подбираем подходящее название для политики.

Подбор названия для политики

Определяем наше устройство с которым будет работать сервер.

Определяем наше устройство с которым будет работать сервер

Я выбрал только Client Friendly Name со значением Router01. Это четко привязывает данный пункт политики к устройству через созданного клиента. Можно идентифицировать устройство Mikrotik по Identity выбрав NAS Identifier.

Client Friendly Name со значением Router01

Без предварительной конфигурации устройства Identity = MikroTik.

Identity = MikroTik

Создание политики сети

Network Policy Server

Назовем её Routers.

etwork Policy Server -Routers

Как и прежде, нужно определить условия.

определить условия

Токен и oid

Токен – jwt токен которые вы получаете от ЕСИА для дальнейшего взаимодействия

oid – уникальный идентификатор владельца токена

Установка

При помощи composer:

Или добавьте в composer.json

Установка роли nps

Имеем Windows Server 2022 Datacenter с уже установленным доменом.

Windows Server 2022 Datacenter

Выбираем сервер, на котором будет разворачиваться роль. Microsoft не рекомендует делать это на контроллере домена, но в некоторых best practices для уменьшения задержек дают совет ставить именно на него. Добавляем роль Network Policy and Access Server вместе с management tools для настройки.

Install-WindowsFeature NPAS -IncludeManagementTools

Запускаем любым удобным способом админку NPS. Например, через менеджер серверов.

Запуск NPS

Регистрируем сервер NPS в AD.

netsh ras add registeredserver

Регистрируем сервер NPS в AD

Итоговые настройки политики сети.

Итоговые настройки политики сети

Выбираем необходимый приоритет среди других политик, если необходимо.

Выбираем необходимый приоритет

Чтобы учетная запись проверялась через NPS в AD у этого пользователя на вкладке Dial-in в разделе Network Access Permission должен быть отмечен пункт Control access through NPS Network Policy.

Network Access Permission

Для возможности авторизовываться через WinBox нужно включить обратимое шифрование в профиле пользователя.

обратимое шифрование

Итоговые установки политики.

У меня не получилось воспроизвести это через PowerShell, даже стандартный example с technet’а. Буду признателен, если подскажете почему.

netsh nps add crp name = “Request Policy Router01” state = “ENABLE” processingorder = “1” policysource = “0” conditionid =”0x1020″ conditiondata = “router01” profileid = “0x1025” profiledata = “0x1” profileid = “0x1009” profiledata = “0x1″”0x2” profileid = “0x1fb0” profiledata = “TRUE”

New Connection Request Policy

Выбираем нужный приоритет двигая выше или ниже пункт политики.

Заключение

Пожалуй, этого достаточно для базового сценария взаимодействия с ЕСИА. В целом, если знать особенности реализации, программное подключение системы к ЕСИА не займет более 1 дня. Если у вас появятся вопросы, добро пожаловать в комменты. Спасибо, что дочитали мой пост до конца, надеюсь, он будет полезен.

Похожее:  Разобрался с работой с AD из PHP... - Моя работа - понимать... — ЖЖ

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *