obsidian-dix/DIX-Notes/DDNS RASTREO CON CLOUDFLARE.md

6.9 KiB
Raw Blame History

Para crear un script que rastree nuestra ip pública con ayuda de cloudflare vamos a necesitar los siguientes datos:

ZONE_ID=""
RECORD_ID=""
API_TOKEN=""
EMAIL=""
DOMAIN=""

Para obtener el ZONE_ID, te recomiendo crear un registro de un subdominio en tu perfil de cloudflare, ejemplo registro:

Tipo: A Nombre: mi-ip Contenido: 187.123.32.45

En contenido va la ip pública.

Una vez creado tu subdomino, debemos crear API Token, vamos a Perfil > Tokens de API > Crear Token > Editar zona DNS > (sección Recursos de Zona) opción 1: Incluir, Opción 2: Zona específica, Opción 3: selecciona tu dominio > Ir a resumen, eso te dará tu ==API_TOKEN ==,

Una Vez tengas el API Token vamos a obtener el ZONE_ID, en tu consola ejecuta el comando:

curl -X GET "https://api.cloudflare.com/client/v4/zones?name=TU-DOMINIO-NO-SUBDOMINIO.com" \
     -H "Authorization: Bearer TU-API-TOKEN" \
     -H "Content-Type: application/json"

Ejecuta ese comando en tu consola linux, la salida será algo como:

{"result":[
	{"id":"TU-ZONE-ID","name":"TU-DOMINIO-NO-SUBDOMINIO.com","status":"active","paused":false, ... (más cosas)

Del primer bloque verás un diccionario con una clave id, el valor es tu ==ZONE_ID==, para obtener el RECORD_ID es un poco similar al paso anterior, el comando a ejecutar es:

curl -s -X GET "https://api.cloudflare.com/client/v4/zones/TU-ZONE-ID/dns_records?type=A&name=TU-SUBDOMINIO.COM" \
     -H "Authorization: Bearer TU-API-TOKEN" \
     -H "Content-Type: application/json"

Obtendrás una respuesta como esta:

{"result":[{"id":"TU-RECORD-ID","name":"TU-SUBDOMINIO.COM","type":"A", ... (más cosas)

Del primer bloque verás un diccionario, con una clave id, el valor es tu ==RECORD_ID==, en el valor de ==EMAIL==, coloca el email con el que inicias sesión en tu cuenta de cloudflare, y en ==DOMAIN== coloca el nombre de tu subdominio, una vez que ya tenemos esos datos podemos continuar con el script completo:

#!/bin/bash

# Configuración
ZONE_ID="abcdef1234567890abcdef1234567890"
RECORD_ID="c3f9a7e6b24d48b2a6f481c2a9d2f9c1"
API_TOKEN="e4b-2f6c9a81d4b87f0a927ec5b3c6a59f0e7a45b"
EMAIL="tu.email@mail.com"
DOMAIN="subdominio.dominio.com"

# Obtener IP actual
IP=$(curl -s https://api.ipify.org)

# Obtener IP actual del DNS
DNS_IP=$(dig +short $DOMAIN @1.1.1.1)

# Comparar
if [ "$IP" != "$DNS_IP" ]; then
  echo "La IP cambió: $DNS_IP$IP. Actualizando en Cloudflare..."
  curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
     -H "Authorization: Bearer $API_TOKEN" \
     -H "Content-Type: application/json" \
     --data "{\"type\":\"A\",\"name\":\"$DOMAIN\",\"content\":\"$IP\",\"ttl\":120,\"proxied\":true}" | jq
else
  echo "La IP no ha cambiado: $IP"
fi

==Versión Mejorada==

#!/bin/bash

# Configuración
ZONE_ID="e70540b388ab9d20bfe27d9a31cd474b"
RECORD_ID="5d05a48c9d76c7767302442fffa096bd"
API_TOKEN="9BD-GB7PtGd5pgXTEBxnv3k1eJlJYJoIWx9HgLLs"
DOMAIN="ip.xala.dev"

# Obtener IP pública actual
IP=$(curl -s https://api.ipify.org)

# Obtener IP configurada en Cloudflare (usando la API)
DNS_IP=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" | jq -r '.result.content')

# Comparar
if [ "$IP" != "$DNS_IP" ]; then
  echo "La IP cambió: $DNS_IP$IP. Actualizando en Cloudflare..."
  curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
     -H "Authorization: Bearer $API_TOKEN" \
     -H "Content-Type: application/json" \
     --data "{\"type\":\"A\",\"name\":\"$DOMAIN\",\"content\":\"$IP\",\"ttl\":120,\"proxied\":true}" | jq
else
  echo "La IP no ha cambiado: $IP"
fi

==LA MEJOR VERSIÓN==

#!/bin/bash

# echo "[$(date '+%Y-%m-%d %H:%M:%S')] Ejecutando actualización de IP..."

# Configuración
ZONE_ID="e70540b388ab9d20bfe27d9a31cd474b"
RECORD_ID="5d05a48c9d76c7767302442fffa096bd"
API_TOKEN="9BD-GB7PtGd5pgXTEBxnv3k1eJlJYJoIWx9HgLLs"
DOMAIN="ip.xala.dev"


# Obtener IP pública actual
IP=$(curl -s https://api.ipify.org)

# Obtener IP registrada en Cloudflare
DNS_IP=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" | jq -r '.result.content')

# Comparar
if [ "$IP" != "$DNS_IP" ]; then
  echo "La IP cambió: $DNS_IP$IP. Actualizando en Cloudflare..."
  curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
     -H "Authorization: Bearer $API_TOKEN" \
     -H "Content-Type: application/json" \
     --data "{\"type\":\"A\",\"name\":\"$DOMAIN\",\"content\":\"$IP\",\"ttl\":120,\"proxied\":true}" | jq
else
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] La IP no ha cambiado: $IP"
fi

# echo "[$(date '+%Y-%m-%d %H:%M:%S')] Fin de ejecución."

integra ntfy, que llegue un mensaje cuando cambie la ip

==MEJORADO, CON PROXIED FALSE==

#!/bin/bash

# Configuración
ZONE_ID="e70540b388ab9d20bfe27d9a31cd474b"
RECORD_ID="5d05a48c9d76c7767302442fffa096bd"
API_TOKEN="9BD-GB7PtGd5pgXTEBxnv3k1eJlJYJoIWx9HgLLs"
DOMAIN="ip.xala.dev"


# Obtener IP pública actual
IP=$(curl -s https://api.ipify.org)

# Obtener IP registrada actualmente en Cloudflare
DNS_RECORD=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json")

DNS_IP=$(echo "$DNS_RECORD" | jq -r '.result.content')

# validaciones
if [ -z "$IP" ]; then
# Notificación vía ntfy
  # curl -d "🌎 [$(date '+%Y-%m-%d %H:%M:%S')] IP actualizada: $DNS_IP → $IP" ntfy.xala.dev/alerts
  curl -d "🚨 [$(date '+%Y-%m-%d %H:%M:%S')] No se pudo obtener la IP pública." ntfy.xala.dev/alerts
  exit 1
fi

if [ "$IP" != "$DNS_IP" ]; then
  curl -d "🌐 La IP ha cambiado: $DNS_IP$IP. Actualizando en Cloudflare..." ntfy.xala.dev/alerts

  UPDATE_RESPONSE=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
    -H "Authorization: Bearer $API_TOKEN" \
    -H "Content-Type: application/json" \
    --data "{
      \"type\": \"A\",
      \"name\": \"$DOMAIN\",
      \"content\": \"$IP\",
      \"ttl\": 1,
      \"proxied\": false
    }")

  SUCCESS=$(echo "$UPDATE_RESPONSE" | jq -r '.success')

  if [ "$SUCCESS" == "true" ]; then
    curl -d "🌎 [$(date '+%Y-%m-%d %H:%M:%S')] IP actualizada: $DNS_IP$IP" ntfy.xala.dev/alerts
  else
    curl -d "🚨 [$(date '+%Y-%m-%d %H:%M:%S')] Falló la actualización en Cloudflare." ntfy.xala.dev/alerts
  fi
else
  echo " [$(date '+%Y-%m-%d %H:%M:%S')] La IP no ha cambiado: $IP"
fi