Ejemplo como actualizar DNS en cloudflare si tienes un servidor web en tu casa u oficina con ip dinamica

8 views
Skip to first unread message

Ciro Vargas C

unread,
Jan 25, 2026, 4:33:01 PM (5 days ago) Jan 25
to oo...@googlegroups.com

Hola Todos  les queria compartir este ejemplo que uso actualmente par actualizar mi dns en cloudflare si mi ip cambia

El ejecutable en este caso debe estar en la carpeta script  y lo pueden poner a correr automáticamente con task scheduler de windows cada por ejemplo media hora.

obviamente no estoy colocando mi toker actual sino  uno cambiado.

deben generar uno para leer y otro para editar

si hay algún error lo deja en el archivo texto "nopudeactDNS.txt"

deben tener una IP public esto no les va a funcionar si tienen CGNAT

funciona muy bien

Este es el código...


#include "common.ch"

FUNCTION Main()
    LOCAL cReadAuthKey := "C0otRwtYXZ4aaaaaaaaaaqauobfuNsKPc2mzByq7e"
    LOCAL cEditAuthKey := "ooRpWRSEKxbbbbbbbbbbbAfFk35MN1IYLXNjC4Zicb"
    LOCAL cRootDomain := "cyrusitexpert.com"
    LOCAL cWWWDomain := "www.cyrusitexpert.com"
    LOCAL cSaaSDomain := "saas.cyrusitexpert.com"
    LOCAL cZoneID, cRootRecordID, cWWWRecordID, cSaaSRecordID, cCurrentIP
    LOCAL cRootDNSIP, cWWWDNSIP, cSaaSDNSIP, cUpdateResult
    run cd c:\script
    cstamp:= dtos(date())+' '+time()
    set printer to c:\script\nopudeactDNS.txt
    set print on
    ? 'Stamp : '+cstamp
    // Step 1: Get Zone ID
    cZoneID := GetCloudflareZoneID(cRootDomain, cReadAuthKey)
    IF Empty(cZoneID)
        ? "Error: Unable to retrieve Zone ID."
        RETURN NIL
    ENDIF

    // Step 2: Get DNS Record IDs for root domain, www subdomain, and saas subdomain
    cRootRecordID := GetCloudflareRecordID(cZoneID, cRootDomain, cReadAuthKey)
    IF Empty(cRootRecordID)
        ? "Error: Unable to retrieve DNS Record ID for root domain."
        RETURN NIL
    ENDIF

    cWWWRecordID := GetCloudflareRecordID(cZoneID, cWWWDomain, cReadAuthKey)
    IF Empty(cWWWRecordID)
        ? "Error: Unable to retrieve DNS Record ID for www subdomain."
        RETURN NIL
    ENDIF

    cSaaSRecordID := GetCloudflareRecordID(cZoneID, cSaaSDomain, cReadAuthKey)
    IF Empty(cSaaSRecordID)
        ? "Error: Unable to retrieve DNS Record ID for saas subdomain."
        RETURN NIL
    ENDIF

    // Step 3: Get current public IP
    cCurrentIP := GetPublicIP()
    IF Empty(cCurrentIP)
        ? "Error: Unable to retrieve public IP."
        RETURN NIL
    ENDIF

    // Step 4: Get the current Cloudflare DNS IPs for root domain, www subdomain, and saas subdomain
    cRootDNSIP := GetCloudflareDNSIP(cZoneID, cRootRecordID, cReadAuthKey)
    IF Empty(cRootDNSIP)
        ? "Error: Unable to retrieve DNS IP for root domain from Cloudflare."
        RETURN NIL
    ENDIF

    cWWWDNSIP := GetCloudflareDNSIP(cZoneID, cWWWRecordID, cReadAuthKey)
    IF Empty(cWWWDNSIP)
        ? "Error: Unable to retrieve DNS IP for www subdomain from Cloudflare."
        RETURN NIL
    ENDIF

    cSaaSDNSIP := GetCloudflareDNSIP(cZoneID, cSaaSRecordID, cReadAuthKey)
    IF Empty(cSaaSDNSIP)
        ? "Error: Unable to retrieve DNS IP for saas subdomain from Cloudflare."
        RETURN NIL
    ENDIF

    // Step 5: Compare and update root domain if needed
    IF cCurrentIP == cRootDNSIP
        ? "No update needed for root domain. DNS is already correct."
    ELSE
        ? "Updating root domain DNS from " + cRootDNSIP + " to " + cCurrentIP
        cUpdateResult := UpdateCloudflareDNS(cZoneID, cRootRecordID, cEditAuthKey, cRootDomain, cCurrentIP)
        IF cUpdateResult
            ? "Root domain DNS successfully updated!"
        ELSE
            ? "Error updating root domain DNS."
        ENDIF
    ENDIF

    // Step 6: Compare and update www subdomain if needed
    IF cCurrentIP == cWWWDNSIP
        ? "No update needed for www subdomain. DNS is already correct."
    ELSE
        ? "Updating www subdomain DNS from " + cWWWDNSIP + " to " + cCurrentIP
        cUpdateResult := UpdateCloudflareDNS(cZoneID, cWWWRecordID, cEditAuthKey, cWWWDomain, cCurrentIP)
        IF cUpdateResult
            ? "www subdomain DNS successfully updated!"
        ELSE
            ? "Error updating www subdomain DNS."
        ENDIF
    ENDIF

    // Step 7: Compare and update saas subdomain if needed
    IF cCurrentIP == cSaaSDNSIP
        ? "No update needed for saas subdomain. DNS is already correct."
    ELSE
        ? "Updating saas subdomain DNS from " + cSaaSDNSIP + " to " + cCurrentIP
        cUpdateResult := UpdateCloudflareDNS(cZoneID, cSaaSRecordID, cEditAuthKey, cSaaSDomain, cCurrentIP)
        IF cUpdateResult
            ? "saas subdomain DNS successfully updated!"
        ELSE
            ? "Error updating saas subdomain DNS."
        ENDIF
    ENDIF
    set print off
    set printer to
    RETURN NIL

//=======================================================================

// Function to get the Cloudflare Zone ID
FUNCTION GetCloudflareZoneID(cDomain, cReadAuthKey)
    LOCAL cCmd, cResponse, cZoneID
    cCmd := 'curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=' + cDomain + '" ' +;
            '-H "Authorization: Bearer ' + cReadAuthKey + '" ' +;
            '-H "Content-Type: application/json"'
   
    cResponse := RUNGET(cCmd)
   
    cZoneID := ExtractJSONValue(cResponse, '"id":"', '"')
    RETURN AllTrim(cZoneID)

// Function to get the Cloudflare DNS Record ID
FUNCTION GetCloudflareRecordID(cZoneID, cDomain, cReadAuthKey)
    LOCAL cCmd, cResponse, cRecordID
    cCmd := 'curl -s -X GET "https://api.cloudflare.com/client/v4/zones/' + cZoneID + '/dns_records?name=' + cDomain + '" ' +;
            '-H "Authorization: Bearer ' + cReadAuthKey + '" ' +;
            '-H "Content-Type: application/json"'
   
    cResponse := RUNGET(cCmd)

    cRecordID := ExtractJSONValue(cResponse, '"id":"', '"')
    RETURN AllTrim(cRecordID)

// Function to get the public IP
FUNCTION GetPublicIP()
    LOCAL cCmd := 'c:\script\curl -s http://ifconfig.me'
    LOCAL cIP := RUNGET(cCmd)
    RETURN AllTrim(cIP)

// Function to get the current DNS IP from Cloudflare
FUNCTION GetCloudflareDNSIP(cZoneID, cRecordID, cReadAuthKey)
    LOCAL cCmd, cResponse, cIP
    cCmd := 'curl -s -X GET "https://api.cloudflare.com/client/v4/zones/' + cZoneID + '/dns_records/' + cRecordID + '" ' +;
            '-H "Authorization: Bearer ' + cReadAuthKey + '" ' +;
            '-H "Content-Type: application/json"'

    cResponse := RUNGET(cCmd)

    cIP := ExtractJSONValue(cResponse, '"content":"', '"')
    RETURN AllTrim(cIP)

// Function to update the DNS record in Cloudflare
FUNCTION UpdateCloudflareDNS(cZoneID, cRecordID, cEditAuthKey, cDomain, cNewIP)
    LOCAL cCmd, cResponse
    LOCAL cJSON := '{ "type": "A", "name": "' + cDomain + '", "content": "' + cNewIP + '", "ttl": 120, "proxied": true }'

    cCmd := 'curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/' + cZoneID + '/dns_records/' + cRecordID + '" ' +;
            '-H "Authorization: Bearer ' + cEditAuthKey + '" ' +;
            '-H "Content-Type: application/json" ' +;
            '--data ' + hb_jsonEncode(cJSON)

    cResponse := RUNGET(cCmd)

    RETURN ('"success":true' $ cResponse)

// Function to run a system command and get output
FUNCTION RUNGET(cCommand)
    LOCAL cOutputFile := "c:\script\output.txt"
    LOCAL cResult

    RUN (cCommand + " > " + cOutputFile)

    IF FILE(cOutputFile)
        cResult := MEMOREAD(cOutputFile)
        FERASE(cOutputFile)
    ELSE
        cResult := ""
    ENDIF

    RETURN AllTrim(cResult)

// Function to extract a value from JSON response
FUNCTION ExtractJSONValue(cJSON, cStart, cEnd)
    LOCAL nStart, nEnd, cValue := ""

    nStart := At(cStart, cJSON)
    IF nStart > 0
        nStart += Len(cStart)
        nEnd := At(cEnd, SubStr(cJSON, nStart))
        IF nEnd > 0
            cValue := SubStr(cJSON, nStart, nEnd - 1)
        ENDIF
    ENDIF

    RETURN cValue
   

///===================================
Reply all
Reply to author
Forward
0 new messages