Autenticación de dous factores dos usuarios de VPN a través de MikroTik e SMS

Ola compañeiros! Hoxe, cando a intensidade das paixóns arredor do "traballo remoto" diminuíu un pouco, a maioría dos administradores gañaron a tarefa de acceso remoto dos empregados á rede corporativa, é hora de compartir a miña experiencia de longa data na mellora da seguridade da VPN. Este artigo non estará de moda agora IPSec IKEv2 e xAuth. Trátase de construír un sistema. autenticación de dous factores (2FA) Usuarios VPN cando MikroTik actúa como servidor VPN. É dicir, cando se utilizan protocolos "clásicos" como PPP.

Autenticación de dous factores dos usuarios de VPN a través de MikroTik e SMS

Hoxe vouche dicir como protexer MikroTik PPP-VPN aínda que a conta de usuario sexa "secuestrada". Cando este esquema foi presentado a un dos meus clientes, describiuno brevemente como "ben, agora é como nun banco!".

O método non usa servizos de autenticación externo. As tarefas son realizadas internamente polo propio router. Sen custo para o cliente que se conecta. O método funciona tanto para clientes de PC como para dispositivos móbiles.

O réxime xeral de protección é o seguinte:

  1. O enderezo IP interno dun usuario que se conectou correctamente ao servidor VPN aparece automaticamente na lista gris.
  2. O evento de conexión xera automaticamente un código único que se envía ao usuario mediante un dos métodos dispoñibles.
  3. Os enderezos desta lista teñen acceso limitado aos recursos da rede local, a excepción do servizo "autenticador", que está á espera de recibir un código de acceso único.
  4. Despois de presentar o código, o usuario ten acceso aos recursos internos da rede.

Primeira o menor problema que tiven que enfrontar foi almacenar información de contacto sobre o usuario para enviarlle o código 2FA. Dado que é imposible crear campos de datos arbitrarios correspondentes a usuarios en Mikrotik, utilizouse o campo "comentario" existente:

/ppp secrets add name=contrasinal Petrov=4M@ngr! comment="89876543210"

O segundo o problema resultou ser máis grave: a elección do camiño e do método de entrega do código. Actualmente están implementados tres esquemas: a) SMS vía módem USB b) correo electrónico c) SMS vía correo electrónico dispoñible para os clientes corporativos do operador de telefonía móbil vermella.

Si, os esquemas de SMS traen custos. Pero se miras, "a seguridade sempre ten que ver con diñeiro" (c).
Persoalmente non me gusta o esquema co correo electrónico. Non porque requira que o servidor de correo estea dispoñible para o cliente que se autentica; non é un problema dividir o tráfico. Non obstante, se un cliente gardaba descoidadamente os contrasinais de VPN e correo electrónico nun navegador e despois perdeu o seu portátil, o atacante obtería acceso completo á rede corporativa desde el.

Entón, decidiuse: entregamos un código único mediante mensaxes SMS.

Terceiro O problema era onde como xerar un código pseudoaleatorio para 2FA en MikroTik. Non hai un análogo da función random() na linguaxe de secuencias de comandos RouterOS, e xa vin varios xeradores de números pseudoaleatorios de guións de muleta. Non me gustou ningún deles por varias razóns.

De feito, hai un xerador de secuencias pseudoaleatorias en MikroTik! Ocúltase dunha mirada superficial no contexto de /certificates scep-server. O primeiro camiño obter un contrasinal único é sinxelo e sinxelo - co comando /certificates scep-server otp generate. Se realizamos unha simple operación de asignación de variables, obteremos un valor de matriz que se pode usar máis tarde nos scripts.

A segunda forma obter un contrasinal único que tamén é fácil de aplicar mediante un servizo externo random.org para xerar o tipo desexado de secuencia de números pseudoaleatorios. Aquí tes un simplificado cantilever exemplo de obter datos nunha variable:

Código
: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

Unha solicitude formateada para a consola (serán necesarios caracteres especiais de escape no corpo do script) recibe unha cadea de seis díxitos na variable $rnd1. O seguinte comando "put" simplemente mostra a variable na consola MikroTik.

O cuarto problema que tivo que resolverse rapidamente: así e onde o cliente conectado transferirá o seu código único na segunda etapa da autenticación.

Autenticación de dous factores dos usuarios de VPN a través de MikroTik e SMS

Debe haber un servizo no enrutador MikroTik que poida aceptar o código e relacionalo cun cliente específico. Se o código proporcionado coincide co esperado, o enderezo do cliente debe incluírse nunha determinada lista "branca", enderezos desde os que se permite o acceso á rede interna da empresa.

Debido á mala elección dos servizos, decidiuse aceptar códigos vía http usando o webproxy integrado en Mikrotik. E xa que o firewall pode funcionar con listas dinámicas de enderezos IP, é o firewall o que realiza a busca do código, facéndoo coincidir coa IP do cliente e engadíndoo á lista "branca" mediante a expresión regular de Layer7. O propio enrutador ten asignado un nome DNS condicional "gw.local", creouse nel un rexistro A estático para emitilo aos clientes PPP:

DNS
/ip dns static add name=gw.local address=172.31.1.1

Capturando o tráfico de clientes non verificados no 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

Neste caso, o proxy ten dúas funcións.

1. Abre conexións tcp cos clientes;

2. En caso de autorización exitosa, redirixe o navegador do cliente a unha páxina ou imaxe que notifique sobre a autenticación correcta:

Configuración de 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

Vou enumerar os elementos de configuración importantes:

  1. interface-list "2fa" - unha lista dinámica de interfaces de cliente, cuxo tráfico require procesamento dentro de 2FA;
  2. address-list "2fa_jailed" - lista "gris" de enderezos IP do túnel dos clientes VPN;
  3. address_list "2fa_approved" - lista "branca" de enderezos IP de túneles de clientes VPN que pasaron con éxito a autenticación de dous factores.
  4. cadea de firewall "input_2fa": comproba os paquetes tcp para a presenza dun código de autorización e fai coincidir o enderezo IP do remitente do código co necesario. As regras da cadea engádense e elimínanse de forma dinámica.

Un diagrama de fluxo simplificado do procesamento de paquetes ten o seguinte aspecto:

Autenticación de dous factores dos usuarios de VPN a través de MikroTik e SMS

Para entrar na comprobación de tráfico de Layer7 dos clientes da lista "gris" que aínda non pasaron a segunda etapa de autenticación, creouse unha regra na cadea de "entrada" estándar:

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

Agora imos comezar a fixar toda esta riqueza ao servizo PPP. MikroTik permítelle usar scripts nos perfís (ppp-profile) e asignalos aos eventos de establecer e romper unha conexión ppp. A configuración do perfil ppp pódese aplicar ao servidor PPP como un todo ou a usuarios individuais. Ao mesmo tempo, o perfil asignado ao usuario ten prioridade, anulando os parámetros do perfil seleccionado para o servidor no seu conxunto cos seus parámetros especificados.

Como resultado deste enfoque, podemos crear un perfil especial para a autenticación de dous factores e asignalo non a todos os usuarios, senón só a aqueles que consideren necesario facelo. Isto pode ser relevante se usa servizos PPP non só para conectar usuarios finais, senón ao mesmo tempo para crear conexións de sitio a sitio.

No perfil especial recén creado, usamos a adición dinámica do enderezo e da interface do usuario conectado ás listas "grises" de enderezos e interfaces:

winbox
Autenticación de dous factores dos usuarios de VPN a través de MikroTik e SMS

Código
/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

É necesario utilizar listas de "lista de enderezos" e "lista de interfaces" para detectar e capturar o tráfico de clientes VPN non secundarios na cadea dstnat (enrutamento previo).

Cando se complete a preparación, créanse cadeas de firewall adicionais e un perfil, escribiremos un script responsable da xeración automática do código 2FA e das regras individuais do firewall.

Documentación wiki.mikrotik.com en PPP-Profile enriquecenos con información sobre variables asociadas aos eventos de conexión e desconexión do cliente PPP "Executa o script no evento de inicio de sesión do usuario. Estas son variables dispoñibles para o script do evento: usuario, enderezo local, enderezo remoto, identificador de chamada, identificador de chamada, interface". Algúns deles son moi útiles para nós.

Código usado no perfil para o evento de conexión PPP activada

#Логируем для отладки полученные переменные 
: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

Especialmente para aqueles aos que lles gusta copiar e pegar sen pensar, advírtoche: o código está tomado da versión de proba e pode conter pequenos erros tipográficos. Non será difícil para unha persoa comprensiva descubrir exactamente onde.

Cando un usuario se desconecta, xérase un evento "On-Down" e chámase o script correspondente con parámetros. A tarefa deste script é limpar as regras do firewall creadas para o usuario desconectado.

Código usado no perfil para o evento de conexión 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]
Despois podes crear usuarios e asignar todos ou algúns deles a un perfil de autenticación de dous factores.

winbox
Autenticación de dous factores dos usuarios de VPN a través de MikroTik e SMS

Código
/ppp secrets set [find name=Petrov] profile=2FA

Como se ve no lado do cliente.

Cando se establece unha conexión VPN, un teléfono ou tableta Android/iOS cunha tarxeta SIM recibe unha SMS como esta:

SMS
Autenticación de dous factores dos usuarios de VPN a través de MikroTik e SMS

Se a conexión se establece directamente desde o teléfono / tableta, pode pasar por 2FA simplemente facendo clic na ligazón da mensaxe. É cómodo.

Se a conexión VPN se establece desde un PC, requirirase ao usuario que introduza un formulario de contrasinal mínimo. Un pequeno formulario en forma de ficheiro HTML entrégaselle ao usuario ao configurar a VPN. O ficheiro pode incluso enviarse por correo para que o usuario o garde e cree un atallo nun lugar cómodo. Parece así:

Etiqueta na mesa
Autenticación de dous factores dos usuarios de VPN a través de MikroTik e SMS

O usuario fai clic no atallo, ábrese un sinxelo formulario de entrada de código, que pegará o código no URL aberto:

Formulario de pantalla
Autenticación de dous factores dos usuarios de VPN a través de MikroTik e SMS

A forma máis primitiva ponse como exemplo. Os que o desexen poden modificar por si mesmos.

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>

Se a autorización foi exitosa, o usuario verá o logotipo de MikroTik no navegador, que debería indicar a autenticación exitosa:

Autenticación de dous factores dos usuarios de VPN a través de MikroTik e SMS

Teña en conta que a imaxe devólvese desde o servidor web MikroTik incorporado mediante a redirección de denegación de WebProxy.

Supoño que a imaxe pódese personalizar usando a ferramenta "hotspot", cargando alí a túa propia versión e configurando a URL de redirección denegada con WebProxy.

Unha gran solicitude para aqueles que están tentando mercar o "xoguete" Mikrotik máis barato por 20 dólares e substituír un enrutador de 500 dólares por el, non o fagas. Dispositivos como "hAP Lite" / "hAP mini" (punto de acceso doméstico) teñen unha CPU moi débil (smips) e é probable que non fagan fronte á carga no segmento empresarial.

Advertencia! Esta solución ten unha desvantaxe: cando os clientes se conectan ou desconectan, prodúcense cambios de configuración, que o router tenta gardar na súa memoria non volátil. Cun gran número de clientes e conexións e desconexións frecuentes, isto pode levar á degradación do almacenamento interno do router.

PD: Os métodos para entregar código ao cliente pódense ampliar e completar na medida en que as súas capacidades de programación sexan suficientes. Por exemplo, podes enviar mensaxes a telegram ou... suxerir opcións!

Espero que o artigo che resulte útil e axude a que as redes das pequenas e medianas empresas sexan un pouco máis seguras.

Fonte: www.habr.com