Autenticação de dois fatores de usuários VPN via MikroTik e SMS

Olá colegas! Hoje, quando a intensidade das paixões em torno do “trabalho remoto” diminuiu um pouco, a maioria dos administradores ganhou a tarefa de acesso remoto dos funcionários à rede corporativa, é hora de compartilhar minha experiência de longa data na melhoria da segurança VPN. Este artigo não estará na moda agora IPSec IKEv2 e xAuth. É sobre construir um sistema. autenticação de dois fatores (2FA) Usuários VPN quando o MikroTik atua como um servidor VPN. Nomeadamente, quando são utilizados protocolos "clássicos" como o PPP.

Autenticação de dois fatores de usuários VPN via MikroTik e SMS

Hoje vou te contar como proteger o MikroTik PPP-VPN mesmo em caso de "sequestro" da conta do usuário. Quando este esquema foi apresentado a um de meus clientes, ele o descreveu brevemente como “bem, agora é como em um banco!”.

O método não usa serviços de autenticador externo. As tarefas são executadas internamente pelo próprio roteador. Sem custo para o cliente conectado. O método funciona para clientes de PC e dispositivos móveis.

O esquema geral de proteção é o seguinte:

  1. O endereço IP interno de um usuário que se conectou com sucesso ao servidor VPN é automaticamente adicionado à lista cinza.
  2. O evento de conexão gera automaticamente um código único que é enviado ao usuário por meio de um dos métodos disponíveis.
  3. Os endereços nesta lista têm acesso limitado aos recursos da rede local, com exceção do serviço “autenticador”, que está aguardando o recebimento de uma senha de uso único.
  4. Após a apresentação do código, o usuário tem acesso aos recursos internos da rede.

primeiro o menor problema que tive que enfrentar foi armazenar informações de contato sobre o usuário para enviar a ele o código 2FA. Como é impossível criar campos de dados arbitrários correspondentes aos usuários no Mikrotik, foi utilizado o campo “comentário” existente:

/ppp segredos adicionar nome=Petrov senha=4M@ngr! comentário = "89876543210"

O segundo o problema acabou sendo mais sério - a escolha do caminho e método de entrega do código. Atualmente estão implementados três esquemas: a) SMS via USB-modem b) e-mail c) SMS via e-mail disponível para clientes corporativos da operadora de celular red.

Sim, os esquemas de SMS trazem custos. Mas se você olhar, "segurança é sempre sobre dinheiro" (c).
Eu pessoalmente não gosto do esquema com e-mail. Não porque requer que o servidor de correio esteja disponível para o cliente que está sendo autenticado - não é um problema dividir o tráfego. No entanto, se um cliente salvar descuidadamente as senhas VPN e de e-mail em um navegador e depois perder seu laptop, o invasor obterá acesso total à rede corporativa a partir dele.

Então, está decidido - entregamos um código único usando mensagens SMS.

Третья O problema era onde como gerar um código pseudoaleatório para 2FA no MikroTik. Não há análogo da função random () na linguagem de script do RouterOS, e já vi vários geradores de números pseudo-aleatórios de script de muleta antes. Não gostei de nenhum deles por vários motivos.

Na verdade, existe um gerador de sequência pseudo-aleatória no MikroTik! Ele está oculto de uma olhada superficial no contexto de /certificates scep-server. O primeiro método obter uma senha de uso único é fácil e simples - com o comando /certificates scep-server otp gerar. Se realizarmos uma simples operação de atribuição de variável, obteremos um valor de array que poderá ser utilizado posteriormente em scripts.

A segunda maneira obtenção de uma senha de uso único que também é fácil de aplicar - usando um serviço externo random.org para gerar o tipo desejado de sequência de números pseudo-aleatórios. aqui é simplificado cantilever exemplo de obtenção de dados em uma variável:

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

Uma solicitação formatada para o console (caracteres especiais de escape serão necessários no corpo do script) recebe uma string de seis dígitos na variável $rnd1. O seguinte comando "put" simplesmente exibe a variável no console do MikroTik.

o quarto problema que teve que ser resolvido rapidamente - é assim e para onde o cliente conectado irá transferir seu código único no segundo estágio de autenticação.

Autenticação de dois fatores de usuários VPN via MikroTik e SMS

Deve haver um serviço no roteador MikroTik que possa aceitar o código e combiná-lo com um cliente específico. Se o código fornecido corresponder ao esperado, o endereço do cliente deve ser incluído em uma determinada lista "branca", endereços a partir dos quais é permitido o acesso à rede interna da empresa.

Devido à má escolha de serviços, optou-se por aceitar códigos via http usando o webproxy embutido no Mikrotik. E como o firewall pode trabalhar com listas dinâmicas de endereços IP, é o firewall que realiza a busca pelo código, combinando-o com o IP do cliente e adicionando-o à lista “branca” usando o regexp Layer7. O próprio roteador recebeu um nome DNS condicional "gw.local", um registro A estático foi criado nele para emissão para clientes PPP:

DNS
/ip dns estático adicionar nome=gw.local endereço=172.31.1.1

Capturando tráfego de clientes não 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

Nesse caso, o proxy tem duas funções.

1. Abra conexões tcp com clientes;

2. Em caso de autorização bem-sucedida, redirecione o navegador do cliente para uma página ou imagem notificando sobre a autenticação bem-sucedida:

Configuração 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 listar os elementos de configuração importantes:

  1. interface-list "2fa" - uma lista dinâmica de interfaces de cliente, cujo tráfego requer processamento no 2FA;
  2. lista de endereços "2fa_jailed" - lista "cinza" de endereços IP de túnel de clientes VPN;
  3. address_list "2fa_approved" - lista "branca" de endereços IP de túnel de clientes VPN que passaram com sucesso na autenticação de dois fatores.
  4. cadeia de firewall "input_2fa" - verifica os pacotes tcp quanto à presença de um código de autorização e corresponde ao endereço IP do remetente do código com o necessário. As regras na cadeia são adicionadas e removidas dinamicamente.

Um fluxograma simplificado de processamento de pacotes se parece com isto:

Autenticação de dois fatores de usuários VPN via MikroTik e SMS

Para entrar na verificação Layer7 do tráfego de clientes da lista "cinza" que ainda não passaram pelo segundo estágio de autenticação, uma regra foi criada na cadeia "input" padrão:

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

Agora vamos começar a atrelar toda essa riqueza ao serviço de PPP. O MikroTik permite que você use scripts em perfis (ppp-profile) e os atribua aos eventos de estabelecimento e interrupção de uma conexão ppp. As configurações do perfil ppp podem ser aplicadas ao servidor PPP como um todo ou a usuários individuais. Ao mesmo tempo, o perfil atribuído ao usuário tem prioridade, substituindo os parâmetros do perfil selecionado para o servidor como um todo com seus parâmetros especificados.

Como resultado dessa abordagem, podemos criar um perfil especial para autenticação de dois fatores e atribuí-lo não a todos os usuários, mas apenas àqueles que considerarem necessário fazê-lo. Isso pode ser relevante se você usar serviços PPP não apenas para conectar usuários finais, mas ao mesmo tempo para construir conexões site a site.

No perfil especial recém-criado, usamos a adição dinâmica do endereço e interface do usuário conectado às listas "cinza" de endereços e interfaces:

caixa de vitória
Autenticação de dois fatores de usuários VPN via 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

É necessário usar as listas "lista de endereços" e "lista de interfaces" para detectar e capturar o tráfego de clientes VPN não secundários na cadeia dstnat (pré-roteamento).

Quando a preparação estiver concluída, cadeias de firewall adicionais e um perfil forem criados, escreveremos um script responsável pela geração automática do código 2FA e regras de firewall individuais.

Documentação wiki.mikrotik.com on PPP-Profile nos enriquece com informações sobre variáveis ​​associadas a eventos de conexão-desconexão do cliente PPP "Execute o script no evento de login do usuário. Estas são as variáveis ​​disponíveis que são acessíveis para o script de evento: user, local-address, remote-address, caller-id, call-id, interface". Alguns deles são muito úteis para nós.

Código usado no perfil para evento de conexão on-up 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

Especialmente para quem gosta de copiar e colar sem pensar, aviso - o código foi retirado da versão de teste e pode conter pequenos erros de digitação. Não será difícil para uma pessoa compreensiva descobrir exatamente onde.

Quando um usuário se desconecta, um evento “On-Down” é gerado e o script correspondente com parâmetros é chamado. A tarefa deste script é limpar as regras de firewall criadas para o usuário desconectado.

Código usado no perfil para evento de conexão 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]
Você pode criar usuários e atribuir todos ou alguns deles a um perfil de autenticação de dois fatores.

caixa de vitória
Autenticação de dois fatores de usuários VPN via MikroTik e SMS

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

Como fica do lado do cliente.

Quando uma conexão VPN é estabelecida, um telefone/tablet Android/iOS com um cartão SIM recebe um SMS como este:

SMS
Autenticação de dois fatores de usuários VPN via MikroTik e SMS

Se a conexão for estabelecida diretamente do telefone / tablet, você poderá passar pelo 2FA simplesmente clicando no link da mensagem. É confortável.

Se a conexão VPN for estabelecida a partir de um PC, o usuário deverá inserir um formulário de senha mínima. Um pequeno formulário na forma de um arquivo HTML é fornecido ao usuário ao configurar a VPN. O arquivo pode até ser enviado por correio para que o usuário o salve e crie um atalho em um local conveniente. Se parece com isso:

Etiqueta na mesa
Autenticação de dois fatores de usuários VPN via MikroTik e SMS

O usuário clica no atalho, um formulário de entrada de código simples é aberto, que irá colar o código no URL aberto:

Formulário de tela
Autenticação de dois fatores de usuários VPN via MikroTik e SMS

A forma mais primitiva é dada como exemplo. Aqueles que desejam podem 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 autorização foi bem-sucedida, o usuário verá o logotipo do MikroTik no navegador, o que deve sinalizar a autenticação bem-sucedida:

Autenticação de dois fatores de usuários VPN via MikroTik e SMS

Observe que a imagem é retornada do servidor da Web MikroTik integrado usando WebProxy Deny Redirect.

Suponho que a imagem possa ser personalizada usando a ferramenta "hotspot", carregando sua própria versão lá e definindo o URL de negação de redirecionamento com o WebProxy.

Um grande pedido para aqueles que estão tentando comprar o Mikrotik de "brinquedo" mais barato por $ 20 e substituir um roteador de $ 500 por ele - não faça isso. Dispositivos como "hAP Lite" / "hAP mini" (ponto de acesso doméstico) têm uma CPU muito fraca (smips) e provavelmente não suportarão a carga no segmento de negócios.

Atenção! Essa solução tem uma desvantagem: quando os clientes se conectam ou desconectam, ocorrem alterações de configuração, que o roteador tenta salvar em sua memória não volátil. Com um grande número de clientes e conexões e desconexões frequentes, isso pode levar à degradação do armazenamento interno do roteador.

PS: Os métodos de entrega de código ao cliente podem ser expandidos e complementados na medida em que seus recursos de programação forem suficientes. Por exemplo, você pode enviar mensagens para o telegrama ou ... sugerir opções!

Espero que o artigo lhe seja útil e ajude a tornar as redes de pequenas e médias empresas um pouco mais seguras.

Fonte: habr.com