Skip to content

Instantly share code, notes, and snippets.

@cfstras
Last active December 19, 2020 15:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cfstras/0f7a1635967b39e19424a210c879cdb9 to your computer and use it in GitHub Desktop.
Save cfstras/0f7a1635967b39e19424a210c879cdb9 to your computer and use it in GitHub Desktop.
Setting up your own DynDns server for Fritz!Box

Based on https://controlc.de/2013/09/10/debian-selbstgehosteter-dyndns-dienst/ and https://github.com/Josef-Friedrich/dyndns

For debian 10

apt install -y bind9 bind9-host bind9utils dnsutils unattended-upgrades vim

echo unattended-upgrades unattended-upgrades/enable_auto_updates boolean true | debconf-set-selections
dpkg-reconfigure -f noninteractive unattended-upgrades

Get your variables ready:

IP_ADDRESS=**enter your ip address here**
BINDDIR="/var/lib/bind"
ETCDIR="/etc/bind"
DYNDNSDOMAIN="d.mydomain.com"
HOSTSERVER="ns1.$DYNDNSDOMAIN"
GAST="example-client.$DYNDNSDOMAIN"

Now, register your new nameserver. Go to your registrar or upstream DNS, and add these entries:

hostname type value
ns1.mydomain.com A $IP_ADDRESS
d.mydomain.com NS ns1.mydomain.com

Now, create the zone. Firstly, the config for the zone:

echo <<EOF > $ETCDIR/named.conf.local
// Dynamic zone
zone "$DYNDNSDOMAIN" {
    type master;
    file "$BINDDIR/$DYNDNSDOMAIN";
    allow-update { any; };
    allow-query { any; };
    allow-transfer { none; };
};
EOF

Then the zone itself:

echo <<EOF > $BINDDIR/$DYNDNSDOMAIN
\$ORIGIN .
\$TTL 300 ; 5 minutes
$DYNDNSDOMAIN IN SOA $HOSTSERVER. hostmaster.$DYNDNSDOMAIN. (
    1 ; serial
    3600 ; refresh (1 hour)
    600 ; retry (10 minutes)
    604800 ; expire (1 week)
    300 ; minimum (5 minutes)
    )
 NS $HOSTSERVER.
\$ORIGIN $DYNDNSDOMAIN.
@   A   $IP_ADDRESS
EOF

Create your key:

ddns-confgen -r /dev/urandom -q -a hmac-md5 -k $DYNDNSDOMAIN -s $DYNDNSDOMAIN. | tee -a $ETCDIR/$DYNDNSDOMAIN.keys > $ETCDIR/key.$GAST

#TODO what's key.$GAST for?

export ZONE_KEY="$(grep 'secret' $ETCDIR/$DYNDNSDOMAIN.keys | sed 's/.*secret "\([^"]\+\)".*/\1/')"
echo "ZONE_KEY=$ZONE_KEY"

chown root:bind $ETCDIR/$DYNDNSDOMAIN.keys
chmod u=rw,g=r,o= $ETCDIR/$DYNDNSDOMAIN.keys

echo -e "// DDNS keys" >> $ETCDIR/named.conf.local
echo -e "include \"$ETCDIR/$DYNDNSDOMAIN.keys\";" >> $ETCDIR/named.conf.local
systemctl restart bash

Now, continue with https://github.com/Josef-Friedrich/dyndns:

Installing and configuring

apt install python3 python3-{venv,dev} git build-essential nginx

python3 -m venv /usr/local/share/python-virtualenv/dyndns
source /usr/local/share/python-virtualenv/dyndns/bin/activate
pip3 install git+https://github.com/cfstras/dyndns/@patches-for-multiuser
pip3 install uwsgi

cat <<EOF > /var/www/$DYNDNSDOMAIN/uwsgi.ini
[uwsgi]
module = dyndns.webapp:app

master = true
processes = 5

socket = /var/www/$DYNDNSDOMAIN/dyndns.sock
chmod-socket = 664
uid = www-data
gid = www-data
vacuum = true

die-on-term = true
EOF

Creating an nginx config

cat <<EOF > /etc/nginx/sites-available/$DYNDNSDOMAIN
server {
    server_name $DYNDNSDOMAIN;
    listen 80;
    listen [::]:80;
    return 301 https://$host$request_uri;
}
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name $DYNDNSDOMAIN;
    ssl_certificate /etc/letsencrypt/live/$DYNDNSDOMAIN/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/$DYNDNSDOMAIN/privkey.pem;

    location / {
                    include uwsgi_params;
                    uwsgi_pass unix:/var/www/$DYNDNSDOMAIN/dyndns.sock;
    }
}
EOF

ln -s /etc/nginx/sites-available/$DYNDNSDOMAIN /etc/nginx/sites-enabled/$DYNDNSDOMAIN

Setup a systemd service

cat <<EOF > /etc/systemd/system/dyndns.service
[Unit]
Description=uWSGI instance to serve dyndns
After=network.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/$DYNDNSDOMAIN
Environment="PATH=/usr/local/share/python-virtualenv/dyndns/bin"
ExecStart=/usr/local/share/python-virtualenv/dyndns/bin/uwsgi --ini uwsgi.ini

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload

Configure our service:

cat <<EOF > /etc/dyndns.yml
secret: 12345678 # only used for zones without users
nameserver: 127.0.0.1
dyndns_domain: $DYNDNSDOMAIN
zones:
  - name: $DYNDNSDOMAIN
    tsig_key: $ZONE_KEY
    users:
        user1: my_secret # user1.$DYNDNSDOMAIN
        user2: their_secret # user2.$DYNDNSDOMAIN
EOF

systemctl enable --now dydndns
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment