-
-
Save corny/7a07f5ac901844bd20c9 to your computer and use it in GitHub Desktop.
#!/bin/sh -e | |
hostname=$1 | |
device=$2 | |
file=$HOME/.dynv6.addr6 | |
[ -e $file ] && old=`cat $file` | |
if [ -z "$hostname" -o -z "$token" ]; then | |
echo "Usage: token=<your-authentication-token> [netmask=64] $0 your-name.dynv6.net [device]" | |
exit 1 | |
fi | |
if [ -z "$netmask" ]; then | |
netmask=128 | |
fi | |
if [ -n "$device" ]; then | |
device="dev $device" | |
fi | |
address=$(ip -6 addr list scope global $device | grep -v " fd" | sed -n 's/.*inet6 \([0-9a-f:]\+\).*/\1/p' | head -n 1) | |
if [ -e /usr/bin/curl ]; then | |
bin="curl -fsS" | |
elif [ -e /usr/bin/wget ]; then | |
bin="wget -O-" | |
else | |
echo "neither curl nor wget found" | |
exit 1 | |
fi | |
if [ -z "$address" ]; then | |
echo "no IPv6 address found" | |
exit 1 | |
fi | |
# address with netmask | |
current=$address/$netmask | |
if [ "$old" = "$current" ]; then | |
echo "IPv6 address unchanged" | |
exit | |
fi | |
# send addresses to dynv6 | |
$bin "http://dynv6.com/api/update?hostname=$hostname&ipv6=$current&token=$token" | |
$bin "http://ipv4.dynv6.com/api/update?hostname=$hostname&ipv4=auto&token=$token" | |
# save current address | |
echo $current > $file |
Only for IPV6 DDNS
filename: dynv6.sh
path:/usr/bin
chmod +x dynv6.sh
#!/bin/sh -e
GETIPV6="https://ip.ddnspod.com"
hostname="xxxxx.v6.rocks"
token="xxxxxxxxxxxxxxxxxxxxxxxxxx"
file=$HOME/.dynv6.addr6
[ -e $file ] && OldIP=cat $file
echo "[Old IP]:$OldIP"
NewIP=$(curl -6 -s -k $GETIPV6)
echo "[New IP]:$NewIP"
if [ "$OldIP" == "$NewIP" ];then
echo "IP IS SAME,SKIP UPDATE."
exit
fi
#send addresses to dynv6
curl "http://dynv6.com/api/update?hostname=$hostname&ipv6=$NewIP&token=$token"
#curl "http://ipv4.dynv6.com/api/update?hostname=$hostname&ipv4=auto&token=$token"
#save current address
echo $NewIP > $file
[root@C921 ~]# crontab -e
*/1 * * * * dynv6.sh &>/dev/null 2>&1
@andi34
the following script was out of work
address=$(wget -O- "https://api6.ipify.org")
"api64.ipify.org " always returns ipv4 address
@tolshao nope, works fine. Typo on your end? api64 vs api6?
I don't like caching the "old" IP in a file because if it was changed manually on dynv6.com or the update went wrong, the script doesn't notice.
So this variant works very well for me:
#!/bin/sh
HOSTNAME_DYNV6="****.dynv6.net"
TOKEN_DYNV6="****"
IP4ADDR=$(curl -s http://ipecho.net/plain)
IP6ADDR=`ip addr show eth0 | grep 'scope global dynamic' | grep -Po 'inet6 \K[0-9a-fA-F:]+'`
if [ "$IP4ADDR" = "" ]
then
echo "Error: unable to determine IPv4 address" 1>&2
fi
if [ "$IP6ADDR" = "" ]
then
echo "Error: unable to determine IPv6 address" 1>&2
fi
if [ "$IP4ADDR" != "" ]
then
ping $HOSTNAME_DYNV6 -4 -c 1 > null # a little dirty - needed to update dns-cache
IP4ADDR_DYNV6=$(dig $HOSTNAME_DYNV6 A +short)
if [ "$IP4ADDR" != "$IP4ADDR_DYNV6" ]
then
echo "IPv4 adress has changed -> update ..."
curl -s "https://ipv4.dynv6.com/api/update?hostname=$HOSTNAME_DYNV6&token=$TOKEN_DYNV6&ipv4=auto"
echo "---"
fi
fi
if [ "$IP6ADDR" != "" ]
then
ping $HOSTNAME_DYNV6 -6 -c 1 > null # a little dirty - needed to update dns-cache
IP6ADDR_DYNV6=$(dig $HOSTNAME_DYNV6 AAAA +short)
if [ "$IP6ADDR" != "$IP6ADDR_DYNV6" ]
then
echo "IPv6 adress has changed -> update ..."
curl -s "https://ipv6.dynv6.com/api/update?hostname=$HOSTNAME_DYNV6&token=$TOKEN_DYNV6&ipv6prefix=auto"
echo "---"
fi
fi
@tm-107 thanks for the script. While this did most of the work for me, I had to modify it to the following for it to work for my needs. For some reason auto was setting the IPV6 address to one that ended in ::
and was missing the last three characters of my address. I made some small modifications to use the current address, including the netmask.
#!/bin/sh
HOSTNAME_DYNV6="****.dynv6.net"
TOKEN_DYNV6="****"
DEVICE_INTERFACE=eno1
IP4ADDR=$(curl -s http://ipecho.net/plain)
IP6ADDR_WITH_MASK=`ip -6 addr list scope global dynamic $DEVICE_INTERFACE | grep -Po 'inet6 \K[0-9a-fA-F:\/]+' | head -n1 | tr -d '\n'`
IP6ADDR=`echo $IP6ADDR_WITH_MASK | tr '/' '\n' | head -n1`
if [ "$IP4ADDR" = "" ]
then
echo "Error: unable to determine IPv4 address" 1>&2
fi
if [ "$IP6ADDR" = "" ]
then
echo "Error: unable to determine IPv6 address" 1>&2
fi
if [ "$IP4ADDR" != "" ]
then
ping $HOSTNAME_DYNV6 -4 -c 1 > null # a little dirty - needed to update dns-cache
IP4ADDR_DYNV6=$(dig $HOSTNAME_DYNV6 A +short)
if [ "$IP4ADDR" != "$IP4ADDR_DYNV6" ]
then
echo "IPv4 adress has changed -> update ..."
curl -s "https://ipv4.dynv6.com/api/update?hostname=$HOSTNAME_DYNV6&token=$TOKEN_DYNV6&ipv4=auto"
echo "---"
fi
fi
if [ "$IP6ADDR" != "" ]
then
ping $HOSTNAME_DYNV6 -6 -c 1 > null # a little dirty - needed to update dns-cache
IP6ADDR_DYNV6=$(dig $HOSTNAME_DYNV6 AAAA +short)
if [ "$IP6ADDR" != "$IP6ADDR_DYNV6" ]
then
echo "IPv6 adress has changed -> update ..."
curl -s "https://ipv6.dynv6.com/api/update?hostname=$HOSTNAME_DYNV6&token=$TOKEN_DYNV6&ipv6prefix=$IP6ADDR_WITH_MASK"
echo "---"
fi
fi
@tolshao and @andi34
curl https://api6.ipify.org
will actually return an IPV4 address, but only if you have disabled IPV6. I imagine that was what happened above.
I made a simple batch file script for my Windows need, hope it can help someone too.
You should use https
Made my shell script like this. Think it's leightweight and easy to read
#!/bin/bash
# dynDNS with dynV6 & ipv6 done right
# Initial values
newIpV6=$(ip -6 addr show scope global | grep inet6 | sed -e 's/^.*inet6 \([^ ]*\)\/.*$/\1/;t;d')
oldIpV6='No data in cachefile'
# Change these parameters as you want to
logfile=~/dynv6.log
cachefile=~/.dynv6cache
token=<your-token>
zone=<your-zone>
if [[ -f $cachefile ]]; then
oldIpV6=$(cat $cachefile)
fi
if [[ $newIpV6 != $oldIpV6 ]]; then
echo "$(date): Updating the DNS. Output can be found in ${logfile}"
echo "$(date): $(curl -k "https://dynv6.com/api/update?token=${token}&zone=${zone}&ipv6=${newIpV6}")" | tee -a $logfile
echo $newIpV6 > $cachefile
else
echo "$(date): IP did not Change. Skipping the update" | tee -a $logfile
fi
Use this as a cron job as often as you need and you should be good to go.
Made my shell script like this. Think it's leightweight and easy to read
#!/bin/bash # dynDNS with dynV6 & ipv6 done right # Initial values newIpV6=$(ip -6 addr show scope global | grep inet6 | sed -e 's/^.*inet6 \([^ ]*\)\/.*$/\1/;t;d') oldIpV6='No data in cachefile' # Change these parameters as you want to logfile=~/dynv6.log cachefile=~/.dynv6cache token=<your-token> zone=<your-zone> if [[ -f $cachefile ]]; then oldIpV6=$(cat $cachefile) fi if [[ $newIpV6 != $oldIpV6 ]]; then echo "$(date): Updating the DNS. Output can be found in ${logfile}" echo "$(date): $(curl -k "https://dynv6.com/api/update?token=${token}&zone=${zone}&ipv6=${newIpV6}")" | tee -a $logfile echo $newIpV6 > $cachefile else echo "$(date): IP did not Change. Skipping the update" | tee -a $logfile fiUse this as a cron job as often as you need and you should be good to go.
I test it on my RPI4b,Which
ip -6 addr show scope global | grep inet6 | sed -e 's/^.inet6 ([^ ])/.*$/\1/;t;d'
will output two AAAA addr,and this script output error like this:
curl: (3) URL using bad/illegal format or missing URL
Sun 05 Feb 2023 09:45:55 AM CST:
can be fix by adding | head -n 1)
can be fix by adding | head -n 1)
Hi there, could you please tell a noob, at which position? I added it behind the URI and it didnt work
dynv6.sh: line 23: ` echo "$(date): $(curl -k "https://dynv6.com/api/update?token=${token}&zone=${zone}&ipv6=${newIpV6}")" | tee -a $logfile | head -n 1)'
Edit: I've read your comment with more care and figured it out. it should be like this:
newIpV6=$(ip -6 addr show scope global | grep inet6 | sed -e 's/^.*inet6 \([^ ]*\)\/.*$/\1/;t;d' | head -n 1)
This is my script (bash), free to use:
#!/bin/bash
bin="curl -fsS"
fqdn=<your_domain>
token='<Your_token>'
ipv4=dig TXT +short o-o.myaddr.l.google.com @ns1.google.com | cut -f2 -d'"'
ipv6=dig -6 TXT +short o-o.myaddr.l.google.com @ns1.google.com | cut -f2 -d'"'
echo "My Ipv6: "$ipv6
echo ""
if [[
then
echo "Updating $fqdn (ipv6)..."
$bin "http://dynv6.com/api/update?hostname=$fqdn&ipv6=$ipv6&token=$token"
echo ""
else
echo "Invalid IPv6 address"
fi
echo "My IPv4: "$ipv4
echo ""
if [[
then
echo "Updating $fqdn (ipv4)..."
$bin "http://dynv6.com/api/update?hostname=$fqdn&token=$token&ipv4=$ipv4"
else
echo "Invalid IPv4 address"
fi
echo "End of DNS records update!"
exit 0
`
`
Here is a node.js implementation of the script, that can be built into an executable with pkg and scheduled using Systemd/Windows Task Scheduler
const os = require('os');
const ip6addr = (os.networkInterfaces())['Ethernet'][1]['address'];
const domain = '<domain>';
const username = '<token>';
const url = `https://dynv6.com/api/update?hostname=${domain}&token=${username}&ipv6=${ip6addr}`;
fetch(url, {
method: 'GET'
}).then((response) => {
response.text().then((data) => {
console.log(data);
});
}).catch((error) => {
console.error(error);
});
Here's a Python updater for IPv4 that updates to the IP of the PC the script is run on.
-Prerequisites
Python (duh)
requests the python module
pip install requests
Once done with the prerequisites, edit the script so the variables match your zone (hostname) and token.
Then run the script and the IPv4 address for your zone should update every 30 seconds!
I created two versions of the updater; an auto and a manual.
Manual Version:
https://gist.github.com/flid0/8784baff35ec061f00432a9db3525c20
Auto Version:
https://gist.github.com/flid0/91bd9a3e15b61a8fd5797c325b3451a0
DM me on Discord if you have any problems:
flido#0001