Atualizar IPv4 e IPv6 no DuckDNS a partir de roteadores ASUS com Asuswrt-Merlin

Há algum tempo eu precisei encontrar uma forma de acessar remotamente um roteador ASUS RT-AC86U em uma conexão da Claro (antiga NET) que passou a usar CGNAT recentemente, ou seja, não consigo mais acessa-lo usando o IPv4 como fazia antes. A solução que encontrei foi fazer o acesso via IPv6. Porém, o serviço de DNS dinâmico da ASUS não suporta IPv6. O DuckDNS suporta IPv6, então optei por usa-lo.

O roteador em questão está com o firmware Asuswrt-Merlin, que permite usar um script que é chamado sempre que o DNS dinâmico é atualizado. Assim, criei um ddns-start com o conteúdo deste script disponibilizado pelo kevinxw, porém alterando-o um pouco para digitar subdomínio e token diretamente no script, uma vez que eu estava usando o DuckDNS como um adicional ao serviço de DNS dinâmico da própria ASUS:

#!/bin/sh

# register a subdomain at https://www.duckdns.org/ to get your token
# put 'hostname|token' in the 'Host Name' field under DDNS
# e.g. myhost|abcdefgh-1234-5678-9876-f71b0ed7a7fe

SUBDOMAIN=
TOKEN=
IPV4=$(nvram get wan0_ipaddr)
IPV6=$(nvram get ipv6_wan_addr | awk -F'/' '{print $1}')

REQUEST_URL="https://www.duckdns.org/update?domains=${SUBDOMAIN}&token=${TOKEN}&ip=${IPV4}&ipv6=${IPV6}"

logger "DDNS Request URL: ${REQUEST_URL}"

# no modification below needed
RESULT=$(curl --silent "${REQUEST_URL}" 2>&1)
logger "DDNS Request result: $RESULT"

if [[ "$RESULT" == "OK" ]];
then
  /sbin/ddns_custom_updated 1
else
  /sbin/ddns_custom_updated 0
fi

O script funcionou perfeitamente e agora eu acesso o tal roteador remotamente usando IPv6, com o endereço fornecido pelo DuckDNS.

Eu tenho esse mesmo roteador e a minha conexão do Vivo Fibra não usa CGNAT e tenho IPv4 válido, mas resolvi instalar a mesma solução no meu roteador apenas para ter uma alternativa a mais. O problema é que o script em questão não conseguia pegar o IPv6 no meu roteador de jeito nenhum.

Usando o nvram no próprio terminal eu percebi que a string ipv6_wan_addr está sempre vazia, sabe-se lá porque. Acredito que a diferença para o outro roteador seja que eu estou usando PPPoE (com o ONU da Vivo em modo bridge), enquanto que o outro roteador está usando DHCP (com o modem da Claro também em modo bridge), devido à diferença do funcionamento da rede das duas operadoras.

A solução que encontrei foi obter o IPv6 de outra forma, usando o comando ip. Tive um pouco de trabalho pois nunca tinha usado ip e awk, mas pesquisando um pouquinho consegui entender as sintaxes e fazer o que eu queria. Talvez não seja a forma mais eficiente de fazer, mas funciona. O resultado ficou assim:

#!/bin/sh

# Asus-Merlin-DuckDNS, modified by Skooter
# Forked from https://gist.github.com/kevinxw/f7a5d5402887ca1b5b2c399c60e0921f

# register a subdomain at https://www.duckdns.org/ to get your token
# put 'hostname|token' in the 'Host Name' field under DDNS
# e.g. myhost|abcdefgh-1234-5678-9876-f71b0ed7a7fe

#DDNS_HOSTNAME_FIELD=$(nvram get ddns_hostname_x)
#SUBDOMAIN=$(echo "$DDNS_HOSTNAME_FIELD" | awk -F'|' '{print $1}')
#TOKEN=$(echo "$DDNS_HOSTNAME_FIELD" | awk -F'|' '{print $2}')
#Skooter: I'm using DuckDNS additionally to the ASUS DDNS service, so 
#I'm setting SUBDOMAIN and TOKEN directly:
SUBDOMAIN=
TOKEN=

IPV4=$(nvram get wan0_ipaddr)
#IPV6=$(nvram get ipv6_wan_addr | awk -F'/' '{print $1}')
#Skooter: For some reason, the nvram string from the original script 
#is empty when I'm using PPPoE so I replaced it with this one:
IPV6=$(ip -6 addr show scope global dynamic | grep inet6 | awk '{print $2}' | awk -F'/' '{print $1}')

#Skooter: my first attempt would depend on an external service, I prefer to 
#get all the information locally, so I no longer use this:
#IPV6=$(curl -6 https://ipv6.icanhazip.com)

REQUEST_URL="https://www.duckdns.org/update?domains=${SUBDOMAIN}&token=${TOKEN}&ip=${IPV4}&ipv6=${IPV6}"

logger "DDNS Request URL: ${REQUEST_URL}"

# no modification below needed
RESULT=$(curl --silent "${REQUEST_URL}" 2>&1)
logger "DDNS Request result: $RESULT"

if [[ "$RESULT" == "OK" ]];
then
  /sbin/ddns_custom_updated 1
else
  /sbin/ddns_custom_updated 0
fi

Com esse script ambos IPv4 e IPv6 são atualizados no DuckDNS, mesmo com o roteador em modo PPPoE. Problema resolvido!

Nota: Em uma primeira tentativa eu havia feito o script funcionar obtendo o IPv6 através do serviço icanhazip.com, mas depois achei melhor fazer algo que obtivesse o IPv6 localmente para não depender de nenhum serviço externo. Deixei o código anterior comentado para caso precise dele no futuro.

0 0 votos
Article Rating

Link permanente para este artigo: https://www.skooterblog.com/2022/10/14/atualizar-ipv4-e-ipv6-no-duckdns-a-partir-de-roteadores-asus-com-asuswrt-merlin/

Inscrever
Notificar sobre
guest

0 Comentários
Inline Feedbacks
Ver todos os comentários
0
Gostaríamos de saber o que você pensa, deixe seu comentáriox