• Stars
    star
    256
  • Rank 159,219 (Top 4 %)
  • Language
    Python
  • License
    GNU General Publi...
  • Created over 10 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Self-hosted dyndns/dynamic DNS server and updater for bind

sftdyn dynamic dns server

sftdyn is a minimalistic dynamic DNS server that accepts update requests via HTTP(S) and forwards them to a locally running DNS server via nsupdate -l.

It lets you easily create a dyndns.org-like service, using your own DNS server, and can (probably) be used with your router.

Operation

  • Some device submits a https request to a "secret URL" of sftdyn
  • From this, sftdyn knows the request origin IP
  • From the "secret URL", sftdyn updates the DNS record of the associated hostname
  • The request therfore updated an IP in your zone

Requirements

Quick Guide

sftdyn is for you if you host a DNS zone and can run a Python server so it updates the nameserver records. This guide assumes that you're using BIND, your zone is dyn.sft.mx, and your server's IP is 12.345.678.90. Substitute the correct values for zone and IP as you use this guide.

Nameserver

bind has to be configured to serve the updatable zone.

Somewhere in named.conf, add

zone "dyn.sft.mx" IN {
    type master;
    file "/etc/bind/dyn.sft.mx.zone";
    journal "/var/cache/bind/dyn.sft.mx.zone.jnl";
    update-policy local;
};

/var/cache/bind and /etc/bind/dyn.sft.mx.zone must be writable for bind.

Create the empty zone file

cp /etc/bind/db.empty /etc/bind/dyn.sft.mx.zone

If you want to use dyn.sft.mx as the hostname for the server that gets IP update requests later, add a record to the zone file (this requires the sftdyn-server to have this static IP, @ means the zone name itself).

@ 10m IN A 12.345.678.90
@ 10m IN AAAA some:ipv6::address

sftdyn

To install sftdyn, use pip install sftdyn or ./setup.py install.

Launch it with python3 -m sftdyn [command-line options].

Configuration is by command-line parameters and conf file. A sample conf file is provided in etc/sample.conf. If no conf file name is provided, /etc/sftdyn/conf is used. Hostnames/update keys are specified in the conf file.

sftdyn should run under the same user as your DNS server, or it might not be able to update it properly. Alternatively, to run sftdyn as the user of your choice, see Advanced setup later in this article.

systemd service

To run sftdyn automatically, you can use a systemd service.

The sftdyn distribution package should automatically install sftdyn.service.

If you have to manually install it, use the example unit etc/sftdyn.service and copy it to /etc/systemd/system/sftdyn.service on the sftdyn host machine.

Enable the launch on boot and also start sftdyn now:

sudo systemctl enable --now sftdyn.service

Unencrypted operation

You can use sftdyn in plain HTTP mode. Your average commercial dynamic DNS provider provides a HTTP interface, so most routers only support that.

Somebody could grab your "secret url" with this and perform unintended updates of your record.

Encrypted operation

Because of the above reason, you should use HTTPS to keep your update url token secret. For that, your server needs a X.509 key and certificate. You can create those with let's encrypt, buy those somewhere, or create a self-signed one.

Let's Encrypt

If you got a certificate by Let's Encrypt, configure sftdyn to use it:

# in sftdyn.conf:
key = "/etc/letsencrypt/live/host.name.lol/privkey.pem"
cert = "/etc/letsencrypt/live/host.name.lol/fullchain.pem"

Make sure the certificate is valid for the domain your sftdyn is getting requests for.

A https request to sftdyn to update an IP will then be secureβ„’ (e.g. with curl).

Self-signed certificate

To generate server.key and a self-signed server.crt valid for 1337 days:

openssl genrsa -out server.key 4096
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 1337 -in server.csr -signkey server.key -out server.crt
rm server.csr

Make sure you enter your server's domain name for Common Name (the hostname you'll use for querying sftdyn with clients.

A https request to sftdyn to update an IP will then be more secureβ„’ than a globally valid certificate like from Let's Encrypt, but you'll need to transfer the server.crt to the device performing the request (e.g. with curl).

Client

The client triggers the IP update at the sftdyn server, so your DNS then delivers the correct IP.

Plastic router

To use your cheap plastic router as client, select user-defined provider, enter http://dyn.sft.mx:8080/yourupdatekey as the update URL, and random stuff as domain name/user name/password (tested with my AVM Fritz!Box. YMMV). Most routers don't support HTTPS update requests (especially not with custom CA-cert, so you'll probably need HTTP.

Request with curl

If you want to update the external IP of some NAT gateway (like home router, ...), and you have a machine in that network which can use curl, choose this client method.

If you use HTTPS with a self-signed certificate, curl will refuse to talk to the server.

  • Use curl -k to ignore the error (Warning: see the security considerations below).
  • Copy server.crt to the client, and use curl --cacert server.crt.
HTTP code Text Response interpretation
200 OK Update successful
200 UPTODATE Update unneccesary
403 BADKEY Unknown update key
500 FAIL Internal error (see the server log)
200 your ip Returned if no key is provided
systemd timer

systemd timers are like cronjobs. Use them to periodically run the update query.

Create /etc/systemd/system/sftdynupdate.timer:

[Unit]
Description=SFTdyn dns updater

[Timer]
OnCalendar=*:0/15
Persistent=true

[Install]
WantedBy=timers.target

Create /etc/systemd/system/sftdynupdate.service:

[Unit]
Description=SFTdyn name update

[Service]
Type=oneshot
User=nobody
ExecStart=/usr/bin/env curl -f -s --cacert /path/to/server.crt https://dyn.sft.mx:4443/yoursecretupdatekey

Activate the timer firing with:

sudo systemctl enable --now sftdyn.timer

Verify the timer is scheduled:

sudo systemctl list-timers

To manually trigger the update (e.g. for testing purposes):

sudo systemctl start sftdyn.service
Cronjob

Cronjobs are the legacy variant to periodically run a task, you could do this like this:

*/10 * * * * curl https://dyn.sft.mx:4443/mysecretupdatekey

Advanced setup

Pre-generated keyfile

By default sftdyn uses a key auto-generated by bind, /var/run/named/session.key. The permissions of this file may be reset on startup, and could be too restrictive for sftdyn.

If you see errors such as these in journalctl -u sftdyn, it may indicate a permission issue with the keyfile:

; TSIG error with server: tsig indicates error
update failed: NOTAUTH(BADSIG)

An alternative approach is to use a pre-generated keyfile dedicated to sftdyn, which lets you have more control over the file permissions.

Create a new key

The example script below generates a keyfile in /etc/bind/keys/sftdyn.key, and changes the user/group ownership to bind:sftdyn. Modify as needed to best suit your specific setup.

b=$(dnssec-keygen -a hmac-sha512 -b 512 -n USER -K /tmp foo)
cat > /etc/bind/keys/sftdyn.key <<EOF
key "sftdyn" {
    algorithm hmac-sha512;
    secret "$(awk '/^Key/{print $2}' /tmp/$b.private)";
};
EOF
rm -f /tmp/$b.{private,key}
chown bind:sftdyn /etc/bind/keys/sftdyn.key # or whatever permissions
chmod 640 /etc/bind/keys/sftdyn.key
Include the key in named.conf
include "/etc/bind/keys/sftdyn.key";
Configure named zone to use the key
zone "dyn.sft.mx" IN {
    type master;
    file "/etc/bind/dyn.sft.mx.zone";
    journal "/var/cache/bind/dyn.sft.mx.zone.jnl";
    allow-update { key "sftdyn"; };
};
Change sftdyn configuration to use the key

Edit the nskeyfile option in the configuration file, by default located in /etc/sftdyn/conf:

nskeyfile = "/etc/bind/keys/sftdyn.key"

About

This software was written after the free dyndns.org service was shut down. After a week or so of using plain nsupdate, we were annoyed enough to decide to write this.

The main goal of this tool is to stay as minimal as possible; for example, we deliberately didn't implement a way to specify the hostname or IP that you want to update; just a simple secret update key is perfectly good for the intended purpose. If you feel like it, you can make the update key look like a more complex request; every character is allowed. Example: host=test.sft.mx,key=90bbd8698198ea76.

The conf file is interpreted as python code, so you can do arbitrarily complex stuff there.

Security considerations

  • When using HTTP, or if your server.key has been stolen or broken, an eavesdropper can steal your update key, and use that to steal your domain name.
  • When using HTTPS with curl -k, a man-in-the-middle can steal your update key.
  • When using HTTPS with a paid certificate, a man-in-the-middle with access to a CA can steal your update key (no problem for government agencies, but this is pretty unlikely to happen).
  • When using HTTPS with a self-signed certificate and curl --cacert server.crt, no man-in-the-middle can steal your update key.

sftdyn is pretty minimalistic, and written in python, so it's unlikely to contain any security vulnerabilities. The python ssl and http modules are used widely, and open-source, so there should be no security vulnerabilities there.

Somebody who knows a valid udpate key could semi-effectively DOS your server by spamming update requests from two different IPs. For each request, nsupdate would be launched and your zone file updated.

Development

For us, the project is feature-complete, it has everything that we currently need. If you actually did implement a useful feature, please send a pull request; We'd be happy to merge it.

If you have any requests, ideas, feedback or bug reports, are simply filled with pure hatred, or just need help getting the damn thing to run, join our chatroom and just ask:

The license is GNU GPLv3 or higher.

More Repositories

1

openage

Free (as in freedom) open source clone of the Age of Empires II engine πŸš€
Python
12,550
star
2

nyan

Typesafe hierarchical key-value database with inheritance and dynamic patching 😺
C++
211
star
3

sticker

Some of the stickers might unsettle you. πŸ”“
136
star
4

abrechnung

Payment tracking and money splitting for groups πŸ’Έ
TypeScript
124
star
5

kevin

A simple-stupid self-hostable continuous integration service. πŸ™ˆ
Python
110
star
6

openage-data

Free (as in freedom) media files for openage.
54
star
7

openage-masterserver

Lobby and matchmaking server for openage in Haskell
Haskell
52
star
8

sftmumblebot

Mumble/IRC text chat bridge 🎀 πŸ’Œ
Python
48
star
9

wirespider

Wireguard Mesh VPN - automatic tunnel and authorization management πŸ•Έ
Rust
35
star
10

stiefelsystem

Boot your operating system on a different hardware device via network πŸ‘’
Python
34
star
11

videoscreen

Play submitted links with mpv on a videowall πŸŽ₯
Python
24
star
12

xautocfg

Automatic keyboard repeat rate configuration for new keyboards
C++
18
star
13

sftscrollbugfixer

Fix the Age of Empires II (TC, HD, DE) scroll bug with a DLL injection
C++
13
star
14

cyberbot

Chatbot for the Matrix Protocol, supporting encryption and plugins.
Python
13
star
15

emacs-elaiza

Chat interface and library for interacting with different LLMs via Emacs.
Emacs Lisp
11
star
16

ceph-mount

Pure-Python CephFS mount helper
Python
7
star
17

openage-pr

openage website and public relations content
CSS
7
star
18

gentoo-overlay

sft overlay - Gentoo package overlay for SFT projects and more 🐧
Shell
6
star
19

splash

gtk3 python speedreading program
Python
6
star
20

sftbackup

simple periodic backup tool based on borgbackup and snapper
Python
6
star
21

abrechnung-legacy-2a

payment and debt management tool for semi-enterprise-grade resource planing. superseeded by https://github.com/SFTtech/abrechnung
JavaScript
5
star
22

aiomatrix

Matrix client API for Python asyncio
Python
4
star
23

starlit-emacs

Deep blue and colorful emacs theme like a clear night sky πŸŒƒ
Emacs Lisp
4
star
24

openage-data-3dmodels

3d models for openage assets
4
star
25

openage-modding

openage content creation guidelines
Python
4
star
26

cooputils

When working in a shell collaboratively using tmux, this collection of scripts can be used to automatically switch to a 'coop' user and choose a TMUX session.
Python
4
star
27

openage-debian

Debian packaging files for openage
3
star
28

openage-blog

Development blog for openage
CSS
3
star
29

sftmake

simple make system in python
Python
3
star
30

sftkit

Software Development Kit for SFT projects
TypeScript
2
star
31

sftbot

State of the art artificial intelligence to perform various cutting-edge cloud-based enterprise tasks.
2
star
32

openage-webdoc

openage online documentation
HTML
2
star
33

sftutils

shell utilities to complement coreutils, moreutils and beyond
Python
2
star
34

factorioplanner

Web interface for planning factories in factorio
1
star
35

kerbmath

mathematic helper software for kerbal space program
Python
1
star
36

dirtreeflattener

Useful when organizing huge directory structures. Unpacks archives and removes unnecessary subdirectory layers.
Python
1
star
37

kicad-lib

Common KiCAD lib for SFT hardware projects
Python
1
star
38

nyan-vscode

Visual Studio Code extension for creating nyan code
1
star
39

flow3rtron

Tron for the CCC Flow3r
Python
1
star
40

openage-kevin

kevin environment for building openage
1
star
41

kevin-win-setup

Tools to automatically download and prepare a free Windows VM for kevin.
Makefile
1
star