Deployment guide

BIND 9

Overview

BIND 9 (ISC BIND) is the most widely deployed DNS software on the internet, maintained by Internet Systems Consortium (ISC). It is a full-featured authoritative DNS server, and optionally a recursive one, with DNSSEC, zone management and the rndc control channel. This guide covers deploying and configuring the SecureAnyCloud BIND 9 image on Ubuntu 24.04 on Azure.

The image installs the current stable ESV branch, BIND 9.20, from the official ISC packages (the ISC ppa:isc/bind repository), not the Ubuntu archive bind9 package. The Ubuntu 24.04 archive ships the 9.18 branch, which reached ISC upstream end of life in 2026. This image deliberately ships a supported, actively patched branch, and unattended security upgrades keep the 9.20 branch patched on your running VM.

Secure by design: not an open resolver. An open recursive resolver resolves arbitrary names for anyone on the internet, which makes it a well-known vector for DNS amplification and reflection DDoS attacks. This image ships as a pure authoritative server with recursion switched off, so no client, local or remote, can use it to resolve external names recursively. A recursive query for an external name such as google.com is answered with REFUSED.

The configuration also sets version none so the BIND version is not leaked, disables zone transfers by default, and enables response rate limiting to blunt amplification abuse. You can enable recursion for your own trusted networks when you need it (see Step 9).

Secure by design: a per-instance control key. The rndc control key works like a remote-control password for the DNS server, so this image never ships a fixed control key. On the first boot of every VM, a fresh per-instance rndc key (hmac-sha256) is generated, and the control channel is bound to 127.0.0.1 port 953 only. The key details are written to /root/bind-credentials.txt (mode 0600, root only).

What you get:

  • BIND 9.20 (current stable ESV) from the official ISC packages, run under systemd as the unprivileged bind user (named.service)
  • Responsible non-open-resolver defaults: recursion no, allow-recursion { none; }, version none, allow-transfer { none; } and response rate limiting
  • One example authoritative zone (example.internal), so dig @<server> www.example.internal resolves to 10.0.0.20 out of the box, plus a documented template for adding your own zones
  • A per-instance rndc control key generated on first boot, with the control channel bound to 127.0.0.1:953 only and documented in /root/bind-credentials.txt (0600)
  • Zone files, DNSSEC keys and journals on a dedicated 20 GiB Azure data disk mounted at /var/lib/bind, so authoritative data survives independently of the OS disk and the volume can be resized independently
  • A minimal nginx on port :80 that serves only an unauthenticated /healthz endpoint (HTTP 200) for Azure Load Balancer health probes. It is not a DNS management UI.
  • Ubuntu 24.04 LTS base with the latest security patches applied at build time, and unattended security upgrades kept enabled (including the ISC repository)
  • Azure Linux Agent for cloud integration and SSH key injection
  • 24/7 SecureAnyCloud support with a guaranteed 24-hour response SLA

Prerequisites

You need an active Azure subscription, an SSH public key, and a VNet with a subnet in the target region.

Subscribe to the BIND 9 listing on Azure Marketplace.

Create Network Security Group rules that allow TCP 22 (administration) and both UDP and TCP 53 (DNS) from the clients that will query the server.

Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM) for a small authoritative server. Use Standard_D2s_v5 or larger for servers that answer heavy query volumes.

1

Deploy from the Azure Portal

Search for BIND 9 in the Marketplace, select the SecureAnyCloud publisher, and select Create.

Configure the Network Security Group to allow UDP 53 and TCP 53 (DNS) from your client networks, and TCP 22 for administration. DNS uses UDP 53 for most queries and falls back to TCP 53 for large responses and zone transfers, so open both.

2

Deploy from the Azure CLI

RG="dns-prod"; LOCATION="eastus"; VM_NAME="ns1" IMAGE_URN="sac1647283583153:bind9-ubuntu-24-04:default:latest" SSH_KEY="$(cat ~/.ssh/id_rsa.pub)" az group create --name "$RG" --location "$LOCATION"
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:bind9-ubuntu-24-04:default:latest
az vm create \
  --resource-group "$RG" --name "$VM_NAME" \
  --image "$IMAGE_URN" \
  --size Standard_B2s \
  --admin-username azureuser \
  --ssh-key-values "$SSH_KEY" \
  --public-ip-sku Standard

Open the DNS and administration ports on the VM's NSG:

az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 53 --priority 1001
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 22 --priority 1002
3

First boot

On first boot, the image resolves the VM public IP and generates a fresh per-instance rndc control key. It verifies the responsible defaults, starts named, and proves that the example zone answers and that the server is not an open resolver. It then writes /root/bind-credentials.txt. This completes within a minute.

SSH in as azureuser and read the details:

sudo cat /root/bind-credentials.txt
4

Confirm the services are running

Confirm that named.service (the BIND daemon) and nginx.service (the health probe) are both active. rndc status reports the server as up, using the per-instance control key. ss confirms that DNS is listening on :53 and that the rndc control channel is bound to 127.0.0.1:953 only.

systemctl is-active named.service nginx.service
sudo rndc status
5

Query the example authoritative zone

The image ships one example authoritative zone, example.internal, so a DNS round trip works immediately. Query it against the loopback address, or against the VM public IP from a client. The aa flag in the header confirms an authoritative answer.

dig @127.0.0.1 www.example.internal dig @127.0.0.1 example.internal SOA +short dig @127.0.0.1 example.internal MX +short dig @127.0.0.1 example.internal TXT +short
6

Review the configuration and responsible defaults

The configuration lives in /etc/bind. named-checkconf validates the whole configuration, and no output means it is valid. The options file locks the server down so that it is not an open resolver.

named -v sudo named-checkconf grep -E 'recursion|allow-recursion|version|allow-transfer|responses-per-second' /etc/bind/named.conf.options
7

Verify the server is not an open resolver

This is the key security property: a recursive query for an external name must be REFUSED. Also confirm that the per-instance rndc key file is present with 0640 root:bind permissions and that the zone data lives on the dedicated data disk.

dig @127.0.0.1 google.com
sudo stat -c '%n %a %U:%G' /etc/bind/rndc.key findmnt /var/lib/bind
8

Add your own authoritative zone

Create a zone file on the data disk and register it in /etc/bind/named.conf.local. For example, create the zone file to serve mycompany.example:

sudo tee /var/lib/bind/db.mycompany.example >/dev/null <<'ZONE' $TTL 3600 @ IN SOA ns1.mycompany.example. admin.mycompany.example. ( 2026071001 3600 900 604800 3600 ) @ IN NS ns1.mycompany.example. ns1 IN A 203.0.113.10 www IN A 203.0.113.20 ZONE
sudo chown bind:bind /var/lib/bind/db.mycompany.example

Add the zone to /etc/bind/named.conf.local, where a commented template is already in place. Then check the configuration and reload:

sudo named-checkconf
sudo named-checkzone mycompany.example /var/lib/bind/db.mycompany.example
sudo rndc reload
9

Enable recursion for your own networks (optional)

If you want this server to also act as a resolving (caching) DNS server for your own trusted clients, edit /etc/bind/named.conf.options and set the following:

recursion yes; allow-recursion { localhost; localnets; 10.0.0.0/8; };

Replace 10.0.0.0/8 with your own trusted client ranges. Never use allow-recursion { any; };, because it turns the server back into an open resolver. Apply the change with sudo named-checkconf && sudo rndc reload.

10

Manage named with rndc

The rndc control channel uses the per-instance key and is bound to loopback. Common operations:

sudo rndc status
sudo rndc reload
sudo rndc reconfig
11

Security recommendations

Restrict the NSG. Allow UDP and TCP 53 only from the client networks that need to query the server, and TCP 22 for administration only.

Keep recursion off unless you need it. If you enable it, scope allow-recursion to your own networks (Step 9), and never to any.

Add DNSSEC signing to production authoritative zones (dnssec-policy) so that resolvers can validate your answers. Keys are stored on the data disk under /var/lib/bind.

Add secondary servers. For resilience, configure secondaries and scope allow-transfer to their addresses instead of { none; }.

Keep the OS and BIND patched. Unattended security upgrades remain enabled on the running VM, including the ISC repository for the 9.20 branch.

Back up /var/lib/bind (the data disk) to preserve your zone files and DNSSEC keys.

12

Support and Licensing

BIND 9 is developed by Internet Systems Consortium (ISC) and distributed under the Mozilla Public License 2.0 (MPL-2.0). This SecureAnyCloud image bundles the unmodified official ISC packages.

SecureAnyCloud provides the packaging, the non-open-resolver hardening, the per-instance rndc key automation, the example zone, and 24/7 support with a guaranteed 24-hour response SLA.

SecureAnyCloud is not affiliated with or endorsed by Internet Systems Consortium (ISC). BIND is a mark of its respective owner and is used here only to identify the software.

Deploy on Azure

Find BIND 9 on Ubuntu 24.04 LTS on the Azure Marketplace, published by SecureAnyCloud. Deploy from the Portal or the Azure CLI as shown above.

Need Help?

Email sales@secureanycloud.com for deployment help, configuration questions or licensing inquiries.

Deploy on Azure

Launch BIND 9 (ISC BIND) 9.20 on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure