How do I a setup local dns caching service on Amazon Linux 2023? The following steps can be used to setup a local DNS caching service for DNS lookups on AL2023:
sudo dnf install -y dnsmasq bind-utils
sudo cp /etc/dnsmasq.conf{,.bak}
cat <<'EOF' | sudo tee /etc/dnsmasq.conf
# https://thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html
# https://thekelleys.org.uk/gitweb/?p=dnsmasq.git
## Server Configuration
# The alternative would be just 127.0.0.1 without ::1
listen-address=::1,127.0.0.1
# Port 53
port=53
# dnsmasq binds to the wildcard address, even if it is listening
# on only some interfaces. It then discards requests that it
# shouldn't reply to. This has the advantage of working even
# when interfaces come and go and change address.
bind-interfaces
interface=lo
# The user to which dnsmasq will change to after startup
user=dnsmasq
# The group which dnsmasq will run as
group=dnsmasq
# PID file
pid-file=/var/run/dnsmasq.pid
## Name resolution options
# Specify the upstream resolver within another file
resolv-file=/etc/resolv.dnsmasq
# Or Specify the upstream AWS VPC Resolver within this config file
# https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html#AmazonDNS
#server=169.254.169.253
#server=fd00:ec2::253
# Uncomment if you specify the upstream server in here so you don't read
# /etc/resolv.conf. Get upstream servers only from cli or dnsmasq conf.
#no-resolv
# Uncomment if specify the upstream server in here so you no longer poll
# the /etc/resolv.conf file for changes.
#no-poll
# Additional hosts files to include
#addn-hosts=/etc/dnsmasq-blocklist
# Send queries for internal domain to another internal resolver
#address=/int.example.com/10.10.10.10
# Examples of blocking TLDs or subdomains
#address=/.local/0.0.0.0
#address=/.example.com/0.0.0.0
# Never forward addresses in the non-routed address spaces
bogus-priv
# Never forward plain names
domain-needed
# Reject private addresses from upstream nameservers
stop-dns-rebind
# Exempt 127.0.0.0/8 and ::1 from rebinding checks
rebind-localhost-ok
# Query servers in order
strict-order
# Set the size of dnsmasq's cache, default is 150 names
cache-size=1000
# Negative replies from upstream servers normally contain
# time-to-live information in SOA records which dnsmasq uses
# for caching. If the replies from upstream servers omit this
# information, dnsmasq does not cache the reply. This option
# gives a default value for time-to-live (in seconds) which
# dnsmasq uses to cache negative replies even in the absence
# of an SOA record.
neg-ttl=60
# Uncomment to enable validation of DNS replies and cache DNSSEC data.
#dnssec
#dnssec-check-unsigned
#trust-anchor=.,19036,8,2,49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5
## Logging directives
#log-async
#log-dhcp
# Uncomment to log all queries
#log-queries
# Alternative would be /tmp/dnsmasq
log-facility=/var/log/dnsmasq.log
EOF
Create the following file with the upstream resolvers:
cat <<'EOF' | sudo tee /etc/resolv.dnsmasq
nameserver 169.254.169.253
#nameserver fd00:ec2::253
EOF
Verify:
sudo dnsmasq --test
Make sure that systemd-resolved is not configured to be a stub resolver:
sudo mkdir -pv /etc/systemd/resolved.conf.d
cat <<'EOF' | sudo tee /etc/systemd/resolved.conf.d/00-override.conf
[Resolve]
DNSStubListener=no
MulticastDNS=no
LLMNR=no
EOF
sudo systemctl daemon-reload
sudo systemctl restart systemd-resolved
Unlink the stub and re-create the /etc/resolv.conf file:
sudo unlink /etc/resolv.conf
cat <<'EOF' | sudo tee /etc/resolv.conf
nameserver 127.0.0.1
search ec2.internal
options edns0
EOF
Enable and start the service:
sudo systemctl enable --now dnsmasq.service
sudo systemctl restart dnsmasq.service
Verify:
dig aws.amazon.com @127.0.0.1
As with everything, please make sure to thoroughly test within your test environment prior to deploying anything to a production environment.