Custom dynamic DNS
Anyone know how to create your own custom dynamic dns solution, like dyndns?
Any how tos would be good.
12 Replies
dyn IN NS server1
dyn IN NS server2
The "dyn.mydomain.example"
$ORIGIN .
$TTL 5 ; 5 seconds
dyn.mydomain.example IN SOA localhost. root.localhost. (
1997022716 ; serial
60 ; refresh (1 minute)
60 ; retry (1 minute)
3600000 ; expire (5 weeks 6 days 16 hours)
10800 ; minimum (3 hours)
)
NS server1
NS server2
$ORIGIN dyn.mydomain.example
home A 1.2.3.4
So now "home.dyn.mydomain.example" is the DNS entry that I'll change.
In named.conf
zone "dyn.mydomain.example" {
type master;
file "src/dyn.mydomain.example";
allow-update {127.0.0.1;};
};
This is weak security 'cos anyone on localhost would be able to update this domain, but since I'm the only one…
Now I can update the value easily:
#!/bin/sh
nsupdate -v << EOF
server 127.0.0.1
zone dyn.mydomain.example
update delete home.mydomain.example
update add home.dyn.mydomain.example. 5 IN A $ip_address
send
EOF
That's how I do it for my home machine. (In fact I run DNS on my home machine and then notify my linode to pick up the updates).
After that you just to decide on how you pick up your IP address and populate it. A simple CGI could do the job.
#!/bin/sh
LINODE_API_KEY=(PUT YOUR LINODE API KEY HERE)
DOMAIN_ID=(PUT YOUR DOMAIN ID HERE)
RESOURCE_ID=(PUT YOUR RESOURCE ID HERE)
WAN_IP=`wget -O - -q http://(PATH_TO_PHP_SCRIPT_HERE)`
OLD_WAN_IP=`cat /tmp/CURRENT_WAN_IP.txt`
if [ "$WAN_IP" = "$OLD_WAN_IP" ]; then
echo "IP Unchanged"
else
echo $WAN_IP > /tmp/CURRENT_WAN_IP.txt
wget -qO- https://api.linode.com/?api_key="$LINODE_API_KEY"\&api_action=domain.resource.update\&DomainID="$DOMAIN_ID"\&ResourceID="$RESOURCE_ID"\&Target="$WAN_IP"
fi
And here's the PHP script that wget is calling:
Put the PHP script on your server, fill in your API key, the two IDs, and the URL, and put the shell script in a cron job on the system whose IP you want to update (in my case, my home file server), and you're good to go.
http://www.linode.com/api/dns/domain.resource.update
#!/bin/sh
LINODE_API_KEY=(PUT YOUR LINODE API KEY HERE)
DOMAIN_ID=(PUT YOUR DOMAIN ID HERE)
RESOURCE_ID=(PUT YOUR RESOURCE ID HERE)
wget -qO- https://api.linode.com/?api_key="$LINODE_API_KEY"\&api_action=domain.resource.update\&DomainID="$DOMAIN_ID"\&ResourceID="$RESOURCE_ID"\&Target=[remote_addr]
To shorten it even more you could just embed the API key and IDs right into the URL. The downside of this method is, as I said, it would hit Linode every time.
And then a domain.resource.list:
You can do the API calls right in your web browser, just build the URL of the request manually and take note of the results.
You can configure the script with a hostname, and it will look up the ResourceID and DomainID for you.
If you install Python, it works on Windows too.
Reviving this old thread, to modernize it since wget does not play well with REST API POST methods.
Here is an updated script:
!/bin/sh
LINODE_API_KEY={YOUR KEY}
DOMAIN_ID={YOUR DOMAIN ID}
RESOURCE_ID={YOUR RECORD ID}
curl -4 -H "Content-Type: application/json" -H "Authorization: Bearer $LINODE_API_KEY" -X PUT -d '{"name": "vpn", "target": "
[remote_addr]", "priority": 50, "weight": 50, "ttl_sec": 300, "tag": null}' https://api.linode.com/v4/domains/$DOMAIN_ID/records/$RESOURCE_ID
Couple of things… I wanted to use WGET, and tried with various flags. The alpine based container that I was running it from did not have curl installed.
I gave up an reformatted the wget into a curl command based on the examples in the documentation.
Note I had to the -4 parameter to the curl command in order to force [remote_addr] to return an IPv4 address. Without the API picked up my IPv6 and create a "AAAA" record with the IPv6 address instead.
Sorry, I could not figure out how to get the code block to format correctly . . .
I wrote this recently, and it's been working great. I have it in a cron job that every 30 minutes.
https://gist.github.com/christr/9de75da7fd1ffbd1aa4f0b33316fff8c