|:.:.:.:.:.:.:.:.:/.:.:.:.:.:./.:.:.:.:.:.:.:.:.:.:.:.:.:./|   '. :.:.:.:.:.:.:.:.:.:.l.ヽ:.:.:.:.l:.:.:.:.:.:.:.:.:.:∧\:.:.:.',
          |:.:.:.:.:.:.:./.:.:.:.:.:./.:.:.:.:.:.:.:.:.:.:.:.: , ′   l :.:.:.:.:.:.:.:.:.:| ∨.:.:.l:.:.:.:.:.:.:.:.:.:.∧ \:.'.
          |:.:.:.:.:.:/.:.:.:.:.: /.:.:.:.:.:.:.:.:. ヽ/ /    |:.:.:.:.:.:.:./:.:.|   y'.:.:|:.:.:.:.|:.:.:.:.:.:.∧   ヘ.
          |:.:.:.:./.:.:.:.//.:.:.:.:.:.:.:.:.:.:/ \,′   !:.:.:.:.:.:/|:.:./,/ '.:.:| :.:.:.|:.:.:.:.:.:.:.:.|
          |:.:.:/.:.:./.:./.:.:.:.:.:.:.:.:./   /` ‐-‐'|:.:.:./ |ァ'´    |:.:| :.:.:.|:.:.:.:.:.:.:.:.|
          |:.:.i.:.:./.:.:.: '.:.:.:.:.:.:.:/   ,/       |:.:.:/   ′    }.:.| :.:.:.|:.:.:.| :.:.:.:|
          |:.:.|:./.: rヘ|:.:.:.:.:.:/:.| 三三三三三  |:./   三三三 ハ|:.:.:.:.|:.:.:.| :.:.:.:|
          |:.:.l〃.:{  |:.:.:.:./.:.:.|             l.'         .i.:.:.i.:.:.:∧ :.:|ヽ :.:|
          |:.:./.:.:.:.\|:.:.:/.:.:.:.:|                '       |:.:.||:.:/  :.:.| '.:.:l
          |:./.:.:.:.:.:.:. !:./.:.:.:.:.:.'、            ,.ー--、    }.:.:|レ′ ∨  V
          |/.:.:.:.:.:.:.:.:V '´  ̄`ヽ.、            ´`¨¨{. |_.  '.:.:.:.|
         /.:.:.:.:.:.:.:./         ヘ `    . __. -r1 |:.:.:.:.:.:.:.:.|
         :.:.:.:.:.:.:, '         '. \    | _.   -┴ー──┴┐
         :.:.:.:.:./           |  \  r' |   -──────i'
    

< KONAKONA.MOE >

Dynamic DNS with a Single Bash Script using Porkbun's API

Last Mod.: 2024-06-05 | Created On: 2024-01-31


This tutorial is about a very simple bash script that I have made to update my DNS records on my registrar (porkbun). It is a showcase of that you don’t need an account on no-ip or whatever “normies” use. This script works, in particular with Porkbun but if you’ve found my website, it probably means that you can take this as inspiration and use it with the API of another registrar.

It’s funny that my ISP offers static IPs… for +36€ a month… I defeated that with a 27 SLOC bash script.

The Script

The source for this bash script can be found on my gitea instance. You don’t have to copy and paste it.

 1#!/bin/sh
 2
 3# This script will grab your ip from an IP api and push it to the porkbun API
 4# It was recommended to set the cronjob to whatever your TTL is.
 5#
 6# Example cronjob for a 600 seconds TTL:
 7# */10 * * * * porkbun-ddns
 8
 9domain="konakona.moe" # The domain name
10subdomain=""          # The subdomain, yes you can leave it blank, see below CNAMEs
11secretapikey=""       # Your secret API key
12apikey=""             # The API key, no idea why they split it in two
13ipapi="ip.me"         # A particular website that will return your IP(v4) as plain text if you curl it
14cachefile="/root/.ddns-cache" # A file, where your IP will be cached
15
16ip=$(curl -s4 $ipapi) # Gets your ip
17
18if [ -z "$ip" ]; then # If there was an error, exit
19    echo "Error getting IP."
20    exit 1
21fi
22
23if [ -f "$cachefile" ]; then # If the cache file exists read it
24    read -r cachedip < "$cachefile"
25fi
26
27# Only exec if the IP != to the ip in the cache file or if the file doesn't exist
28if [ "$ip" != "$cachedip" ] || [ -z "$cachedip" ]; then
29    echo "$ip" > "$cachefile" # Cache the IP
30
31    # Push the new IP to Porkbun, docs see below
32    curl -X POST -H "Content-Type: application/json" -d "{
33        \"secretapikey\": \"$secretapikey\",
34        \"apikey\": \"$apikey\",
35        \"content\": \"$ip\",
36        \"ttl\": \"600\"
37    }" https://porkbun.com/api/json/v3/dns/editByNameType/"$domain"/A/"$subdomain"
38    echo
39else
40    echo "Your IP has not changed."
41fi

Using CNAMEs

You don’t need to make copies of this script for each and every sub-domain that you are going to use if they are hosted on the same IP! In my case I just set up this script to push the new IPs on konakona.moe and CNAMEd everything else to it.

Setting it up

After downloading the script with wget or something and editing it, make it executable with chmod +x porkbun-ddns, then copy it somewhere in your $PATH. I think /usr/local/bin/ is the standard for scripts and random binaries like this.

Now you need to make a cronjob. As stated on the script, it was recommended that the cronjob’s cycle to be set to whatever your domain’s TTL is, in my case 600 seconds or 10 minutes:

crontab -e

1*/10 * * * * porkbun-ddns

chmod and Change Owner

Maybe changing the mode of the script would be a good idea because it contains the credentials for Porkbun:

1chmod 770 /usr/local/bin/porkbun-ddns
2chown root:root /usr/local/bin/porkbun-ddns
3
4# Now check
5ls -laFh /usr/local/bin/porkbun-ddns

The output should be something like:

1.rwxrwx--- root root 1.0 KB Sat Jan 27 23:35:29 2024  porkbun-ddns*

Happy self-hosting!!!


Prev:
Simple Statistics for your Server
Next:
Fixing Syncthing's Favicon with Caddy