Get ipv6 address of server for ddns update

{
	"up": true,
	"pending": false,
	"available": true,
	"autostart": true,
	"dynamic": false,
	"uptime": 143626,
	"l3_device": "eth123",
	"proto": "static",
	"device": "eth123",
	"updated": [
		"addresses"
	],
	"metric": 0,
	"dns_metric": 0,
	"delegation": true,
	"ipv4-address": [
		{
			"address": "redacted",
			"mask": 24
		}
	],
	"ipv6-address": [
		
	],
	"ipv6-prefix": [
		
	],
	"ipv6-prefix-assignment": [
		{
			"address": "redacted::",
			"mask": 64,
			"preferred": 462980,
			"valid": 1067780,
			"local-address": {
				"address": "redacted::1",
				"mask": 64
			}
		},
		{
			"address": "redacted:1::",
			"mask": 64,
			"local-address": {
				"address": "redacted:1::1",
				"mask": 64
			}
		}
	],

There seem to be no specific prefix, but you can fetch the IPv6 address and trim the suffix.

OK I see the point.
You seem to know this all in and out. This is what I had so far:

NET_IF6=$1
HOST_SFX6=$2

. /lib/functions/network.sh
network_flush_cache
network_get_prefix6 NET_PFX6 "${NET_IF6}"
echo "${NET_PFX6%/*}${HOST_SFX6}"

I would probably find out how to get the address, but the trimming part is more obscure (I don't do scripting usually, so for me it is alot of looking around man and web pages to get these special parts done).

1 Like

That's easy when you fetch the right address:

echo "${NET_ADDR6%::*}::"

I now have this:

NET_IF6="${1}"
HOST_SFX6="${2}"

. /lib/functions/network.sh
network_flush_cache
network_get_subnet6 NET_ADDR6 "${NET_IF6}"
echo "${NET_ADDR6%::*}::${HOST_SFX6}"

But as you say, I need to ge the right address. By change this returns the right address, but can I be sure that the provider prefix address is always the first address being returned or could that also be the ULA address sometimes while WAN6 is up and running?

And still DDNS LUCI is complaining:
Advanced Settings - IP address source [IPv6]: can not detect local IP. Please select a different Source combination

Any idea why that is ???

. /lib/functions/network.sh
network_flush_cache
network_get_subnets6 NET_SUBS6 "${NET_IF6}"
for NET_SUB6 in ${NET_SUBS6}
do if [ "${NET_SUB6::2}" != "fd" ]
then echo "${NET_SUB6%::*}::"; break; fi
done

https://github.com/openwrt/openwrt/blob/master/package/base-files/files/etc/uci-defaults/12_network-generate-ula#L8

1 Like

Great the script works. Still some questions:

  • for what is sed -n -e "1p" needed?
  • why is DDNS LUCI still complaining Advanced Settings - IP address source [IPv6]: can not detect local IP. Please select a different Source combination

Does the script option for DDNS work at all? Is this a bug?

To limit result to a single match.
Actually, we can just break the loop.

Sorry, no idea, I'm behind the ISP NAT. :sweat:

If its allowed to guess (I didn't use DDNS since years) I would say you have assigned the wrong (wan-)interface in DDNS settings.
Assuming you are trying to deal with ipv6 for DDNS also I would choose wan6 instead of default wan.
It might be that you didn't choose IPv6 network in settings too. Your DDNS provider has to support it also.

1 Like

This is the script I use to update my DDNS and it also updates the firewall too.

#!/bin/sh

# CONFIGURABLE PARAMETER: PREFIX
# Set the prefix to the name of the rules that need to be updated. (Can update multiple rules with same name)
PREFIX=NAS
PREFIX_LEN=${#PREFIX}

# CONFIGURABLE PARAMETER: getIP
# Set your method of getting IPv6 address in here
# Current method is through ip neighbor with MAC address (Lowercase, :)(getIP=$(ip neighbor | grep "Your MAC Here" | grep -v "STALE" | cut -d" " -f1))
# One example is wget which accesses a page on the web-server showing current IP address (getIP=$(wget --read-timeout=10 http://checkipv6.dyndns.com -q -O -))
# Another option could be nslookup your domain to get the IPv6 address. getIP=$(nslookup -query=AAAA $hostname)
printf "Getting your IPv6 address... \n"
getIP=$(ip -6 neigh | grep "00:11:32:2b:15:e3" | grep -v "fe80" | cut -d" " -f1)

if [ "$getIP" = "" ]
then
    printf "Failed to get IP."
    exit 0
fi

# Set m flag accordingly, only first match is accepted.
prefix6=$(echo "$getIP" | grep -m 1 -E -o "([0-9a-fA-F]{1,4}(:?)){8}")

if [ "$prefix6" = "" ]
then
    printf "Request successful, but no IPv6 detected. \n"
    exit 0
fi

printf "Your current IPv6: {$prefix6}\n\n"

changed=0
index=0
name=$(uci get firewall.@rule[$index].name 2> /dev/null)

while [ "$name" != "" ]
do
    subname=${name:0:$PREFIX_LEN}

    if [ "$subname" == "$PREFIX" ]
    then
        dest_ip=$(uci get firewall.@rule[$index].dest_ip 2> /dev/null)
        printf "Current stored IP address: {$dest_ip} \n"

        if [ "$dest_ip" != "$prefix6" ]
        then
            printf "The IP has changed! \n"
            printf "Updating\n\n"
            changed=1
            curl --silent "https://myusername:mypassword@domains.google.com/nic/update?hostname=mysubdomain.mydomain.com&myip=${prefix6}"
			uci set firewall.@rule[$index].dest_ip=$prefix6
            uci commit firewall
        else
            printf "IP is the same, no changes made.\n"
        fi

        break 2
    fi

    index=$(expr $index + 1)
    name=$(uci get firewall.@rule[$index].name 2> /dev/null)
done

if [ $changed -eq 1 ] 
then
    printf "Restarting firewall... \n"
    /etc/init.d/firewall reload 2> /dev/null
    printf "All up to date. \n"
fi

exit 0

Create a blank rule named NAS in Network > Firewall > Traffic Rules > Add. In advanced settings set "Restrict to address family" to IPv6.

Save the script somewhere and make a cron job to run it every couple of hours.

1 Like

-the DDNS provider supports AAAA, I tested it already manually, it works
-IP address version is on IPv6 (cf IP address source [IPv6])
-Event network [IPv6] is wan6, because the dynamic prefix comes from wan6
-Lookup hostname does have an AAAA record

I can see no good reasons why DDNS LUCI should complain.

OK the problem was that I tried to pass the interface and the suffix as script parameters. DDNS will then complain. So I had to put those parameters inside the script.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.