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
#!/bin/bash
## 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.