Disappearing ip address against my domain

Hi for months everything has worked fine after a reboot of my server one of many my dns record keeps disappearing after an hour or two any idea how to find out whats going on i get no logs from syslog even though i have enabled the logging. Manually calling the ddclient pushes the update and the daemon runs every 5 mins cleared caache and it still dose not update

Is the affected DNS record for a hostname that a DynDNS client (such as ddclient) is configured to update?

If so, how is ddclient determining the public IP? (Which use=, usev4= or usev6= option is configured in ddclient?)

Also, is this an IPv4 or IPv6 address? (A or AAAA record?)

fiwswe

1 Like

I will answer here as the original author seems not to be here any more. But i got the same problem.

ddclient is configured from the nextbox installation.

The ddclient.conf contains:
protocol=dyndns2
daemon=300
use=cmd, cmd=’curl https://checkipv4.dedyn.io’
ssl=yes
server=update.dedyn.io
login=’hostname.dedyn.io’
password=’xxxx’ (should be valid)
hostname.dedyn.io

The v6 Adress is in the account, the v4 Adress is missing.
If I enter the v4 Adress manually it works for some minutes, but regardless how much ttl I enter it is gone after some minutes. Most likely after the next time the demon was running on the nextbox.

Hi sorry,

I ended up just writing a script to do the job

It was ddclient that I was using and it worked fine when I forced it it was set up to run as daemon and it was working fine for almost a year but it suddenly stopped working no idea why I tried everything to debug but gave up and wrote this instead.

#!/usr/bin/env bash
# Dynamic DNS update script with IP change detection + 30-minute forced update
# Stores state in ~/.ddns-state (or change path below)

set -u
set -e

# ================= CONFIG =================
STATE_FILE="${HOME}/.ddns-state"
CACHE_IP_VAR="EXTERNAL_IP"
CACHE_TIMER_VAR="DDNS_UPDATETIMER"
UPDATE_URL="https://update.dedyn.io/"
AUTH="REDACTED URL + KEY"
CHECK_IP_URL="https://checkip.amazonaws.com"
FORCE_UPDATE_EVERY_MINUTES=30
# ==========================================

mkdir -p "$(dirname "$STATE_FILE")" 2>/dev/null || true

# ------------------------------------------------
# Helper: read cached value or return empty string
# ------------------------------------------------
read_cached() {
    local varname="$1"
    local value=""
    if [[ -f "$STATE_FILE" ]]; then
        value=$(grep -E "^${varname}=" "$STATE_FILE" | cut -d'=' -f2- | tr -d '[:space:]' || true)
    fi
    echo "$value"
}

# ------------------------------------------------
# Helper: write/update one variable in the state file
# ------------------------------------------------
write_cached() {
    local varname="$1"
    local newvalue="$2"

    # Remove old line if exists
    if [[ -f "$STATE_FILE" ]]; then
        grep -v "^${varname}=" "$STATE_FILE" > "${STATE_FILE}.tmp" 2>/dev/null || true
        mv -f "${STATE_FILE}.tmp" "$STATE_FILE" 2>/dev/null || true
    fi

    # Append new value
    printf '%s=%s\n' "$varname" "$newvalue" >> "$STATE_FILE"
}

# ------------------------------------------------
# Main logic
# ------------------------------------------------

CURRENT_IP=$(curl -s --connect-timeout 8 --max-time 12 "$CHECK_IP_URL" | tr -d '[:space:]')

if [[ -z "$CURRENT_IP" ]]; then
    echo "Error: Could not retrieve current IP address" >&2
    exit 1
fi

CACHED_IP=$(read_cached "$CACHE_IP_VAR")
LAST_UPDATE=$(read_cached "$CACHE_TIMER_VAR")

# Default to very old timestamp if missing/invalid
if [[ -z "$LAST_UPDATE" ]] || ! [[ "$LAST_UPDATE" =~ ^[0-9]+$ ]]; then
    LAST_UPDATE=0
fi

NOW=$(date +%s)
MINUTES_SINCE_LAST=$(( (NOW - LAST_UPDATE) / 60 ))

NEEDS_UPDATE=false

if [[ "$CACHED_IP" != "$CURRENT_IP" ]]; then
    echo "IP changed: ${CACHED_IP:-none} ? $CURRENT_IP"
    NEEDS_UPDATE=true
elif (( MINUTES_SINCE_LAST >= FORCE_UPDATE_EVERY_MINUTES )); then
    echo "Periodic update triggered (${MINUTES_SINCE_LAST} minutes since last update)"
    NEEDS_UPDATE=true
else
    echo "IP unchanged and update not due yet (${MINUTES_SINCE_LAST} min / ${FORCE_UPDATE_EVERY_MINUTES} min)"
fi

if [[ "$NEEDS_UPDATE" == true ]]; then
    echo "Updating DDNS..."

    HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
        --user "$AUTH" \
        --connect-timeout 10 \
        --max-time 15 \
        "$UPDATE_URL")

    if [[ "$HTTP_STATUS" =~ ^2 ]]; then
        echo "Update successful (HTTP $HTTP_STATUS)"

        # Update both values
        write_cached "$CACHE_IP_VAR"    "$CURRENT_IP"
        write_cached "$CACHE_TIMER_VAR" "$NOW"

        echo "State updated:"
        echo "  $CACHE_IP_VAR    = $CURRENT_IP"
        echo "  $CACHE_TIMER_VAR = $NOW ($(date -d "@$NOW"))"
    else
        echo "Update FAILED - HTTP status: $HTTP_STATUS" >&2
        exit 2
    fi
fi

exit 0

@danielv I don’t use ddclient myself. However I suspect a ddclient configuration error that might lead to some sort of mixup between updating/deleting AAAA and A records.

Check to see if you have a public IPv6 and IPv4 address on the host running ddclient. Then try to see what exact URLs ddclient is actually sending to deSEC. (Maybe run ddclient with the --daemon=0 --debug --verbose options for testing.)

HTH
fiwswe

1 Like

@Bobstefanio Generally ok but why does your script periodically try to update when the IP hasn’t changed? That only generates server load at deSEC without any benefit. Maybe modify the logic to update when the A/AAAA record at deSEC does not match the current IP?

Also, unless I’m missing something, the $UPDATE_URL does not include the IP determined in $CURRENT_IP, instead relying on the IP curl uses to contact deSEC. If you have both public IPv4 and IPv6 addresses this may lead to issues.

HTH
fiwswe

1 Like

@fiwswe Point taken about IPv4 and IPv6 however I have specifically requested from my internet provider for an IPv4 only as they do some weird stuff on their router when its in IPv6 due to them using something called DS-lite so for now I only have an IPv4 Address.

I have it updating forced every 30 minutes as I do not want my services to be offline I would like the IP address to be there and when I was not updating the IP address due to the DDCLIENT issue deSec would periodically delete the ip address and then I could not access my services, I was not sure on the time that this occurred if you know what the time out is I would happily reduce that time to auto update to a few hours or are you saying I dont need the force update at all ? If so I will give it a try without it.

@Bobstefanio You could easily add ?myipv4=${CURRENT_IP} to the URL used by curl to make any ambiguity go away.

deSEC does not delete DNS records on its own. So your issue with disappearing records was probably caused by erroneous update requests (possibly from a misconfigured ddclient). So if that issue is resolved, you no longer need to to periodically update the existing record.

But as I mentioned a good optimization would be to check the actual IP deSEC has and only update if it differs from your current one. E.g. use something like dig +short @ns1.desec.io hostname.dedyn.io a to get the A record from deSEC (or dig +short hostname.dedyn.io a for using your local resolver) and compare the result with $CURRENT_IP. Then update if there is a difference.

1 Like

The IP is probably dissappering, because of the default update logic of deSEC.

See update logic here Github link and maybe you even like the script I have written there.

I run $ sudo ddclient -daemon=0 -debug -verbose -noquiet

Output:
SUCCESS: mydomain.dedyn.io: skipped: IP Address was already set to “correct IPv4 Adress”
so no IPv4 Adress is set in the webinterface of desec.

Using “$ sudo ddclient -daemon=0 -debug -verbose -noquiet -force”

helps, because it will set the IPv4 Adress even if cached locally.

The config File should be fine. Not touched for 4 years.

But the Provider Connection (Deutsche Telekom) has a public v6 and v4 adress. Maybe they have changed something recently. So as it seems usually it now sets the v6 adress and the v4 adress gets deleted.
Unfortunately the nextbox only works with IPv4 as there is a docker problem with the v6 adress afaik.

@danielv Like I wrote, I don’t use ddclient. Try to figure out a way to see the URL ddclient is using to update the deSEC server. I think --exec or --noexec might do the trick.

Since your connection has both public IPv4 and IPv6 addresses I suspect that the URL is not explicitly stating the IP parameter. If so, the deSEC auto detection may determine the IP and that may be different than what you intended. Show us the URL and we can at least point to the problem. Then you need to figure out how to fix it.

One other note: While looking at ddclient documentation I saw indications that use should be replaced by usev4/usev6 and cmd by cmdv4/cmdv6.

1 Like

Hi, thanks for the hints.

.the url? It talks to http://update.dedyn.io/nic/update?system=dyndns&hostname=hostname.dedyn.io&myip=A.B.C.D and uses the credentials provided.

SENDING: GET /nic/update?system=dyndns&hostname=hostname.dedyn.io&myip=A.B.C.D HTTP/1.0

When doing it directly with the ddclient it works.
Whatever the nextbox is doing is ignoring v4 most of the times and saying no v4 set.

B) If I use usev4 and cmdv4, it does not work. In the installed version those are unrecognized keywords. (Version 3.9.1)

Not sure if this is an actual problem or just an error in the debug output, but the URL should use https not http.

So what is this “nextbox” you have mentioned a few times?

By “directly” do you mean manually on a different host?

Who is saying no v4 set? Is there an error message or log entry? If ddclient on the “nextbox” can’t determine the public IPv4 address for some reason then it is possible that the update request might go out without a valid myip parameter. In that case deSEC would try to determine the IP from the source address of the request. And if that happens to be an IPv6 address, you might get an AAAA record but no A record.

Does the “nextbox” have an IPv4 address? Does DNS resolution work on the “nextbox”?

I was looking at the latest version on GitHub, which is ≄ v4.0.0. That may explain the issue with usev4/cmdv4.

1 Like

The nextbox is a hardwarebundle (raspberry pi plus SSD) to have a nextcloud hosted at home.
So nextcloud with some changes to make it easier to use for everyday user.
It’s from Nitrokey, located in Teltow.

By directly i mean on the same hardware. On OS Level.
The Nextcloud is in a docker container on this hardware.

The nextcloud log. (updated deSEC IPv4 (None) and IPv6 (2003:xxxx) address for ‘hostname.dedyn.io’)
It wants to update every 5 minutes. Then doing so only if the Adress has changed.
But I don’t know who starts this every 5 minutes. Changes in the ddclient.conf on the host did not change anything. Had the nextcloud-daemon restarted after changes.

And yes, I get an AAAA record but no A record set.
Sometimes the log says it has an v4 Adress but then it won’t set because it’s still the same as in the ddclient cache file.

So everything on your site seems correct.
Just behaving as expected after I have seen the logs.

If I update some of the software myself the next automatic update may fail. So this isn’t a real option.
Most probably it will break things.

So thanks a lot. Time for me to get a ticket at nitrokey.

I’m just a deSEC user, not affiliated in any way :wink:

I still think the most likely cause for your issue is a problem determining the public IPv4 address on the NextBox. The root cause may be a network issue or a problem resolving DNS requests on the box. Hard to tell from here.

Given that you seem to want to only set an A record, maybe you can find a way to add &ipv6=preserve or &ipv6= to the URL parameters ddclient uses? That would prevent changing or delete any AAAA record at least.

Unfortunately, while there exists an IPv6-only update6.dedyn.io, there is no corresponding update4.dedyn.io for IPv4-only AFAICT. And update.dedyn.io listens on both IPv4 and IPv6. So choosing a server that only answers to IPv4 is not a viable solution to your issue.

1 Like

That sounds like a good plan – yesterday, we got support requests from two other Nextbox users who experience the same problem.

When opening the ticket, please tell them that

  1. The value of IPv6 parameter is misformatted (: in IP addresses is transmitted as %3A which is incorrect);
  2. Both the myipv4 and myipv6 parameters should be specified (with an IP address, empty [for deletion], or preserve) so that there are no surprises from connection IP inference;
  3. Updates should only be sent when there’s a change and not every 5 minutes.

Thanks!

Stay secure,
Peter

2 Likes

Hey @danielv ,
the dyndns update problem with your Nextbox was most likely caused by a bug on our (Nextbox/Nitrokey’s) side. An unreliable service for determining the ipv4 was used, resulting in an empty update and therefor unwanted deletion of the A record. There are some details in our forum.
It should be fixed by the update we roll out today/tomorrow.
@peter if you could relay this information to the other two Nextbox users you mentioned, that would really appreciate that!
Best
Jan Knittel
from Nitrokey

Good to know the issue was found.

However given the ddclient config @danielv posted above he was already using the deSEC service for determining the public IPv4 address.

Or is there a second different configuration on the box?

2 Likes

yeah, the source configuration is in another file.
The used ddclient in earlier releases. But now its part of:

/usr/lib/python3/dist-packages/nextbox_daemon/consts.py

(A hint in the old file would habe been a good idea)
Solution posted in the nitrokey forums.

Patch will be released asap.
Thanks everyone for helping!