Nuevo script para DNS dinámico con DigitalOcean

Anteriormente había estado usando un script para actualizar mediante una tarea cron la IP de un registro A de un nombre de dominio de manera tal que sirviera para ingresar a la red de mi casa. Hoy revisando los logs de Digital Ocean, veo que hay un montón de peticiones repetidas dirigidas precisamente a ese cambio, por lo que supuse que no estaba funcionando.

Analizando el script, veo que el problema esta en que ocurren errores de autenticación el cual probablemente tiene que ver con la forma como están escritas las variables. Así que decidí hacer las cosas un poco más simples en un nuevo script y que me notifique usando Slack.

Para este script, de antemano tendremos que saber el ID del registro que vamos a editar. En mi caso, solo tenía que reciclar los datos del archivo secrets anterior, o bien, en el panel de control de Digital Ocean podemos conocerlos.

Creamos el archivo update-dns.sh. Añadimos el contenido siguiente al archivo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/bin/bash
################################################################################
##                                                                            ##
##   Este modifica un registro de un nombre de dominio asociado a una         ##
##   cuenta de Digital Ocean, usando la API v2. Este script depende de curl,  ##
##   por lo que hay que instalarlo antes de ejecutarlo. Lo que hace es        ##
##   comparar la IP pública vs la IP almacenada en el registro del dominio    ##
##   de Digital Ocean, si la condición no se cumple, entonces actualiza       ##
##   el registro usando la API de Digital Ocean y notifica a través de        ##
##   Slack sobre la actualización y cual es la IP nueva.                      ##
##                                                                            ##
################################################################################
## Estas variables son obtenidas de Digital Ocean
ACCESS_TOKEN=      ## Token de la API de Digital Ocean
DOMAIN=            ## Nombre de dominio a editar
RECORD_ID=         ## ID del registro que editaremos
## Estas son las variables relacionadas con la IP
PUBLIC_IP=$(curl -s http://checkip.amazonaws.com/)  ## IP pública
RECORD_IP=$(curl -s -X GET -H "Content-Type: application/json" -H "Authorization: Bearer "$ACCESS_TOKEN"" "https://api.digitalocean.com/v2/domains/"$DOMAIN"/records/"$RECORD_ID"" | sed -e 's/^.*"data":"\([^"]*\)".*$/\1/')  ## IP almacenada en el registro
## Notificaciones en Slack
SLACKURL=          ## URL de la API de Slack para notificaciones
if ping -q -w 1 -c 1 1.1.1.1 >/dev/null 2>&1
then
    if [ "$PUBLIC_IP" != "$RECORD_IP" ]
    then
        curl -s -X PUT -H "Content-Type: application/json" -H "Authorization: Bearer "$ACCESS_TOKEN"" -d '{"data":"'${PUBLIC_IP}'"}' "https://api.digitalocean.com/v2/domains/"$DOMAIN"/records/"$RECORD_ID""
        curl -X POST -H 'Content-type: application/json' --data '{"text":"La IP del homelab ha cambiado. Ahora es: '${PUBLIC_IP}'"}' ${SLACKURL}
    fi
fi

Analizando un poco lo que hace el script, se trata de dos condicionales ir uno dentro del otro, donde el primero comprueba que hay conexión a internet, comprobando con el comando ping si hay respuesta por parte de la IP 1.1.1.1, el popular servicio DNS de Cloudflare. Si la respuesta es correcta, entonces verifica que la IP pública no ha cambiado comprobando contra el registro almacenado en Digital Ocean, y si esta ha cambiado, entonces en el segundo condicional procede a ingresar el nuevo valor y notificar a través de Slack.

Ahora, podemos guardarlo y darle permisos de ejecución.

1
$ chmod +x update-dns.sh

Ahora solo es cuestión de añadirlo como una tarea cron. En mi caso personal, lo ejecuto cada 2 minutos. Abrimos el crontab -e

1
*/2 * * * * /home/usuario/scripts/update-dns.sh

y así, en un script mucho más simple, tendremos la misma función de DNS dinámico y sin hacer tantas peticiones a la API de Digital Ocean.


Moisés Serrano Samudio Médico de atención primaria, fotógrafo aficionado, apasionado de las tecnologías relacionadas con el EdTech y el eHealth y diseñador/desarrollador de sitios web de salud. Médico, apasionado del EdTech/eHealth y diseñador/desarrollador de sitios web de salud.
Moisés Serrano Samudio

@linkmoises

Médico de atención primaria, fotógrafo aficionado, apasionado de las tecnologías relacionadas con el EdTech y el eHealth.

Entradas relacionadas

  1. Aún no hay comentarios...

Deja una respuesta

Su email no será publicado. Required fields are marked *