dnsmasq
Overview
This guide shows you how to deploy and configure dnsmasq on Ubuntu 24.04 on Azure with the SecureAnyCloud Azure Marketplace image. dnsmasq is a small, widely deployed network infrastructure daemon. It combines a caching DNS forwarder, a DHCP server and a TFTP boot server in a single lightweight package. It suits local networks, edge sites, labs and container hosts that need name resolution and address assignment without heavyweight services.
The image installs dnsmasq 2.90 from the Ubuntu 24.04 archive and configures it as a secure-by-default caching DNS forwarder. Unattended security upgrades remain enabled on the running VM, so the package keeps receiving patches.
Not an open resolver. An open recursive or forwarding resolver resolves arbitrary names for anyone on the internet. Such a resolver is a well-known DNS amplification and reflection DDoS vector. This image ships with dnsmasq's local-service mode, so the server answers DNS only for hosts whose source address is on a local subnet of this VM. A query that arrives from the public internet is silently dropped, never answered and never reflected. The server therefore cannot be abused as an amplifier.
The forwarder also sets domain-needed and bogus-priv, so unqualified names and private reverse lookups are never sent upstream. It sets no-resolv with an explicit upstream list (1.1.1.1, 9.9.9.9).
DHCP and TFTP are off by default. dnsmasq can also serve DHCP and TFTP. Running a DHCP server on a network you do not own is a rogue DHCP hazard, and an open TFTP root is a data exfiltration vector. This image therefore ships with neither enabled, with no dhcp-range and no enable-tftp. You turn them on deliberately for your own network (see Step 9 and Step 10).
No bootstrap credential. dnsmasq has no login or admin password of any kind. You configure it entirely through files under /etc/dnsmasq.d/. There is nothing to leak, so no shared secret ships in the image.
What you get:
dnsmasq2.90 from the Ubuntu 24.04 archive, run under systemd as the unprivileged dnsmasq user (dnsmasq.service).- A secure caching DNS forwarder configuration:
local-service(not an open resolver),no-resolvwith explicit upstreams,domain-needed,bogus-privand a response cache. - A shipped local example record (
ns.dnsmasq.internalresolves to10.0.0.53), so a DNS round trip works out of the box even before any upstream is reachable. - DHCP and TFTP present in the daemon but disabled by default, with a documented opt-in for your own network.
- The systemd-resolved stub listener disabled, so dnsmasq owns port 53 while the host still resolves names through its own upstreams.
- An Ubuntu 24.04 LTS base with the latest security patches applied at build time, and unattended security upgrades kept enabled.
- The 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 and subnet in the target region.
You also need a subscription to the dnsmasq listing on Azure Marketplace.
Add network security group rules that allow TCP 22 (admin) 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) is ample for a caching forwarder that serves a local network. Sites with very high query volumes can use Standard_D2s_v5 or larger.
Deploy from the Azure Portal
Search for dnsmasq in Azure Marketplace, select the SecureAnyCloud publisher, and choose 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, so open both.
Deploy from the Azure CLI
RG="dns-prod"; LOCATION="eastus"; VM_NAME="dnsmasq1" IMAGE_URN="sac1647283583153:dnsmasq: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:dnsmasq: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 admin 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 1002First boot
On first boot, the image resolves the VM public IP and asserts the secure defaults (local-service on, DHCP and TFTP off). It tests the dnsmasq configuration and starts the service. It proves that the local record answers and that upstream forwarding works. Finally, it writes /root/dnsmasq-credentials.txt.
First boot completes within a minute. SSH in as azureuser and read the details:
sudo cat /root/dnsmasq-credentials.txtConfirm the service is running
dnsmasq.service is active and owns port 53. ss confirms that dnsmasq is the listener on :53 for both UDP and TCP.
systemctl is-active dnsmasq.service
sudo ss -tulnp | grep -E ':53 ' || echo "(dnsmasq is not yet listening on :53)"Test DNS resolution
The image ships one local example record, ns.dnsmasq.internal, so a DNS round trip works immediately without any upstream. Forwarding of external names to the upstream resolvers also works out of the box.
Query the loopback address, or the VM public IP from a client:
dig @127.0.0.1 ns.dnsmasq.internal +short dig @127.0.0.1 example.com +shortReview the configuration
The SecureAnyCloud configuration lives in /etc/dnsmasq.d/00-sac.conf. The command dnsmasq --test validates the whole configuration. The version is 2.90 from the Ubuntu archive.
dnsmasq --version | head -1 sudo dnsmasq --test cat /etc/dnsmasq.d/00-sac.confVerify the responsible defaults
This check covers the key security property. local-service is present, so the server answers only local subnet clients and is not an open resolver. There is no dhcp-range and no enable-tftp, so DHCP and TFTP are off by default.
grep -E '^\s*(local-service|no-resolv|domain-needed|bogus-priv)' /etc/dnsmasq.d/00-sac.conf echo '--- DHCP and TFTP are off by default (the next command returns nothing): ---'
grep -E '^\s*(dhcp-range|enable-tftp)' /etc/dnsmasq.d/00-sac.conf || echo 'confirmed: no dhcp-range and no enable-tftp are set'Point clients at the server
Configure the devices or the router on your local network to use the VM as their DNS server. On a Linux client, set the nameserver to the VM address. Replace <public-ip> with the VM public IP, or with its private IP inside the VNet:
echo "nameserver <public-ip>" | sudo tee /etc/resolv.confBecause of local-service, dnsmasq answers only clients whose address is on a subnet local to the VM. Keep the server and its clients on the same VNet or a peered network.
Enable DHCP for your own subnet (optional)
dnsmasq can hand out DHCP leases on a subnet you control. Enable DHCP only on a network where you are the intended DHCP server.
Add a stanza like the following to /etc/dnsmasq.d/00-sac.conf. Adjust the interface and range to your subnet:
interface=eth0 dhcp-range=192.0.2.50,192.0.2.150,255.255.255.0,12h dhcp-option=option:router,192.0.2.1Open UDP 67 in the network security group, then restart the service with sudo systemctl restart dnsmasq.
Adding an interface= line also disables local-service. If you enable DHCP, add an explicit except-interface or an address-based restriction. This keeps the DNS forwarder from answering untrusted sources.
Enable TFTP and PXE boot (optional)
dnsmasq includes a TFTP server for network boot. To serve a TFTP root, add the following to /etc/dnsmasq.d/00-sac.conf:
enable-tftp tftp-root=/srv/tftp dhcp-boot=pxelinux.0Create /srv/tftp and place your boot files there. Open UDP 69 in the network security group, and restart with sudo systemctl restart dnsmasq.
Keep the TFTP root read-only, and populate it with only the files you intend to serve.
Add local DNS records and custom upstreams (optional)
To add your own local names or change the upstream resolvers, add a file such as /etc/dnsmasq.d/50-local.conf:
# local names answered directly by dnsmasq host-record=app.internal,10.0.0.20 address=/dev.internal/10.0.0.30
# use your own upstream resolvers instead of the defaults server=10.0.0.1Validate with sudo dnsmasq --test and apply with sudo systemctl reload dnsmasq.
Security recommendations
Restrict the network security group. Allow UDP and TCP 53 only from the client networks that need to query the server, and TCP 22 for administration only.
Keep it a local service. The shipped local-service default means the server never answers the public internet. If you add an interface= line for DHCP, add an explicit source restriction again, so the DNS forwarder does not become an open resolver.
Enable DHCP and TFTP only where you own the network. A stray DHCP server or an open TFTP root on someone else's network is a security incident.
Keep the OS and dnsmasq patched. Unattended security upgrades remain enabled on the running VM.
Monitor the leases file. If you enable DHCP, /var/lib/misc/dnsmasq.leases records active leases.
Support and licensing
dnsmasq is free software written by Simon Kelley and distributed under the GNU General Public License, version 2 (GPL-2.0). This SecureAnyCloud image bundles the unmodified Ubuntu archive package.
SecureAnyCloud provides the packaging and the secure caching forwarder hardening. It also provides the not-an-open-resolver defaults, the DHCP-and-TFTP-off-by-default posture and the local example record. Support is 24/7, with a guaranteed 24-hour response SLA.
SecureAnyCloud is not affiliated with or endorsed by the dnsmasq project or Simon Kelley. dnsmasq is used here only to identify the software.
Deploy on Azure
Find dnsmasq on Ubuntu 24.04 LTS in Azure Marketplace, published by SecureAnyCloud. Deploy from the Azure 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 dnsmasq 2.90 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
Overview
This guide shows you how to deploy and configure dnsmasq on AWS with the SecureAnyCloud AWS Marketplace image. dnsmasq is a lightweight, widely deployed network infrastructure daemon. From a single small binary, it provides a caching DNS forwarder, a DHCP server, a TFTP and PXE boot server and IPv6 router advertisement. It is a mainstay of routers, home labs and small to medium networks. It handles local name resolution and address assignment without the weight of separate BIND, DHCP and TFTP daemons.
The image installs dnsmasq 2.90 from the Ubuntu archive and runs it under systemd as the packaged, unprivileged dnsmasq user. dnsmasq answers DNS on port 53 over both UDP and TCP. There is no web interface and no database. A documented drop-in file, /etc/dnsmasq.d/00-sac.conf, plus the main /etc/dnsmasq.conf, are the whole configuration.
Secure by default, not an open resolver. An unrestricted public DNS forwarder can be abused for DNS amplification and reflection attacks. This image avoids that. The shipped configuration sets local-service, so dnsmasq answers DNS only for clients whose source address is on a local subnet of the instance. It silently drops every other source.
The forwarder ignores the host resolver list and forwards to explicit upstream resolvers. It caches answers and refuses to forward unqualified names and private reverse lookups. It also serves a demonstration local host record, so a DNS round trip works out of the box with no upstream needed. dnsmasq has no login, so no shared or default credential of any kind ships in the image.
DHCP and TFTP ship disabled. A rogue DHCP server or an open TFTP root is dangerous on a network you do not own. Both ship off, with no dhcp-range and no enable-tftp configured, and their ports are closed in the security group. You turn them on deliberately for your own network, as shown below.
What you get:
dnsmasq2.90 from the Ubuntu archive, run under systemd as the unprivileged dnsmasq user (dnsmasq.service).- A DNS endpoint on
0.0.0.0:53for both UDP and TCP, configured as a caching forwarder to upstream resolvers1.1.1.1and9.9.9.9. - A secure-by-default drop-in configuration at
/etc/dnsmasq.d/00-sac.confwithlocal-serviceset, so the image is not an open resolver. - A demonstration local host record,
ns.dnsmasq.internal, answered locally so a DNS round trip works immediately even with no upstream reachable. - DHCP and TFTP ready to enable for your own network, both off by default and fully documented below.
- The operating system stub resolver listener disabled, so dnsmasq owns port 53 cleanly while the operating system keeps resolving names through the upstream resolver list.
Connecting to your instance
Connect over SSH on port 22 as the default login user for the AMI variant you launched. dnsmasq has no login or password of its own, so nothing secret ships in the image.
For Ubuntu 24.04 LTS, the SSH login user is ubuntu. The service is dnsmasq.service, and the configuration is at /etc/dnsmasq.d/00-sac.conf.
ssh -i /path/to/key.pem ubuntu@<public-ip>Prerequisites
You need an AWS account and a key pair in the target region.
You also need a subscription to the dnsmasq listing on AWS Marketplace.
Add a security group that allows TCP 22 (admin) from your address, and UDP 53 and TCP 53 (DNS) from the clients that will query the server.
Recommended instance type: m5.large (2 vCPU, 8 GB RAM) is ample for a departmental resolver, or for the DNS, DHCP and TFTP needs of a small network. dnsmasq is extremely light. You need larger sizes only for very high query volumes.
Launch from AWS Marketplace
Search for dnsmasq in AWS Marketplace and select the SecureAnyCloud listing. Choose Continue to Subscribe, then Continue to Configuration, then Continue to Launch.
Choose the m5.large instance type, your key pair and a security group. Configure the security group to allow UDP 53 and TCP 53 from the clients that will query the server, and TCP 22 for administration. Keep port 53 restricted to the internal subnets whose clients will use the resolver.
Launch from the AWS CLI
AWS_REGION="us-east-1" aws ec2 run-instances \
--region "$AWS_REGION" \
--image-id <dnsmasq-ami-id> \
--instance-type m5.large \
--key-name <your-key-pair> \
--security-group-ids <your-sg-id> \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=dnsmasq1}]'Open UDP 53, TCP 53 and TCP 22 in <your-sg-id>, scoped to the sources that need them.
First boot
On first boot, the image resolves this instance's IP through EC2 instance metadata (IMDSv2) for the endpoint notes. It reasserts that the shipped configuration is secure, meaning that local-service is set and that DHCP and TFTP are off. It verifies the configuration syntax with dnsmasq --test and starts dnsmasq. It proves that both the local record and upstream forwarding are answering. Finally, it writes the informational note /root/dnsmasq-aws-info.txt.
First boot completes within seconds. SSH in as ubuntu and read the note:
sudo cat /root/dnsmasq-aws-info.txtThe note records this instance's DNS endpoint and example queries. dnsmasq has no password, so the note holds no secret. The note is 0600 root:root.
Confirm the service is running
dnsmasq.service is active, and dnsmasq --version reports 2.90. ss confirms that dnsmasq is listening on :53 for DNS over both UDP and TCP.
systemctl is-active dnsmasq.service dnsmasq --version | head -1 sudo ss -tulnp | grep ':53 'Query the resolver
dnsmasq answers the demonstration record ns.dnsmasq.internal locally, so a DNS round trip works immediately with no upstream needed. A query for an external name is forwarded to the upstream resolvers and cached.
dig +noall +answer @127.0.0.1 ns.dnsmasq.internal dig +short @127.0.0.1 example.comThe first query returns 10.0.0.53, the shipped local record, answered straight from dnsmasq. The second query is forwarded to the upstream resolvers 1.1.1.1 and 9.9.9.9, and it returns the real address for the name.
Review the secure-by-default configuration
Everything dnsmasq does is in /etc/dnsmasq.d/00-sac.conf. The shipped configuration sets local-service and ignores the host resolver list. It forwards to explicit upstreams and refuses to forward unqualified names and private reverse lookups. It caches answers and serves the demonstration record.
sudo grep -vE '^\s*#|^\s*$' /etc/dnsmasq.d/00-sac.confConfirm the image is not an open resolver
This is the security posture that matters for a public-facing DNS server. Because local-service is set, dnsmasq answers DNS only for clients whose source address is on a local subnet of the instance. It silently drops queries from any other source, so it cannot be abused for DNS amplification. DHCP and TFTP ship off. Confirm all three from the shipped configuration:
grep -E '^\s*local-service' /etc/dnsmasq.d/00-sac.conf && echo 'local-service: ON'
grep -qE '^\s*dhcp-range' /etc/dnsmasq.d/00-sac.conf && echo 'DHCP: on' || echo 'DHCP: OFF by default'
grep -qE '^\s*enable-tftp' /etc/dnsmasq.d/00-sac.conf && echo 'TFTP: on' || echo 'TFTP: OFF by default'With local-service set, dnsmasq answers a query from a client on the instance's own subnet. It drops a query that arrives from an off-subnet source, for example the open internet.
local-service takes effect only while no interface= or listen-address= option is set, so this image deliberately pins neither.
Widen who the resolver answers
local-service answers clients on subnets that the instance itself has an interface on. In a typical VPC deployment, that is your instance's own subnet, which is what you want.
To serve clients on other subnets you control, add explicit interface or address bindings, or replace local-service with a more specific setting. A common pattern is to bind dnsmasq to the private interface and allow your VPC CIDR. Edit /etc/dnsmasq.d/00-sac.conf, make your change, then restart:
# example: after editing the configuration to widen the served client scope
sudo dnsmasq --test sudo systemctl restart dnsmasqAlways run dnsmasq --test first. It validates the configuration, and dnsmasq refuses to start on a syntax error. Keep the served scope to networks you control, so the server never becomes an open resolver.
Enable DHCP for your own subnet
dnsmasq is also a DHCP server, and it ships off. To hand out addresses on a subnet you own, add an interface and a dhcp-range, open UDP 67 in the security group, and restart. Never run DHCP on a subnet you do not control.
# add to /etc/dnsmasq.d/00-sac.conf, adjusting the interface and range to your subnet:
# interface=eth0
# dhcp-range=192.0.2.50,192.0.2.150,255.255.255.0,12h
sudo dnsmasq --test sudo systemctl restart dnsmasqdnsmasq then answers DHCP on the named interface. It also resolves the names of the hosts it leases, so DNS and DHCP stay consistent.
Enable TFTP and PXE boot
dnsmasq includes a TFTP server for network boot, and it ships off. To serve TFTP, add enable-tftp and a tftp-root, open UDP 69 in the security group, and restart. Combine it with the DHCP boot options for PXE.
# add to /etc/dnsmasq.d/00-sac.conf:
# enable-tftp
# tftp-root=/srv/tftp
sudo mkdir -p /srv/tftp
sudo dnsmasq --test sudo systemctl restart dnsmasqKeep the TFTP root to files you intend to serve. Restrict UDP 69 to the network that boots from it.
Review the configuration and info note
Everything dnsmasq does is in its configuration files, and the per-instance details are in the info note. Read both with sudo.
sudo cat /etc/dnsmasq.d/00-sac.conf
sudo cat /root/dnsmasq-aws-info.txtThe info note is 0600 root:root and holds no secret. It records this instance's DNS endpoint and example queries for convenience.
Security recommendations
Restrict the security group to your use case. Allow UDP 53 and TCP 53 only from the client subnets that will query the resolver, and TCP 22 only from your administration address. Open UDP 67 (DHCP) or UDP 69 (TFTP) only if you enable those services, and only to the network that uses them.
Keep the served scope tight. local-service keeps the resolver from answering off-subnet clients. If you widen the scope, add only networks you control, so the server never becomes an open resolver.
Never run DHCP on a network you do not own. A rogue DHCP server disrupts every client on the segment. Enable DHCP only on subnets you control.
Keep the TFTP root minimal. Serve only the boot files you intend to, and keep UDP 69 restricted.
Keep the OS patched. Unattended security upgrades remain enabled on the running instance.
Support and licensing
dnsmasq is free software by Simon Kelley, distributed under the GNU General Public License, version 2 or version 3. The shipped package declares GPL-2 or GPL-3. This SecureAnyCloud image bundles the unmodified dnsmasq package from the operating system archive.
SecureAnyCloud provides the packaging, the systemd hardening, and the secure-by-default, not-an-open-resolver configuration. It also provides the per-instance first-boot automation, the paired deploy guide and 24/7 support.
SecureAnyCloud is not affiliated with or endorsed by the dnsmasq project or Simon Kelley. dnsmasq is used here only to identify the software.
Deploy on AWS
Find dnsmasq in AWS Marketplace, published by SecureAnyCloud. Launch from the AWS console or the AWS CLI as shown above.
Need Help?
Email sales@secureanycloud.com for deployment help, configuration questions or licensing inquiries.
Deploy on AWS
Launch dnsmasq on AWS, with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com