Dynamic DNS doesn't work for some DDNS providers after core update 159 -> 160

I get a completely clean log result. It just says

Dynamic DNS update for my.domain.name (Dynu) successful

Looking at the ddns git repository again the following clients

had an update to use https for the update rather than http as the passwords were being sent in the clear.

For noip the difference is that the url for the update has https at the start instead of http but all the rest of the url is the same. No other change made. The change was linked to Bug 12658

Not sure if changing to using https would give the error you are seeing or not.

I have raised this as a bug 12705 – DYDNS for freedns.afraid.org fails gives endless failure log entries

1 Like

Hey Guys,
i ran into the same problem. After some research i got it to work. Since ddns switched to the new api you have to activate Dynamic DNS Update in the so called Update interface v2 (FreeDNS - Free subdomain AND domain hosting!) and check the tokens matching those you typed in the ddns settings in the webinterface. After a ddns -d update-all --force the update went through successfully.
I hope this helps you.
Greetings
Steffen

5 Likes

Thank you very much Steffen. It worked for me too.

The difference now is that for any domain you have in the service, you must setup each one in web interface of ipfire, because everyone has its own token.

Thanks again.

Thank you Steffen.
Playing around bit, showed me that each click to ‘enable Dynamic DNS’ on the freedns page generates a new token.
Besides this, the entry goes green in IPFire but the logs show an error. This is because the message, that the IP hasn’t changed.

Just for completeness.

Just another point.

Looking at update interface v2 tips, there’s a tip for using one token for all the domains that we could have setted.

As I stated early, each domain has its own token, but with this it’s not necesary to configure each one in ipfire web interface.

I cannot be restarting ipfire every moment without “serious consequences for me” :rofl: :rofl: :rofl:. I will wait for another moment for testing.

1 Like

Found the issue.

Line 1207 of providers.py reads
if output.startswith("Updated") or output.startswith("No IP changed detected"):
this should be
if output.startswith("Updated") or output.startswith("No IP change detected"):

2 Likes

Hi Bernhard, where is located providers.py?, I cannot find it with the command locate in my system.

About what you posted, I don’t know if my sight is bad but it seems like the two sentences are the same?

The file is located in directory /usr/lib/python3.8/site-packages/ddns.
The difference is the ‘d’ in ‘changed’ <-> ‘change’. :wink:

1 Like

Definitively, my sight is bad. I have glasses to read but I don’t use it so much. :flushed:

Thank you.

Hi everyone can I just confirm what the providers.py?, above is doing ?

And what its all about ?

I did the following:
Logged in to my existing freedns,afraid.org

I navigated dieectly to FreeDNS - Free subdomain AND domain hosting! ( Its almost impossible to find it in the menus !)
I clicked on Randomised update Token , marked the check box next to my dynamic entries name,
I clicked Apply button next to the Action Enable Dynamic DNS… ( Good tip from Feles about each click of apply changes the token thanks )
I then copied the last section in the URL string the “code” part and used this in the token box in IPFire’s dynamic update…

After a short while it updated as it would and should do …

Unfortunately it only seems to do the one update if you then force an ip change ( I simply did a reboot ) then the update looks like its being held off for 12 hours irrespective of the actual ip change?

I do notice a bit of log entries saying its failed etc :

07:30:00 ddns[27780]: Further updates will be withheld until 2021-10-22 16:20:04.595146
07:30:00 ddns[27780]: DDNSUpdateError: The update could not be performed
07:30:00 ddns[27780]: Last failure message:
07:30:00 ddns[27780]: An update has not been performed because earlier updates failed for xxxxxx.mo oo.com
07:25:00 ddns[27307]: Further updates will be withheld until 2021-10-22 16:20:04.595146
07:25:00 ddns[27307]: DDNSUpdateError: The update could not be performed
07:25:00 ddns[27307]: Last failure message:
07:25:00 ddns[27307]: An update has not been performed because earlier updates failed for xxxxxx.mo oo.com
07:20:04 ddns[26804]: DDNSUpdateError: The update could not be performed
07:20:04 ddns[26804]: Dynamic DNS update for xxxxxxx.mooo.com (freedns.afraid.org) failed:
07:16:42 ddns[26485]: Dynamic DNS update for xxxxxxx.mooo.com (freedns.afraid.org) successful

I will observe after some days reboots and report back.

I did the force update from the command line (ddns -d update-all --force) and that did update successfully . ( so the token is correct ) but the method of traking a change and then updating the new Ip back to freedns.afraid.org fails to run ?

If i make the edit you refer to (providers.py) then an exception is thrown in the logs:

Dynamic DNS update for xxxxxx.mooo.com (freedns.afraid.org) threw an unhandle d exception: Traceback (most recent call last): File “/usr/lib/python3.8/urlli b/request.py”, line 1350, in do_open h.request(req.get_method(), req.selecto r, req.data, headers, File “/usr/lib/python3.8/http/client.py”, line 1255, in request self._send_request(method, url, body, headers, encode_chunked) Fil e “/usr/lib/python3.8/http/client.py”, line 1301, in _send_request self.endh eaders(body, goudarasencode_chunked=encode_chunked) File “/usr/lib/python3.8/http/clie nt.py”, line 1250, in endheaders self._send_output(message_body, encode_chun ked=encode_chunked) File “/usr/lib/python3.8/http/client.py”, line 1010, in _s end_output self.send(msg) File “/usr/lib/python3.8/http/client.py”, line 9 50, in send self.connect() File “/usr/lib/python3.8/http/client.py”, line 1424, in connect self.sock = self._context.wrap_socket(self.sock, File “/u sr/lib/python3.8/ssl.py”, line 500, in wrap_soc

The structure of DDNS handling in IPFire is as follows ( in short ):

  • main program, handles the options and functions
  • helper objects for sending requests and receiving responses
  • provider.py defines the special methods for the various providers, each object contains the update URL and the parsing of the response also

As the suffix .py suggests, this is programmed as Python modules.

In case of FreeDNS the update process send the HTTP request, as documented on the FreeDNS page. The answer depends on the novelty of the IP.
If it is a new IP, FreeDNS answers with “Updated”.
If the IP didn’t change since the last request, FreeDNS answers with “No IP change detected”.
The faulty condition compares with “… changed…”, what raises an unspecific error. Therefore the next update is delayed.

The errors you see should not occur. Did you really delete only the superfluous character? How did you edit the file?
I’ll investigate the error message further.

Bernhard

1 Like

So a little update on my part :slight_smile:
On this install I am actually using 2 separate dydns services freedns.afraid.org and no-ip.com
( Site is remote and I must keep in connection)

I understood from your post that the change required was the one on line 1207 and I simply altered it with nano via ssh from a shell in ubuntu.

Here is my complete section for freedns.afraid.org: I simply did a backspace delete from an ssh shell using the installed (via pakfire) nano
MY section as-is

class DDNSProviderFreeDNSAfraidOrg(DDNSProvider):
handle = “freedns.afraid.org
name = “freedns.afraid.org
website = “http://freedns.afraid.org/

    # No information about the request or response could be found on the vendor
    # page. All used values have been collected by testing.
    url = "https://sync.afraid.org/u/"
    can_remove_records = False
    supports_token_auth = True

    def update_protocol(self, proto):

            # Add auth token to the update url.
            url = "%s%s/" % (self.url, self.token)

            # Send update to the server.
            response = self.send_request(url)

            # Get the full response message.
            output = response.read().decode()

            # Handle success messages.
            if output.startswith("Updated") or output.startswith("No IP change detected"):
                    return

            # Handle error codes.
            if output == "ERROR: Unable to locate this record":
                    raise DDNSAuthenticationError
            elif "is an invalid IP address" in output:
                    raise DDNSRequestError(_("Invalid IP address has been sent"))

            # If we got here, some other update error happened.
            raise DDNSUpdateError

The edit should be ok.
Did you enter the token without the trailing ‘/’?
I’ll check whether this matters.
EDIT: The / char doesn’t matter. :face_with_raised_eyebrow:

So just for the info: I tried this “Cleanly” on another site:
If you simply change the token and DONT run the above things still stay the same and you see:

15:25:11 ddns[17797]: Not Found
15:25:11 ddns[17797]: DDNSNotFound: Not found
15:25:11 ddns[17797]: Dynamic DNS update for xxxxx.mooo.com (freedns.afraid.org) failed:

Run the above command you then get a success but you have the errors saying Further updates will be withheld until … (12 Hours later)

If you then do the edit to the The file is located in directory /usr/lib/python3.8/site-packages/ddns.
Line 1207 of providers.py reads
if output.startswith("Updated") or output.startswith("No IP changed detected"):
this should be
if output.startswith("Updated") or output.startswith("No IP change detected"):

It would appear to initially work and you see it update the ip to the site but it throws the exception in logs as before and suggest it will hold off for 12 hours ( But on this install I dont get the unhandle d exception on this box but my second dns id dynu.com here and not NO-ip as the unhandle d exception shown above …
:frowning:

15:45:17 ddns[5101]: Further updates will be withheld until 2021-10-23 00:35:01.570360
15:45:17 ddns[5101]: DDNSUpdateError: The update could not be performed
15:45:17 ddns[5101]: Last failure message:
15:45:17 ddns[5101]: An update has not been performed because earlier updates failed for xxxx.mooo .com
15:44:39 ddns[4637]: Further updates will be withheld until 2021-10-23 00:35:01.570360
15:44:39 ddns[4637]: DDNSUpdateError: The update could not be performed
15:44:39 ddns[4637]: Last failure message:
15:44:39 ddns[4637]: An update has not been performed because earlier updates failed for gkioka.mooo .com
15:40:00 ddns[19535]: Further updates will be withheld until 2021-10-23 00:35:01.570360
15:40:00 ddns[19535]: DDNSUpdateError: The update could not be performed
15:40:00 ddns[19535]: Last failure message:
15:40:00 ddns[19535]: An update has not been performed because earlier updates failed for xxxx.mooo .com
15:35:01 ddns[19037]: DDNSUpdateError: The update could not be performed
15:35:01 ddns[19037]: Dynamic DNS update for xxxx.mooo.com (freedns.afraid.org) failed:
15:34:22 ddns[18966]: Dynamic DNS update for xxxx.mooo.com (freedns.afraid.org) successful
15:34:21 ddns[18966]: Dynamic DNS update for xxxx.freeddns.org (Dynu) successful
15:30:01 ddns[18458]: Further updates will be withheld until 2021-10-23 00:25:11.287760
15:30:01 ddns[18458]: DDNSNotFound: Not found
15:30:01 ddns[18458]: Last failure message:
15:30:01 ddns[18458]: An update has not been performed because earlier updates failed for xxxx.mooo .com
15:25:11 ddns[17797]: Not Found
15:25:11 ddns[17797]: DDNSNotFound: Not found
15:25:11 ddns[17797]: Dynamic DNS update for xxxx.mooo.com (freedns.afraid.org) failed:

Where do you find logs like this

In messages I can see this

 cat  /var/log/messages | grep DNS
Oct 20 11:15:07 ipfire ipfire: Dynamic DNS hostname modified
Oct 20 11:15:31 ipfire ipfire: Dynamic DNS hostname modified

Same as in Web GUI - Logs - System logs - Ipfire

Time 	Section 	 
12:25:08	ipfire: 	NTP synchronisation event
11:15:31	ipfire: 	Dynamic DNS hostname modified
11:15:07	ipfire: 	Dynamic DNS hostname modified

If I go to Web GUI - Logs - System logs - Dynamic DNS, it is empty (no info at all)

These logs are in Web GUI - Logs - System logs - Dynamic DNS

I’ve investigated the errors.
Inspection into the files ( exception is raised in the standard library! ) didn’t give a hint for the reason.

Could you please post the output of
ddns -d update-all --force
Try also to catch the error messages as they are listed on the console. Redirect to a text file may help also.

BTW: the error ‘DDNSNotFound’ means, that the server could not be reached.
Just try to send the update URL from the shell using curl.

1 Like

I’ve sent a fix for this IP change(d) issue to our development mailing list.

The fixed version hopefully will be part of the upcomming Core update 161, or if to late it will be part of 162.

Thanks a lot for all the detailed research and reporting.

4 Likes