dnsmasq on AWS User Guide
Overview
This guide covers the deployment and configuration of dnsmasq on AWS using cloudimg AWS Marketplace images. dnsmasq is a lightweight, widely deployed network infrastructure daemon that provides a caching DNS forwarder, a DHCP server, a TFTP and PXE boot server and IPv6 router advertisement, all from a single small binary. It is a mainstay of routers, home labs and small to medium networks because it does the whole job of local network 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, run 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-cloudimg.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 and silently drops every other source. The forwarder ignores the host resolver list and forwards to explicit upstream resolvers, caches answers, refuses to forward non qualified names and private reverse lookups, and 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, so both ship off, with no dhcp-range and no enable-tftp configured and their ports closed in the security group. You turn them on deliberately for your own network, as shown below.
What is included:
-
dnsmasq 2.90 from the Ubuntu archive, run under systemd as the unprivileged
dnsmasquser (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-cloudimg.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, 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.
| OS variant | SSH login user | Notes |
|---|---|---|
| Ubuntu 24.04 LTS | ubuntu |
dnsmasq.service; config at /etc/dnsmasq.d/00-cloudimg.conf |
ssh -i /path/to/key.pem ubuntu@<public-ip>
Prerequisites
-
An AWS account and a key pair in the target region
-
Subscription to the dnsmasq listing on AWS Marketplace
-
A security group allowing 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 a small network's DNS, DHCP and TFTP. dnsmasq is extremely light; larger sizes are only needed for very high query volumes.
Step 1: Launch from AWS Marketplace
Search dnsmasq in AWS Marketplace, select the cloudimg listing, and click Continue to Subscribe, then Continue to Configuration and 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.
Step 2: 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.
Step 3: First boot
On first boot the image resolves this instance's IP through EC2 instance metadata (IMDSv2) for the endpoint notes, reasserts that the shipped configuration is secure (that local-service is set and that DHCP and TFTP are off), verifies the configuration syntax with dnsmasq --test, starts dnsmasq, proves both the local record and upstream forwarding are answering, and writes the informational note /root/dnsmasq-aws-info.txt. This completes within seconds. SSH in as ubuntu and read the note:
sudo cat /root/dnsmasq-aws-info.txt
The note records this instance's DNS endpoint and example queries. dnsmasq has no password, so the note holds no secret. It is 0600 root:root.
Step 4: Confirm the service is running
dnsmasq.service is active, dnsmasq --version reports 2.90, and ss confirms it 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 '

Step 5: Query the resolver
The demonstration record ns.dnsmasq.internal is answered locally by dnsmasq, 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.com
The first query returns 10.0.0.53, the shipped local record, answered straight from dnsmasq. The second is forwarded to the upstream resolvers 1.1.1.1 and 9.9.9.9 and returns the real address for the name.

Step 6: Review the secure by default configuration
Everything dnsmasq does is in /etc/dnsmasq.d/00-cloudimg.conf. The shipped configuration sets local-service, ignores the host resolver list and forwards to explicit upstreams, refuses to forward non qualified names and private reverse lookups, caches answers, and serves the demonstration record.
sudo grep -vE '^\s*#|^\s*$' /etc/dnsmasq.d/00-cloudimg.conf

Step 7: Confirm 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 and 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-cloudimg.conf && echo 'local-service: ON'
grep -qE '^\s*dhcp-range' /etc/dnsmasq.d/00-cloudimg.conf && echo 'DHCP: on' || echo 'DHCP: OFF by default'
grep -qE '^\s*enable-tftp' /etc/dnsmasq.d/00-cloudimg.conf && echo 'TFTP: on' || echo 'TFTP: OFF by default'
With local-service set, a query from a client on the instance's own subnet is answered, while a query arriving from an off subnet source (for example the open internet) is dropped. Note that local-service only takes effect while no interface= or listen-address= option is set, so this image deliberately pins neither.

Step 8: Widen who the resolver answers
local-service answers clients on subnets 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 stance. A common pattern is to bind dnsmasq to the private interface and allow your VPC CIDR. Edit /etc/dnsmasq.d/00-cloudimg.conf, make your change, then restart:
# example: after editing the configuration to widen the served client scope
sudo dnsmasq --test
sudo systemctl restart dnsmasq
Always 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.
Step 9: Enable DHCP for your own subnet
dnsmasq is also a DHCP server, shipped 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-cloudimg.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 dnsmasq
dnsmasq then answers DHCP on the named interface and also resolves the names of the hosts it leases, so DNS and DHCP stay consistent.
Step 10: Enable TFTP and PXE boot
dnsmasq includes a TFTP server for network boot, shipped 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-cloudimg.conf:
# enable-tftp
# tftp-root=/srv/tftp
sudo mkdir -p /srv/tftp
sudo dnsmasq --test
sudo systemctl restart dnsmasq
Keep the TFTP root to files you intend to serve, and keep UDP 69 restricted to the network that boots from it.
Step 11: Review the configuration and info note
Everything dnsmasq does is in its configuration files, and the per instance details are in the info note. Both are readable with sudo.
sudo cat /etc/dnsmasq.d/00-cloudimg.conf
sudo cat /root/dnsmasq-aws-info.txt
The info note is 0600 root:root and holds no secret. It records this instance's DNS endpoint and example queries for convenience.
Step 12: 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-servicekeeps 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.
Step 13: 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 cloudimg image bundles the unmodified dnsmasq package from the operating system archive. cloudimg provides the packaging, the systemd hardening, the secure by default configuration and not an open resolver posture, the per instance first boot automation, the paired deploy guide, and 24/7 support.
cloudimg 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 on the AWS Marketplace, published by cloudimg. Launch from the AWS console or the AWS CLI as shown above.
Need Help?
Email support@cloudimg.co.uk for deployment help, configuration questions, or licensing enquiries.