احراز هویت دو مرحله ای کاربران VPN از طریق MikroTik و SMS

سلام همکاران! امروز، هنگامی که شدت شور و شوق در مورد "کار از راه دور" کمی فروکش کرد، اکثر ادمین ها وظیفه دسترسی از راه دور کارمندان به شبکه شرکتی را به دست آوردند، وقت آن است که تجربه دیرینه خود را در بهبود امنیت VPN به اشتراک بگذارم. این مقاله اکنون مد نخواهد بود IPSec IKEv2 و xAuth. این در مورد ساخت یک سیستم است. احراز هویت دو مرحله ای (2FA) کاربران VPN زمانی که MikroTik به عنوان یک سرور VPN عمل می کند. یعنی زمانی که از پروتکل های "کلاسیک" مانند PPP استفاده می شود.

احراز هویت دو مرحله ای کاربران VPN از طریق MikroTik و SMS

امروز به شما خواهم گفت که چگونه از MikroTik PPP-VPN محافظت کنید حتی اگر حساب کاربری "ربوده شده باشد". هنگامی که این طرح به یکی از مشتریان من معرفی شد، او به طور خلاصه آن را اینگونه توصیف کرد: "خب، اکنون دقیقاً مانند یک بانک است!".

این روش از خدمات احراز هویت خارجی استفاده نمی کند. وظایف به صورت داخلی توسط خود روتر انجام می شود. بدون هزینه برای مشتری اتصال. این روش هم برای مشتریان رایانه شخصی و هم برای دستگاه های تلفن همراه کار می کند.

طرح کلی حفاظت به شرح زیر است:

  1. آدرس IP داخلی کاربری که با موفقیت به سرور VPN متصل شده است به طور خودکار در لیست خاکستری قرار می گیرد.
  2. رویداد اتصال به طور خودکار یک کد یک بار مصرف ایجاد می کند که با استفاده از یکی از روش های موجود برای کاربر ارسال می شود.
  3. آدرس‌های موجود در این لیست دسترسی محدودی به منابع شبکه محلی دارند، به استثنای سرویس "Authenticator" که منتظر دریافت رمز عبور یک‌بار مصرف است.
  4. پس از ارائه کد، کاربر به منابع داخلی شبکه دسترسی دارد.

ابتدا کوچکترین مشکلی که من با آن روبرو شدم ذخیره اطلاعات تماس کاربر برای ارسال کد 2FA برای او بود. از آنجایی که ایجاد فیلدهای داده دلخواه مربوط به کاربران در Mikrotik غیرممکن است، از فیلد "نظر" موجود استفاده شد:

/ppp secrets add name=Patrov password=4M@ngr! نظر = "89876543210"

دوم مشکل جدی تر بود - انتخاب مسیر و روش تحویل کد. در حال حاضر سه طرح اجرا شده است: الف) پیامک از طریق مودم USB ب) پست الکترونیکی ج) پیامک از طریق ایمیل که برای مشتریان شرکتی اپراتور سلول قرمز در دسترس است.

بله، طرح های پیامکی هزینه دارد. اما اگر نگاه کنید، "امنیت همیشه در مورد پول است" (ج).
من شخصاً طرح با ایمیل را دوست ندارم. نه به این دلیل که به سرور ایمیل نیاز دارد که برای کلاینت احراز هویت در دسترس باشد - تقسیم ترافیک مشکلی نیست. با این حال، اگر مشتری با بی دقتی رمز عبور vpn و ایمیل را در یک مرورگر ذخیره کند و سپس لپ تاپ خود را گم کند، مهاجم از طریق آن به شبکه شرکت دسترسی کامل پیدا می کند.

بنابراین، تصمیم گرفته شده است - ما یک کد یک بار مصرف را با استفاده از پیام های SMS تحویل می دهیم.

Третья مشکل از کجا بود نحوه تولید یک کد شبه تصادفی برای 2FA در MikroTik. هیچ آنالوگی از تابع تصادفی () در زبان برنامه نویسی RouterOS وجود ندارد، و من قبلا چندین تولید کننده اعداد شبه تصادفی اسکریپت زیربغل را دیده ام. من به دلایل مختلف هیچ کدام را دوست نداشتم.

در واقع یک مولد توالی شبه تصادفی در میکروتیک وجود دارد! از یک نگاه سطحی در زمینه / Certificates scep-server پنهان است. اولین راه دریافت رمز عبور یک بار مصرف آسان و ساده است - با دستور /گواهینامه های scep-server otp تولید می کند. اگر یک عملیات انتساب متغیر ساده انجام دهیم، مقدار آرایه ای به دست می آید که می تواند بعداً در اسکریپت ها استفاده شود.

راه دوم به دست آوردن یک رمز عبور یک بار مصرف که همچنین به راحتی اعمال می شود - با استفاده از یک سرویس خارجی 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

باید سرویسی در روتر میکروتیک وجود داشته باشد که بتواند کد را بپذیرد و آن را با یک کلاینت خاص مطابقت دهد. اگر کد ارائه شده با کد مورد انتظار مطابقت داشته باشد، آدرس مشتری باید در لیست "سفید" مشخصی قرار گیرد، آدرس‌هایی که اجازه دسترسی به شبکه داخلی شرکت را دارند.

با توجه به انتخاب نامناسب خدمات، تصمیم گرفته شد که کدها را از طریق http با استفاده از 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
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. آدرس-لیست "2fa_jailed" - لیست "خاکستری" آدرس های IP تونل مشتریان VPN.
  3. address_list "2fa_approved" - لیست "سفید" آدرس های IP تونل مشتریان VPN که احراز هویت دو مرحله ای را با موفقیت پشت سر گذاشته اند.
  4. زنجیره فایروال "input_2fa" - بسته های tcp را برای وجود کد مجوز بررسی می کند و آدرس IP فرستنده کد را با کد مورد نیاز مطابقت می دهد. قوانین در زنجیره به صورت پویا اضافه و حذف می شوند.

یک فلوچارت ساده شده از پردازش بسته به صورت زیر است:

احراز هویت دو مرحله ای کاربران VPN از طریق MikroTik و SMS

برای ورود به بررسی Layer7 از ترافیک مشتریان از لیست "خاکستری" که هنوز مرحله دوم احراز هویت را پشت سر نگذاشته اند، یک قانون در زنجیره "ورودی" استاندارد ایجاد شده است:

رمز
/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 نه تنها برای اتصال کاربران نهایی، بلکه در عین حال برای ایجاد ارتباطات سایت به سایت استفاده کنید، ممکن است این موضوع مرتبط باشد.

در نمایه ویژه جدید ایجاد شده، از افزودن پویا آدرس و رابط کاربر متصل به لیست های "خاکستری" آدرس ها و رابط ها استفاده می کنیم:

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 (پیش مسیریابی) استفاده شود.

هنگامی که آماده سازی کامل شد، زنجیره های فایروال اضافی و یک نمایه ایجاد شد، ما یک اسکریپت می نویسیم که مسئول تولید خودکار کد 2FA و قوانین جداگانه فایروال است.

مستندات wiki.mikrotik.com در PPP-Profile ما را با اطلاعاتی در مورد متغیرهای مرتبط با رویدادهای اتصال-قطع کلاینت PPP غنی می کند "اسکریپت را در رویداد ورود کاربر اجرا کنید. اینها متغیرهای موجودی هستند که برای اسکریپت رویداد قابل دسترسی هستند: کاربر، آدرس محلی، آدرس راه دور، شناسه تماس گیرنده، شناسه نامیده، رابط". برخی از آنها برای ما بسیار مفید هستند.

کد مورد استفاده در نمایه برای رویداد 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 روی پایین

: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 برقرار می شود، یک تلفن یا تبلت Android/iOS با سیم کارت پیامکی مانند زیر دریافت می کند:

پیامک
احراز هویت دو مرحله ای کاربران VPN از طریق MikroTik و SMS

اگر اتصال مستقیماً از تلفن / رایانه لوحی برقرار شود، می توانید به سادگی با کلیک کردن بر روی پیوند پیام، از 2FA عبور کنید. راحت است.

اگر اتصال VPN از رایانه شخصی برقرار شود، کاربر باید حداقل فرم رمز عبور را وارد کند. یک فرم کوچک در قالب یک فایل 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

توجه داشته باشید که تصویر از وب سرور داخلی MikroTik با استفاده از WebProxy Deny Redirect بازگردانده می شود.

تصور می‌کنم می‌توان تصویر را با استفاده از ابزار "هات‌اسپات" سفارشی‌سازی کرد، نسخه خود را در آنجا آپلود کرد و URL Redirect URL را با WebProxy روی آن تنظیم کرد.

یک درخواست بزرگ از کسانی که سعی می کنند ارزان ترین "اسباب بازی" Mikrotik را به قیمت 20 دلار بخرند و یک روتر 500 دلاری را با آن جایگزین کنند - این کار را نکنید. دستگاه هایی مانند "hAP Lite" / "hAP mini" (نقطه دسترسی خانگی) دارای یک CPU (smips) بسیار ضعیف هستند و به احتمال زیاد با بار در بخش تجاری مقابله نخواهند کرد.

هشدار! این راه حل یک عیب دارد: هنگامی که کلاینت ها متصل یا قطع می شوند، تغییرات پیکربندی رخ می دهد که روتر سعی می کند آن را در حافظه غیر فرار خود ذخیره کند. با تعداد زیاد کلاینت ها و اتصالات و قطع های مکرر، این می تواند منجر به تخریب حافظه داخلی در روتر شود.

PS: روش های تحویل کد به مشتری را می توان تا جایی که توانایی های برنامه نویسی شما کافی است گسترش و تکمیل کرد. مثلا میتونید به تلگرام پیام بدید یا ... گزینه های پیشنهادی!

امیدوارم مقاله برای شما مفید باشد و به امنیت شبکه های کسب و کارهای کوچک و متوسط ​​کمک کند.

منبع: www.habr.com