DNS Dinâmico · 8 min read · Oct 02, 2025

Como Implantar um Servidor DNS Dinâmico com Docker no Debian 10

DNS dinâmico é um serviço de rede para mapear nomes de domínio a endereços IP dinâmicos (temporários, frequentemente alterados). É usado para acessar computadores que não possuem um endereço IP estático, como aqueles em redes SOHO (Pequeno Escritório/Casa), e é frequentemente usado em combinação com o redirecionamento de portas para acessar sistemas que estão atrás de firewalls NAT. Este artigo irá guiá-lo através da configuração completa de um servidor DNS dinâmico em um contêiner Docker em um sistema Debian 10, incluindo a configuração dos registros DNS necessários, colocando a API de gerenciamento atrás de um proxy reverso Nginx HTTPS e automatizando as atualizações de registros DNS do lado do cliente.

Requisitos

  • Um único servidor Debian 10, opcionalmente com conectividade IPv6. (192.0.2.2 e 2001:0db8::0db9 serão usados como marcadores para o IPv4 e IPv6 do servidor, respectivamente.)
  • Acesso ao usuário root ou a um usuário com privilégios sudo.
  • As portas tcp/53 e udp/53 devem estar disponíveis no host.
  • Um nome de domínio registrado e acesso aos seus servidores de nomes/zonefile. Crie registros DNS para este domínio conforme mostrado na próxima seção.
  • A variável de ambiente $EDITOR deve estar definida.
  • Opcionalmente, qualquer sistema cliente Linux/Unix para configurar atualizações automáticas de registros DNS.

Criando registros DNS.

Você precisará criar pelo menos 2 registros DNS para que seu servidor DNS dinâmico funcione. Primeiro, escolha um subdomínio como ns1.seu_dominio que apontará para o endereço IPv4 do seu servidor. Em segundo lugar, escolha um subdomínio como ddns.seu_dominio que será delegado a ns1.seu_dominio.

Seu servidor DNS dinâmico lidará com todos os registros sob ddns.seu_dominio. O terceiro registro, do tipo AAAA, é opcional. Os registros correspondentes se parecem com o seguinte:

ns1.seu_dominio A 192.0.2.2
ddns.seu_dominio NS ns1.seu_dominio
ns1.seu_dominio AAAA 2001:0db8::0db9 (opcional)

Exemplo de registros DNS

Você deve criar esses registros no painel de controle do seu registrador de domínio. Observe que pode levar até 24 horas para que esses registros se propaguem corretamente, mas geralmente leva apenas alguns minutos.

Instalação

Se você não estiver usando o usuário root, recomendamos que você inicie um shell root temporário, uma vez que a maioria dos comandos mostrados neste guia requerem privilégios elevados. Para iniciar um shell root, use um dos seguintes comandos:

sudo su - root
sudo -s

Etapa 1: Atualizando e instalando dependências.

É sempre uma boa prática atualizar seu sistema primeiro:

apt update
apt upgrade -y
reboot

Após a reinicialização, instale os pacotes de software necessários para esta configuração:

  • certbot será usado para obter certificados SSL/TLS.
  • make é necessário para construir a imagem do docker na qual o servidor DDNS será executado.
  • apt-transport-https, ca-certificates, curl, gnupg2 e software-properties-common são necessários para instalar o repositório Docker e sua chave GPG correspondente.
  • dnsutils fornece dig, que será usado para testes.
apt install -y certbot make apt-transport-https curl ca-certificates software-properties-common gnupg2 dnsutils

Etapa 2: Instalar Docker CE.

Adicione a chave GPG do Docker:

curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -

Instale o repositório docker:

add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian buster stable"

Atualize o cache do repositório do Debian e, em seguida, instale o docker e suas dependências:

apt update
apt install -y docker-ce docker-ce-cli containerd.io

Uma vez que a instalação esteja completa, certifique-se de que o serviço docker esteja habilitado e em execução da seguinte forma:

systemctl enable --now docker.service

Etapa 3: Baixar e construir docker-ddns

Nosso servidor DNS dinâmico será alimentado por um contêiner docker que usa Bind como o servidor DNS e uma API de gerenciamento escrita em Go. Primeiro, clone o repositório do Github e construa a imagem do contêiner com os seguintes comandos:

git clone https://github.com/dprandzioch/docker-ddns.git
cd docker-ddns
make image

Aguarde o processo terminar, o que pode levar um tempo, e depois abra o arquivo envfile com um editor de texto:

$EDITOR envfile

E insira o seguinte:

SHARED_SECRET=seu_segredo   
ZONE=ddns.seu_dominio   
RECORD_TTL=60

O segredo compartilhado é uma senha que será usada para autenticar com a API de gerenciamento. ZONE indica qual zona DNS seu servidor será responsável, e o TTL do registro especifica por quanto tempo os registros DNS podem ser armazenados em cache. Um TTL de 60 segundos é recomendado para IPs dinâmicos que mudam frequentemente.

Se necessário, você pode gerar uma string aleatória de 40 caracteres para o segredo usando o seguinte comando:

cat /dev/urandom | tr -dc "a-zA-Z0-9" | fold -w 40 | head -1

Agora podemos criar o contêiner:

docker create -it -p 127.0.0.1:8080:8080 -p 53:53 -p 53:53/udp --env-file envfile -v /mnt/ddns-data:/var/cache/bind --name ddns-server davd/docker-ddns

Este comando criará um contêiner chamado ddns-server a partir da imagem que construímos anteriormente e mapeará as portas 8080/tcp, 53/tcp e 53/udp do host para o contêiner. Ele também montará o diretório /mnt/ddns-data do host, em /var/cache/bind no sistema de arquivos do contêiner. Isso é usado para persistir dados DNS entre a recriação do contêiner.

Verifique se o contêiner foi criado com o comando:

docker container ls -a

Uma única entrada deve ser exibida com o nome ddns-server.

Etapa 4: Serviço systemd (opcional)

Esta etapa é para uma gestão mais simples, mas não é estritamente necessária. Se você optar por não usar um serviço systemd, terá que gerenciar o contêiner manualmente ou usar outra solução de gerenciamento. Observe que para implantações de contêiner maiores e mais complexas, uma solução de orquestração como Kubernetes ou Docker Swarm é recomendada. Neste caso, um serviço systemd é perfeitamente adequado, pois estamos executando apenas um único contêiner.

Para poder gerenciar este contêiner como um serviço do sistema, vamos envolvê-lo em uma unidade systemd. Crie o arquivo /etc/systemd/system/ddns-server-ct.service com seu editor de texto:

$EDITOR /etc/systemd/system/ddns-server-ct.service

E adicione o seguinte:

[Unit]  
Description=Contêiner Docker do Servidor DDNS  
After=docker.service  
Requires=docker.service  
Requires=network.target  
[Service]  
Type=oneshot  
TimeoutStartSec=240  
Restart=no  
RemainAfterExit=yes  
ExecStart=/usr/bin/docker start ddns-server  
ExecStop=/usr/bin/docker stop ddns-server  
[Install]  
WantedBy=multi-user.target

Salve e saia, depois defina as permissões corretas neste arquivo de unidade:

chmod 664 /etc/systemd/system/ddns-server-ct.service

Carregue o novo arquivo de serviço com o seguinte comando:

systemctl daemon-reload

Agora você deve ser capaz de iniciar e parar este contêiner usando systemctl como qualquer outro serviço do sistema.

Se você quiser que o servidor DDNS inicie automaticamente na inicialização do sistema, execute o seguinte:

systemctl enable ddns-server-ct.service

Etapa 5: Testando seu servidor

Antes de prosseguir com a configuração, vamos testar a API de gerenciamento localmente. Inicie o contêiner:

systemctl start ddns-server-ct.service

Envie uma solicitação GET para a API para criar um novo registro:

NOTA: A API atualmente só é acessível localmente (ou seja, a partir do localhost).

curl "http://127.0.0.1:8080/update?secret=seu_segredo&domain=test1&addr=1.1.1.1"

Curl deve retornar a seguinte resposta:

{"Success":true,"Message":"Registro A atualizado para test1 para o endereço IP 1.1.1.1","Domain":"test1","Domains":["test1"],"Address":"1.1.1.1","AddrType":"A"}

NOTA: O domínio test1 refere-se a test1.ddns.seu_dominio. uma vez que o servidor está lidando com a zona ddns.seu_dominio.

Realize uma consulta DNS para verificar se o registro foi realmente criado e para testar a resolução DNS:

dig +short -t A test1.ddns.seu_dominio @127.0.0.1

A saída deve ser 1.1.1.1.

Etapa 6: Proxy reverso

Como a API funciona sobre HTTP, seu segredo de autenticação pode potencialmente ser capturado sempre que você enviar uma solicitação pela rede. Um atacante poderia então manipular seus registros DNS usando seu segredo. Vamos configurar um proxy reverso usando Nginx e protegê-lo usando HTTPS. Primeiro, obtenha um certificado SSL da Let’s Encrypt usando certbot:

certbot certonly --standalone --agree-tos -m [email protected] -d ns1.seu_dominio

A propriedade do seu domínio será verificada e um certificado será emitido. Em seguida, instale o Nginx e certifique-se de que ele esteja habilitado e em execução:

apt install -y nginx systemctl enable --now nginx.service

Em seguida, desative o arquivo de bloco de servidor padrão, pois não é necessário:

unlink /etc/nginx/sites-enabled/default

Agora criaremos um novo arquivo de configuração para o proxy reverso, por exemplo:

$EDITOR /etc/nginx/sites-available/ddns-api-proxy.conf

E cole o seguinte, garantindo que você substitua os endereços IP e nomes de domínio pelos seus:

server {  
listen 192.0.2.2:8080;  
server_name ns1.seu_dominio;  
ssl on;  
ssl_certificate /etc/letsencrypt/live/ns1.seu_dominio/fullchain.pem;  
ssl_certificate_key /etc/letsencrypt/live/ns1.seu_dominio/privkey.pem;  
  
location /update {  
proxy_pass http://127.0.0.1:8080;  
}  
location / {  
return 404;  
}  
access_log /var/log/nginx/ddns-api-access.log;  
error_log /var/log/nginx/ddns-api-error.log;  
}

Opcional: Se você quiser que a API seja acessível via IPv6, adicione a seguinte linha após a diretiva listen existente:

listen [2001:0db8::0db9]:8080;

Habilite esta configuração e aplique as alterações recarregando o Nginx:

ln -s /etc/nginx/sites-available/ddns-api-proxy.conf /etc/nginx/sites-enabled/
systemctl reload nginx.service

A API agora deve ser acessível pela internet e aceitará apenas conexões HTTPS. Para testá-la, emita o comando:

curl "https://ns1.seu_dominio:8080/update?secret=seu_segredo&domain=test2&addr=1.1.1.2"

Deve retornar o seguinte:

{"Success":true,"Message":"Registro A atualizado para test2 para o endereço IP 1.1.1.2","Domain":"test2","Domains":["test2"],"Address":"1.1.1.2","AddrType":"A"}

Etapa 7: Configuração do cliente

Você pode configurar atualizações automáticas de registros em qualquer roteador que suporte provedores de DNS dinâmico personalizados, como Pfsense. Você também pode configurá-los na maioria dos outros dispositivos em sua rede de escritório ou doméstica. Para atualizar ou criar um registro, uma solicitação GET deve ser enviada para o seguinte endpoint:

https://ns1.seu_dominio:8080/update?secret=seu_segredo&domain=seu_subdominio&addr=seu_endereco_ip

Você também pode atualizar os registros de vários subdomínios com uma única solicitação. Por exemplo, para criar/atualizar registros para sub1.ddns.seu_dominio e sub2.ddns.seu_dominio com o endereço IP 198.51.100.100, você enviaria uma solicitação GET para esta URL:

https://ns1.seu_dominio:8080/update?secret=seu_segredo&domain=sub1,sub2&addr=198.51.100.100

O parâmetro addr também pode conter um endereço IPv6 para criar/atualizar registros DNS AAAA, por exemplo:

https://ns1.seu_dominio:8080/update?secret=seu_segredo&domain=queijo&addr=2001:0db8:aaaa::

Para automatizar essas atualizações em um cliente Linux, salve o seguinte script bash como /opt/ddns-update.sh:

#!/bin/bash  
  
while [ -z $CURRENTIP ]
do  
CURRENTIP=`dig -r +short myip.opendns.com @resolver1.opendns.com 2>/dev/null`  
sleep 1  
done  
curl -s "https://ns1.seu_dominio:8080/update?secret=seu_segredo&domain=seu_subdominio&addr=${CURRENTIP}"

Este script emprega um loop while em torno de um comando dig que obtém o endereço IP público do cliente e o armazena em uma variável. O loop garante que o IP público seja obtido corretamente. Em seguida, cURL é usado para enviar uma solicitação API para atualizar o registro DNS com este IP recém-obtido. Certifique-se de substituir os valores para seu_segredo e seu_subdominio.

Em seguida, torne este script executável:

chmod +x /opt/ddns-update.sh

Depois, inicie o editor crontab:

crontab -e

Adicione a seguinte linha ao final do seu crontab:

*/2 * * * * /opt/ddns-update.sh

Salve e saia. O script agora será executado a cada dois minutos, mantendo seu registro DNS dinâmico atualizado com o último endereço IP público do cliente.

Leitura Adicional

  • Artigo sobre DNS Dinâmico na Wikipedia
  • docker-ddns no Github
Share: X/Twitter LinkedIn

Receba novas postagens na sua caixa de entrada

Sem spam. Cancele a assinatura a qualquer momento.