Netgate Discussion Forum
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Search
    • Register
    • Login

    Cloudflare dynamic dns not working

    Scheduled Pinned Locked Moved DHCP and DNS
    43 Posts 22 Posters 22.7k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • B
      basse
      last edited by

      Is this still broken in 2.2.3?

      Shouldn't it be possible to use a "custom" dyndns entry instead of the api?

      Edit:
      I used @__det0nat3__ solution, thanks!

      1 Reply Last reply Reply Quote 0
      • F
        freke
        last edited by

        Thank you det0nat3!!!

        n1!

        I'm on 2.2.3-RELEASE (amd64) and still not working as is but your fix did the trick!

        Would be great if it was in 2.2.4 ;)

        1 Reply Last reply Reply Quote 0
        • H
          HammyHavoc
          last edited by

          Just updated to 2.2.4 and now getting this error:

          /rc.dyndns.update: DynDNS: PAYLOAD: E_INVLDINPUT

          DynDNS was previously working flawlessly after following this thread, any suggestions? Do I just redo the edit?

          1 Reply Last reply Reply Quote 0
          • B
            basse
            last edited by

            @HammyHavoc:

            Just updated to 2.2.4 and now getting this error:

            /rc.dyndns.update: DynDNS: PAYLOAD: E_INVLDINPUT

            DynDNS was previously working flawlessly after following this thread, any suggestions? Do I just redo the edit?

            Yeah, just happend to me too, seems like the update did an overwrite of the file.
            Is there an ETA of a fix for this?

            1 Reply Last reply Reply Quote 0
            • D
              doktornotor Banned
              last edited by

              Any manual patches need to be re-applied after upgrading the OS.  https://github.com/pfsense/pfsense/pull/1916

              You can use this URL with System Patches package: https://github.com/doktornotor/pfsense/commit/9aa75e0d5e6b75c0e138408a80ce9615b4136391.patch

              1 Reply Last reply Reply Quote 0
              • B
                bonkas
                last edited by

                Has anyone had any luck on the 2.2.5 update? Aparently CloudFlare DNS was fixed.

                When I try this I get "Invalid HostName" - I have tried the zone ID, hostname but no luck.

                1 Reply Last reply Reply Quote 0
                • H
                  humungus
                  last edited by

                  @bonkas:

                  Has anyone had any luck on the 2.2.5 update? Aparently CloudFlare DNS was fixed.

                  When I try this I get "Invalid HostName" - I have tried the zone ID, hostname but no luck.

                  On 2.2.5, Works no problem for me as of right now. I used the API. Never had it set up before. Got to this article when using my password returned 0.0.0.0

                  use your CloudFlare API

                  1 Reply Last reply Reply Quote 0
                  • F
                    f34rinc
                    last edited by

                    @humungus:

                    On 2.2.5, Works no problem for me as of right now.

                    use your CloudFlare API

                    To add onto what humungus said about the API.  On 2.2.5 when trying to setup a DDNS entry with CloudFlare instead of entering in the password for your CloudFlare account put in the API Key from the CloudFlare My Account page.

                    1 Reply Last reply Reply Quote 0
                    • B
                      bonkas
                      last edited by

                      Yep I have been using the API key as password - Not getting any luck.

                      If I wrongly set my username or password fields I get an authentication failure - So these details are correct.

                      The issue I am having is I am confused about what to put for the hostname - neither the domain name, zone ID or host ID seem to work, I get the error below:

                      • Zone or Host ID was not found, check your hostname.
                      1 Reply Last reply Reply Quote 0
                      • I
                        InsaneNutter
                        last edited by

                        I've just set Dymanic DNS up with Cloudflare and it seems to work fine, the updated IP address does take a few minutes to show on Cloudflare however, which initially lead me to believe Dymanic DNS wasn't working.

                        Service Type: Cloudflare
                        Interface to monitor: LAN
                        Hostname: office.mydomain.com
                        MX: Leave blank
                        Wildcard: No wildcard
                        Username: Email address used to log in to my Cloudflare account
                        Password: Your Cloudflare API key

                        Obviously ensure the A record you want to update already exists for the domain in question on your Cloudflare account.

                        1 Reply Last reply Reply Quote 1
                        • B
                          bonkas
                          last edited by

                          Yep exactly same settings as I have set but still no luck after enabling it again.

                          I get the error: "php-fpm[40812]: /services_dyndns_edit.php: DynDNS (removed domain name): ERROR - Zone or Host ID was not found, check your hostname."

                          But the custom script I has setup works fine…

                          If you need to see the custom script let me know - I found it on this forum to get cloudflare working.

                          1 Reply Last reply Reply Quote 0
                          • F
                            fredrikpf
                            last edited by

                            So here is the latest script in PHP I use to get this working without needing to mess with pfsense = it will always work. You need to serve it from the server in pfsense (don't think 2.3 does php anymore though) or a local server in your network. If you don't have a local server but an external, you can simply modify it to put it on an external server to use the connecting IP to update the DNS record. First off, you need to know your records and their respective default data such as record ID, easiest is to just curl the data:

                            curl https://www.cloudflare.com/api_json.html  -d 'a=rec_load_all'  -d 'tkn=thiiissiiisssyoouuuuurAPIkeeeeey'  -d 'email=admin@example.com'  -d 'z=example.com'

                            Now as hinted earlier in this post, when using Cloudflare as a CDN for your websites as I do, I have a minimum of 1 dynamic origin record going to my pfSense (which is the one I'm interested in updating) and 1 public record that routes my website through the CDN platform. You don't want your dynamic IP to go through Cloudflare and need to make sure you don't activate it and need to use service-mode 0 for that record every time you update it. If you don't you'll break stuff such as OpenVPN as the Cloudflare proxies are for web traffic only. In the event where I need to offroute from the CDN I also update my www record as well, but keep it in service mode 1 so it still goes through the CDN.

                            
                            	//////////////////////////////////////start fetching IP
                            	$url = "http://whatismyip.akamai.com/";
                                    $headers = array(
                                        "GET HTTP/1.1",
                                        "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
                                        "Accept-Language: sv-SE,sv;q=0.8,en-US;q=0.6,en;q=0.5",
                                        "Cache-Control: no-cache",
                                        "Pragma: no-cache",
                                        "Connection: keep-alive",
                            			"User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:44.0) Gecko/20100101 Firefox/44.0"
                            
                                    );
                            
                                    $ch = curl_init();
                                    curl_setopt($ch, CURLOPT_URL,$url);
                                    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); // Return page in string
                                    curl_setopt($ch, CURLOPT_ENCODING , "gzip");     
                                    curl_setopt($ch, CURLOPT_TIMEOUT, 60);
                                    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
                                    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE); // Follow redirects
                            
                                    $data = curl_exec($ch);
                            
                                    if (curl_errno($ch)) {
                                        print "Error: " . curl_error($ch);
                                    } else {
                                        curl_close($ch);
                                    } 
                            
                            	///////////////////////////////////////end fetching IP
                            	//everyhing above can be removed if you put the script on an external server and change $data to $_SERVER['REMOTE_ADDR']
                            
                            	//set up the array
                            	$request = array();
                            	//the action you are taking
                            	$request['a'] = 'rec_edit'; 
                            	//your API key
                            	$request['tkn'] = 'add_your_tkn_value_here';
                            	//your zone, example.com 
                            	$request['z'] = 'add_your_zone_value_here'; 
                            	//admin@example.com
                            	$request['email'] = 'add_your_email_value_here'; 
                            	//the rr-id derived from the CURL command
                            	$request['id'] = 'add_your_rr_id_value_here'; 
                            	//the record type you are setting
                            	$request['type'] = 'A'; 
                            	//the value of the record e.g. a subdomain such as www
                            	$request['name'] = 'add_your_rr_name_value_here';  
                            	//this is your new IP, if you want to put the script on an external server
                            	//change $data to $_SERVER['REMOTE_ADDR'], make sure that the request isn't proxied
                            	$request['content'] = $data; 
                            	//this means you will stick to bypass, so you don't accidently turn on the CDN
                            	$request['service_mode'] = '0'; 
                            	//set the time to live of the record as preferred, keep it short so you don't need to wait to be able to 
                            	//reconnect any of your services such a website proxied through Cloudflare or OpenVPN in the event of a new IP
                            	$request['ttl'] = '120'; 
                            
                            	//the actual API call to update the data per input above
                            	$response = @json_decode(file_get_contents('https://www.cloudflare.com/api_json.html?' . http_build_query($request)), true);
                            
                            	if(!$response || $response['result'] != 'success'){
                            		print 'Failed to update DNS. :-(';
                            		var_dump($response);
                            	}
                            	else{
                            		echo "Successfully updated!";
                            	}
                            
                            	//this next call is for my www record, notice "service mode" is missing, which means it will default to 1 and keep it in proxied mode
                            	$request = array();
                            	$request['a'] = 'rec_edit';
                            	$request['tkn'] = 'add_your_tkn_value_here';
                            	$request['z'] = 'add_your_zone_value_here';
                            	$request['email'] = 'add_your_email_value_here';
                            	$request['id'] = 'add_your_rr_id_value_here';
                            	$request['type'] = 'A';
                            	$request['name'] = 'add_your_rr_name_value_here'; 
                            	$request['content'] = $data;
                            	$request['ttl'] = '120';
                            
                            	$response = @json_decode(file_get_contents('https://www.cloudflare.com/api_json.html?' . http_build_query($request)), true);
                            
                            	if(!$response || $response['result'] != 'success'){
                            		print 'Failed to update DNS. :-(';
                            		var_dump($response);
                            	}
                            	else{
                            		echo "Successfully updated!";
                            	}
                            
                            echo "
                            ".$data;
                            ?>
                            
                            

                            Now to get this to work with pfSense you need to set your Dynamic DNS settings to Service Type: Custom and then set the update URL further down the page. Obviously make sure that WAN is the interface to monitor.

                            1 Reply Last reply Reply Quote 0
                            • F
                              fredrikpf
                              last edited by

                              As Cloudflare is deprecating their v1 API here is my updated code for v4.

                              First get the relevant zone id's with curl:

                              curl -X GET 'https://api.cloudflare.com/client/v4/zones' \
                                  -H 'X-Auth-Email: 'mail@example.com \
                                  -H 'X-Auth-Key: 'API-key \
                                  -H 'Content-Type: application/json'
                              

                              Use the zone ID from the curl command above to get all the records for the zone, make note of the record id's.

                              curl -X GET 'https://api.cloudflare.com/client/v4/zones/<zone_id>/dns_records' \
                                  -H 'X-Auth-Email: 'mail@example.com \
                                  -H 'X-Auth-Key: 'API-key \
                                  -H 'Content-Type: application/json'</zone_id>
                              

                              Now replace the e-mail, API-key, zone ID + resource id in the URL in the PHP script and you are good to go:

                              
                              $url = "http://whatismyip.akamai.com/";
                                      $headers = array(
                                          "GET HTTP/1.1",
                                          "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
                                          "Accept-Language: sv-SE,sv;q=0.8,en-US;q=0.6,en;q=0.5",
                                          "Cache-Control: no-cache",
                                          "Pragma: no-cache",
                                          "Connection: keep-alive",
                              			"User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:44.0) Gecko/20100101 Firefox/44.0"
                              
                                      );
                              
                                      $ch = curl_init();
                                      curl_setopt($ch, CURLOPT_URL,$url);
                                      curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); // Return page in string
                                      curl_setopt($ch, CURLOPT_ENCODING , "gzip");     
                                      curl_setopt($ch, CURLOPT_TIMEOUT, 60);
                                      curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
                                      curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE); // Follow redirects
                              
                                      $ip = curl_exec($ch);
                              
                                      if (curl_errno($ch)) {
                                          print "Error: " . curl_error($ch);
                                      } else {
                                          // Show me the result
                                          curl_close($ch);
                                      } 
                              
                              $headers2=array(
                              	'X-Auth-Email: mail@example.com',
                              	'X-Auth-Key: API-key',
                                  'Content-Type: application/json'
                              );
                              
                              /////////////////////
                              $curl = curl_init("https://api.cloudflare.com/client/v4/zones/<zone_id>/dns_records/<record_id>");
                              $data = array(
                              	 "type" => "A",
                                   "name" => "origin.example.com",
                                   "content" => $ip,
                                   "proxied"=> false 
                              );  
                              
                              $json = json_encode($data);
                              
                              curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
                              curl_setopt($curl, CURLOPT_HEADER, false);
                              curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
                              curl_setopt($curl, CURLOPT_HTTPHEADER, $headers2);
                              curl_setopt($curl, CURLOPT_POSTFIELDS, $json);
                              
                              // Make the REST call, returning the result
                              $response = curl_exec($curl);
                              if (!$response) {
                                  die("Connection Failure.n");
                              }
                              ////////////////////////////////////////
                              
                              ?></record_id></zone_id>
                              
                              1 Reply Last reply Reply Quote 0
                              • K
                                Khampol
                                last edited by

                                Hi @fredrikpf,

                                Thanks to update for CF api v.4. I still use myself v.1  :P
                                For curl command thats ok, but for PHP script… How use it ... with pfsense ... ?

                                I normally, with v.1, use in pfsense > dynamic DNS > Custom .... In "Update URL" i have something like :

                                https://www.cloudflare.com/api_json.html?a=rec_edit&tkn=eerzzzzwwweeeerrrr2211111&id=xxzzzz55558&email=mymail@gmail.com&z=xxxxccc.com&type=A&name=xxxxccc.com&content=%IP%&service_mode=0&ttl=1
                                

                                Do u have an idea…?

                                1 Reply Last reply Reply Quote 0
                                • L
                                  lucaslittermentz
                                  last edited by

                                  Hello.

                                  I tried to input a domain that goes like example.com.br and the original script would fail because it selects the host as being the last and the previous strings separated by "." (dots) so it ended up trying to fetch the zone for com.br instead of example.com.br.
                                  Is there any chance that we could get a script that deals with this on its own or maybe a list to select TLDs or even a button to specify that the TLD has 2 levels?

                                  Thanks!

                                  1 Reply Last reply Reply Quote 0
                                  • K
                                    Khampol
                                    last edited by

                                    Hey @lucaslittermentz,

                                    Dont bother… Just use this : https://www.dnsomatic.com/ .... Far easier  8)

                                    1 Reply Last reply Reply Quote 0
                                    • jimpJ
                                      jimp Rebel Alliance Developer Netgate
                                      last edited by

                                      @lucaslittermentz:

                                      I tried to input a domain that goes like example.com.br and the original script would fail because it selects the host as being the last and the previous strings separated by "." (dots) so it ended up trying to fetch the zone for com.br instead of example.com.br.
                                      Is there any chance that we could get a script that deals with this on its own or maybe a list to select TLDs or even a button to specify that the TLD has 2 levels?

                                      This has already been fixed on 2.3.3 and 2.4 snapshots.
                                      https://redmine.pfsense.org/issues/6778

                                      Remember: Upvote with the 👍 button for any user/post you find to be helpful, informative, or deserving of recognition!

                                      Need help fast? Netgate Global Support!

                                      Do not Chat/PM for help!

                                      1 Reply Last reply Reply Quote 0
                                      • K
                                        Khampol
                                        last edited by

                                        This has already been fixed

                                        Well, great then !  THX ! :)

                                        1 Reply Last reply Reply Quote 0
                                        • A
                                          AndrewBucklin
                                          last edited by

                                          Why is the TTL field hidden for CloudFlare Dynamic DNS provider?
                                          The CloudFlare v4 api documentation shows the TTL value is supported: https://api.cloudflare.com/#dns-records-for-a-zone-update-dns-record

                                          1 Reply Last reply Reply Quote 0
                                          • First post
                                            Last post
                                          Copyright 2025 Rubicon Communications LLC (Netgate). All rights reserved.