Como entregar IPv6+IPv4 no Mikrotik/RouterOS através de PPPoE/DHCPv6 PD e registrando os logs em um banco de dados
Neste tutorial vamos aprender como entregar IPv6 para clientes finais utilizando RouterOS/Mikrotik (Concentrador PPPoE) e registrar os logs dos prefixos IPv6 entregue na WAN (Remote IPv6 Prefix Pool) e na LAN (DHCPv6 PD Pool).
Ainda hoje encontramos alguns bugs no Mikrotik, e um dos maiores motivos de buscar essa solução foi que freeradius não registra os logs de IPv6 PD (Mikrotik), o IPv6 que vai se configurar na LAN cliente (o mais importante a ser guardado), seria muito mais fácil para muitos sistemas se implementassem o Delegated-IPv6-Prefix, mas já faz 6 anos (jan/2020) que é motivo de discussão lá no forum. E para variar a solução é dar aquele jeitinho…. (Popular gambiarra) 😛
Para montar esse servidor de logs você precisa apenas de um serviço WEB (Apache/NGINX) PHP7+ e um banco de dados MySQL/MariaDB.
Requisito para montar um servidor do zero:
– Debian 10 Stretch / Instalação Limpa
– Como criar um servidor WEB Apache + PHP + MariaDB + phpMyAdmin no Debian 10 Buster “LAMP”
Você precisa ter um pouquinho de conhecimento em IPv6 e saber dividir as subclasses. Recomendo dar uma olhadinha no http://ipv6.nic.br/ lá irá encontrar cursos do NIC.BR.
Recomendo você instalar uma calculadora de IPv6. Aqui vai uma calculador muito boa que uso no dia a dia.
# apt install wget python-ipaddr # wget https://blog.remontti.com.br/arquivos/Home/ip6calc -O /bin/ip6calc # chmod +x /bin/ip6calc
Para fazer o calculo use ex.:
# ip6calc 2001:db8:abcd::/48
Para esse projeto desenvolvi em PHP alguns arquivos onde fica “ouvido” os logs que o Mikrotik irá enviar e uma telinha simples para fazer buscas dos IPs nesse banco de dados. Já disponibilizei ele lá no github.
Com seu servidor web configurado, seria bacana criar um host no seu dns e configurar nesse seu servdor web um domínio virtual ex.: log6.seudominio.com.br onde você irá jogar os arquivos do projeto. Mas como muitos não tem essa facilidade vou tentar deixar aqui a forma mais simples, que é jogar os arquivos no diretório padrão do apache “/var/www/html”, assim qualquer um consegue montar 🙂
Acessamos o diretório base então
# cd /var/www/html # wget https://github.com/remontti/LogIPv6RouterOS/archive/master.zip # apt install unzip # unzip master.zip # mv LogIPv6RouterOS-master logs6 # cd logs6
Por segurança crie/edite um .htaccess para proteger que apenas determinados IPs tenham acesso. (apensar de ter um token)
# vim .htaccess
Altere pelo IPs que você deseja que tenham acesso. (Seus router e seu NOC)
Options -Indexes <RequireAll> <RequireAny> Require ip 200.200.200.0/24 Require ip 192.168.0.0/26 Require ip 2001:db8::/32 </RequireAny> </RequireAll>
Precisaremos criar um banco de dados e nossa tabela. Para gerar suas senhas/token recomendo https://senhasegura.remontti.com.br/ e gerar algo aleatório.
# mariadb -p
Crie o banco de dados, não esqueça de alterar a senha (SUA_SENHA_DA_CONEXAO)
CREATE DATABASE logs6; GRANT ALL PRIVILEGES ON logs6.* TO 'logs6'@'localhost' IDENTIFIED BY 'SUA_SENHA_DA_CONEXAO'; FLUSH PRIVILEGES; quit;
Importe a tabela utilizando a senha criada anteriormente
# mariadb -u logs6 logs6 < logs6_mikrotik.sql -p
Agora altere no arquivo config.php o token para validar seu envio de dados e acessar o interface simples que desenvolvi para buscas, e a senha de conexão com banco (db_password).
?php /* Your security token */ $token = 'xxxxxxxxxxxxx'; /* Set langage */ // Portugês Brasil: pt-br // English: en $lang = 'pt-br'; /* Db conect */ $db_host = 'localhost'; $db_user = 'logs6'; $db_password = 'SUA_SENHA_DA_CONEXAO'; $db_name = 'logs6';
Agora acesse sua http(s)://URL/logs6/. Você deve receber a seguinte tela.
Já pode autenticar com seu token (ainda não terá logs, então não adianta querer fazer buscas rsrsrs)
Se alguém tiver ideias melhores/criticas todas são bem vindas, sinta-se a vontade para criar forks do projeto.
Para entregar IPv6 em seu Mk é claro que precisa ter conectividade v6 em seu concentrador PPPoE (Não vou entrar em detalhes nessa parte pois entraria na questão roteamento da sua rede, mas se vale de ajuda como dica um iBGP/OSPF resolve fácil)
Servidor preparado para receber os logs vamos ao routerOS/Mikrotik. Você precisará criar duas Pool, uma para WAN outra para a LAN, como recomendação do nic.br para LAN do cliente devemos enviar um prefixo /56 (mas isso não é uma regra). A calcular pode ajudar muito nessa parte. No meu exemplo vou reservar um prefixo /48 para entregar prefixos /64 na WAN (65.536 prefixos/64), e um prefixo /45 entregando prefixos /56 oque daria 2.048 prefixos (clientes).
Alteramos no profile. Menu PPP aba Profiles.
Remote IPv6 Prefix Pool selecione sua pool_wan e DHCPv6 PD Pool sua pool_lan
Na abra Protocol, Use IPv6 selecione yes.
Vamos ao pulo do gato na aba Scripts. A ideia aqui é toda vez que um PPPoE conectar ou desconectar ele execute um script. Vai ser necessário que você altere o TOKEN que você configurou lá no config.php, informe a URL (URLUP) correta que encontrará seu arquivo log6.php e em checkconnection informe o IP do seu servidor (explico o motivo a seguir).
:global TOKEN "xxxxxxxxxxxxxxxx"; :global URLUP "http://logs6.remontti.com.br/log6.php"; :global checkconnection "200.200.200.200";
A lógica é: Antes de tentar enviar as informações/valores (via post ao log6.php) fazer uma verificação se a conexão exite com o servidor de log, isso foi necessário ao simular uma "queda de energia", as vezes ele pode autenticar antes de conseguir uma conexão (se seu o usuários estiver no routerOS e ai perdemos todos os logs) nesse caso ele fica aguardando por até 5 min na tentativa (ping ao ip checkconnection) antes prosseguir, caso exista uma conexão (checkconnection) então prossegue com o script coletando as informações.
Eu aproveitei coletar IPv4 como localAddr (NAS), remoteAddr (IPv4 entregue ao cliente) isso vai facilitar também em uma analise se você quiser bater com os dados do freeradius (radacct), já aproveitei também para capturar o callerId (MAC), serviço PPP calledId. Acredito que com essas informações podem ser uteis para outros fins. Seguindo o script todo o PPPoE que subir ele vai criar um prefixo (WAN) RemoteIPv6 e em seguida precisei fazer um while que setei 60 seg para que a cada segundo ele tente identificar em /ipv6 dhcp-server binding se o cliente solicitou o prefixo que ele vai auto se configurar em sua LAN, passando por esses requisitos ele irai gerar um LOG (que você também pode estar salvando em um servidor de log remoto) e finalizando fará um fetch com os dados do binding caso ele consiga ou enviará null para a URL e assim o servidor salva-lo no banco de dados. Você verá dois logs na tela de logs, um azul quando uma conexão subir e um vermelho quando desconectar, se você desejar não ter esses logs é só remover as linha "log warning message=..... / :log error message=....."
Acesse PPP vá até a aba profile e configure os script do profile. Não esqueça de alterar as variáveis globais.
On UP
{ :global TOKEN "xxxxxxxxxxxxxxxx"; :global URLUP "http://________________/logs6/log6.php"; :global checkconnection "200.200.200.200"; :local ii 0; :local tt 300; # Aguarda até 5min para tentar while ( $ii < $tt && ([/ping $checkconnection count=1]=0) ) do={ :put $ii :set $ii ($ii + 1) :delay delay-time=1s :log error "Awaiting connection ... $checkconnection"; } :local localAddr $"local-address" :local remoteAddr $"remote-address" :local callerId $"caller-id" :local calledId $"called-id" :local interfaceName [/interface get $interface name] :local RemoteIPv6 [/ipv6 nd prefix get value-name=prefix [find interface=$interfaceName]] :local i 0; :local x 1; :local t 60; # Segundos aguardando ipv6 ser configurado no cliente while ($i < $t && [ :len [/ipv6 dhcp-server binding find server=$interfaceName] ] < $x) do={ :put $i :set $i ($i + 1) :delay delay-time=1s } if ($i = $t) do={ :log warning message="UP: $user | $callerId | $calledId | $remoteAddr | $localAddr | $RemoteIPv6 | NULL" /tool fetch url="$URLUP" http-data="action=i&token=$TOKEN&user=$user&mac=$callerId&nas=$localAddr&service=$calledId&ipv4=$remoteAddr&remoteipv6=$RemoteIPv6" http-method=post } else={ :local DHCPv6PD [/ipv6 dhcp-server binding get value-name=address [find server=$interfaceName]] :log warning message="UP: $user | $callerId | $calledId | $remoteAddr | $localAddr | $RemoteIPv6 | $DHCPv6PD" /tool fetch url="$URLUP" http-data="action=i&token=$TOKEN&user=$user&mac=$callerId&nas=$localAddr&service=$calledId&ipv4=$remoteAddr&remoteipv6=$RemoteIPv6&dhcpv6pd=$DHCPv6PD" http-method=post } file remove log6.php }
E ao desconectar vamos enviar ao servidor que o mesmo descontou.
On Down
{ :global TOKEN "xxxxxxxxxxxxxxxx" :global URLDOWN "http://________________/logs6/log6.php" :local localAddr $"local-address" :local callerId $"caller-id" /tool fetch url="$URLDOWN" http-data="action=u&token=$TOKEN&user=$user&mac=$callerId&nas=$localAddr" http-method=post :log warning message="DOWN: $user | $callerId | $localAddr" file remove log6.php }
Para concluir em IPv6 -> ND
Marque todas as opções.
No menu IP -> DNS também informe os DNS IPv6. Só assim o cliente irá aprender um DNSv6 (Advertise DNS)
Agora todo PPPoE que autenticar um log será registrado, o legal aqui é que se alguém não utiliza Radius poderá também ter um log 🙂
No arquivo log6.php que recebe os logs sempre que um usuário conectar ele irá verificar se não existe uma conexão em aberta, pois em casos de quedas de energia não vai existir tempo para ele informar que o pppoe desconectou, então ele fecha a conexão com a hora da nova conexão, logo esse IP pode ter sido utilizado por algum outro usuário, neste caso ele registra a hora que fechou a conexão com "falha" (failure), para no caso de uma investigação você observar se o mesmo ip não teve algum outro usuário que usou na horário solicitado.
Pelo phpMyAdmin também fica muito fácil de fazer buscas.
Para quem deseja bloquear um cliente IPv6, uma solução é no Router criar outra Pool6 com uma classe "invalida" por exemplo 2001:db8:6666::/48, e no freeradius usar o attibute Mikrotik-Delegated-IPv6-Pool, pode ser na tabela radreply (dizendo para qual usuário) ou para um grupo de configurações (radgroupreply) "plano".
Freeradius
Ex.: radreply
INSERT INTO `radreply` (`username`, `attribute`, `op`, `value`) VALUES ('nome_user', 'Mikrotik-Delegated-IPv6-Pool', '=', 'ipv6_drop');
Ex.: radgroupreply
INSERT INTO `radgroupreply` (`groupname`, `attribute`, `op`, `value`) VALUES ('PLANO_BLOQUEADO', 'Mikrotik-Delegated-IPv6-Pool', '=', 'ipv6_drop');
Desta forma o routerOS interpretará o nome da pool pelo atriburo Mikrotik-Delegated-IPv6-Pool, e assim que o cliente logar ele não pegará do bloco válido. Até poderia usar uma válido e bloquear no firewall (mas isso é coisa de sistema amador #ficadica).
Se seu freradius é antigo (v2.x) precisará ter o dictionary atualizado.
Vou deixar um exemplo de como configurar um pppoe cliente em um mikrotik, já que percebi um bug quando ele precisa renovar seu IPv6.
/interface pppoe-client add add-default-route=yes disabled=no interface=ether1 name=pppoe-out1 password=SENHA use-peer-dns=yes user=SENHA /ipv6 dhcp-client add interface=pppoe-out1 pool-name=DHCPv6PD pool-prefix-length=56 request=prefix /ipv6 address add advertise=yes from-pool=DHCPv6PD interface=INTERFACE_LAN /ppp profile set *0 on-up="{\r\ \n /delay delay-time=5s\r\ \n /ipv6 dhcp-client renew numbers=0\r\ \n /delay delay-time=2s\r\ \n /ipv6 dhcp-client renew numbers=0\r\ \n}" /ipv6 firewall mangle add action=change-mss chain=forward new-mss=clamp-to-pmtu passthrough=yes \ protocol=tcp tcp-flags=syn
Gambiarazinha no profile para renovar o IP sem dor de cabeça toda vez que ele autenticar (bugs)
{ /delay delay-time=5s /ipv6 dhcp-client renew numbers=0 /delay delay-time=2s /ipv6 dhcp-client renew numbers=0 }
Gostou? Espero que você consiga implementar seu IPv6 e esteja seguro com os logs armazenado!
Se quiser fazer uma doação para o café ficarei muito feliz pelo seu reconhecimento!
Se não puder doar pode deixar seu agradecimento nos comentário também ficarei feliz em saber que ajudei. Se tiver qualquer pergunta deixe-a também. Se preferir entrar em Contato clique aqui.
Abraço!
Quero deixar minha contribuição para quem usa Ubuntu 22.04.4 LTS com PHP 8.1.2 e Mysql Ver 8.0.36.
É importante deixar o fuso horário correto, senão as tabelas não irão mostrar as desconexões.
Para isso faça:
Em seguida reinicie o mysql:
Existe um problema ao consultar log quando a data final for maior que a data atual. Esse erro é mostrado no log do Apache com a seguinte informação:
Para corrigir esse erro, edite o arquivo index.php e faça as seguintes modificações:
Substitua a linha 4 para:
Substitua a linha 83 para:
E para os clientes que possuem apenas IPv4 e você deseja que esteja no log, recomendo a dica do colega Marcelo:
“Trocar de lugar a linha #18 do RemoteIPV6 e colocar ela na linha #32 embaixo da linha do :local DHCPv6PD”
Fazendo isso o script não para (por erro de no such item, interface inexiste em IPv6) para quem tem apenas IPv4.
Rudimar, muito obrigado pelo seu trabalho. Recomendo atualizar o seu Git com essas correções.
Prezados, quero deixar minha contribuição aqui para quem usa Ubuntu 22.04.4 LTS com PHP 8.1.2 e Mysql Ver 8.0.36.
É importante deixar o fuso horário correto, senão as tabelas não irão mostrar as desconexões.
Para isso faça: sudo dpkg-reconfigure tzdata
Em seguida reinicie o mysql: sudo service mysql restart
Existe um problema ao consultar log quando a data final for maior que a data atual. Esse erro é mostrado no log do Apache com a seguinte informação: PHP Fatal error: Uncaught mysqli_sql_exception: Incorrect TIMESTAMP value: ‘2024-04-31 00:00:00’ in /var/www/html/logs6/func.php:39
Para corrigir esse erro, edite o arquivo index.php e faça as seguintes modificações:
Substitua a linha 4 para:
$today = date(“Y-m”); $todaycompleto = date(“Y-m-d h:i:s”);
Substitua a linha 83 para:
<input type="text" class="form-control" id="stop" name="stop" placeholder="” value=””>
E para os clientes que possuem apenas IPv4 e você deseja que esteja no log, recomendo a dica do colega Marcelo:
“Trocar de lugar a linha #18 do RemoteIPV6 e colocar ela na linha #32 embaixo da linha do :local DHCPv6PD”
Fazendo isso o script não para (por erro de no such item, interface inexiste em IPv6) para quem tem apenas IPv4.
Rudimar, muito obrigado pelo seu trabalho. Recomendo atualizar o seu Git com essas correções.
Substitua a linha 83 para:
Substitua a linha 83 para:
Não aceita comentário com PHP… edita por favor
Substitua a linha 83 para:
aqui tive que mudar o diretorio para apenas /
depois disso funciona bem,
muito obrigado.
fiz a instação direitinho, to acessando tanto o banco de dados , quanto a pagina de pesquisa, mas por algum motivo nao esta gravando no banco de dados os logs, ja liberei os ips , coloquei o mariadb para ser acessado por fora dele mesmo.
Boa tarde, por algum motivo não recebo os log´s no servidor, alguem sabe como eu posso validar o motivo, como gero um comando para validar o erro de log ou identifico este problema. Outra coisa que observo é que no phpmyadmin tenho o erro mysqli::real_connect(): (HY000/1045): Access denied for user ‘pma’@’localhost’ (using password: YES), parece que nao esta sendo importada a tabela algo deste tipo.
cara, muito bom, parabéns, se eu for pedir demais, será que tem como fazer um tutorial mostrando como integrar com o Mk-Auth, séria de grande ajuda, somos um provedor pequeno ainda mais queremos implementar o IPv6 em todos os clientes, o Mk-Auth é o fusquinha dos Provedores hehee.
Boa noite!
Esses laboratorios com Microtik, é possivel fazer em ambiente virtualizado?
Aqui da erro ao consultar, mas esta gravando em db
Fatal error
: Call to undefined method mysqli_result::fetch_all() in
/var/www/logs6/func.php
on line
44
Provavelmente as configurações no config.php estão erradas. Verifique o arquivo original se não apagou uma “virgula” ou algo do tipo…
Estão corretas…
Acabo de refazer a conf, tanto estão corretas que com phpmyadmin consigo ver os dados dentro do db.
Resolvido.. Estava rodando debian 9, atualizei juntamente com php7.3 e rodando certinho aqui.
Agradeço muito a resposta. Parabéns pela contribuição.
Boa Tarde Rudimar;
aqui só estou conseguindo o registro dos clientes em Dual stack
os que estão somente em IPV4 não está registrando…
tbm, somente ipv4 não registra.
dual stack tá de boa.
agora não consigo acessar pela web o relatorio, só consigo vê pelo phpmyadmin. dá um erro
se eu digitar em “ip ou usuario” apresenta esse erro
Error: SELECT * FROM logs WHERE dhcpv6pd LIKE ‘%100.64.0.88%’ AND start > ‘2021-06-01 00:00:00’ AND stop ‘2021-06-01 00:00:00’ AND stop IS NULL ORDER BY id DESC
se eu deixo tudo em branco, nao aparece nada. mas os dados estão no bando de dados.
consegui resolver.
troca de lugar a linha #18 do RemoteIPV6 e coloca no ela na linha #32 em baixo da linha do “local DHCPv6PD”
agora estou tentando ver pq a pagina web nao carrega o banco de dados. não aparece relatorio.
Obrigado Marcelo, funcionando perfeitamente agora…
Meu amigo, Meus Parabéns!!
uma coisa é certa: quando ajudamos o nosso próximo, Deus Abençoa grandemente a vida daquele quem ajudou, e este é você
saiba que a sua recompensa já esta registrado, e no tempo certo a receberá!
Obrigado pela sua Ajuda, que Deus lhe abençoe Grandemente!
Tem como fazez uma rede somente com ipv6?
Tem sim, porem infelizmente vai ter roteador de cliente que não é compatível, dual skatak é a melhor opção hoje
Sabe me dizer como posso cortar o cliente com ipv6 no mk-auth
Cria um plano de bloqueio e entrega uma poolname de ipv6 “inválido” 2001:db8::….
Olá amigo. Ótimo artigo, muito bem explicado.
Tenho uma dúvida, ele ira funcionar se a minha rede só tem IPv4, ou é obrigatório ter o IPv6?
Não faz sentido rsrsrs, além do mais bora implementar IPv6. Logo logo ipv4 para e ai? Pense nisso…
Boa tarde!
Amigo, primeiramente meus parabéns pela iniciativa, ative aqui na rede e funcionou perfeitamente.
Queria fazer uma pequena observação, pelo que percebi o script no profile do pppoe so envia dados para o servidor de log quando ele tem o conjunto /64 wan /56 lan de um determinado cliente, ou seja, ele não registra os que estão somente com o /64 na wan.
qual seria o problema de ele não registrar este /64, usuários maliciosos ou terceiros poderia se utilizar deste equipamento e o servidor de log não iria pegar o /64 dele.
por este motivo pergunto, o que poderia ser modificado no script para ele registrar /64
Não entendi muito bem, na teoria é para salvar no BD os ips de wan e lan. Me chama no telegram @remontti trocar uma idea!
Primero quero aradecer pelo artigo. Obg e parabéns!
Uso o MKAuth + Mikrotik, dá pra integrar essa solução ao MKAuth?
Consigo armazenar Logs do IPv4 tbm? Em uma parte do artigo vc cita IPV4 e fiquei com essa dúvida.
Sim vc consegue integrar com o Mkauth. E sim ele vai armazenar os ipv4 tb 🙂
root@vLogs:/bin# ip6calc 2001:db8:abcd::/48
-bash: /usr/bin/ip6calc: Permissão negada
Não mesmo no usuario root
instalei Phpmyadmin e deu erro nao carrego nem /logs6 tbm nao Não é possível acessar esse site
porem php normal acesso normalmente.
Chama lá no grupo do telegram q tento ajudar https://t.me/remontticombr
dentro da pasta nao acessa joguei os arquivos pra /html funcionou
Olá consigo ver pelo phpmyadmin porem pelo http://x.x.x.x/logs6/ não aparece nada!
Alguma erro? Está colocando a data hora certa?
Está colocando a data hora certa?
Sim!
Chama no telegram.
Comigo esta acontecendo conseguiu resolver o problema de nao aparecer pela interface web ?