Porkbun DNS updater

I recently switched to porkbun where I have a subdomain configured for my home network address. I tried to configur the OpenWrt DDNS Service using a custom profile, but I could not manage to get the update URL right.
There is a shell script which works. This is the correct call to the API:

curl -X POST "https://porkbun.com/api/json/v3/dns/editByNameType/$domain/A/$record" \
    -H "Content-Type: application/json" \
    --data "{ \"apikey\": \"$apikey\", \"secretapikey\": \"$apisec\", \"content\": \"$ourip\", \"ttl\": \"300\" }"

... this is my attempt to configure DDNS on OpenWrt:

config ddns 'global'
        option ddns_dateformat '%F %R'
        option ddns_loglines '250'
        option ddns_rundir '/var/run/ddns'
        option ddns_logdir '/var/log/ddns'

config service 'Porkbun'
        option use_ipv6 '0'
        option lookup_host 'HOST.DOMAIN.COM'
        option username 'MYAPIKEY'
        option password 'MYSECRETKEY'
        option ip_source 'network'
        option ip_network 'wan'
        option interface 'wan'
        option use_syslog '2'
        option check_unit 'minutes'
        option force_unit 'minutes'
        option retry_unit 'seconds'
        option enabled '1'
        option use_https '1'
        option cacert '/etc/ssl/certs'
        option domain 'HOST.DOMAIN.COM'
        option param_enc 'encoded'
        option param_opt 'optional'
        option update_url 'http://porkbun.com/api/json/v3/dns/editByNameType/DOMAIN.COM/A/HOST -H Content-Type: "application/json" --data "{ \"apikey\": \"[USERNAME]\", \"secretapikey\": \"[PASSWORD]\", \"content\": \"[IP]\", \"ttl\": \"300\" }"'

The log shows a cURL Error: '3' when it tries to update the ip address.

One thing is that in the API call you use https, in the DDNS you have http.
Another thing is that in DDNS you have domain HOST.DOMAIN.COM while in the update_url it is broken into DOMAIN.COM/A/HOST
Also curl error 3 is malformed url, so verify that the url is correct.

1 Like

Thanks for the very quick response!
You are right about https - but according to the documentation this is handled by use_https '1'. And according to the log https is used.
You are also right about the url which is broken up. That's why I hardcoded that part into the update_url.
According to your tip about the malformed url I tried to find out what is acutally sent to the server. The log shows the following:

/usr/bin/curl -RsS -o /var/run/ddns/Porkbun.dat --stderr /var/run/ddns/Porkbun.err --interface eth1 --capath /etc/ssl/certs --noproxy '*' 'https://porkbun.com/api/json/v3/dns/editByNameType/DOMAIN.COM/A/HOST -H Content-Type: "application/json" --data "{ "apikey": "MYAPIKEY", "secretapikey": "MYSECRETKEY", "content": "XXX.XXX.XXX.XXX", "ttl": "300" }"'

It seems correct, but I am probably missing some detail.

Request method -X POST is missing for sure.

1 Like

Thank you for your assistance! So - as far as I understand the updater it is not possible to send the command which would be necessary to update porkbun dns. As a fallback I wrote a script which is called periodically:


olddns=$(curl -s -X POST "https://porkbun.com/api/json/v3/dns/retrieveByNameType                                                                                                                                        /$domain/A/$record" \
        -H "Content-Type: application/json" \
        --data "{ \"apikey\": \"$apikey\", \"secretapikey\": \"$apisec\" }" | gr                                                                                                                                        ep -oE 'content":"[0-9.]*' | grep -oE [0-9.]*)

ourip=$(ip -4 addr show eth1 | sed -Ene 's/^.*inet ([0-9.]+)\/.*$/\1/p')

# update dns record if necessary
if [[ $olddns != $ourip ]]; then
  curl -X POST "https://porkbun.com/api/json/v3/dns/editByNameType/$domain/A/$re                                                                                                                                        cord" \
    -H "Content-Type: application/json" \
    --data "{ \"apikey\": \"$apikey\", \"secretapikey\": \"$apisec\", \"content\                                                                                                                                        ": \"$ourip\", \"ttl\": \"300\" }"

1 Like

basic bash script to be enabled by cron:

oldip=$(nslookup testing.domain.com | awk '/^Address: / { print $2 }')
newip=$(curl http://canhazip.com)

if [[ $oldip != $newip ]]; then

curl --header "Content-Type: application/json" \
  --request POST \
  --data '{ 
    "apikey" : "YOUR API KEY HERE",
    "secretapikey" : "API SECRET HERE",
    "content" : '$newip',
    "ttl" : "600"
  }' \