Authentification à deux facteurs des utilisateurs VPN via MikroTik et SMS

Bonjour collègues! Aujourd'hui, alors que l'intensité des passions autour du "travail à distance" s'est quelque peu apaisée, que la majorité des administrateurs ont remporté la tâche d'accès à distance des employés au réseau de l'entreprise, il est temps de partager ma longue expérience dans l'amélioration de la sécurité VPN. Cet article ne sera plus à la mode désormais IPSec IKEv2 et xAuth. Il s'agit de construire un système. authentification à deux facteurs (2FA) Utilisateurs VPN lorsque MikroTik agit en tant que serveur VPN. A savoir, lorsque des protocoles "classiques" tels que PPP sont utilisés.

Authentification à deux facteurs des utilisateurs VPN via MikroTik et SMS

Aujourd'hui, je vais vous dire comment protéger MikroTik PPP-VPN même en cas de "détournement" du compte utilisateur. Lorsque ce schéma a été présenté à l'un de mes clients, il l'a brièvement décrit comme "eh bien, maintenant c'est comme dans une banque !".

La méthode n'utilise pas de services d'authentification externes. Les tâches sont exécutées en interne par le routeur lui-même. Aucun frais pour le client qui se connecte. La méthode fonctionne à la fois pour les clients PC et les appareils mobiles.

Le régime général de protection est le suivant :

  1. L'adresse IP interne d'un utilisateur qui s'est connecté avec succès au serveur VPN est automatiquement mise en liste grise.
  2. L'événement de connexion génère automatiquement un code à usage unique qui est envoyé à l'utilisateur à l'aide de l'une des méthodes disponibles.
  3. Les adresses de cette liste ont un accès limité aux ressources du réseau local, à l'exception du service "authentificateur", qui attend de recevoir un mot de passe à usage unique.
  4. Après avoir présenté le code, l'utilisateur a accès aux ressources internes du réseau.

première le moindre problème auquel j'ai dû faire face était de stocker les coordonnées de l'utilisateur pour lui envoyer le code 2FA. Comme il est impossible de créer des champs de données arbitraires correspondant aux utilisateurs dans Mikrotik, le champ « commentaire » existant a été utilisé :

/ppp secrets add name=Mot de passe Petrov=4M@ngr ! commentaire="89876543210"

La seconde le problème s'est avéré plus sérieux - le choix du chemin et de la méthode de livraison du code. Trois schémas sont actuellement mis en œuvre : a) SMS via modem USB b) e-mail c) SMS via e-mail disponible pour les entreprises clientes de l'opérateur cellulaire rouge.

Oui, les systèmes SMS entraînent des coûts. Mais si vous regardez, "la sécurité est toujours une question d'argent" (c).
Personnellement, je n'aime pas le schéma avec e-mail. Non pas parce qu'il nécessite que le serveur de messagerie soit disponible pour le client en cours d'authentification - ce n'est pas un problème de diviser le trafic. Cependant, si un client enregistrait négligemment les mots de passe vpn et e-mail dans un navigateur, puis perdait son ordinateur portable, l'attaquant obtiendrait un accès complet au réseau de l'entreprise à partir de celui-ci.

Alors, c'est décidé - nous livrons un code unique à l'aide de messages SMS.

Третья Le problème était où comment générer un code pseudo-aléatoire pour 2FA dans MikroTik. Il n'y a pas d'analogue de la fonction random() dans le langage de script RouterOS, et j'ai déjà vu plusieurs générateurs de nombres pseudo-aléatoires de script de béquille. Je n'aimais aucun d'entre eux pour diverses raisons.

En fait, il existe un générateur de séquences pseudo-aléatoires dans MikroTik ! Il est caché d'un regard superficiel dans le contexte de /certificates scep-server. La première méthode obtenir un mot de passe à usage unique est facile et simple - avec la commande /certificates scep-server otp générer. Si nous effectuons une simple opération d'affectation de variable, nous obtiendrons une valeur de tableau qui pourra être utilisée ultérieurement dans des scripts.

deuxième méthode obtention d'un mot de passe à usage unique également facile à appliquer - en utilisant un service externe Random.org pour générer le type souhaité de séquence de nombres pseudo-aléatoires. Voici une version simplifiée cantilever exemple d'obtention de données dans une variable :

Code
: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

Une requête formatée pour la console (des caractères spéciaux d'échappement seront requis dans le corps du script) reçoit une chaîne de six chiffres dans la variable $rnd1. La commande "put" suivante affiche simplement la variable dans la console MikroTik.

Le quatrième problème qui devait être résolu rapidement - c'est comment et où le client connecté transférera son code à usage unique lors de la deuxième étape de l'authentification.

Authentification à deux facteurs des utilisateurs VPN via MikroTik et SMS

Il doit y avoir un service sur le routeur MikroTik qui peut accepter le code et le faire correspondre avec un client spécifique. Si le code fourni correspond à celui attendu, l'adresse du client doit être incluse dans une certaine liste "blanche", les adresses à partir desquelles l'accès au réseau interne de l'entreprise est autorisé.

En raison du mauvais choix de services, il a été décidé d'accepter les codes via http en utilisant le proxy Web intégré à Mikrotik. Et puisque le pare-feu peut fonctionner avec des listes dynamiques d'adresses IP, c'est le pare-feu qui effectue la recherche du code, en le faisant correspondre avec l'IP du client et en l'ajoutant à la liste « blanche » à l'aide de l'expression régulière Layer7. Le routeur lui-même s'est vu attribuer un nom DNS conditionnel "gw.local", un enregistrement A statique a été créé dessus pour être délivré aux clients PPP :

DNS
/ip dns static add name=gw.adresse locale=172.31.1.1

Capture du trafic des clients non vérifiés sur le proxy :
/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

Dans ce cas, le proxy a deux fonctions.

1. Ouvrez les connexions TCP avec les clients ;

2. En cas d'autorisation réussie, redirigez le navigateur client vers une page ou une image notifiant la réussite de l'authentification :

Configuration proxy
/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

Je vais lister les éléments de configuration importants :

  1. interface-list "2fa" - une liste dynamique d'interfaces client, dont le trafic nécessite un traitement dans 2FA ;
  2. address-list "2fa_jailed" - liste "grise" des adresses IP de tunnel des clients VPN ;
  3. address_list "2fa_approved" - liste "blanche" des adresses IP de tunnel des clients VPN qui ont réussi l'authentification à deux facteurs.
  4. chaîne de pare-feu "input_2fa" - il vérifie les paquets tcp pour la présence d'un code d'autorisation et fait correspondre l'adresse IP de l'expéditeur du code avec celle requise. Les règles de la chaîne sont ajoutées et supprimées dynamiquement.

Un organigramme simplifié du traitement des paquets ressemble à ceci :

Authentification à deux facteurs des utilisateurs VPN via MikroTik et SMS

Pour entrer dans le contrôle Layer7 du trafic des clients de la liste "grise" qui n'ont pas encore passé la deuxième étape d'authentification, une règle a été créée dans la chaîne "d'entrée" standard :

Code
/ip firewall filter add chain=input !src-address-list=2fa_approved action=jump jump-target=input_2fa

Commençons maintenant à attacher toute cette richesse au service PPP. MikroTik vous permet d'utiliser des scripts dans des profils (profil ppp) et de les affecter aux événements d'établissement et de rupture d'une connexion ppp. Les paramètres du profil ppp peuvent être appliqués à la fois au serveur PPP dans son ensemble et à des utilisateurs individuels. Dans le même temps, le profil attribué à l'utilisateur est prioritaire, remplaçant les paramètres du profil sélectionné pour le serveur dans son ensemble par ses paramètres spécifiés.

Grâce à cette approche, nous pouvons créer un profil spécial pour l'authentification à deux facteurs et l'attribuer non pas à tous les utilisateurs, mais uniquement à ceux qui le jugent nécessaire. Cela peut être pertinent si vous utilisez les services PPP non seulement pour connecter les utilisateurs finaux, mais en même temps pour établir des connexions site à site.

Dans le profil spécial nouvellement créé, nous utilisons l'ajout dynamique de l'adresse et de l'interface de l'utilisateur connecté aux listes « grises » d'adresses et d'interfaces :

boîte à victoire
Authentification à deux facteurs des utilisateurs VPN via MikroTik et SMS

Code
/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

Il est nécessaire d'utiliser à la fois les listes « liste d'adresses » et « liste d'interfaces » pour détecter et capturer le trafic des clients VPN non secondaires dans la chaîne dstnat (préroutage).

Une fois la préparation terminée, des chaînes de pare-feu supplémentaires et un profil sont créés, nous écrirons un script responsable de la génération automatique du code 2FA et des règles de pare-feu individuelles.

Documentation wiki.mikrotik.com sur PPP-Profile nous enrichit d'informations sur les variables associées aux événements de connexion-déconnexion du client PPP "Exécuter le script sur l'événement de connexion de l'utilisateur. Ce sont des variables disponibles qui sont accessibles pour le script d'événement : utilisateur, adresse locale, adresse distante, identifiant de l'appelant, identifiant de l'appelé, interface". Certains d'entre eux nous sont très utiles.

Code utilisé dans le profil pour l'événement de connexion 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

Surtout pour ceux qui aiment copier-coller sans réfléchir, je vous préviens - le code est tiré de la version de test et peut contenir des fautes de frappe mineures. Il ne sera pas difficile pour une personne compréhensive de déterminer exactement où.

Lorsqu'un utilisateur se déconnecte, un événement "On-Down" est généré et le script correspondant avec paramètres est appelé. La tâche de ce script est de nettoyer les règles de pare-feu créées pour l'utilisateur déconnecté.

Code utilisé dans le profil pour l'événement de connexion 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]
Vous pouvez ensuite créer des utilisateurs et affecter tout ou partie d'entre eux à un profil d'authentification à deux facteurs.

boîte à victoire
Authentification à deux facteurs des utilisateurs VPN via MikroTik et SMS

Code
/ppp secrets set [find name=Petrov] profile=2FA

À quoi cela ressemble du côté client.

Lorsqu'une connexion VPN est établie, un téléphone/tablette Android/iOS avec une carte SIM reçoit un SMS comme celui-ci :

SMS
Authentification à deux facteurs des utilisateurs VPN via MikroTik et SMS

Si la connexion est établie directement depuis le téléphone/tablette, alors vous pouvez passer par 2FA simplement en cliquant sur le lien du message. C'est confortable.

Si la connexion VPN est établie à partir d'un PC, l'utilisateur devra saisir un formulaire de mot de passe minimal. Un petit formulaire sous forme de fichier HTML est remis à l'utilisateur lors de la mise en place du VPN. Le fichier peut même être envoyé par courrier afin que l'utilisateur le sauvegarde et crée un raccourci dans un endroit pratique. Il ressemble à ceci :

Étiquette sur la table
Authentification à deux facteurs des utilisateurs VPN via MikroTik et SMS

L'utilisateur clique sur le raccourci, un simple formulaire de saisie de code s'ouvre, qui collera le code dans l'URL ouverte :

Formulaire d'écran
Authentification à deux facteurs des utilisateurs VPN via MikroTik et SMS

La forme la plus primitive est donnée en exemple. Ceux qui le souhaitent peuvent modifier eux-mêmes.

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>

Si l'autorisation a réussi, l'utilisateur verra le logo MikroTik dans le navigateur, ce qui devrait signaler une authentification réussie :

Authentification à deux facteurs des utilisateurs VPN via MikroTik et SMS

Notez que l'image est renvoyée par le serveur Web MikroTik intégré à l'aide de WebProxy Deny Redirect.

Je suppose que l'image peut être personnalisée à l'aide de l'outil "hotspot", en y téléchargeant votre propre version et en y définissant l'URL Deny Redirect avec WebProxy.

Une grande demande à ceux qui essaient d'acheter le Mikrotik "jouet" le moins cher pour 20 $ et de remplacer un routeur de 500 $ par celui-ci - ne faites pas ça. Les appareils comme "hAP Lite" / "hAP mini" (point d'accès domestique) ont un processeur très faible (smips), et il est probable qu'ils ne feront pas face à la charge du segment professionnel.

Attention! Cette solution a un inconvénient : lorsque les clients se connectent ou se déconnectent, des changements de configuration se produisent, que le routeur tente d'enregistrer dans sa mémoire non volatile. Avec un grand nombre de clients et des connexions et déconnexions fréquentes, cela peut entraîner une dégradation de la mémoire interne du routeur.

PS : Les méthodes de livraison du code au client peuvent être étendues et complétées dans la mesure où vos capacités de programmation sont suffisantes. Par exemple, vous pouvez envoyer des messages au télégramme ou ... suggérer des options !

J'espère que l'article vous sera utile et contribuera à sécuriser un peu plus les réseaux des petites et moyennes entreprises.

Source: habr.com