Fritz!Box DynDNS – some gory details

2020-02-29

Usually a Fritz!Box can use existing Dynamic DNS services like DynDNS or No-IP without problems. It supports a bunch of predefined services but you can also specify a custom URL with some placeholders. The “fun” started when/if I wanted to implement a custom DynDNS service for my own domain and had to find out some non-obvious things.

The goal was to setup a simple DynDNS service for two different Fritz!Boxes on two locations.

Hardware / Firmware / Documentation

The following two Fritz!Boxes should be configured:

  • FRITZ!Box 7490 (FRITZ!OS: 07.12)
  • FRITZ!Box WLAN 3270 v3 (FRITZ!OS 05.54, Firmware-Version: 96.05.54)
  • Both boxes use “Fritz!Box DDNS/1.0.1” as their User-Agent string

The “DynDNS” settings page of both boxes have a Help-Button pointing to these pages:

Another “source of truth” is the knowledge base section about Dynmic DNS (German only).

Documented features

Both pages describe that both boxes support the following features for custom URLs:

  • some placeholders: <ipaddr>, <ip6addr>, <username>, <pass> (or <passwd>), <domain>, <dualstack> and <ip6lanprefix>.

  • Base64 encoding: <b64>data</b64>.

  • two URLs separated by space for combined IPv4/IPv6 support1

The placeholders <username>, <pass> and <domain> are replaced with the values of the corresponding input fields in the dialog. The Fritz!Box provides the other values.

Let’s look into some promised gory details.

Placeholders – Details

Some things I’ve noticed playing around with the placeholders:

  • There is no escaping!

    When the Fritz!Box replaces the placeholders in the URL it does not escape special characters in the value. The service might interpret the URL in unexpected ways and might reject the request (see URL-Encoding).

    The values for <ipaddr> and <ip6addr> are provided by the FRITZ!Box and they contain only IP addresses – so there should be no problem. The values for <username> and <domain> come directly from user accessible input fields, but they usually do not contain special characters besides . – so propably no problem here, too. Only <pass> is prone to contain special characters which might indeed spoil URL-parsing. On the other hand it is odd to put the password into the URL because DynDNS services either uses HTTP-Basic Authentication or some other custom schema.

    Summary: Strange but no gapping hole for my usecases.

  • <ipaddr> is sometimes <ip6addr>

    If there are two URLs configured then the second URL receives the same value for <ipaddr> and <ip6addr> – both are replaced with the IPv6 address. The DynDNS service for the second URL has therefore no chance to get the IPv4 address via a placeholder. Therefore you can use two different DynDNS services at the same time only if the second service supports IP-autodetection and the Fritz!Box uses IPv4 to connect to that service2.

  • The UI fields User Name, Password and Domain cannot be empty.

    If a DynDNS service does’t use Basic Authentication but – for example – a custom access token as a parameter, then both User Name and Password must be filled with some dummy values like guest. Same game for Domain but guest is a silly name for that.

  • Missing feature: hashing data

    Encoding some data to Base64 is supported using <b64>data</b64>. The same syntax for hashing data using MD5, SHA1 and SHA256 would be nice for some DynDNS services. They use custom access tokens containing stuff like the user name, password, domain, IP address, API-keys etc, hash that data up and put it into the URL. Most probably they want to avoid transmitting the password in cleartext using Basic Authentication.

  • Undocumented values for <dualstack> and <ip6lanprefix>

    These two values are only documented in the German help pages for the 7490 - the English page and the pages for the 3270v3 don’t mention them.

    In my setup <dualstack> is 1 for a real dual-stack setup – i.e. both IPv4 and IPv6 addresses are public addresses.

    <ip6lanprefix> is like 2001:db8:xxxx:xx01::/64. This is only a subnet of the “public” prefix 2001:db8:xxxx:xx00/56 which is displayed in the “Online-Monitor” section of the box.

  • Hard to search for – hard to find

    The help pages do not contain the placeholder in text form! Both the documentation and examples are images so Google & Co cannot find them. And – a minor point – the text inside the images is German – even in the English version.

Support for HTTPS

According to some warning the Fritz!Box supports only plain HTTP:

Unfortunately the Fritz!Box can send DDNS updates only unencrypted via HTTP, while AWS API Gateway provides only HTTPS. :( If you intend to use this solution with a Fritz!Box, you need an additional proxy in between which does HTTP->HTTPS translation. https://github.com/bbock/aws-lambda-dyndns/blob/master/Readme.md#fritzbox-users

My findings are a bit different but not without some salt:

  • Both Fritz!Boxes (the 7490 and the 3270v3) do support HTTPS – but with different feature sets.

    The more modern 7490 has no problem connecting to a contemporary AWS REST API-Gateway which is reachable via HTTPS only. The older 3270v3 does not like the API-Gateway HTTPs – the UI says: “everything OK” but the IP is not changed and API-Gateway does not log anything as if no connection happened. This might be incompatible/outdated TLS versions, ciphers, hashes, key exchanges, missing root certificates and so on.

    I did not dig down that rabbit hole much but noticed that remote access to the 3270v3 also has SSL/TLS problems: Firefox quite outright rejects the connection with the error SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY. This cannot be bypassed using the normal UI but only by setting these values in the about:config page:

     security.ssl3.dhe_rsa_aes_128_sha	false
     security.ssl3.dhe_rsa_aes_256_sha	false
    

    After the facts I’ve found a Knowledgebase article about the same fact: Kein HTTPS-Internetzugriff auf FRITZ!Box möglich” (German)

  • The boxes use HTTPS on the default port 443 only. They will silently use plain HTTP if another port is specified in the URL. Given the URL https://example.com:8080/ the boxes will honour the port 8080 but ignore the protocol https.

    That one took my be surprise!

Authentication

The Fritz!Boxes use Basic Authentication for the DynDNS service. Of course this means that the password is transmitted unencrypted by default (see “Support for HTTPS”). The surprising things are:

  • The Fritz!Box sends the Authorization header with the password right upfront in the first request – it does not wait until the server requests authentication. The good side the medal is: Only one request is required. The bad side: Whatever the Password field in the UI contains is leaked very easily.

    Other authentication mechanisms seems not to be supported. This would be useless because the first request has already leaked the password.

  • The usual URL syntax http://username:password@host/... is not supported – both items are ignored and do not affect the Basic Authentication process.

Responses

It is unclear how the Fritz!Boxes handle the status codes. But it seems that the boxes do not rely on the status code (and perhaps the response content) alone. The “Overview” section in the UI indicates that they also perform a DNS lookup to check the result. I wonder how this works with DNS caches.

The Fritz!Boxes will retry the requests if the response indicates an error. The 3270v3 seems to retry after 29 minutes, the 7490 after 1 hour. Update: The TTL for the DNS records was set to 3600 seconds (1 hour) – this might or might not matter.

Summary

This article is not a rant about AVM and their Fritz!Boxes. Most day-to-day usecases regarding DynDNS seems to be covered sufficiently. The HTTPS problems of the 3270v3 are annoying (especially that the reason is hard to come by) but not a deal breaker for implementing my own DynDNS service.


  1. This one is really hard to notice! ↩︎

  2. : That was my Plan B during debugging :-) ↩︎

Fritz!BoxDynDNS

Dynamic DNS with AWS Route 53 – the Good, the Bad and the Ugly

Setup a new PostgreSQL database on AWS-RDS