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.2ddns.your_domain NS ns1.your_domainns1.your_domain AAAA 2001:0db8::0db9 (facoltativo)
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 - rootsudo -sPasso 1: Aggiornamento e installazione delle dipendenze.
È sempre buona pratica aggiornare prima il tuo sistema:
apt updateapt upgrade -yrebootDopo 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 dnsutilsPasso 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 updateapt install -y docker-ce docker-ce-cli containerd.ioUna volta completata l’installazione, assicurati che il servizio docker sia abilitato e in esecuzione come segue:
systemctl enable --now docker.servicePasso 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.gitcd docker-ddnsmake imageAspetta che il processo finisca, il che potrebbe richiedere un po’ di tempo, poi apri il file envfile con un editor di testo:
$EDITOR envfileE inserisci quanto segue:
SHARED_SECRET=your_secret
ZONE=ddns.your_domain
RECORD_TTL=60Il 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 -1Possiamo 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-ddnsQuesto 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.targetSalva ed esci, quindi imposta i permessi corretti su questo file di unità:
chmod 664 /etc/systemd/system/ddns-server-ct.serviceCarica il nuovo file di servizio con il seguente comando:
systemctl daemon-reloadOra 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.servicePasso 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.serviceInvia 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.1L’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_domainLa 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.serviceQuindi disabilita il file di blocco del server predefinito, poiché non è necessario:
unlink /etc/nginx/sites-enabled/defaultOra creeremo un nuovo file di configurazione per il proxy inverso, ad esempio:
$EDITOR /etc/nginx/sites-available/ddns-api-proxy.confE 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.serviceL’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_addressPuoi 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.shPoi avvia l’editor crontab:
crontab -eAggiungi la seguente riga alla fine del tuo crontab:
*/2 * * * * /opt/ddns-update.shSalva 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
Ricevi i nuovi post nella tua casella di posta.
Nessuno spam. Disiscriviti in qualsiasi momento.