Fritz-DNS – An authoritative DNS server for AVM FRITZ!Box routers

AVM FRITZ!Box Cable 6591

In my home network, I am using an AVM FRITZ!Box Cable 6690. It handles DHCP, DNS, Wifi and recently also interfaces my home network via WireGuard to my servers.

Just like the venerable Dnsmasq AVM’s FRITZ!OS uses hostnames learned from its DHCP leases and makes them resolvable via its internal DNS server.

Unfortunately, this feature in FRITZ!OS has some limitations:

  1. The name of the DNS Zone is hard coded to and can not be adjusted. Hence, the resolvable names have the following schema:
  2. The internal DNS server only supports recursive DNS looks. It does not act as an authoritative DNS server. Hence the local zone can not be delegated.
  3. AXFR zone transfers are not supported.

My solution to these shortcomings is Fritz-DNS which:

  • is a small tool written in the Go programming language.
  • is a small authoritative DNS server which serves A/AAAA resource records for local hosts connected to an AVM Fritz Box home WiFi router.
  • can be used in a hidden master configuration as it supports AXFR zone transfers.
  • uses the custom extension (X_AVM-DE_GetHostListPath) of the TR-064 Hosts SOAP-API as documented here to retrieve a list of local hosts.
  • supports the generation of AAAA (IPv6) resource records based on the hosts MAC addresses using 64-Bit Extended Unique Identifier (EUI-64) and a configured unique local address (ULA) prefix.
  • does not yet support PTR resource records (to be implemented…)
  • is licensed under the Apache 2.0 license

You can find Fritz-DNS at GitHub:

Here is a small figure illustrating the interaction of Fritz-DNS with the Fritz!Box and other DNS servers / clients:

CLI Usage

Usage of fritz-dns
  -ipv6-ula-prefix string
    	Fritz Box IPv6 ULA Prefix (default "fd00::/64")
  -pass string
    	FritzBox password
  -port int
    	Listen port (default 53)
  -soa-expire duration
    	SOA expire value (default 744h0m0s)
  -soa-mbox string
    	SOA mailbox value
  -soa-minttl duration
    	SOA minimum TTL value (default 1h0m0s)
  -soa-ns string
    	Authorative DNS server for the zone
  -soa-refresh duration
    	SOA refresh value (default 2h0m0s)
  -soa-retry duration
    	SOA retry value (default 1h0m0s)
  -ttl duration
    	default TTL values for records (default 5m0s)
  -url string
    	FritzBox URL (default "")
  -user string
    	FritzBox username (default "admin")
  -zone string
    	DNS Zone (default "")

GoSƐ – A terascale file-uploader

GoSƐ is a modern and scalable file-uploader focusing on scalability and simplicity. It is a little hobby project I’ve been working on over the last weekends.

The only requirement for GoSƐ is a S3 storage backend which allows to it to scale horizontally without the need for additional databases or caches. Uploaded files a divided into equally sized chunks which are hashed with a MD5 digest in the browser for upload. This allows GoSƐ to skip chunks which already exist. Seamless resumption of interrupted uploads and storage savings are the consequence.

And either way both upload and downloads are always directed directly at the S3 server so GoSƐ only sees a few small HTTP requests instead of the bulk of the data. Behind the scenes, GoSƐ uses many of the more advanced S3 features like Multi-part Uploads and Pre-signed Requests to make this happen.

Users have a few options to select between multiple pre-configured S3 buckets/servers or enable browser & mail notifications about completed uploads. A customisable retention / expiration time for each upload is also selectable by the user and implemented by S3 life-cycle policies. Optionally, users can also opt-in to use an external service to shorten the URL of the uploaded file.

Currently a single concurrent upload of a single file is supported. Users can observe the progress via a table of details statistics, a progress-bar and a chart showing the current transfer speed.

GoSƐ aims at keeping its deployment simple and by bundling both front- & backend components in a single binary or Docker image. GoSƐ has been tested with AWS S3, Ceph’s RadosGW and Minio. Pre-built binaries and Docker images of GoSƐ are available for all major operating systems and architectures at the release page.

GoSƐ is open-source software licensed under the Apache 2.0 license.

Live Demo



  • De-duplication of uploaded files based on their content-hash
    • Uploads of existing files will complete in no-time without re-upload
  • S3 Multi-part uploads
    • Resumption of interrupted uploads
  • Drag & Drop of files
  • Browser notifications about failed & completed uploads
  • User-provided object expiration/retention time
  • Copy URL of uploaded file to clip-board
  • Detailed transfer statistics and progress-bar / chart
  • Installation via single binary or container
    • JS/HTML/CSS Frontend is bundled into binary
  • Scalable to multiple replicas
    • All state is kept in the S3 storage backend
    • No other database or cache is required
  • Direct up & download to Amazon S3 via presigned-URLs
    • Gose deployment does not see an significant traffic
  • UTF-8 filenames
  • Multiple user-selectable buckets / servers
  • Optional link shortening via an external service
  • Optional notification about new uploads via shoutrrr
    • Mail notifications to user-provided recipient
  • Cross-platform support:
    • Operating systems: Windows, macOS, Linux, BSD
    • Architectures: arm64, amd64, armv7, i386


I consider the current state of GoSƐ to be production ready. Its basic functionality is complete. However, there are still some ideas which I would like to work on in the future:

Also checkout the GitHub Issue Tracker for a detailed overview.

Running a Xilinx hw_server as Docker Container

This article describes the necessary steps to run a Xilinx hw_server as a Docker container.

Xilinx’s hw_server is a command line utility which handles JTAG communication between a Xilinx FPGA board and usually the Vivado IDE. It can be used to configure the FPGA bitstream, connect to the embedded logic analyzer cores (ILA) or perform debugging of processor cores via GDB and the Xilinx System Debugger (XSDB). The hw_server is usually used when those tasks shall performed remotely as the connection between Vivado or XSDB is established via TCP connection and allows us to run it on a remote system.

Running the hw_server as a Docker container has the benefit that its installation is simplified to starting a Docker container by running:

docker run --restart unless-stopped --privileged --volume /dev/bus/usb:/dev/bus/usb --publish 3121:3121 --detach

It also allows us to run the hw_server on architectures which are not natively supported by Xilinx such as the commonly used Aarch / ARM64 and ARMv7 architectures found in Raspberry Pis.

This is enabled by Dockers support for running container images for non-native architectures. I am using the aptman/qus image to setup this user-mode emulation. qemu-user-static (qus) is a compilation of utilities, examples and references to build and execute OCI images (aka docker images) for foreign architectures using QEMU’s user-mode emulation.

Run the following commands to run the hw_server on a embedded device:

# Install docker
sudo apt-get update && sudo apt-get upgrade
curl -sSL | sh

# Start Docker
sudo systemctl enable --now docker

# Enable qemu-user emulation support for running amd64 Docker images
# *Note:* only required if your system arch is not amd64!
docker run --rm --privileged aptman/qus -s -- -p x86_64

# Run the hw_server
docker run --restart unless-stopped --privileged --volume /dev/bus/usb:/dev/bus/usb --publish 3121:3121 --detach

This setup has been tested with a Raspberry Pi 4 running the new 64-bit Debian Bullseye Raspberry Pi OS.

The pre-built Docker image for the hw_server of Vivado 2021.2 is available via

Detailed instructions can be found in the following Git repo:

Casting between Qt and OpenCV primitives

opencv_qtAs a follow-up to the previous post, I’d like to present some code which I think might be helpful for other Qt / OpenCV projects as well.

This code was written for Pastie. Pastie is a piece of software I wrote as part my image processing seminar. It makes use of the well known libraries:

  • Qt for the graphical user interface
  • OpenCV for image processing and computer vision

I wrote a C++ header file to facilitate the co-operation of those two libraries. This file enables the conversion / casting of OpenCV and Qt types e.g.:

#include <QImage>
#include <cv/core.hpp>

QImage qimg("filename.png");
cv::Mat cvimg = toCv(qimg);

The source code is available at GitHub.

The following conversions are supported:

QImage cv::Mat
QTransform cv::Mat
QPoint cv::Point2i
QPointF cv::Point2f
QRect cv::Rect2i
QRectF cv::Rect2f
QSize cv::Size

You can find some examples in the real code here and here.


Seit fast zwei Monaten schreibe ich jetzt am Lehrstuhl für Betriebssysteme meine Bachelorarbeit:

Eine generische Speicherverwaltung mit Hilfe von Seitentabellen für ein
minimalistisches Betriebssystem

oder auf Englisch

A generic memory management with paging for a minimalistic operating

Huh?! Was ist das? Was machst du da?“ Da dies häufig die erste Reaktion von Freunden und Familie ist, möchte ich versuchen das Thema meiner Arbeit hier kurz und verständlich vorzustellen. Wer Interesse an einem tieferem Verständnis und technischen Details hat, lade ich gerne zu meinem Abschlussvortrag Ende Mai ein. Zu dem „Was machst du da?“ kann ich schon einmal sagen, dass ich viel am Programmieren bin und dabei unheimlich viel praktische Erfahrung sammele. Und es nen riesen Spaß macht 😀

Meine Arbeit dreht sich also um Betriebssysteme. Die Aufgabe von Betriebssystemen ist es verfügbare Ressourcen zu verwalten und diese mit einer einheitlichen Schnittstelle dem Nutzer zu Verfügung zu stellen. In meinem Fall arbeite ich an der Verwaltung des Arbeitsspeichers.
Arbeitsspeicher (engl. RAM für Random Access Memory) findet man in Handys, TVs, MP3 Playern, Laptops und vor allem in Server und Hochleistungsrechnern. Es ist einer recht schneller dafür auch leicht flüchtiger Speicher, den man gut mit dem menschlichen Kurzeitgedächtnis vergleichen kann. „Random Access“ steht für einen wahlfreien Zugriff, also dass man alle Informtionen ohne vorheriges „Spulen“ oder „Nadel umsetzen“ abfragen kann – um mal in nostalgischen Analogien zu sprechen.


Dieses Zitat, das gerne dem Microsoft Gründer Bill Gates zugeschrieben wird, dürfte vielleicht einigen von euch bekannt sein. Waren im Jahr 1981 noch 640 KB das Maß der Dinge haben heutige Server 64 GB und mehr. Dies entspricht verblüffend genau einer Verdopplung der Kapazität alle zwei Jahre wie es Gordon Moore bereits schon 1965 postuliert hat.

Aber nun mal wieder zurück zu meiner Arbeit: diese rasante Entwicklung der Speicherkapazität hat Betriebssysteme vor einigen Jahre vor wesentliche Probleme gestellt.
Stellen wir uns vor – ähnlich wie die Größe des Speichers, hätte sich die Anzahl der Autohalter in Deutschland entwickelt. Den Zulassungsstellen wären recht schnell die Nummernschilder ausgegangen, da es einfach nicht genügend unterschiedliche Kombinationen von Landkreis und Buchstaben/Zahlen gäbe. Und wer möchte schon das gleiche Nummernschild wie sein Nachbar haben. Jedes Auto muss also eindeutig identifizierbar und jeder Speicherplatz eindeutig adressierbar sein. Mit zunehmender Anzahl an Autohaltern, bzw. der Speicherkapazität, steigt daher auch Komplexität der Verwaltung.

In meinem Beispiel könnte man dieses Problem beispielsweise durch einen zusätzlichen Buchstaben für das Bundesland auf jedem Nummernschild lösen. Man denke an die Einführung der EU-Kennzeichen.
Und damit bin ich auch schon beim Ziel meiner Arbeit: Ich möchte dieses Verwaltungsproblem für beliebe große Speicherkapazitäten und beliebig viele Verwaltungsinstanzen lösen ohne die Kompexität dadurch zu steigern.

Puh, das soll erst einmal reichen. Ende Mai werde ich diese, meine erste wissenschaftliche, Arbeit abschließen. So lange behalte ich meine Lösung noch für mich :p