Blogs

Cloudflare: Host your website without a static IP Address

No need for a public static IP Address when you have Cloudflare! 🌐


Introduction 🌟

Hey everyone, I hope you're all enjoying the blogs I'm writing and finding them helpful!
This blog is about something I had to invest some time in to find the proper solution for my situation.

If you don't know what a dynamic DNS is, check out this blog !


So what is the case? ℹ

I had an extra computer, which I hadn't used in a long time, so I thought it could be a good idea to use it as a web server instead of having a virtual machine through a cloud provider (I was using AWS). This way, I won't have to keep an eye on my AWS environment for any extra charges. Plus, I have the required physical hardware anyway.. so why not? 😉

Before you head into the steps, please ensure your web server is up and running.


How I did it! 🚀

  1. Create an account on Cloudflare (select the free plan as it's more than enough for this)

  2. Register your domain on Cloudflare.

    This step can include changing the name servers in your domain's registrar to use Cloudflare's ones.
  3. Create an API token that has the edit permissions for the Zone's DNS.

  4. Get your zone ID by sending a GET request to this API:

    • https://api.cloudflare.com/client/v4/zones

    • Add the the header Authorization with value Bearer {your-cloudflare's API token}

  5. Get your Record ID by sending a GET Request to this API:

    • https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records

    • Find the right record to update

  6. ssh into your computer (the one that will be used as a web server)

  7. Create a new folder and name it cron

    1. mkdir cron

  8. Inside that folder, create a folder to contain the logic of handling the public IP address change

    1. cd cron

    2. mkdir public-ip

    3. cd public-ip

  9. Create a text file to store the Cloudflare's API token

    1. vim cloudflare_token.txt

    2. Paste the token inside this file.

  10. Create a text file to store the current public IP address.

    1. touch public_ip.txt

  11. Create a bash script to handle the detect/update the public IP address.

    1. vim public-ip.sh

  12. Paste the below code into the script

    Before you paste, modify the script to match your system; for example, you need to change the username for the paths.
    #!/bin/bash

    LOG_DIR="/var/log/public_ip"
    LOGFILE="$LOG_DIR/public_ip_$(date '+%Y-%m-%d').log"

    mkdir -p "$LOG_DIR"

    log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOGFILE"
    }

    log "Starting the script"

    CLOUDFLARE_TOKEN_FILE_NAME="/home/{username}/cron/public-ip/cloudflare_token.txt"
    CLOUDFLARE_TOKEN=$(cat $CLOUDFLARE_TOKEN_FILE_NAME)

    PUBLIC_IP_FILE_NAME="/home/{username}/cron/public-ip/public_ip.txt"
    STORED_PUBLIC_IP=$(cat $PUBLIC_IP_FILE_NAME)

    function getCurrentPublicIP(){
    local ip=$(curl -s https://ipinfo.io/ip)
    echo "$ip"
    }

    function updateCloudflareDNS(){
    log "Updating Cloudflare DNS A record"
    log "Authorization: Bearer $CLOUDFLARE_TOKEN"
    response=$(curl --silent --request PUT \
    --url https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records/{record_id} \
    --header "Content-Type: application/json" \
    --header "Authorization: Bearer $CLOUDFLARE_TOKEN" \
    --data "{
    \"comment\": \"{add your comment here}\",
    \"name\": \"{your-domain.com}\",
    \"proxied\": true,
    \"settings\": {},
    \"tags\": [],
    \"ttl\": 3600,
    \"content\": \"$1\",
    \"type\": \"A\"
    }")

    log "Cloudflare API response: $response"
    }

    CURRENT_PUBLIC_IP=$(getCurrentPublicIP)

    log "Stored Public IP: $STORED_PUBLIC_IP"
    log "Current Public IP: $CURRENT_PUBLIC_IP"

    echo $CURRENT_PUBLIC_IP > $PUBLIC_IP_FILE_NAME 2>> $LOGFILE
    if [[ "$STORED_PUBLIC_IP" == "$CURRENT_PUBLIC_IP" ]]; then
    log "IP has NOT changed; Nothing to do."
    else
    log "IP has changed!"
    log "Storing public IP in a local file"
    rm $PUBLIC_IP_FILE_NAME
    echo $CURRENT_PUBLIC_IP > $PUBLIC_IP_FILE_NAME 2>> $LOGFILE

    updateCloudflareDNS $CURRENT_PUBLIC_IP

    fi
  13. Save the script and exit.

    We are almost done, we just need to register our cron job now!
  14. Let's add a new cron job through these steps:

    1. crontab -e

    2. Paste this line (don't forget to modify to match your system):

      */1 * * * * /home/{username}/cron/public-ip/public_ip.sh
    3. Save and exit

    This is going to run your cron job every minute. The cron job will check the current public IP address. If it's changed, it will send an API request to Cloudflare to update your DNS records.


Summary ✅

By utilizing Cloudflare as a reverse proxy, you ensure that your domain consistently resolves to the correct IP address, even when changes occur, such as after a router reboot. This approach eliminates the need to purchase a static public IP address, as your IP is automatically updated via an API request whenever it changes.