DDNS Cloudflare

  • Currently to use DDNS with Cloudflare users need provide Global API key witch is give to many unwanted permissions.
    Is it possible to implement Cloudflare APIv4 for DDNS over Authorization Bearer API Tokens which can be limited by zone and permissions type? Like here: https://api.cloudflare.com/#dns-records-for-a-zone-update-dns-record.
    As workaround: maybe there a way to trigger custom user script on WAN IP change in pfSense?
    If I understand correct Shellcmd plugin provide such possibility > afterfilterchangeshellcmd is what I need as filter_configure() run every rc.newwanip?
    If yes, then I can solve this by running custom bash script =)

    Updated, link to FR:

  • After testing, workaround with afterfilterchangeshellcmd working.
    But it will be cool if pfSense will support Cloudflare APIv4 by native DDNS & store API token as a secret, not plaintext.
    Maybe for someone my findings will be useful:
    To create API tocket go to https://dash.cloudflare.com/profile/api-tokens
    You need configure permissions for your token.

        Account -> Access: Organizations, Identity Providers, and Groups: Read
        Zone -> Zone: Read
        Zone -> DNS: Edit
    Account Resources:
        Include -> Your Account
    Zone Resources:
        Include -> Specific zone: Your DNS Zone

    After this you need install ShellCmd plugin & pfBlockerNG-devel (needed to have JQ package) in pfSense.
    afterfilterchangeshellcmd can be used only once in this plugin, so I created structure that can be scaled in future:

    1. type afterfilterchangeshellcmd to run script
    /bin/sh -c /root/shellcmd_after_filterchanges.sh
    1. type earlyshellcmd to create script itself. If you need in future run more then one script - add it HERE:
    echo -e "#!/bin/sh \n/bin/sh -c /root/shellcmd_after_ddns.sh \n" > /root/shellcmd_after_filterchanges.sh; chmod 700 /root/shellcmd_after_filterchanges.sh
    1. type earlyshellcmd to create ddns script. NOTE Before use this part modify variables RECORD, ZONE and TOKEN, TTL & PROXIED to your needs! Proxied true mean hide IP behind Cloudflare, false by default.
    echo -e '#!/bin/sh \n \nRECORD="dyn-ipv4.example.com" \nZONE="example.com" \nTOKEN="Get it from https://dash.cloudflare.com/profile/api-tokens" \nTTL="120" \nPROXIED="false" \nCHECK_IP_SERVICE="ifconfig.co" \nZONES=`curl -X GET "https://api.cloudflare.com/client/v4/zones?name=$ZONE&status=active&match=all" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json"` \nZONES_SUCCESS=`echo $ZONES | /usr/local/bin/jq -r ".success"` \nif [ "$ZONES_SUCCESS" = "true" ]; then \nZONE_ID=`echo $ZONES | /usr/local/bin/jq -r ".result | .[0].id"` \nDNS_RECORDS=`curl -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?type=A&name=$RECORD&match=all" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json"` \nDNS_RECORDS_SUCCESS=`echo $DNS_RECORDS | /usr/local/bin/jq -r ".success"` \nif [ "$DNS_RECORDS_SUCCESS" = "true" ]; then \nRECORD_ID=`echo $DNS_RECORDS | /usr/local/bin/jq -r ".result | .[0].id"` \nIP=`curl -4 $CHECK_IP_SERVICE` \nUPDDATE_DNS_RECORD=`curl -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" --data "{\"type\":\"A\",\"name\":\"$RECORD\",\"content\":\"$IP\",\"ttl\":$TTL,\"proxied\":$PROXIED}"` \nUPDDATE_DNS_RECORD_SUCCESS=`echo $UPDDATE_DNS_RECORD | /usr/local/bin/jq -r ".success"` \nif [ "$UPDDATE_DNS_RECORD_SUCCESS" = "true" ]; then \necho "DynDNS updated: $RECORD to $IP" \nelse \necho "DynDNS update failed: $RECORD to $IP" \nexit 1 \nfi \nelse \necho "Error while tried to get DNS records of Zone: $ZONE_ID" \nexit 1 \nfi \nelse \necho "Error while tried to get Zones" \nfi \n' > /root/shellcmd_after_ddns.sh; chmod 700 /root/shellcmd_after_ddns.sh

  • @dragoangel /usr/local/bin/jq doesn't appear to be installed by default, at least on my box. Where did you install it from?

    /root/shellcmd_after_ddns.sh: /usr/local/bin/jq: not found
    echo: write error on stdout
    Error while tried to get Zones

  • @jkm hm, need look to my installed packages =) will reply soon

  • @jkm to have JQ you need install pfBlockerNG-devel, this package needed to parse JSON reply from Cloudflare API as object. I has it on all of my pfSense instances as must have package. Thanks for note, I updated How-to.

  • @dragoangel Thank you! This is working perfectly!

  • @jkm glad that it can help somebody 👍

Log in to reply