DNS Dinamico · 8 min read · Oct 02, 2025

Come distribuire un server DNS dinamico con Docker su Debian 10

Il DNS dinamico è un servizio di rete per mappare nomi di dominio a indirizzi IP dinamici (temporanei, in continua evoluzione). Viene utilizzato per accedere a computer che non hanno un indirizzo IP statico, come quelli nelle reti SOHO (Small Office/Home Office), ed è spesso utilizzato in combinazione con il port forwarding per accedere a sistemi che si trovano dietro firewall NAT. Questo articolo ti guiderà attraverso la configurazione completa di un server DNS dinamico in un contenitore Docker su un sistema Debian 10, inclusa la configurazione dei record DNS richiesti, il posizionamento dell’API di gestione dietro un proxy inverso Nginx HTTPS e l’automazione degli aggiornamenti dei record DNS lato client.

Requisiti

  • Un singolo server Debian 10, eventualmente con connettività IPv6. (192.0.2.2 e 2001:0db8::0db9 saranno utilizzati come segnaposto per l’IPv4 e l’IPv6 del server rispettivamente.)
  • Accesso all’utente root, o a un utente con privilegi sudo.
  • Le porte tcp/53 e udp/53 devono essere disponibili sull’host.
  • Un nome di dominio registrato e accesso ai suoi nameserver/file di zona. Crea record DNS per questo dominio come mostrato nella sezione successiva.
  • La variabile ambiente $EDITOR deve essere impostata.
  • Facoltativamente, qualsiasi sistema client Linux/Unix per impostare aggiornamenti automatici dei record DNS.

Creazione dei record DNS.

Dovrai creare almeno 2 record DNS affinché il tuo server DNS dinamico funzioni. Prima, scegli un sottodominio come ns1.your_domain che punterà all’indirizzo IPv4 del tuo server. In secondo luogo, scegli un sottodominio come ddns.your_domain che sarà delegato a ns1.your_domain.

Il tuo server DNS dinamico gestirà tutti i record sotto ddns.your_domain. Il terzo record, di tipo AAAA, è facoltativo. I record corrispondenti sono simili ai seguenti:

ns1.your_domain A 192.0.2.2
ddns.your_domain NS ns1.your_domain
ns1.your_domain AAAA 2001:0db8::0db9 (facoltativo)

Esempio di record DNS

Dovresti creare questi record nel pannello di controllo del tuo registrar di domini. Si prega di notare che potrebbero essere necessarie fino a 24 ore affinché questi record si propaghino correttamente, ma di solito richiede solo pochi minuti.

Installazione

Se non stai utilizzando l’utente root, ti consigliamo di avviare una shell root temporanea, poiché la maggior parte dei comandi mostrati in questa guida richiede privilegi elevati. Per avviare una shell root, utilizza uno dei seguenti comandi:

sudo su - root
sudo -s

Passo 1: Aggiornamento e installazione delle dipendenze.

È sempre buona pratica aggiornare prima il tuo sistema:

apt update
apt upgrade -y
reboot

Dopo il riavvio, installa i pacchetti software richiesti per questa configurazione:

  • certbot sarà utilizzato per ottenere certificati SSL/TLS.
  • make è necessario per costruire l’immagine docker in cui verrà eseguito il server DDNS.
  • apt-transport-https, ca-certificates, curl, gnupg2 e software-properties-common sono necessari per installare il repository Docker e la sua corrispondente chiave GPG.
  • dnsutils fornisce dig, che sarà utilizzato per i test.
apt install -y certbot make apt-transport-https curl ca-certificates software-properties-common gnupg2 dnsutils

Passo 2: Installare Docker CE.

Aggiungi la chiave GPG di Docker:

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

Installa il repository docker:

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

Aggiorna la cache del repository di Debian e poi installa docker e le sue dipendenze:

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

Una volta completata l’installazione, assicurati che il servizio docker sia abilitato e in esecuzione come segue:

systemctl enable --now docker.service

Passo 3: Scarica e costruisci docker-ddns

Il nostro server DNS dinamico sarà alimentato da un contenitore docker che utilizza Bind come server DNS e un’API di gestione scritta in Go. Prima, clona il repository Github e costruisci l’immagine del contenitore con i seguenti comandi:

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

Aspetta che il processo finisca, il che potrebbe richiedere un po’ di tempo, poi apri il file envfile con un editor di testo:

$EDITOR envfile

E inserisci quanto segue:

SHARED_SECRET=your_secret   
ZONE=ddns.your_domain   
RECORD_TTL=60

Il segreto condiviso è una password che sarà utilizzata per autenticarsi con l’API di gestione. ZONE indica quale zona DNS sarà responsabile il tuo server, e il TTL del record specifica per quanto tempo i record DNS possono essere memorizzati nella cache. Un TTL di 60 secondi è raccomandato per IP dinamici che cambiano frequentemente.

Se necessario, puoi generare una stringa casuale di 40 caratteri per il segreto utilizzando il seguente comando:

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

Possiamo ora creare il contenitore:

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

Questo comando creerà un contenitore chiamato ddns-server dall’immagine che abbiamo costruito in precedenza e mapperà le porte 8080/tcp, 53/tcp e 53/udp dall’host al contenitore. Monta anche la directory /mnt/ddns-data dall’host, su /var/cache/bind nel filesystem del contenitore. Questo è utilizzato per mantenere i dati DNS attraverso la ricreazione del contenitore.

Verifica che il contenitore sia stato creato con il comando:

docker container ls -a

Dovrebbe essere restituita una singola voce con il nome ddns-server.

Passo 4: Servizio systemd (facoltativo)

Questo passaggio è per una gestione più semplice ma non è strettamente necessario. Se scegli di non utilizzare un servizio systemd, dovrai gestire il contenitore manualmente o utilizzare un’altra soluzione di gestione. Si prega di notare che per distribuzioni di contenitori più grandi e complesse, è consigliata una soluzione di orchestrazione come Kubernetes o Docker Swarm. In questo caso, un servizio systemd è perfettamente adatto, poiché stiamo eseguendo solo un singolo contenitore.

Per poter gestire questo contenitore come un servizio di sistema, lo incapsuleremo in un’unità systemd. Crea il file /etc/systemd/system/ddns-server-ct.service con il tuo editor di testo:

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

E aggiungi quanto segue:

[Unit]  
Description=DDNS Server Docker Container  
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

Salva ed esci, quindi imposta i permessi corretti su questo file di unità:

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

Carica il nuovo file di servizio con il seguente comando:

systemctl daemon-reload

Ora dovresti essere in grado di avviare e fermare questo contenitore utilizzando systemctl come qualsiasi altro servizio di sistema.

Se desideri che il server DDNS si avvii automaticamente all’avvio del sistema, esegui il seguente comando:

systemctl enable ddns-server-ct.service

Passo 5: Testare il tuo server

Prima di procedere con la configurazione, testeremo l’API di gestione localmente. Avvia il contenitore:

systemctl start ddns-server-ct.service

Invia una richiesta GET all’API per creare un nuovo record:

NOTA: L’API è attualmente accessibile solo localmente (cioè da localhost).

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

Curl dovrebbe restituire la seguente risposta:

{"Success":true,"Message":"Updated A record for test1 to IP address 1.1.1.1","Domain":"test1","Domains":["test1"],"Address":"1.1.1.1","AddrType":"A"}

NOTA: Il dominio test1 si riferisce a test1.ddns.your_domain. poiché il server gestisce la zona ddns.your_domain.

Esegui una ricerca DNS per verificare che il record sia stato effettivamente creato e per testare la risoluzione DNS:

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

L’output dovrebbe essere 1.1.1.1.

Passo 6: Proxy inverso

Poiché l’API funziona su HTTP, il tuo segreto di autenticazione può potenzialmente essere sniffato ogni volta che invii una richiesta attraverso la rete. Un attaccante potrebbe quindi manipolare i tuoi record DNS utilizzando il tuo segreto. Imposteremo un proxy inverso utilizzando Nginx e lo proteggeremo utilizzando HTTPS. Prima, ottieni un certificato SSL da Let’s Encrypt utilizzando certbot:

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

La proprietà del tuo dominio sarà verificata e un certificato sarà emesso. Successivamente, installa Nginx e assicurati che sia abilitato e in esecuzione:

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

Quindi disabilita il file di blocco del server predefinito, poiché non è necessario:

unlink /etc/nginx/sites-enabled/default

Ora creeremo un nuovo file di configurazione per il proxy inverso, ad esempio:

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

E incolla quanto segue, assicurandoti di sostituire gli indirizzi IP e i nomi di dominio con i tuoi:

server {  
listen 192.0.2.2:8080;  
server_name ns1.your_domain;  
ssl on;  
ssl_certificate /etc/letsencrypt/live/ns1.your_domain/fullchain.pem;  
ssl_certificate_key /etc/letsencrypt/live/ns1.your_domain/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;  
}

Facoltativo: Se desideri che l’API sia accessibile tramite IPv6, aggiungi la seguente riga dopo la direttiva listen esistente:

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

Abilita questa configurazione e applica le modifiche ricaricando Nginx:

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

L’API dovrebbe ora essere accessibile su Internet e accetterà solo connessioni HTTPS. Per testarlo, emetti il comando:

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

Dovrebbe restituire quanto segue:

{"Success":true,"Message":"Updated A record for test2 to IP address 1.1.1.2","Domain":"test2","Domains":["test2"],"Address":"1.1.1.2","AddrType":"A"}

Passo 7: Configurazione del client

Puoi impostare aggiornamenti automatici dei record su qualsiasi router che supporti fornitori di DNS dinamici personalizzati, come Pfsense. Puoi anche configurarli sulla maggior parte degli altri dispositivi nella tua rete d’ufficio o domestica. Per aggiornare o creare un record, deve essere inviata una richiesta GET al seguente endpoint:

https://ns1.your_domain:8080/update?secret=your_secret&domain=your_subdomain&addr=your_ip_address

Puoi anche aggiornare i record di più sottodomini con una singola richiesta. Ad esempio, per creare/aggiornare i record per sub1.ddns.your_domain e sub2.ddns.your_domain con l’indirizzo IP 198.51.100.100, dovresti inviare una richiesta GET a questo URL:

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

Il parametro addr può anche contenere un indirizzo IPv6 per creare/aggiornare record DNS AAAA, ad esempio:

https://ns1.your_domain:8080/update?secret=your_secret&domain=cheese&addr=2001:0db8:aaaa::

Per automatizzare questi aggiornamenti su un client Linux, salva il seguente script bash come /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.your_domain:8080/update?secret=your_secret&domain=your_subdomain&addr=${CURRENTIP}"

Questo script utilizza un ciclo while avvolto attorno a un comando dig che ottiene l’indirizzo IP pubblico del client e lo memorizza in una variabile. Il ciclo assicura che l’IP pubblico venga correttamente recuperato. Quindi, cURL viene utilizzato per inviare una richiesta API per aggiornare il record DNS con questo IP appena recuperato. Assicurati di sostituire i valori per your_secret e your_subdomain.

Successivamente, rendi questo script eseguibile:

chmod +x /opt/ddns-update.sh

Poi avvia l’editor crontab:

crontab -e

Aggiungi la seguente riga alla fine del tuo crontab:

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

Salva ed esci. Lo script verrà ora eseguito ogni due minuti, mantenendo il tuo record DNS dinamico aggiornato con l’ultimo indirizzo IP pubblico del client.

Ulteriori letture

  • Articolo Wikipedia sul DNS dinamico
  • docker-ddns su Github
Share: X/Twitter LinkedIn

Ricevi i nuovi post nella tua casella di posta.

Nessuno spam. Disiscriviti in qualsiasi momento.