Hello all
A Very old topic, I know, but if it can help someone…
I already did that a long time ago (with IPCop in fact, so a very looong time ago), and I had to do it again. I had to search a little bit in my memory, IPFires files and the Internet, so I came here… disappointed. I need to work a bit more… 
You’ll find good information (quite old anyway) on ‘Jurassic blog’ from François (in french)
Here’s a solution
working with IPFire vanilla.
Suppose my domain is holmes.tld, with a working dyn.holmes.tld subdomain dedicated, and a working bakerst.dyn.holmes.tld subsubdomain
I want to update the IP of bakerst.dyn.holmes.tld
On my DNS server (bind9 on debian 12)
Generating key
I did that with a TSIG HMAC-MD5 key (don’t know if there could be security problems with this algorithm) generate with tsig-keygen
(note the trailing dot in the command and the key name). Not sure it will work with other algorithms as I can’t specify which one to use on IPFire.
# tsig-keygen -a HMAC-MD5 bakerst.dyn.holmes.tld.
key “bakerst.dyn.holmes.tld.” {
algorithm hmac-md5;
secret “kaHQJpDtt+h2nBrfGinFxg==”;
};
You’ll find a lot of docs talking about dnssec-keygen
, but it is not used anymore for dynamic dns keys generation as explained in man :
In prior releases, HMAC algorithms could be generated for use as TSIG keys, but that feature was removed in BIND 9.13.0. Use
tsig-keygen
to generate TSIG keys.
Copy the result in a file in /etc/bind
(for example) named as you want (you can have more than a key)
# tsig-keygen -a HMAC-MD5 bakerst.dyn.holmes.tld. >> /etc/bind/dynamic.keys
# cat /etc/bind/dynamic.keys
key “bakerst.dyn.holmes.tld.” {
algorithm hmac-md5;
secret “kaHQJpDtt+h2nBrfGinFxg==”;
};
Bind config
Change permissions on the file : root:bind
and 640
are far enough, then add the key(s) in bind
’s config with an “include
”. For example, just add that line at the end of /etc/bind/named.conf
include “/etc/bind/dynamic.keys”;
Debian allow /var/lib/bind to store dynamics configs and everything work smoothly. As I’m using ISPConfig to deal with DNS, I can’t force bind to store configs elsewhere than in /etc/bind (actually). So, I need to change apparmor
’s named
config to allow bind
to read and write pri.dyn.*
files (pri
is for primary DNS configs in ISPConfig, may be you’ll have different prefixes, dyn
is because I choose dyn
as dedicated subdomain for all my domains) and *.jnl
files (the journal files are already in pri.dyn.*
). Edit /etc/apparmor.d/user.sbin.named
(bind
usage is around line 20) and add
/etc/bind/pri\.dyn\.* rw,
Then restart apparmor
and bind
. That should do the job.
From elsewhere (a debian host with bind installed)
Testing the DNS server
# dig +short bakerst.dyn.holmes.tld
123.45.67.89
123.45.67.89 come from your ‘A’ record
TSIG keys are symmetric. From DNS server copy the dynamic.keys
file somewhere (/etc/bind/
is a good choice) and check permissions.
test connection with nsupdate
in manual mode with -v
add zone
and update
accordingly, then show
will preview and send
ask the server. Note the trailing dots in the “… SECTION”
# nsupdate -k /etc/bind/dynamic.keys -v
> zone dyn.holmes.tld
> update add bakerst.dyn.holmes.tld. 30 A 0.0.0.0
> show
Outgoing update query:
;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 0
;; flags:; ZONE: 0, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0
;; ZONE SECTION:
;dyn.holmes.tld. IN SOA
;; UPDATE SECTION:
bakerst.dyn.holmes.tld. 30 IN A 0.0.0.0
> send
> quit
If send doesn’t react more, then everything is working from this point.
# dig +short bakerst.dyn.holmes.tld
123.45.67.89
0.0.0.0
0.0.0.0
has been added
remove 0.0.0.0
with an ‘update delete
’ in place of the ‘update add
’
# dig +short bakerst.dyn.holmes.tld
123.45.67.89
0.0.0.0
has been removed
From IPFire server
Dynamic DNS service
check “Guess the real public IP…” unless your modem is bridged.
add a host with :
Service is “nsupdate”
Hostname MUST be bakerst.dyn.holmes.tld
Username MUST be bakerst.dyn.holmes.tld.
(WITH a trailing dot)
Password MUST be kaHQJpDtt+h2nBrfGinFxg==
(WHITOUT double quotes, WITHOUT algorithm)
Check “enable” box
et voilà ! Read the logs to see if everything works
if it doesn’t start, try ddns -d update-all --force
It will give more information on transactions
[…]
Registered new provider: Zoneedit (``zoneedit.com``)
Registered new provider: zzzz (``zzzz.io``)
Running on distribution: ipfire-2
Loading configuration file /var/ipfire/ddns/ddns.conf
Updating bakerst.dyn.holmes.tld forced
Sending request (GET): ``https://checkip4.dns.lightningwirelabs.com
Request header:
User-agent: IPFireDDNSUpdater/014
Pragma: no-cache
Response header (Status Code 200):
date: Thu, 21 Aug 2025 12:56:10 GMT
upgrade: h2,h2c
connection: Upgrade
x-content-type-options: nosniff
x-frame-options: deny
referrer-policy: strict-origin
x-xss-protection: 1; mode=block
content-length: 35
content-type: text/plain
strict-transport-security: max-age=31536000; includeSubDomains; preload
Scriptlet:
key **** ****
update delete bakerst.dyn.holmes.tld. A
update add bakerst.dyn.holmes.tld. 60 A 156.78.91.232
send
quit
Dynamic DNS update for bakerst.dyn.holmes.tld (BIND nsupdate utility) successful
Logging successful update for bakerst.dyn.holmes.tld
Opening database /var/lib/ddns.db