MikroTik と SMS による VPN ユーザーの XNUMX 要素認証

こんにちは、同僚です! 「リモートワーク」に対する情熱の激しさが少し落ち着き、大多数の管理者が従業員の企業ネットワークへのリモート アクセスというタスクを獲得した今日、VPN セキュリティの向上に関する私の長年の経験を共有する時が来ました。 この記事は、IPSec IKEv2 と xAuth の今では流行らないでしょう。 それはシステムを構築することです。 二要素認証 (2FA) MikroTik が VPN サーバーとして機能する場合の VPN ユーザー。 つまり、PPP などの「クラシック」プロトコルが使用される場合です。

MikroTik と SMS による VPN ユーザーの XNUMX 要素認証

今日は、ユーザーアカウントの「ハイジャック」の場合でもMikroTik PPP-VPNを保護する方法を説明します。 このスキームを私の顧客の XNUMX 人に紹介したとき、彼はそれを「銀行と同じだ!」と簡単に説明しました。

このメソッドは外部認証サービスを使用しません。 タスクはルーター自体によって内部的に実行されます。 接続するクライアントには費用はかかりません。 この方法は、PC クライアントとモバイル デバイスの両方で機能します。

一般的な保護スキームは次のとおりです。

  1. VPN サーバーに正常に接続したユーザーの内部 IP アドレスは、自動的にグレーリストに登録されます。
  2. 接続イベントは、利用可能な方法のいずれかを使用してユーザーに送信されるワンタイム コードを自動的に生成します。
  3. このリスト内のアドレスは、ワンタイム パスコードの受信を待機している「認証」サービスを除き、ローカル ネットワーク リソースへのアクセスが制限されています。
  4. コードを提示すると、ユーザーはネットワークの内部リソースにアクセスできるようになります。

最初の 私が直面しなければならなかった最も小さな問題は、2FA コードを送信するためにユーザーの連絡先情報を保存することでした。 Mikrotik ではユーザーに対応する任意のデータ フィールドを作成することができないため、既存の「コメント」フィールドが使用されました。

/ppp シークレット追加 名前=ペトロフ パスワード=4M@ngr! コメント="89876543210"

2番目 問題はさらに深刻であることが判明しました。コードを配信するパスと方法の選択です。 現在、XNUMX つのスキームが実装されています: a) USB モデム経由の SMS b) 電子メール c) 赤い携帯電話会社の法人クライアントが利用できる電子メール経由の SMS。

はい、SMS スキームにはコストがかかります。 しかし、よく見てみると、「安全性は常にお金に関するものです」(c)。
私は個人的に電子メールの仕組みが好きではありません。 これは、認証されるクライアントがメール サーバーを使用できる必要があるためではありません。トラフィックを分割しても問題はありません。 ただし、クライアントが不用意に VPN パスワードと電子メール パスワードの両方をブラウザに保存し、ラップトップを紛失した場合、攻撃者はそこから企業ネットワークに完全にアクセスできるようになります。

そこで、SMS メッセージを使用してワンタイム コードを配信することにしました。

Третья 問題はどこにあったのか MikroTik で 2FA の疑似ランダム コードを生成する方法。 RouterOS スクリプト言語には、random() 関数に相当するものはなく、これまでにいくつかの松葉杖スクリプトの疑似乱数ジェネレーターを見てきました。 さまざまな理由から、どれも好きではありませんでした。

実際、MikroTik には擬似ランダム シーケンス ジェネレーターがあります。 /certificates scep-server のコンテキストでは、表面的には隠されています。 第一の方法 ワンタイム パスワードの取得は、次のコマンドを使用すると簡単で簡単です。 /certificates 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

コンソール用にフォーマットされたリクエスト (スクリプト本体ではエスケープ特殊文字が必要です) は、1 桁の文字列を $rndXNUMX 変数に受け取ります。 次の「put」コマンドは、MikroTik コンソールに変数を表示するだけです。

XNUMX番目の問題 これはすぐに解決する必要がありました。これは、接続されたクライアントが認証の第 XNUMX 段階でワンタイム コードを転送する方法と場所です。

MikroTik と SMS による VPN ユーザーの XNUMX 要素認証

MikroTik ルーターには、コードを受け入れて特定のクライアントと照合できるサービスが必要です。 提供されたコードが予想されるコードと一致する場合、クライアントのアドレスは特定の「ホワイト」リストに含まれ、そのアドレスから企業の内部ネットワークへのアクセスが許可されます。

サービスの選択が適切でなかったため、Mikrotik に組み込まれている Web プロキシを使用して http 経由でコードを受け入れることが決定されました。 また、ファイアウォールは IP アドレスの動的リストを操作できるため、コードの検索を実行し、それをクライアント IP と照合し、レイヤー 7 正規表現を使用して「ホワイト」リストに追加します。 ルーター自体には条件付き DNS 名「gw.local」が割り当てられており、PPP クライアントに発行するための静的な A レコードがルーター上に作成されています。

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

この場合、プロキシには XNUMX つの機能があります。

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. address-list "2fa_jailed" - VPN クライアントのトンネル IP アドレスの「グレー」リスト。
  3. address_list "2fa_approved" - XNUMX 要素認証に正常に合格した VPN クライアントのトンネル IP アドレスの "white" リスト。
  4. ファイアウォール チェーン "input_2fa" - TCP パケットに認証コードが存在するかどうかをチェックし、コード送信者の IP アドレスを必要な IP アドレスと照合します。 チェーン内のルールは動的に追加および削除されます。

パケット処理の簡略化されたフローチャートは次のようになります。

MikroTik と SMS による VPN ユーザーの XNUMX 要素認証

認証の第 7 段階をまだ通過していない「グレー」リストのクライアントからのトラフィックの LayerXNUMX チェックに入るために、標準の「入力」チェーンにルールが作成されています。

コード
/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 サーバー全体と個々のユーザーの両方に適用できます。 同時に、ユーザーに割り当てられたプロファイルが優先され、サーバー全体に対して選択されたプロファイルのパラメーターが、指定されたパラメーターで上書きされます。

このアプローチの結果、XNUMX 要素認証用の特別なプロファイルを作成し、それをすべてのユーザーではなく、そうする必要があると考えられるユーザーにのみ割り当てることができます。 これは、PPP サービスをエンド ユーザーの接続に使用するだけでなく、同時にサイト間の接続の構築にも使用する場合に関係する可能性があります。

新しく作成された特別なプロファイルでは、接続されたユーザーのアドレスとインターフェイスをアドレスとインターフェイスの「グレー」リストに動的に追加します。

ウィンボックス
MikroTik と SMS による VPN ユーザーの XNUMX 要素認証

コード
/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

dstnat (プレルーティング) チェーン内の非セカンダリ VPN クライアントからのトラフィックを検出してキャプチャするには、「address-list」リストと「interface-list」リストの両方を使用する必要があります。

準備が完了し、追加のファイアウォール チェーンとプロファイルが作成されたら、2FA コードと個々のファイアウォール ルールの自動生成を担当するスクリプトを作成します。

ドキュメント wiki.mikrotik.com PPP-Profile では、PPP クライアントの接続/切断イベントに関連する変数に関する情報が充実しています。 「ユーザーのログインイベントでスクリプトを実行します。 イベント スクリプトでアクセスできる変数は次のとおりです: user、local-address、remote-address、caller-id、caller-id、interface"。 それらの中には私たちにとって非常に役立つものもあります。

PPP 接続開始イベントのプロファイルで使用されるコード

#Логируем для отладки полученные переменные 
: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]
その後、ユーザーを作成し、そのすべてまたは一部を XNUMX 要素認証プロファイルに割り当てることができます。

ウィンボックス
MikroTik と SMS による VPN ユーザーの XNUMX 要素認証

コード
/ppp secrets set [find name=Petrov] profile=2FA

クライアント側でどのように見えるか。

VPN 接続が確立されると、SIM カードを装着した Android/iOS スマートフォン/タブレットは次のような SMS を受信します。

SMS
MikroTik と SMS による VPN ユーザーの XNUMX 要素認証

携帯電話/タブレットから直接接続が確立されている場合は、メッセージのリンクをクリックするだけで 2FA を通過できます。 快適ですよ。

VPN 接続が PC から確立される場合、ユーザーは最小限のパスワード フォームを入力する必要があります。 VPN を設定するときに、HTML ファイル形式の小さなフォームがユーザーに提供されます。 ファイルはメールで送信することもできるので、ユーザーはファイルを保存し、便利な場所にショートカットを作成できます。 次のようになります。

テーブル上のラベル
MikroTik と SMS による VPN ユーザーの XNUMX 要素認証

ユーザーがショートカットをクリックすると、単純なコード入力フォームが開き、開いた URL にコードが貼り付けられます。

画面フォーム
MikroTik と SMS による VPN ユーザーの XNUMX 要素認証

最も原始的な形式を例として示します。 ご希望の方はご自身で改造も可能です。

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 ロゴが表示され、認証が成功したことを示すはずです。

MikroTik と SMS による VPN ユーザーの XNUMX 要素認証

画像は、WebProxy Deny Redirect を使用して組み込みの MikroTik Web サーバーから返されることに注意してください。

画像は「ホットスポット」ツールを使用してカスタマイズでき、そこに独自のバージョンをアップロードし、WebProxy でリダイレクト URL を拒否するように設定できると思います。

最も安価な「おもちゃ」の Mikrotik を 20 ドルで購入し、500 ドルのルーターをそれに置き換えようとしている人たちへの大きなお願いですが、そんなことはしないでください。 「hAP Lite」/「hAP mini」(ホームアクセスポイント)などのデバイスは、CPU(smips)が非常に弱く、ビジネスセグメントの負荷に対応できない可能性があります。

警告! このソリューションには XNUMX つの欠点があります。それは、クライアントが接続または切断すると、設定の変更が発生し、ルータがその変更を不揮発性メモリに保存しようとすることです。 クライアントの数が多く、接続と切断が頻繁に行われると、ルーターの内部ストレージの劣化が生じる可能性があります。

PS: プログラミング能力が十分である限り、コードをクライアントに配信する方法を拡張および補足できます。 たとえば、メッセージを電報に送信したり、オプションを提案したりできます。

この記事があなたのお役に立ち、中小企業のネットワークを少しでも安全にするのに役立つことを願っています。

出所: habr.com