Olá colegas! Hoje, quando a agitação em torno do "trabalho remoto" diminuiu um pouco, a maioria dos administradores resolveu a questão do acesso remoto dos funcionários à rede corporativa. Chegou a hora de compartilhar meu antigo desenvolvimento para aumentar a segurança da VPN. Neste artigo, não falaremos sobre os modernos IPSec IKEv2 e xAuth. A conversa será sobre a construção de um sistema para usuários da VPN, quando o MikroTik atua como servidor VPN. Ou seja, quando são utilizados protocolos "clássicos" como PPP.

Hoje vou contar como proteger o MikroTik PPP-VPN mesmo no caso de um "sequestro" da conta do usuário. Quando este esquema foi implementado para um dos meus clientes, ele o descreveu brevemente como "agora é como um banco!".
O método não utiliza serviços de autenticação externos. As tarefas são realizadas pelos recursos internos do próprio roteador. Sem custos para o cliente conectado. O método funciona tanto para clientes de PC quanto para dispositivos móveis.
O esquema geral de proteção é o seguinte:
- O endereço IP interno do usuário que se conectou com sucesso ao servidor VPN é automaticamente adicionado à "lista cinza".
- O evento de conexão gera automaticamente um código único, que é enviado ao usuário por um dos métodos disponíveis.
- Os endereços que estão nessa lista têm o acesso restrito aos recursos da rede local, exceto ao serviço de "autenticador", que aguarda a recepção do código único de senha.
- Após a apresentação do código, o usuário ganha acesso aos recursos internos da rede.
Primeiro O menor problema que enfrentei foi armazenar informações de contato do usuário para o envio do código 2FA. Como não é possível criar campos de dados arbitrários correspondentes aos usuários no MikroTik, utilizei o campo "comentário" existente:
/ppp secrets add name=Petrov password=4M@ngr! comment=«89876543210»
Segundo O problema acabou sendo mais sério — a escolha do caminho e do método de entrega do código. No momento, foram implementadas três esquemas: a) SMS via modem USB b) e-mail c) SMS via e-mail disponível para os clientes corporativos da operadora de celular vermelha.
Sim, os esquemas com SMS geram custos. Mas se analisarmos, "a segurança sempre envolve dinheiro".
O esquema de e-mail não me agrada. Não porque exija a disponibilidade do servidor de e-mail para o cliente autenticado - não é problema dividir o tráfego. No entanto, se o cliente imprudentemente salvou senhas tanto no VPN quanto no e-mail no navegador, e depois perdeu o laptop, o invasor terá acesso total à rede corporativa.
Então, está decidido - enviaremos um código único por meio de mensagens SMS.
Terceiro o problema estava em onde e como gerar um código pseudoaleatório para 2FA no MikroTik. Na linguagem de script do RouterOS não há uma função equivalente à random() e já vi vários geradores de números pseudoaleatórios improvisados. Nenhum deles me agradou por vários motivos.
Na verdade, há um gerador de sequências pseudoaleatórias no MikroTik! Ele está escondido a um olhar superficial no contexto \/certificates scep-server. A primeira maneira obter uma senha única é fácil - com o comando /certificates scep-server otp generate. Se realizarmos uma operação simples de atribuição à variável, obteremos um valor do tipo array que pode ser usado em scripts posteriores.
Segunda maneira obter uma senha única, que também é fácil de aplicar - usando um serviço externo para gerar a sequência desejada de números pseudoaleatórios. Aqui está um exemplo simplificado interface gráfica de como obter 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
A solicitação formatada para o console (no corpo do script será necessário escapar caracteres especiais) obtém uma string de seis caracteres-dígitos na variável $rnd1. O próximo comando 'put' simplesmente exibe a variável no console do MikroTik.
O quarto problema, que teve que ser resolvido rapidamente - é como e onde o cliente conectado vai enviar seu código único na segunda fase de autenticação.

No roteador MikroTik, deve existir um serviço capaz de receber o código e associá-lo a um cliente específico. Se o código fornecido coincidir com o esperado, o endereço do cliente deve ser colocado em uma espécie de ‘lista branca’, cujos endereços têm acesso à rede interna da empresa.
Devido à escassa seleção de serviços, foi tomada a decisão de aceitar códigos via http utilizando o webproxy embutido no MikroTik. E como o firewall é capaz de trabalhar com listas dinâmicas de endereços IP, a busca pelo código, a correspondência com o IP do cliente e a inclusão na lista "branca" é realizada exatamente pelo firewall através de Layer7 regexp. O próprio roteador recebeu o nome DNS condicional "gw.local", no qual foi criada uma entrada A estática para fornecimento aos clientes PPP:
DNS
/ip dns static add name=gw.local address=172.31.1.1
Captura de tráfego proxy de clientes não verificados:
/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 possui duas funções.
1. Abrir conexões tcp com clientes;
2. Em caso de autorização bem-sucedida, redirecionar o navegador do cliente para uma página ou imagem informando sobre a conclusão bem-sucedida da autenticação:
Configuração do 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 importantes da configuração:
- interface-list "2fa" — lista dinâmica de interfaces de clientes, cujo tráfego requer processamento no contexto do 2FA;
- address-list "2fa_jailed" — lista "cinza" de endereços IP de túneis de clientes VPN;
- address_list "2fa_approved" — lista "branca" de endereços IP de túneis de clientes VPN que passaram com sucesso pela autenticação de dois fatores.
- cadeia do firewall "input_2fa" — nela ocorre a verificação de pacotes tcp em busca de um código de autorização e a correspondência do endereço IP do remetente do código com o exigido. As regras nesta cadeia são adicionadas e removidas dinamicamente.
Um diagrama de bloco simplificado do processamento do pacote é assim:
Para que o tráfego dos clientes na lista "cinza" que ainda não passaram pela segunda etapa da autenticação sejam verificados por Layer7, foi criada uma regra na cadeia padrão "input":
Código
/ip firewall filter add chain=input !src-address-list=2fa_aprovado action=pular jump-target=input_2fa
Agora começaremos a integrar toda essa riqueza ao serviço PPP. O MikroTik permite o uso de scripts em perfis (ppp-profile) e atribuí-los a eventos de estabelecimento e interrupção de conexão ppp. As configurações do ppp-profile podem ser aplicadas tanto ao servidor PPP como a usuários individuais. Nesse caso, o perfil atribuído ao usuário tem prioridade, sobrepondo suas configurações definidas às configurações do perfil escolhido para o servidor como um todo.
Como resultado dessa abordagem, podemos criar um perfil especial para autenticação de dois fatores e atribuí-lo apenas aos usuários que consideramos necessário. Isso pode ser relevante se os serviços PPP forem usados não apenas para conectar usuários finais, mas também para estabelecer conexões site-to-site.
No perfil especial recém-criado, usamos a adição dinâmica de endereços e interfaces dos usuários conectados nas listas "grays".
winbox
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 em conjunto as listas "address-list" e "interface-list" para determinar e capturar o tráfego de clientes VPN que não passaram pela autenticação secundária na cadeia dstnat (prerouting).
Quando a preparação terminar, cadeias adicionais do firewall e o perfil foram criados, escreveremos um script responsável pela autogeração do código 2FA e das regras específicas do firewall.
no PPP-Profile nos enriquece com informações sobre as variáveis relacionadas aos eventos de conexão e desconexão do cliente PPP "Execute script on user login-event. These are available variables that are accessible for the event script: user, local-address, remote-address, caller-id, called-id, interface". Algumas delas serão muito úteis para nós.
Código utilizado no perfil para o evento de conexão PPP on-up
#Логируем для отладки полученные переменные :log info ("endereço-local")
:informação de log ("endereço-remoto")
:informação de log ("id-do-chamador")
:informação de log ("id-chamado")
:informação de log ([/int pptp-server get ("interface") nome])
#Объявляем свои локальные переменные
:lista local "2fa_restrito"
:local viamodem falso
:porta-modem local "usb2"
#ищем автоматически созданную запись в адрес-листе "2fa_jailed"
:número-rec local1 [/ip fi address-list find address=("endereço-remoto") lista=$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
:telefone virtual [/ppp secret get [find name=$user] comment]#Готовим тело сообщения. Если клиент подключается к VPN прямо с телефона ему достаточно
#будет перейти прямо по ссылке из полученного сообщения
:mensagem local ("Seu código: " .$comm1."n Ou abra o link http://gw.local/otp/".$comm1."/")# Отправляем SMS по выбранному каналу - USB-модем или email-to-sms
se $viamodem faça={
/tool sms send phone-number=$vphone message=$msgboby port=$modemport }
senão={
/tool e-mail send server=a.b.c.d from=admin@mydomain.example to=mail2sms@mcommunicator.ru subject="@".$vphone body=$msgboby }#Генерируем Layer7 regexp
expressão regular local ("otp\/".$comm1)
:comentário local ("2fa_".("endereço-remoto"))
/ip firewall layer7-protocol add name=("comentário_v") comentário=(
"endereço-remoto") regexp=(
"expressão_regular_v")
#Генерируем правило проверяющее по 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=("comentário_v") protocolo=tcp endereço-fonte=(
"endereço-remoto") limite-destino=1,1,endereço-fonte/1m40s
Especialmente para aqueles que gostam de copiar e colar sem pensar, aviso: o código foi retirado de uma versão de teste e pode conter pequenos erros de digitação. Alguém que entende não terá dificuldade em perceber onde exatamente.Quando o usuário se desconecta, um evento "On-Down" é gerado e o script correspondente é chamado com os parâmetros. A tarefa desse script é limpar as regras do firewall criadas para o usuário desconectado.
Código utilizado no perfil para o evento de conexão PPP on-down
:comentário local ("2fa_".("endereço-remoto"))
/ip firewall address-list remove [find address=("endereço-remoto") list=2fa_aprovado]
/ip firewall filter remove [find chain="input_2fa" src-address=("endereço-remoto") ]
/ip firewall layer7-protocol remove [find name=$vcomment]
Após isso, é possível criar usuários e atribuir a todos ou a alguns deles um perfil com autenticação de dois fatores.winbox
Código
/ppp secrets set [find name=Petrov] profile=2FAComo isso aparece do lado do cliente.
Ao estabelecer uma conexão VPN, um SMS com um conteúdo semelhante a este chega ao telefone/tablet Android/iOS com cartão SIM:
SMSka
Se a conexão for estabelecida diretamente a partir do telefone/tablet, é possível passar pela 2FA apenas clicando no link da mensagem. Isso é conveniente.
Se a conexão VPN for estabelecida com o PC, o usuário precisará de uma forma mínima de inserir a senha. Um pequeno formulário em formato HTML é enviado ao usuário ao configurar a VPN. O arquivo pode até ser enviado por e-mail, para que o usuário o salve e crie um atalho em um local conveniente. Assim é que parece:
Atalho na área de trabalho
O usuário clica no atalho, abrindo um formulário simples para inserir o código, que será inserido na URL aberta:
Captura de tela do formulário
O formulário é bem simples, fornecido como exemplo. Aqueles que desejarem podem adaptá-lo às suas necessidades.
2fa_login_mini.html
<html> <head> <title>Login com OTP por SMS</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <form name="login" action="/pt/location.href='http://gw.local/otp/'+document.getElementById(‘text').value/" method="post" <input id="text" type="text" data-trp-original-action="location.href='http://gw.local/otp/'+document.getElementById(‘text').value"/><input type="hidden" name="trp-form-language" value="pt"/> <input type="button" value="Iniciar sessão" onclick="location.href='http://gw.local/otp/'+document.getElementById('text').value"/> </form> </body> </html>Se a autenticação for bem-sucedida, o usuário verá o logotipo da MikroTik no navegador, o que deve servir como um sinal de autenticação bem-sucedida:
Observa-se que a imagem é retornada do servidor web incorporado da MikroTik através do WebProxy Deny Redirect.
Acredito que a imagem pode ser personalizada usando a ferramenta 'hotspot', carregando sua própria versão e configurando a URL Deny Redirect no WebProxy.
Um grande pedido para aqueles que tentam substituir o roteador de $500 por um MikroTik 'brinquedo' de $20 — não façam isso. Dispositivos como 'hAP Lite'/'hAP mini' (home access point) têm um CPU muito fraco (smips) e provavelmente não conseguirão lidar com a carga no segmento empresarial.
Atenção! Esta solução tem uma desvantagem: ao conectar e desconectar clientes, ocorrem alterações na configuração, que o roteador tenta manter 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.
P.S.: os métodos de entrega do código ao cliente podem ser ampliados e complementados até onde suas habilidades de programação permitirem. Por exemplo, pode-se enviar mensagens no telegram ou... sugerir outras opções!
Espero que o artigo seja útil e ajude a tornar as redes de pequenas e médias empresas um pouco mais seguras.
Fonte: habr.com




