I made a simple script and a custom Cron Job configd to monitor for changes and push the new IP to Cloudflare. The script can be used on another system rather than OPNSense, but the configd was made specifically for OPNSense use only.
Credit: Special thanks to Steve@Tech Otaku for the API scripts.
Original scripts: https://www.tech-otaku.com/web-development/using-cloudflare-api-manage-dns-records/#435
You can check out my YouTube channel if you prefer video content over written posts. Here’s the link to the video:
➡️ Step 1: Enable SSH service, permit root user login, and permit password login
** Note: you should make a backup of system configuration under System ‣ Configuration ‣ Backups in case things go south. You should be able to reverse any actions and restore the system to the known working state.
***This tutorial assumes that you already has an A record (or subdomain added on your Cloudflare DNS Records.
To enable the SSH server, permit root user login, and permit password login, navigate to System ‣ Settings ‣ Administration
Click Save when finished.
➡️ Step 2: Remote login to your OPNSense via SSH
Open Terminal or Command Prompt and login on using the below command:
┌──(sysadmin102㉿sysadmin102)-[~]
└─$ ssh root@opnsense.sysadmin102.org
Last login: Sun Aug 27 09:40:46 2023 from 2603:8000:e700:80fb:7f08:1d41:7194:876c
----------------------------------------------
| Hello, this is OPNsense 23.7 | @@@@@@@@@@@@@@@
| | @@@@ @@@@
| Website: https://opnsense.org/ | @@@\\\ ///@@@
| Handbook: https://docs.opnsense.org/ | )))))))) ((((((((
| Forums: https://forum.opnsense.org/ | @@@/// \\\@@@
| Code: https://github.com/opnsense | @@@@ @@@@
| Twitter: https://twitter.com/opnsense | @@@@@@@@@@@@@@@
----------------------------------------------
*** OPNsense.sysadmin102.org: OPNsense 23.7.2 ***
0) Logout 7) Ping host
1) Assign interfaces 8) Shell
2) Set interface IP address 9) pfTop
3) Reset the root password 10) Firewall log
4) Reset to factory defaults 11) Reload all services
5) Power off system 12) Update from console
6) Reboot system 13) Restore a backup
Enter an option: 8
You can substitute the Fully Qualified Domain Name (FQDN) with a valid IP Address.
Select Option 8 to open Shell
➡️ Step 3: Download the configd and bash script from github
3.1 Use the curl command to clone the script to your local folder /usr/home.
root@OPNsense:~ # cd /usr/home
root@OPNsense:/usr/home # curl -LJO https://raw.githubusercontent.com/nn0x96a/Cloudflare-Dynamic-DNS/main/Update_Cloudflare_Dynamic_IP.sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 902 100 902 0 0 1948 0 --:--:-- --:--:-- --:--:-- 1952
root@OPNsense:/usr/home # ls
Update_Cloudflare_Dynamic_IP.sh
root@OPNsense:/usr/home #
3.2 Use cd command to change the directory to action.d folder
root@OPNsense:/usr/home # cd /usr/local/opnsense/service/conf/actions.d
root@OPNsense:/usr/local/opnsense/service/conf/actions.d #
3.3 Use the curl command to clone the actions_Cloudflare_DDNS.conf to your local folder
root@OPNsense:/usr/local/opnsense/service/conf/actions.d # curl -LJO https://raw.githubusercontent.com/nn0x96a/Cloudflare-Dynamic-DNS/main/actions_Cloudflare_DDNS.conf
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 219 100 219 0 0 458 0 --:--:-- --:--:-- --:--:-- 459
root@OPNsense:/usr/local/opnsense/service/conf/actions.d # ls
actions_Cloudflare_DDNS.conf actions_filter.conf actions_openssh.conf
actions_acmeclient.conf actions_firmware.conf actions_openvpn.conf
actions_auth.conf actions_health.conf actions_proxy.conf
actions_captiveportal.conf actions_ids.conf actions_syslog.conf
actions_configd.conf actions_interface.conf actions_system.conf
actions_cron.conf actions_ipfw.conf actions_template.conf
actions_dhcpd.conf actions_ipsec.conf actions_unbound.conf
actions_dhcpd6.conf actions_monit.conf actions_webgui.conf
actions_dns.conf actions_netflow.conf actions_zfs.conf
root@OPNsense:/usr/local/opnsense/service/conf/actions.d #
**Note: If you store the Update_Cloudflare_Dynamic_IP.sh anywhere other than /usr/home, you will need to modify the actions_Cloudflare_DDNS.conf
3.4 Restart configd service
root@OPNsense:/usr/local/opnsense/service/conf/actions.d # service configd restart
Stopping configd...done
Starting configd.
root@OPNsense:/usr/local/opnsense/service/conf/actions.d #
➡️ Step 4: Obtain the required parameters for the script
4.1 Use the cd command to get back to folder where the script located:
root@OPNsense:/usr/local/opnsense/service/conf/actions.d # cd /usr/home
root@OPNsense:/usr/home # ls
Update_Cloudflare_Dynamic_IP.sh
root@OPNsense:/usr/home #
The following parameters need to be set for the script to work:
TOKEN="Replace with API Token"; \
ZONE_ID="Replace with Zone ID"; \
DNS_ID="Replace with DNS ID"; \
TYPE="A"; \
NAME="Replace with DNS Record Name"; \
4.2 Create a new API Token:
Follow the official guidance to create a new API Token: https://developers.cloudflare.com/fundamentals/api/get-started/create-token/
Copy the new API token to a text file.
4.3 Zone ID:
Follow the offical guidance to find your Zone ID: https://developers.cloudflare.com/fundamentals/get-started/basic-tasks/find-account-and-zone-ids/
4.4 DNS ID:
4.4.a Copy the below script to text file.
4.4.b Replace with your API Token created in step 4.2
4.4.c Replace Zone ID with your actual ID
Copy and paste the script to a new Terminal or Command Prompt.
┌──(sysadmin102㉿sysadmin102)-[~]
└─$ TOKEN="********6dpaSHsHSuE7gyrjgu1Hzc********"; \
ZONE_ID="********7961c234582ace******"; \
TYPE="A"; \
PROXIED="false"; \
TTL="120";\
curl -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$DNS_ID" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
--data '{"type":"'"$TYPE"'","name":"'"$NAME"'","content":"'"$CONTENT"'","proxied":'"$PROXIED"',"ttl":'"$TTL"'}' \
| python -m json.tool;
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2577 0 2516 100 61 3429 83 --:--:-- --:--:-- --:--:-- 3510
{
"result": [
{
"id": "*****725c72dcd2bb1ebe****",
"zone_id": "*****987961c234582aced*****",
"zone_name": "sysadmin102.org",
"name": "openvpn.sysadmin102.org",
"type": "A",
"content": "127.0.0.1",
"proxiable": true,
"proxied": false,
"ttl": 120,
"locked": false,
"meta": {
"auto_added": false,
"managed_by_apps": false,
"managed_by_argo_tunnel": false,
"source": "primary"
},
"comment": null,
"tags": [],
"created_on": "2023-08-27T17:34:04.920836Z",
"modified_on": "2023-08-27T21:07:01.019364Z"
},
In the above example, *****725c72dcd2bb1ebe**** is the DNS Record ID for subdomain openvpn.sysadmin102.org. That’s the subdomain that I want to point to my Dynamic IP at home.
➡️ Step 5: Modify and the script file
Modify the script file with the required parameter obtained in step 4 using Easy Text Editor (ee).
root@OPNsense:/usr/local/opnsense/service/conf/actions.d # cd /usr/home
root@OPNsense:/usr/home # ee Update_Cloudflare_Dynamic_IP.sh
#!/usr/bin/env sh
# Instructions on how to use this script:
# git clone https://github.com/nn0x96a/Cloudflare-Dynamic-DNS
# chmod 755 Update_Cloudflare_Dynamic_IP.sh
# Set the required parameters
# ./Update_Cloudflare_Dynamic_IP.sh
# SCRIPT: Update_Cloudflare_Dynamic_IP.sh
# AUTHOR: NHAN NGUYEN
# Use: This script will update your DNS Record IP
#Set the below parameters:
TOKEN="********6dpaSHsHSuE7gyrjgu1Hzc********"; \
ZONE_ID="*****987961c234582aced*****"; \
DNS_ID="*****725c72dcd2bb1ebe****"; \
TYPE="A"; \
NAME="openvpn"; \
CONTENT="$(curl -s checkip.amazonaws.com)"; \
PROXIED="false"; \
TTL="120";\
#Command
curl -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$DNS_ID" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
--data '{"type":"'"$TYPE"'","name":"'"$NAME"'","content":"'"$CONTENT"'","proxied":'"$PROXIED"',"ttl":'"$TTL"'}' \
Once you done, Click ESC to escape to Menu. Enter to leave editor, and Enter to save changes.
➡️ Step 6: Create a new Cron Job to push Dynamic IP to Cloudflare
To setup a new Cron job go to System ‣ Settings‣ Cron and click Add on the bottom right corner of the form.
Click Save to add new Cron job.
Click Appy to aply the new changes.
With the below setting this Cron Job will run every minute. This is to force update right the way. You should change it to every 5 minutes or every hour.
I set my Cloudflare DNS IP to loopback IP: 127.0.0.1 to see if the script is working. If it is, the new IP should reflect on DNS Records within minutes.
DNS Records 2 minutes later:
➡️ If you think this tutorial is helpful, please subscribe to my YouTube channel for more tutorials: https://www.youtube.com/@sysadmin102