Home / Alt manpages / nsupdate(1)

  • nsupdate(1)
  • User command
  • linux

Safely Add and Remove DNS Records with nsupdate

You will finish with a repeatable way to submit one authenticated Dynamic DNS update, check that the change reached the zone, and avoid exposing the TSIG secret in shell history or 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.

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. This 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 that 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.

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 that it contains no sensitive key material.

6. Understand transport and common traps

nsupdate normally uses UDP and switches to TCP when an update is too large. Use -v to force TCP, which can be useful for 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.

Do not edit a dynamically managed zone file by hand. Manual edits can conflict with updates and lose data. Also check that every record belongs to the same zone: one request cannot update records across different zones. If you omit zone, nsupdate tries to discover the correct zone from the input, but spelling it explicitly makes a reviewable batch easier to audit.

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 itself as narrow as possible. Privilege does not grant DNS update permission; the server's update policy and TSIG identity decide that.

Done means

  • You confirmed the installed BIND 9.18.39 nsupdate version.
  • You used a protected key file or the intentionally local -l mode, and did not expose a real secret with -y.
  • Your batch names one zone and sends one reviewed request.
  • Any deletion was deliberate, and you have a restoration record if it matters.
  • Prerequisites protect names where a race or CNAME conflict would be harmful.
  • You queried the authoritative server and confirmed the resulting owner, type, TTL and value.