Home / Alt manpages / nsupdate(1)

  • nsupdate(1)
  • User command
  • linux

Add and Remove DNS Records Safely with nsupdate

One wrong nsupdate batch can wipe a live A record in seconds. This guide gets you a repeatable way to submit one authenticated Dynamic DNS update, check it landed, and keep the TSIG secret out of shell history and process listings. The examples match nsupdate from BIND 9.18.39, installed here as package bind9-dnsutils version 1:9.18.39-0ubuntu0.24.04.7.

Allow about fifteen minutes, plus whatever time your DNS administrator needs to provide an authorised key and confirm the target zone. You need a shell, permission to update the zone, a TSIG key file or local BIND access, and a DNS lookup tool for verification. These commands change live DNS data: do not run the update examples against a production name until you have checked every name, address, TTL and deletion.

1. Check the installed command

Start with read-only checks. They need no elevated privileges and confirm which binary and version will handle the update:

$ command -v nsupdate
/usr/bin/nsupdate
$ nsupdate -V
nsupdate 9.18.39-0ubuntu0.24.04.7-Ubuntu

The exact version line can include distribution text. The useful checkpoint is that it reports BIND 9.18.39. An update request is sent to the zone's primary server, identified by the zone SOA MNAME, unless the input selects a server explicitly.

2. Choose authentication without leaking a secret

For a remotely managed zone, prefer -k KEYFILE. The file can contain a named.conf-format key statement, or a DNSSEC key pair in the documented K{name}.+157.+{random} form. Check its permissions and pass its path as an ordinary argument:

$ KEYFILE='/path/to/ddns-update.key'
$ test -r "$KEYFILE" && echo 'key file is readable'
key file is readable
$ nsupdate -k "$KEYFILE"

The last command opens interactive mode. It is shown here only to explain the option; press Ctrl-D at an empty prompt if you started it accidentally. In a real batch, provide the complete input through a file or standard input as shown later.

Security warning

Do not put a real secret in -y unless you have a controlled reason. Its format is [hmac:]keyname:secret, and the clear-text argument can appear in ps output or shell history. A key file avoids that particular exposure. Protect the file as a credential and do not paste it into tickets, logs or an article.

For a BIND server configured with update-policy local;, nsupdate -l selects localhost and the TSIG key in /run/session.key. That mode cannot be redirected to another server with a server input command: it is local administrative access, not a general-purpose remote update method.

3. Build one small update request

Use a temporary input file with placeholders replaced by values approved for your zone. This example replaces an A record and adds a new one. The zone line removes ambiguity; the server line is optional when normal SOA discovery is correct.

$ cat > /tmp/nsupdate-request.txt <<'EOF'
server dns-primary.example.net
zone example.net.
ttl 300
update delete oldhost.example.net. A
update add newhost.example.net. 300 A 192.0.2.44
send
EOF
$ nsupdate -k "$KEYFILE" /tmp/nsupdate-request.txt
$ status=$?
$ printf 'nsupdate status: %s\n' "$status"
nsupdate status: 0

Each input command occupies one line. The send line submits the accumulated prerequisites and updates as one DNS UPDATE message; a blank line does the same thing. The default class is IN, and the default TTL applies to records added later unless an update add line supplies its own TTL.

Destructive action

update delete oldhost.example.net. A removes every A record at that name. It does not remove other record types. To remove one exact record, include its data, for example update delete oldhost.example.net. 0 IN A 192.0.2.44; the TTL is ignored but accepted for compatibility. If you need an undo path, save the current record value first and prepare an update add request that restores it.

Keep the temporary file private while it contains operational names or key-related material. Remove it after checking the result with rm -- /tmp/nsupdate-request.txt; that deletion is irreversible, so do not use it until you have retained any recovery data you still need. The file in this example contains no secret because the key is supplied separately.

4. Add a prerequisite when a name must be unused

DNS names cannot be both a CNAME and an ordinary record set. Before creating a CNAME, require the name to have no records of any type:

$ cat > /tmp/nsupdate-cname.txt <<'EOF'
zone example.net.
prereq nxdomain nickname.example.net.
update add nickname.example.net. 300 CNAME somehost.example.net.
send
EOF
$ nsupdate -k "$KEYFILE" /tmp/nsupdate-cname.txt
nsupdate status: 0

The prerequisite is evaluated by the authoritative server. If the name already exists, the complete request fails and the CNAME is not added. That is safer than checking with a separate lookup and racing another writer. Do not treat a non-zero status as harmless: inspect the server, zone, key policy and exact owner name before trying again.

5. Verify the authoritative result

A zero exit status means nsupdate completed its request successfully. Confirm the record at the authoritative server, rather than relying only on a recursive cache:

$ dig @dns-primary.example.net newhost.example.net. A +noall +answer
newhost.example.net. 300 IN A 192.0.2.44

Your output may show a different remaining TTL because authoritative servers decrement it while the record is cached. Check that the owner name, type and value are correct. If a resolver still returns the old answer, query the primary first and allow existing caches to expire; do not immediately submit repeated updates.

Tip

For a request that fails, add -d to enable update tracing, or use the input command show before send to inspect the message that will be sent. Avoid sharing debug output until you have checked it contains no sensitive key material.

Common traps

  • Hand-editing the zone file. A dynamically managed zone should not be edited by hand: manual edits can conflict with updates and lose data.
  • Spanning more than one zone. One request cannot update records across different zones; check that every record in a batch belongs to the same zone.
  • Skipping the zone line. If you omit it, nsupdate tries to discover the correct zone from the input, but spelling it explicitly makes a reviewable batch easier to audit.
  • Using sudo out of habit. No sudo is normally required. Use elevated privileges only when your local key file or the BIND session key is deliberately readable only by a privileged account, and keep the command as narrow as possible: privilege does not grant DNS update permission, the server's update policy and TSIG identity decide that.

nsupdate normally uses UDP and switches to TCP when an update is too large. Use -v to force TCP, which can help with a batch of updates or a network path that handles TCP more reliably. Use -4 or -6 when testing a specific address family. These options change transport selection, not zone authorisation.

Done means

  • Version confirmed: you checked the installed BIND 9.18.39 nsupdate version.
  • Secret protected: you used a protected key file or the intentionally local -l mode, and did not expose a real secret with -y.
  • One reviewed batch: your batch names one zone and sends one reviewed request.
  • Deletion deliberate: any deletion was intentional, and you have a restoration record if it matters.
  • Prerequisites set: they protect names where a race or CNAME conflict would be harmful.
  • Result verified: you queried the authoritative server and confirmed the resulting owner, type, TTL and value.