Buscar este blog

domingo, 30 de agosto de 2026

DynDns OVH Sincronización de IP pública dinámica

 Si tienes un servidor en casa o detrás de una conexión con IP dinámica, sabes que tarde o temprano tu dirección IP pública cambia y tu dominio deja de apuntar a tu equipo. En esta entrada explico cómo resolverlo con OVH usando su API compatible con DynDNS y un pequeño script en Bash que se ejecuta desde cron: comprueba tu IP pública, la compara con la que tiene el DNS y solo envía la actualización cuando es necesario.

1. Qué necesitas en OVH antes de empezar

  1. Un dominio gestionado en OVH (por ejemplo, tudominio.com).
  2. Activar el servicio DynHost en el panel de OVH: Web Cloud → Dominios → tu dominio → Zona DNS → DynHost.
  3. Crear unas credenciales DynHost (un identificador y una contraseña). El identificador suele tener el formato tudominio.com-dyndns. Anótalas: las necesitarás en el script.
  4. Crear el registro DynHost (un registro A de tipo dinámico) para el subdominio que quieras actualizar, por ejemplo mihost.tudominio.com.

Con esto, OVH expone un endpoint compatible con el protocolo DynDNS2 que permite actualizar la IP del registro mediante una simple petición HTTPS.

2. La API de actualización de OVH

El endpoint es:

https://dns.eu.ovhapis.com/nic/update?system=dyndns&hostname=HOST&myip=IP

Parámetros:

ParámetroDescripción
system=dyndnsProtocolo DynDNS2 (fijo).
hostnameNombre completo del registro a actualizar, p. ej. mihost.tudominio.com.
myipNueva dirección IP pública que se quiere asignar.

La autenticación se envía en la propia URL (método usuario:contraseña delante del dominio). Las respuestas habituales son:

  • good <IP> → actualización realizada correctamente.
  • nochg <IP> → la IP enviada ya coincide con la registrada; no hubo cambio.
  • badauth → credenciales incorrectas.
  • abuse → bloqueo temporal por abuso (demasiadas peticiones).

3. Requisitos en el servidor

  • bash, curl y herramientas básicas (awk, tail, date).
  • dig (paquete dnsutils); si no está disponible, el script usa getent automáticamente.
  • cron para la ejecución periódica.

4. El script completo

Guarda el siguiente contenido como update_ipv4.sh. Solo tienes que adaptar las variables HOSTNAME y UPDATE_URL con tu host y tus credenciales de OVH:

#!/bin/bash

SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
HOSTNAME="mihost.tudominio.com"
UPDATE_URL="https://tudominio.com-dyndns:TU_TOKEN_SECRETO@dns.eu.ovhapis.com/nic/update"
LOG_FILE="$SCRIPT_DIR/update_ipv4.log"
IP_HISTORY_FILE="$SCRIPT_DIR/ip_history.log"
LAST_UPDATE_FILE="$SCRIPT_DIR/last_update"
FORCE_INTERVAL=21600 # 6 horas

log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') $*" >> "$LOG_FILE"
}

MISSING_DEPS=0
for cmd in curl awk cat tail date readlink; do
    if ! command -v "$cmd" >/dev/null 2>&1; then
        echo "$(date '+%Y-%m-%d %H:%M:%S') ERROR: dependencia no encontrada: $cmd" >> "$LOG_FILE" 2>/dev/null
        MISSING_DEPS=1
    fi
done
HAS_DIG=0
HAS_GETENT=0
command -v dig >/dev/null 2>&1 && HAS_DIG=1
command -v getent >/dev/null 2>&1 && HAS_GETENT=1
if [ $HAS_DIG -eq 0 ]; then
    if [ $HAS_GETENT -eq 1 ]; then
        log "AVISO: dig no disponible, se usara getent para resolver el host"
    else
        log "ERROR: no hay herramienta para resolver DNS (se necesita dig o getent)"
        MISSING_DEPS=1
    fi
fi
if [ $MISSING_DEPS -eq 1 ]; then
    exit 1
fi

IP=$(curl -s --max-time 10 https://api.ipify.org || curl -s --max-time 10 https://ifconfig.me || curl -s --max-time 10 https://icanhazip.com)
if ! [[ "$IP" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
    log "ERROR: no se pudo obtener la IP publica"
    exit 1
fi

HOST_IP=""
if [ $HAS_DIG -eq 1 ]; then
    HOST_IP=$(dig +short A "$HOSTNAME" 2>/dev/null | grep -m1 -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$')
fi
if [ -z "$HOST_IP" ] && [ $HAS_GETENT -eq 1 ]; then
    HOST_IP=$(getent hosts "$HOSTNAME" 2>/dev/null | grep -m1 -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+')
fi

LAST_ASSIGNED_IP=$(tail -n1 "$IP_HISTORY_FILE" 2>/dev/null | awk '{print $NF}')

LAST_UPDATE=$(cat "$LAST_UPDATE_FILE" 2>/dev/null)
[[ "$LAST_UPDATE" =~ ^[0-9]+$ ]] || LAST_UPDATE=0
NOW=$(date +%s)

FORCED=0
if [ $((NOW - LAST_UPDATE)) -ge $FORCE_INTERVAL ]; then
    FORCED=1
fi

if [ "$IP" = "$LAST_ASSIGNED_IP" ] && [ "$IP" = "$HOST_IP" ] && [ $FORCED -eq 0 ]; then
    log "OMITIDO: IP=$IP sin cambios (host=$HOST_IP, ultima_asignada=$LAST_ASSIGNED_IP)"
    exit 0
fi

if [ $FORCED -eq 1 ]; then
    MOTIVO="actualizacion forzada cada 6h"
else
    MOTIVO="cambio detectado (host=$HOST_IP, ultima_asignada=$LAST_ASSIGNED_IP)"
fi

RESPONSE=$(curl -s --max-time 15 "${UPDATE_URL}?system=dyndns&hostname=${HOSTNAME}&myip=${IP}")
CURL_EXIT=$?

if [ $CURL_EXIT -ne 0 ]; then
    log "ERROR: curl fallo con codigo $CURL_EXIT ($MOTIVO)"
    exit 1
fi

case "$RESPONSE" in
    good*|nochg*)
        echo "$(date '+%Y-%m-%d %H:%M:%S') $IP" >> "$IP_HISTORY_FILE"
        echo "$NOW" > "$LAST_UPDATE_FILE"
        log "ACTUALIZADO: IP=$IP RESPUESTA=$RESPONSE ($MOTIVO)"
        ;;
    *)
        log "ERROR: respuesta inesperada='$RESPONSE' IP=$IP ($MOTIVO)"
        exit 1
        ;;
esac

Dale permisos de ejecución y restringe el acceso, ya que el fichero contiene tus credenciales:

chmod 700 update_ipv4.sh

5. Cómo funciona

  1. Verifica dependencias: comprueba que curl y las herramientas necesarias existen; si falta dig, usa getent como alternativa. Si falta algo crítico, anota el error en el log y sale.
  2. Obtiene tu IP pública consultando varios servicios externos en cascada (api.ipify.org, ifconfig.me, icanhazip.com) para no depender de uno solo.
  3. Resuelve tu hostname con dig para saber qué IP tiene el DNS actualmente.
  4. Lee el estado local: la última IP asignada (fichero ip_history.log) y el momento de la última actualización enviada (fichero last_update con un timestamp Unix).
  5. Decide:
    • Si la IP pública coincide con la última asignada y con la del DNS, y no han pasado 6 horas, no envía nada (registro OMITIDO).
    • Si hay discrepancia, envía la actualización (registro ACTUALIZADO).
    • Independientemente de lo anterior, cada 6 horas fuerza una actualización como medida de seguridad.
  6. Envía la petición con curl y solo actualiza el estado local si OVH responde good o nochg; en caso contrario registra el error para reintentar en la siguiente ejecución.

6. Ficheros generados

FicheroContenido
update_ipv4.logLog de ejecuciones: ACTUALIZADO, OMITIDO, AVISO y ERROR.
ip_history.logHistórico de IPs asignadas con fecha.
last_updateTimestamp de la última petición enviada (para la regla de las 6 horas).

Ejemplo de log:

2026-01-15 10:59:37 ACTUALIZADO: IP=203.0.113.42 RESPUESTA=good 203.0.113.42 (cambio detectado (host=198.51.100.7, ultima_asignada=198.51.100.7))
2026-01-15 11:10:01 OMITIDO: IP=203.0.113.42 sin cambios (host=203.0.113.42, ultima_asignada=203.0.113.42)

7. Programación con cron

Edita el crontab del usuario y añade una ejecución periódica; por ejemplo, cada 10 minutos:

crontab -e
*/10 * * * * /ruta/a/update_ipv4.sh

No te preocupes por la frecuencia: el propio script evita enviar peticiones innecesarias, así que ejecutarlo a menudo no satura la API de OVH.

8. Resolución de problemas

SíntomaCausa probableSolución
badauthCredenciales DynHost incorrectas.Revisar identificador y contraseña en el panel de OVH.
abuseBloqueo por exceso de peticiones.Esperar y reducir la frecuencia de actualización.
ERROR: no se pudo obtener la IP publicaSin salida a internet o servicios caídos.Comprobar conectividad con curl -s https://api.ipify.org.
El host no resuelve la IP nuevaPropagación DNS o caché.Esperar unos minutos y verificar con dig +short mihost.tudominio.com.
El cron no ejecuta el scriptRutas relativas o falta de permisos.Usar rutas absolutas en el crontab y chmod 700.

9. Nota de seguridad

El script contiene las credenciales DynHost en la variable UPDATE_URL. Mantén el fichero con permisos restrictivos (chmod 700), no lo subas a repositorios públicos y, si compartes el código (como en esta entrada), sustituye siempre tu dominio y tus credenciales por marcadores genéricos.

Con esto tendrás tu subdominio de OVH apuntando siempre a tu IP pública actual, sin dependencias externas ni clientes de DynDNS de terceros: solo bash, curl y cron.

No hay comentarios:

Publicar un comentario

DynDns OVH Sincronización de IP pública dinámica

  Si tienes un servidor en casa o detrás de una conexión con IP dinámica, sabes que tarde o temprano tu dirección IP pública cambia y tu dom...