terça-feira, 8 de julho de 2025

Dica - Atualizando DDNS com No-IP - Minha Transição para o Docker Oficial do No-IP

Olá, pessoal!


No meu setup de rede doméstica, sempre usei o serviço de DDNS da No-IP para manter meus servidores acessíveis via hostnames dinâmicos, como meuddns1.ddns.net e meuddns2.ddns.net.

Por algum tempo, usei o DUC (Dynamic Update Client ou Cliente de Atualização Dinâmica) do próprio No-IP, rodando no Linux, para fazer isso (falei sobre isso aqui). Entretanto, como estava ainda aprendendo sobre redes e pra que isso tudo servia, com alguma frequência eu apagava e reinstalava o Ubuntu Server onde isso ficava.

Depois comecei a fazer isso com o DuckDNS. Comentei sobre isso aqui. Mas o problema era sempre o mesmo. Hardware fraco, software em constante modificação.

Em 2023, quando comprei o meu Synology, um hardware robusto para ser o server base daqui de casa, resolvi atualizar o DNS via DuckDNS rodando em um container Docker do próprio DuckDNS. Nesse post aqui, falei como fiz isso e comentei que o No-IP não tinha um container Docker para fazer isso, ao contrário do DuckDNS. Mostrei inclusive como era possível usar um container não oficial (aanousakis/no-ip), o único que encontrei, para atualizar meu IP público no No-IP.

As vantagens em usar um Docker ao contrário de uma DUC (um programa dedicado para isso) são: a economia de recursos; aprendizado; simplicidade do processo.

Nesses dois anos, não tive problemas como esse container. Porém, há alguns dias, comecei a ter problemas com ele, incluindo erros como "database is locked", e decidi migrar para a imagem oficial do No-IP (noipcom/noip-duc) que eu, até então, nem sabia que tinha sido lançado. Neste post, vou compartilhar por que fiz essa mudança, como funciona a nova DDNS Key da No-IP, e como configurei o novo docker-compose.yml para gerenciar dois hostnames no meu Portainer.

Por que abandonar o velho Docker?

O contêiner aanousakis/no-ip era simples e funcional, mas começou a apresentar instabilidades. O erro mais comum que encontrei foi:

failed to create task for container: failed to
initialize logging driver: database is locked

Esse problema sugeria conflitos no acesso a arquivos de configuração, possivelmente devido à falta de um volume persistente ou permissões inadequadas. Além disso, como era uma imagem não oficial, não havia garantia de atualizações regulares ou suporte para as mudanças recentes no sistema da No-IP, como a introdução da DDNS Key. Resolvi buscar uma solução mais robusta e oficial, que me levasse à nova imagem noipcom/noip-duc, mantida pela própria No-IP.

A novidade da DDNS Key

Recentemente, a No-IP introduziu as DDNS Keys, uma alternativa mais segura às credenciais tradicionais de login (e-mail e senha). Com a DDNS Key, você gera um par de username e senha específicos para seus hostnames no painel da No-IP (my.noip.com). Cada chave é vinculada a um ou mais hostnames, permitindo atualizações seguras sem expor sua conta principal.

Para criar uma DDNS Key:

  1. Acesse o painel da No-IP.
  2. Vá para a seção de DDNS Keys.
  3. Crie uma nova chave, associando-a aos seus hostnames.
  4. Anote o username e a senha gerados, que serão usados no contêiner Docker.

A grande vantagem da DDNS Key é a segurança: se a chave for comprometida, você pode revogá-la sem afetar sua conta No-IP. Além disso, ela é compatível com a nova imagem oficial, que usa o hostname all.ddnskey.com para atualizações via DDNS Key.

Configurando o novo Docker oficial

A imagem noipcom/noip-duc é mantida pela No-IP e está hospedada no GitHub Container Registry (ghcr.io/noipcom/noip-duc). Ela é leve, confiável e suporta as DDNS Keys nativamente. Como eu gerencio dois hostnames com chaves diferentes, configurei dois serviços no mesmo stack do Portainer, cada um com sua própria DDNS Key e volume persistente no meu HD externo (/volume).

Aqui está o docker-compose.yml final que estou usando:

version: '3.9' services: noip-duc-1: image: ghcr.io/noipcom/noip-duc:latest container_name: noip-duc-1 environment: - NOIP_USERNAME=<username_do_ddnskey_não_é_do_NoIP> - NOIP_PASSWORD=<senha_do_ddnskey_não_é_do_NoIP> - NOIP_HOSTNAMES=<seuddns.ddns.net - INTERVAL=5 volumes: - /etc/localtime:/etc/localtime:ro - /volume/docker/noip/noip-data-1:/config restart: unless-stopped noip-duc-2: image: ghcr.io/noipcom/noip-duc:latest container_name: noip-duc-2 environment: - NOIP_USERNAME=<username_do_outro_ddnskey_não_é_do_NoIP> - NOIP_PASSWORD=<senha_do_outro_ddnskey_não_é_do_NoIP> - NOIP_HOSTNAMES=<seuoutroddns.ddns.net - INTERVAL=5 volumes: - /etc/localtime:/etc/localtime:ro - /volume/docker/noip/noip-data-2:/config restart: unless-stopped

Explicando o docker-compose.yml

  • Imagem: Uso a ghcr.io/noipcom/noip-duc:latest para garantir a versão mais recente.
  • Contêineres: Criei dois serviços (noip-duc-1 e noip-duc-2) para gerenciar os meus DDNS do NoIP separadamente, já que optei por que cada um tivesse sua própria DDNS Key.
  • Variáveis de ambiente:
    • NOIP_USERNAME e NOIP_PASSWORD: As credenciais da DDNS Key para cada hostname.
    • NOIP_HOSTNAMES: O hostname específico que cada contêiner atualiza.
    • INTERVAL: Configurado para 5 minutos, definindo a frequência de verificação do IP.
  • Volumes:
    • /etc/localtime:/etc/localtime:ro: Sincroniza o fuso horário do host.
    • /volume/docker/noip/noip-data-1:/config e noip-data-2: Diretórios no meu HD externo para persistir configurações, evitando erros como o "database is locked".
  • Restart policyunless-stopped garante que os contêineres reiniciem automaticamente, exceto se eu os parar manualmente.

Passos para implantar

  1. Criei os diretórios no HD externo (mas se você tiver acesso pelo Windows ou Mac, pode simplesmente criar a pasta sem precisar de fazer isso):
    sudo mkdir -p /volume3/docker/noip/noip-data-1 /volume3/docker/noip/noip-data-2
    sudo chmod 700 /volume3/docker/noip/noip-data-1 /volume3/docker/noip/noip-data-2
    sudo chown 1000:1000 /volume3/docker/noip/noip-data-1 /volume3/docker/noip/noip-data-2
  2. Salvei o docker-compose.yml em /volume/docker/noip.
  3. Implantei no Portainer:
    • Acessei Stacks > Add stack.
    • Colei o conteúdo do docker-compose.yml no Web editor.
    • Cliquei em Deploy the stack.
  4. Verifiquei os logs:
    docker logs noip-duc-1
    docker logs noip-duc-2
    Os logs mostraram mensagens como [INFO noip_duc::observer] update successful, confirmando que os IPs estavam atualizados.

Solucionando problemas iniciais

Durante a configuração, enfrentei alguns desafios:

  • Erro de variável: Inicialmente, usei EMAIL_PASSWORD em vez de NOIP_PASSWORD, o que causou um erro de "missing required argument --password". Corrigir para NOIP_PASSWORD resolveu.
  • Lentidão nos logs: O Portainer demorava para carregar os logs, mas após a correção da configuração, o problema desapareceu.
  • Volume inexistente: Tive que criar manualmente os diretórios /volume/docker/noip/noip-data-1 e noip-data-2 para evitar erros de "bind mount failed".

Resultado final

Com o novo setup, meus hostnames estão atualizando o IP daqui de casa sem falhas. Você pode testar dando um < ping>:

ping meuddns1.ddns.net
ping meuddns2.ddns.net

Ambos responderam com latência baixa (~0.2 ms), confirmando que tudo está funcionando. No painel da No-IP, os hostnames estão associados ao IP correto, e os logs dos contêineres mostram atualizações regulares a cada 5 minutos.

A migração para a imagem oficial noipcom/noip-duc foi um grande acerto. A DDNS Key trouxe mais segurança, e o uso de volumes persistentes no meu HD externo eliminou os erros de "database is locked". Se você também usa o No-IP para DDNS, recomendo experimentar a imagem oficial e configurar a DDNS Key.

O DuckDNS tem várias opções de atualização, bem mais flexíveis que como o No-IP. Eu optei por fazer os dois para poder ter DDNSs distintos para serviços distintos.

Por hoje é isso, pessoal!

Nenhum comentário:

Postar um comentário