Cómo implementar un servidor DNS dinámico con Docker en Debian 10

Ejemplo de registros DNS

El DNS dinámico es un servicio de red para asignar nombres de dominio a direcciones IP dinámicas (temporales, que cambian con frecuencia). Se usa para acceder a computadoras que no tienen una dirección IP estática, como las de las redes SOHO (Small Office/Home Office), y a menudo se usa en combinación con el reenvío de puertos para acceder a sistemas que están detrás de firewalls NAT. Este artículo lo guiará a través de la configuración completa de un servidor DNS dinámico en un contenedor Docker en un sistema Debian 10, incluida la configuración de los registros DNS requeridos, la ubicación de la API de administración detrás de un proxy inverso Nginx HTTPS y la automatización del DNS del lado del cliente. registrar actualizaciones.

Requisitos

  • Un solo servidor Debian 10, opcionalmente con conectividad IPv6. (192.0.2.2 y 2001:0db8::0db9 se utilizarán como marcadores de posición para el servidor IPv4 e IPv6, respectivamente).
  • Acceso al usuario root, o un usuario con privilegios sudo.
  • Los puertos tcp/53 y udp/53 deben estar disponibles en el host.
  • Un nombre de dominio registrado y acceso a sus servidores de nombres/archivo de zona. Cree registros DNS para este dominio como se muestra en la siguiente sección.
  • los $EDITOR Se debe establecer la variable de entorno.
  • Opcionalmente, cualquier sistema cliente Linux/Unix para configurar actualizaciones automáticas de registros DNS.

Creación de registros DNS.

Deberá crear al menos 2 registros DNS para que funcione su servidor DNS dinámico. Primero, elija un subdominio como ns1.your_domain que apuntará a la dirección IPv4 de su servidor. En segundo lugar, elija un subdominio como ddns.your_domain que se delegará a ns1.your_domain.

Su servidor DNS dinámico manejará todos los registros en ddns.su_dominio. El tercer registro, de tipo AAAA, es opcional. Los registros correspondientes tienen el siguiente aspecto:

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

Ejemplo de registros DNS

You should create these records in your domain registrar’s control panel. Please note that it may take up to 24 hours for these records to propagate well, but it usually takes minutes.

Installation

 

If you are not using the root user, we recommend you start a temporary root shell, since most commands shown in this guide required elevated privileges. To launch a root shell, use one of the following commands:

sudo su - root
sudo -s

Paso 1: Actualización e instalación de dependencias.

Siempre es una buena práctica actualizar su sistema primero:

apt update
apt upgrade -y
reboot

Después del reinicio, instale los paquetes de software necesarios para esta configuración:

  • cerbot se utilizará para obtener certificados SSL/TLS.
  • hacer es necesario para crear la imagen de la ventana acoplable en la que se ejecutará el servidor DDNS.
  • apt-transporte-https, certificados ca, rizo, gnupg2 y software-propiedades-comunes son necesarios para instalar el repositorio de Docker y su clave GPG correspondiente.
  • dnsutils proporciona excavarque se utilizará para la prueba.
apt install -y certbot make apt-transport-https curl ca-certificates software-properties-common gnupg2 dnsutils

Paso 2: Instale Docker CE.

Agregue la clave GPG de Docker:

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

Instale el repositorio docker:

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

Actualice el caché del repositorio de Debian y luego instale docker y sus dependencias:

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

Una vez que se complete la instalación, asegúrese de que el servicio Docker esté habilitado y ejecutándose de la siguiente manera:

systemctl enable --now docker.service

Paso 3: Descargue y cree docker-ddns

Nuestro servidor DNS dinámico estará alimentado por un contenedor docker que utiliza Bind como servidor DNS y una API de administración escrita en Go. Primero, clone el repositorio de Github y cree la imagen del contenedor con los siguientes comandos:

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

Espere a que finalice el proceso, lo que puede llevar un tiempo, luego abra el archivo envfile con un editor de texto:

$EDITOR envfile

E ingresa lo siguiente:

SHARED_SECRET=your_secret 
ZONE=ddns.your_domain 
RECORD_TTL=60

El secreto compartido es una contraseña que se usará para autenticarse con la API de administración. ZONE indica de qué zona DNS será responsable su servidor, y el registro TTL especifica cuánto tiempo se pueden almacenar en caché los registros DNS. Se recomienda un TTL de 60 segundos para cambios frecuentes de IP dinámicas.

Si es necesario, puede generar una cadena aleatoria de 40 caracteres para el secreto mediante el siguiente comando:

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

Ahora podemos crear el contenedor:

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 creará un contenedor llamado ddns-server a partir de la imagen que creamos anteriormente y asignará los puertos 8080/tcp, 53/tcp y 53/udp del host al contenedor. También montará el directorio /mnt/ddns-data desde el host, en /var/cache/bind en el sistema de archivos del contenedor. Esto se usa para conservar los datos DNS en la recreación del contenedor.

Verifique que el contenedor se haya creado con el comando: Publicidad

docker container ls -a

Se debe generar una sola entrada con el nombre ddns-server.

Paso 4: servicio Systemd (opcional)

Este paso es para una gestión más sencilla, pero no es estrictamente necesario. Si elige no usar un servicio systemd, deberá administrar el contenedor manualmente o usar otra solución de administración. Tenga en cuenta que para implementaciones de contenedores más grandes y complejas, se recomienda una solución de orquestación como Kubernetes o Docker Swarm. En este caso, un servicio systemd encaja perfectamente, ya que solo estamos ejecutando un único contenedor.

Para poder administrar este contenedor como un servicio del sistema, lo envolveremos en una unidad systemd. Cree el archivo /etc/systemd/system/ddns-server-ct.service con su editor de texto:

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

Y agrega lo siguiente:

[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

Guarde y salga, luego configure los permisos correctos en este archivo de unidad:

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

Cargue el nuevo archivo de servicio con el siguiente comando:

systemctl daemon-reload

Ahora debería poder iniciar y detener este contenedor utilizando systemctl como cualquier otro servicio del sistema.

Si desea que el servidor DDNS se inicie automáticamente al iniciar el sistema, ejecute lo siguiente:

systemctl enable ddns-server-ct.service

Paso 5: Probar su servidor

Antes de continuar con la configuración, probaremos la API de administración localmente. Inicie el contenedor:

systemctl start ddns-server-ct.service

Envíe una solicitud GET a la API para crear un nuevo registro:

NOTA: La API actualmente solo es accesible localmente (es decir, desde localhost).

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

Curl debería devolver la siguiente respuesta:

{"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: El dominio test1 se refiere a test1.ddns.your_domain. ya que el servidor está manejando ddns.your_domain. zona.

Realice una búsqueda de DNS para verificar que el registro se haya creado y para probar la resolución de DNS:

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

El resultado debe ser 1.1.1.1.Publicidad

Paso 6: proxy inverso

Dado que la API funciona a través de HTTP, su secreto de autenticación puede potencialmente ser rastreado cada vez que envía una solicitud a través de la red. Un atacante podría manipular sus registros DNS utilizando su secreto. Configuraremos un proxy inverso usando Nginx y lo aseguraremos usando HTTPS. Primero, obtenga un certificado SSL de Let’s Encrypt usando certbot:

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

Se verificará la propiedad de su dominio y se emitirá un certificado. A continuación, instale Nginx y asegúrese de que esté habilitado y ejecutándose:

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

Luego deshabilite el archivo de bloqueo del servidor predeterminado, ya que no es necesario:

unlink /etc/nginx/sites-enabled/default

Ahora crearemos un nuevo archivo de configuración para el proxy inverso, por ejemplo:

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

Y pegue lo siguiente, asegurándose de reemplazar las direcciones IP y los nombres de dominio con los suyos propios:

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;
}


Opcional: Si desea que se pueda acceder a la API a través de IPv6, agregue la siguiente línea después de la directiva de escucha existente:

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

Habilite esta configuración y aplique los cambios recargando Nginx:

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

La API ahora debería ser accesible a través de Internet y solo aceptará conexiones HTTPS. Para probarlo, emita el comando:

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

Debería devolver lo siguiente:

{"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"}

Paso 7: Configuración del cliente

Puede configurar actualizaciones automáticas de registros en cualquier enrutador que admita proveedores de DNS dinámicos personalizados, como Pfsense. También puede configurarlos en la mayoría de los demás dispositivos de su oficina o red doméstica. Para actualizar o crear un registro, se debe enviar una solicitud GET al siguiente punto final:

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

También puede actualizar los registros de múltiples subdominios con una sola solicitud. Por ejemplo, para crear/actualizar registros para sub1.ddns.su_dominio y sub2.ddns.su_dominio con la dirección IP 198.51.100.100, enviaría una solicitud GET a esta URL:

https://ns1.su_dominio:8080/update?secret=su_secreto&dominio=sub1,sub2&addr=198.51.100.100

El parámetro addr también puede contener una dirección IPv6 para crear/actualizar registros DNS AAAA, por ejemplo:

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

Para automatizar estas actualizaciones en un cliente Linux, guarde el siguiente 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.your_domain:8080/update?secret=your_secret&domain=your_subdomain&addr=${CURRENTIP}»


Este script emplea un ciclo while envuelto alrededor de un comando dig que obtiene la dirección IP pública del cliente y la almacena en una variable. El bucle asegura que la IP pública se obtenga correctamente. Luego, cURL se usa para enviar una solicitud API para actualizar el registro DNS con esta IP recién obtenida. Asegúrate de reemplazar los valores de your_secret y your_subdomain.

A continuación, haga que este script sea ejecutable:

chmod +x /opt/ddns-update.sh

Luego inicie el editor crontab:

crontab -e

Agregue la siguiente línea al final de su crontab:

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

Guardar y Salir. El script ahora se ejecutará cada dos minutos, manteniendo su registro de DNS dinámico actualizado con la última dirección IP pública del cliente.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *