Para crear un script que rastree nuestra ip pública con ayuda de cloudflare vamos a necesitar los siguientes datos: ```bash 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: ```bash 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: ```bash {"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: ```bash 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: ```bash {"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: ```bash #!/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== ```bash #!/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== ```bash #!/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== ```bash #!/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 ```