Cfg - Dominio en Duck DNS

Crear un dominio y configurar actualización de IP

Versión 1.0

Última modificación: 18/08/2026 17:56

Objetivo ⮴

Crea un dominio en Duck DNS y configurar una tarea para actualizar la IP a la que apunta el dominio.

Crear un dominio ⮴

El dominio se obtiene en la pagína web de Duck DNS.

Cuenta / Dominio ⮴

  • account: favoritos.jp@gmail.com

  • type: free

  • token: 2ace515f-6068-4b4e-a7da-14ba6ab24eff

  • created date:15 Jul 2026, 19:13:47

  • Dominio: lozjim.duckdns.org -> 77.229.231.193

Sincronizar la IP del router con el dominio ⮴

El dominio debe apuntar a la IP pública asiganada por el proveedor, y dado que no es fija hay que crear una tarea (cron) que actualice la IP que tiene asignado el dominio en Duck DNS con la IP pública del router.

Esto se hace con un script y una tarea en el cron del root que lo ejecute.

El log se crea en el archivo asignado en la variable $LOG_FILE del script de actualización.

Tareas a realizar como root/sudo: ⮴


    # Crear un directorio para almacenar el script y el archivo de configuración
    mkdir -p /etc/duckdns

    # Script
    nano /etc/duckdns/update_ip_dns.sh
    # Añadir el contenido del script

    # Archivo de configuración
    nano /etc/duckdns/config

    # Añadir el contenido en `/etc/duckdns/config` lo siguiente: 
    TOKEN="2ace515f-6068-4b4e-a7da-14ba6ab24eff"
    DOMAIN="lozjim.duckdns.org"

    # Asignar permisos
    chmod 700 /etc/duckdns/update_ip_dns.sh
    chmod + /etc/duckdns/update_ip_dns.sh
    chmod 600 /etc/duckdns/config

    # Instalar si es necesario
    apt install curl

    # Añadir la tarea al cron
    crontab -e
      
    @reboot /etc/duckdns/update_ip_dns.sh
    */5 * * * * /etc/duckdns/update_ip_dns.sh

Script de actualizacion: ⮴


  #!/bin/bash

  #  @reboot /etc/duckdns/update_ip_dns.sh
  #  */5 * * * * /etc/duckdns/update_ip_dns.sh
  #  chmod 600 /etc/duckdns/config
  #  chmod 700 /etc/duckdns/update_ip_dns.sh

  CONFIG_FILE="/etc/duckdns/config"
  LOG_FILE="/var/log/duckdns/update_ip_duckdns.log"
  MAX_LOG_SIZE=1048576  # 1 MB en bytes
  MAX_BACKUPS=5

  # Crear directorios si no existen
  mkdir -p "$(dirname "$CONFIG_FILE")"
  mkdir -p "$(dirname "$LOG_FILE")"

  # Cargar configuración
  # shellcheck disable=SC1090
  if [[ -f "$CONFIG_FILE" ]]; then
    source "$CONFIG_FILE"
  else
    {
      echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: No existe el archivo $CONFIG_FILE"
    } >> "$LOG_FILE"
    exit 1
  fi

  # Validar que las variables necesarias existen
  if [[ -z "$TOKEN" ]] || [[ -z "$DOMAIN" ]]; then
    {
      echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: TOKEN o DOMAIN no definidos en $CONFIG_FILE"
    } >> "$LOG_FILE"
    exit 1
  fi

  # Función para rotar logs
  rotate_logs() {
      local log_dir=""
      local log_name=""

      log_dir=$(dirname "$LOG_FILE")
      log_name=$(basename "$LOG_FILE")

      # Renombra los logs existentes de mayor a menor
      for i in $(seq $((MAX_BACKUPS - 1)) -1 1); do
          if [[ -f "$log_dir/$log_name.$i" ]]; then
              if [[ $i -ge $MAX_BACKUPS ]]; then
                  rm "$log_dir/$log_name.$i"
              else
                  mv "$log_dir/$log_name.$i" "$log_dir/$log_name.$((i + 1))"
              fi
          fi
      done

      # El log actual se convierte en duck.log.1
      if [[ -f "$LOG_FILE" ]]; then
          mv "$LOG_FILE" "$log_dir/$log_name.1"
      fi
  }

  # Verifica si el log necesita rotación
  if [[ -f "$LOG_FILE" ]] && [[ $(stat -c%s "$LOG_FILE") -ge $MAX_LOG_SIZE ]]; then
      rotate_logs
  fi

  # Ejecuta la actualización y registra
  {
      #echo "-------------------------------------------------------------------------------"
      resultado="$(echo url="https://www.duckdns.org/update?domains=${DOMAIN}&token=${TOKEN}&ip=" | curl -k -s -K - )"
      if [[ "$resultado" == "OK" ]]; then
        echo "[$(date '+%Y-%m-%d %H:%M:%S')] Actualizar IP : $resultado - $(curl -s https://api.ipify.org)"
      else
        echo "[$(date '+%Y-%m-%d %H:%M:%S')] Actualizar IP : Error"
        #echo "$resultado"
      fi

  } >> "$LOG_FILE"