Debian put out two DNS advisories in the same week. DSA-6505-1 for bind9 came out on 2026-09-17 and DSA-6507-1 for unbound followed on 2026-09-19. If a Debian 13 box runs a recursive resolver for your LAN, VPN, containers or your mail server's DNSBL lookups, it probably uses one of these two packages. The Unbound advisory mentions possible code execution in the DNSSEC validator. This is one checklist for the BIND9 and Unbound security updates: find which resolver you run, check whether it's reachable from outside, patch it, and confirm that the running daemon is the fixed build.
What happened: BIND9 and Unbound security updates in Debian 13
DSA-6505-1: bind9
ISC published a batch of BIND 9 advisories on 2026-09-16, and the fixes are in BIND 9.20.29 and 9.21.26. Debian released the trixie update the next day. The DSA says the flaws "may result in denial of service or cache poisoning". The Debian security tracker lists 14 CVEs for DSA-6505-1, all fixed in 1:9.20.29-1~deb13u1. Whichever count you go by, the fix is the same package.
Two of the ISC advisories show what's in the batch:
- CVE-2026-81736: remote CPU denial of service through cached SVCB/HTTPS AliasMode trees. ISC rates it CVSS 7.5 (High),
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H. It only affects resolvers, and ISC lists no workaround. - CVE-2026-19033: on a secondary zone protected by TSIG,
namedcan start serving transferred data before the final TSIG-signed message arrives. ISC rates it CVSS 6.5 (Medium),CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:L. This one affects authoritative secondaries too, so the update applies to you even if your BIND doesn't recurse.
DSA-6507-1: unbound
The Unbound DSA covers 34 CVEs according to the Debian tracker, and the description names denial of service, cache poisoning, DNS cookie bypass and possible arbitrary code execution. Trixie moves from Unbound 1.22.0 to upstream 1.26.1. The update includes fixes from the NLnet Labs releases 1.25.1 (2026-05-20), 1.25.2 (2026-07-22) and 1.26.1 (2026-09-16). Not every advisory from those releases is on the DSA's CVE list, so check the DSA-6507-1 tracker page for the exact list. NLnet Labs rates these highest:
- CVE-2026-81642 (Critical): heap buffer overflow and possible remote code execution when digesting a DNSKEY. It hits the DNSSEC validator. An attacker needs a zone they control and a way to make your resolver query it, which an open resolver hands them.
- CVE-2026-81634 (High): possible heap buffer overflow during DNSSEC canonicalisation.
- CVE-2026-82717 (High): CNAME synthesis can lead to heap corruption.
- CVE-2026-44690 (High): cross-zone wildcard cache poisoning by manipulating RRSIG labels.
- CVE-2026-40691 and CVE-2026-32665 (High): denial of service in DNSCrypt over TCP and DNS-over-QUIC.
NLnet Labs doesn't publish numeric CVSS base scores for these. Its advisories page links each severity label to a CVSS vector, and the vectors are a mix of v3.1 and v4.0. For example, CVE-2026-44690 (High) is CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N.
Who is affected
On Debian 13 (trixie), you're affected if the installed version is lower than the fixed version in this table:
| Source package | Vulnerable (trixie) | Fixed (trixie-security) | Upstream fix |
|---|---|---|---|
| bind9 | 1:9.20.26-1~deb13u1 | 1:9.20.29-1~deb13u1 | BIND 9.20.29 |
| unbound | 1.22.0-2+deb13u3 | 1.26.1-0+deb13u1 | Unbound 1.26.1 |
Debian 12 (bookworm) isn't covered by these DSAs. On 2026-09-24 the Debian security tracker still marked bookworm's bind9 (1:9.18.49-1~deb12u2) as vulnerable to all 14 CVEs of DSA-6505-1, and bookworm's unbound (1.17.1-2+deb12u4) as vulnerable to all 34 CVEs of DSA-6507-1. 12 of the 14 ISC advisories list BIND 9.18 up to 9.18.50 as affected, and none of them names a patched 9.18 release: all 14 are fixed in 9.20.29. If you still run a resolver on bookworm, treat it as unpatched. Move it to trixie, or at least make sure only trusted clients can reach it (see the hardening section).
How to check your systems
Which resolver is installed?
dpkg -l 'bind9*' 'unbound*' 'libunbound*' | grep '^ii'
apt policy bind9 unboundIn apt policy, compare Installed with Candidate. If the candidate is the fixed version but it's not installed yet, your security repository is set up correctly. If the candidate is still the old version, check that trixie-security is in your sources and run apt update.
To compare versions in a script, let dpkg do the comparison:
v=$(dpkg-query -W -f='${Version}' bind9 2>/dev/null)
if [ -n "$v" ] && dpkg --compare-versions "$v" lt '1:9.20.29-1~deb13u1'; then echo "bind9 $v is VULNERABLE"; fi
v=$(dpkg-query -W -f='${Version}' unbound 2>/dev/null)
if [ -n "$v" ] && dpkg --compare-versions "$v" lt '1.26.1-0+deb13u1'; then echo "unbound $v is VULNERABLE"; fiWhat is listening on port 53?
ss -tulpn 'sport = :53'A resolver that only listens on loopback looks like this:
udp UNCONN 0 0 127.0.0.1:53 0.0.0.0:* users:(("unbound",pid=812,fd=5))
tcp LISTEN 0 256 127.0.0.1:53 0.0.0.0:* users:(("unbound",pid=812,fd=6))If you see 0.0.0.0:53, [::]:53 or a public address, the daemon accepts packets on every interface or on that public address. That doesn't prove it answers recursive queries from anyone, but it means you have to test. Also check the other ports Unbound can use for encrypted DNS (853 for DoT/DoQ, 443 for DoH) if you've enabled them.
Is it an open resolver?
Test from a machine outside your network, such as a different VPS or a phone hotspot. Replace the address with your server's public IP:
dig @203.0.113.10 debian.org A +norecurse +short
dig @203.0.113.10 debian.org ALook at the status: field and the flags. REFUSED (or a timeout) is what you want. NOERROR with an answer and the ra flag means anyone on the internet can use your resolver. You're then a DDoS amplifier, and every remote bug in the tables above can be triggered by strangers.
Fix: patch, restart and verify
Upgrade the packages
apt update
apt install --only-upgrade bind9 bind9-libs bind9-utils bind9-dnsutils bind9-host
apt install --only-upgrade unbound libunbound8 unbound-anchor--only-upgrade skips packages that aren't installed, so you can run both lines on any host. A plain apt upgrade works too.
The Unbound update jumps from 1.22 to 1.26, so validate your config before and after the upgrade. Options behave differently across four upstream releases, and a config error means no DNS:
unbound-checkconf
named-checkconfRestart and check with needrestart
Warning: restarting the resolver drops the cache and breaks name resolution for its clients until it's back up. If the host itself uses this resolver in /etc/resolv.conf, everything on it that needs DNS will fail during that window. On a remote box, run the config check above first, because a resolver that won't start takes out DNS for all its clients. Keep a console or out-of-band access available.
systemctl restart named
systemctl restart unbound
systemctl status named unbound --no-pagerRestart only the service you actually run. In trixie the BIND unit is named.service. The package scripts normally restart the daemon during the upgrade, but don't rely on that. Check whether anything is still running old library code:
needrestart -r l-r l only lists what needs a restart and doesn't restart anything. This matters because libunbound8 and bind9-libs are shared libraries. Other daemons that link against them keep running the old code until you restart them.
Confirm the running version
The installed package version isn't enough. Ask the running daemon:
named -v
unbound -V | head -n 1
dig @127.0.0.1 version.bind CHAOS TXT +short
systemctl show -p ActiveEnterTimestamp named unboundnamed -v and unbound -V read the binary on disk. The CHAOS query goes to the process that's actually running. If you've hidden the version (version in BIND, hide-version: yes in Unbound), the query returns nothing. In that case, check that ActiveEnterTimestamp is later than the upgrade.
Check DNSSEC validation and the cache
dig @127.0.0.1 debian.org SOA +dnssecThe header should show status: NOERROR and the ad flag:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4711
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1No ad flag means the resolver isn't validating. Fix that, because several of these CVEs are in the validation code and so is most of the protection against spoofed data. A restart already empties the in-memory cache. If you applied the update with a reload, or you suspect the cache was poisoned before you patched, flush it explicitly:
rndc flush
unbound-control flush_bogus
unbound-control reloadunbound-control reload flushes the cache and re-reads the config. It only works if control-enable is set and the keys from unbound-control-setup exist. rndc flushtree example.com and unbound-control flush_zone example.com remove one name and everything below it.
Hardening: keep recursion private
The fix is the patch. Limiting who can send queries means the next Unbound or BIND bug can only be triggered by your own clients. The defaults are safer than you might expect, but they're easy to open up by accident:
- Unbound listens on localhost if no
interface:is set. By defaultaccess-controlonly allows 127.0.0.0/8 and refuses everyone else. Problems usually start with someone addinginterface: 0.0.0.0and anallowrule that's too broad. - BIND defaults
allow-recursionandallow-query-cachetolocalhost; localnets;.localnetsmeans every network the host has an interface on. On a VPS with a public /24 on eth0, that's your neighbours on the provider network. Set it explicitly.
server:
interface: 127.0.0.1
interface: 10.8.0.1
access-control: 127.0.0.0/8 allow
access-control: 10.8.0.0/24 allow
access-control: 0.0.0.0/0 refuse
hide-version: yesFor BIND, define the acl at the top level of /etc/bind/named.conf.options, outside the options { ... }; block, and merge the three lines into your existing options block:
acl trusted { 127.0.0.1; ::1; 10.8.0.0/24; };
options {
allow-recursion { trusted; };
allow-query-cache { trusted; };
version none;
};Don't add a second options block; named accepts only one. Run named-checkconf before you reload. Then add a firewall rule so port 53 isn't reachable from the internet at all, and repeat the external dig test. The same rules for exposing services apply here as in web server security basics for self-hosters. Because a resolver parses untrusted packets all day, it's also a good candidate for the unit-file restrictions described in sandboxing systemd services on Debian 13. Test any sandbox drop-in on a non-production host first, because named needs write access to its zone and cache directories.
What to watch next
- Bookworm: watch the tracker pages for
bind9andunbound. When I checked, both were still marked vulnerable on Debian 12. - Regressions: Unbound moves several upstream versions in one step. A follow-up
DSA-6507-2wouldn't be surprising, so subscribe to debian-security-announce or runapt list --upgradablefrom a timer. - Other packages:
needrestartwill show anything else linked againstlibunbound8. Restart those services too.
Takeaways
- Check
apt policy bind9 unbound. On Debian 13 you need 1:9.20.29-1~deb13u1 or 1.26.1-0+deb13u1. - Run
unbound-checkconfornamed-checkconfbefore restarting, and have console access ready. - Restart the daemon, run
needrestart -r l, and confirm the running version with the CHAOS query or the unit start time. - Check that DNSSEC validation works (
adflag) and flush the cache if you have any doubt. - Run
ss -tulpn 'sport = :53'and test withdigfrom outside. Any answer other than REFUSED means you need to lock down recursion. - Set explicit recursion ACLs. Don't rely on BIND's
localnetsdefault on a public VPS. - Debian 12 hosts are still vulnerable according to the tracker. Upgrade them or firewall them.
Sources
- [SECURITY] [DSA 6505-1] bind9 security update
- [SECURITY] [DSA 6507-1] unbound security update
- Debian Security Tracker: DSA-6505-1
- Debian Security Tracker: DSA-6507-1
- Debian Security Tracker: bind9
- Debian Security Tracker: unbound
- Debian Security Tracker: CVE-2026-19033
- Debian Security Tracker: CVE-2026-82720
- ISC: CVE-2026-19033
- ISC: CVE-2026-81736
- ISC: BIND 9 Security Vulnerability Matrix
- NLnet Labs: Unbound security advisories
- NLnet Labs: CVE-2026-81642
- NLnet Labs: CVE-2026-82720
- unbound.conf(5) — Debian trixie
- unbound-control(8) — Debian trixie
- rndc(8) — Debian trixie
- needrestart(1) — Debian trixie
- BIND 9.20.29 Configuration Reference
Comments