If you want to do anything with your home network or raspberry pi from outside of your network or from the Internet, you must have i static IP which costs you money, another option is Cloudflare dynamic DNS Raspberry Pi.
Here we set up our DDNS with Cloudflare on Raspberry Pi.
If you do not have money to buy a domain this tutorial is still helpful for you, stay here!
Pre-requisites for Setup DDNS on Cloudflare
- The domain name (Do not worry if you do not have one, I will take care of it!)
A quick note: the .tk, .cl, etc domain will not work but do not worry scroll down I will show you how you get a FREE domain.
- Linux machines or Raspberry Pi
- A script (that I am going to give you)
- Cloudflare Account
Ok, everything you need to know now let’s jump into the main part of this tutorial.
For those, who do not have a Domain
- Go to Github Education pack
- And sign up for this
- After getting approved choose any domain you want
Type offer: .tech, .me, etc domain for 100% FREE
Step 1: Connect your domain to Cloudflare
- (If you do have a Cloudflare account) visit https://dash.cloudflare.com/sign-up.
- Login to your Cloudflare account
- Click on Add site
- Enter your website’s root domain and then click Add Site.
E.g: If your website is www.example.com, type example.com.
- Click Next.
- Select a plan level, I go with a Free plan
- Click Confirm in the Confirm Plan window that appears.
- Copy the 2 Cloudflare nameservers displayed.
- Setup those nameservers for your domain
In this step, you can also knock your Domain registrar for help
- Wait for nameserver to update
This process can take up to 24 hours but in my personal experience, it could take only a few minutes.
Step 2: Create A record for Raspberry Pi
- Login to Cloudflare
- Go to Cloudflare Dashboard Home
- Choose your domain
- Navigate to its DNS tab
- Select Add record.
- Choose “A” as type
- Enter your desired subdomain name like “home-network” as Name
- As the IPv4 address, enter 0.0.0.0
- Finally, click on save.
Step 3: Grab the necessary details from Cloudflare
Here you need 2 things,
Frist is Gobel API Token
- Login to Cloudflare
- Go to Cloudflare Dashboard Home
- Choose your domain
- Scroll down the page till you see an API section on the right sidebar
- Under the API section click on “Get your API token”
- Here from top navigation tabs click on “API Tokens”
- Scroll down until you see “Globel API Key”
- Click on View
- Copy the API here!
- Take this into a safe place
The second one is zone Id
- Login to Cloudflare
- Go to Cloudflare Dashboard Home
- Choose your domain
- Scroll down the page till you see an API section on the right sidebar
- Under the API section copy the Zone ID
- Take this into a safe place
Step 4: Setup File for DDNS on Raspberry Pi
- Open terminal or SSH on Raspberry Pi
- Make a folder by executing ‘mkdir cloudflare-ddns-updater’
$ sudo mkdir cloudflare-ddns-updater
- Make a file by executing ‘touch cloudflare.sh’
$ sudo touch cloudflare.sh
- Copy the below script and past it into cloudflare.sh (created above)
#!/bin/bash
auth_email="" # The email used to login 'https://dash.cloudflare.com'
auth_key="" # Top right corner, "My profile" > "Global API Key"
zone_identifier="" # Can be found in the "Overview" tab of your domain
record_name="" # Which record you want to be synced
proxy=true # Set the proxy to true or false
###########################################
## Check if we have an public IP
###########################################
ip=$(curl -s https://api.ipify.org || curl -s https://ipv4.icanhazip.com/)
if [ "${ip}" == "" ]; then
message="No public IP found."
>&2 echo -e "${message}" >> ~/log
exit 1
fi
###########################################
## Seek for the A record
###########################################
echo " Check Initiated" >> ~/log
record=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records?name=$record_name" -H "X-Auth-Email: $auth_email" -H "X-Auth-Key: $auth_key" -H "Content-Type: application/json")
###########################################
## Check if the domaine has an A record
###########################################
if [[ $record == *""count":0"* ]]; then
message=" Record does not exist, perhaps create one first? (${ip} for ${record_name})"
>&2 echo -e "${message}" >> ~/log
exit 1
fi
###########################################
## Get the existing IP
###########################################
old_ip=$(echo "$record" | grep -Po '(?<="content":")[^"]*' | head -1)
# Compare if they're the same
if [[ $ip == $old_ip ]]; then
message=" IP ($ip) for ${record_name} has not changed."
echo "${message}" >> ~/log
exit 0
fi
###########################################
## Set the record identifier from result
###########################################
record_identifier=$(echo "$record" | grep -Po '(?<="id":")[^"]*' | head -1)
###########################################
## Change the IP@Cloudflare using the API
###########################################
update=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records/$record_identifier"
-H "X-Auth-Email: $auth_email"
-H "X-Auth-Key: $auth_key"
-H "Content-Type: application/json"
--data "{"id":"$zone_identifier","type":"A","proxied":${proxy},"name":"$record_name","content":"$ip"}")
###########################################
## Report the status
###########################################
case "$update" in
*""success":false"*)
message="$ip $record_name DDNS failed for $record_identifier ($ip). DUMPING RESULTS:n$update"
>&2 echo -e "${message}" >> ~/log
exit 1;;
*)
message="$ip $record_name DDNS updated."
echo "${message}" >> ~/log
exit 0;;
esac
- Open the file in your favorite editor (I use nano for this)
$ nano cloudflare.sh
- Config the script,
- Enter the email that you used to sign up on Cloudflare as auth_email
- Enter the Glodel API key that you copied on step 3 as auth_key
- Enter the Zone ID that you copied on step 3 as zone_identifier
- Enter the subdomain (with the root domain, e.g home-network.mydomain.com) you choose in step 2 as record_name
- Close the file by pressing Ctrl + X then press ‘Y’ to save.
- Make the script executable by executing the following command
$ sudo chmod +x cloudflare.sh
Now everything is done if you want to test, run the script, and see the Cloudflare dashboard record.
Step 5: Automate the script
- Open crontab in edit mode
$ sudo cronttab -e
- Choose your editor I go with ‘nano’ by pressing 1
- Add the following line to this file
*/1 * * * * /bin/bash [PATH_TO_SCRIPT]
E.g:
*/1 * * * * /bin/bash /root/cloudflare-ddns-updater/cloudflare.sh
- Close the file by pressing Ctrl + X then press ‘Y’ to save.
That’s all you need.
After a minute you see your DNS will be replaced with your Public IP of course automatically.
If you have any questions or issues regarding this feel free to commend here.
5 thoughts on “Cloudflare dynamic DNS Raspberry Pi [100% FREE]”
As of Nov 2022, there are some issues when running the script, here is version which I modified and it works for me https://gist.github.com/lukedesu/80751505133828c122470bc56388b6c0
Hopefully help someone, Thanks
I tried to run this script and it returned these problems. Any idea what went wrong?
./cloudflare.sh: line 58: -H: command not found
./cloudflare.sh: line 59: -H: command not found
./cloudflare.sh: line 60: -H: command not found
./cloudflare.sh: line 61: –data: command not found
I use Cloudflare on some of my websites and I m really happy with them.
Hello a good idea! I am a beginner in terms of www. My domain is listed as dyndns at selfhost.de. I have created several subdomains. What does the script have to look like in order to redirect them?