dnscrypt-proxy
Overview
dnscrypt-proxy is a flexible DNS proxy that encrypts your DNS traffic. It sits between your clients and the public internet. It accepts ordinary DNS queries on port 53 and forwards every one of them to a public upstream resolver over an encrypted transport, so your internet provider and any network on the path can no longer see or tamper with the names you look up. It supports the modern encrypted DNS protocols, including DNSCrypt v2, DNS over HTTPS, Anonymized DNSCrypt and Oblivious DoH.
This guide covers the deployment and configuration of dnscrypt-proxy on Ubuntu 24.04 on Azure, using SecureAnyCloud Azure Marketplace images. The image installs dnscrypt-proxy 2.1.18 from the official prebuilt release binary. It runs under systemd as an unprivileged dnscrypt-proxy user with only the CAP_NET_BIND_SERVICE capability, so that it can bind the standard privileged DNS port.
It answers DNS on port 53 over both UDP and TCP on all interfaces. It forwards to upstreams that are chosen automatically, by lowest latency, from a cryptographically signed public resolver list. There is no web interface and no database. A single flat TOML file (/etc/dnscrypt-proxy/dnscrypt-proxy.toml) is the whole configuration.
Secure by default. Upstream selection is restricted to resolvers that validate DNSSEC, keep no logs, and apply no filtering, so you get authentic, private, unfiltered answers. The image ships with no shared or default credential of any kind, because dnscrypt-proxy has no login.
The resolver binds all interfaces so that it can serve a whole network, but the stock Azure Network Security Group opens only SSH. Port 53 is therefore not reachable from the internet until you deliberately open it. Because dnscrypt-proxy has no built-in allow-from access control list, the Network Security Group is your access control. Open UDP and TCP 53 only to the client subnets that you control, never to the whole internet, so that the resolver is never abused as an open resolver.
What you get:
dnscrypt-proxy2.1.18 from the official prebuilt release binary, run under systemd as the unprivileged dnscrypt-proxy user (dnscrypt-proxy.service)- A DNS endpoint on
0.0.0.0:53(UDP and TCP) that forwards every query to an encrypted upstream (DNSCrypt v2 or DNS over HTTPS) - Automatic selection of DNSSEC-validating, no-log, non-filtering encrypted resolvers from a minisign-signed public resolver list
- The whole configuration in one readable file,
/etc/dnscrypt-proxy/dnscrypt-proxy.toml, with ready-to-edit example blocklists, allow lists, cloaking and forwarding rules alongside it - The systemd-resolved stub listener disabled so that dnscrypt-proxy owns port 53 cleanly, while the OS keeps resolving names through its own upstream list
Prerequisites
Before you deploy, make sure you have:
- An active Azure subscription, an SSH public key, and a VNet and subnet in the target region
- A subscription to the dnscrypt-proxy listing on Azure Marketplace
- Network Security Group rules allowing TCP 22 (admin) and UDP 53 + TCP 53 (DNS) only from the client subnets that will use the resolver
Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM) is ample for a departmental resolver. dnscrypt-proxy is extremely light, and larger sizes are only needed for very high query volumes.
Deploy from the Azure Portal
Search for dnscrypt-proxy in the Marketplace, select the SecureAnyCloud publisher, and click Create. Configure the Network Security Group to allow TCP 22 for administration, and UDP 53 and TCP 53 from the clients that will use the resolver. Keep port 53 scoped to your own client subnets, never 0.0.0.0/0.
Deploy from the Azure CLI
RG="dns-prod"; LOCATION="eastus"; VM_NAME="dnscrypt1" IMAGE_URN="sac1647283583153:dnscrypt-proxy-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:dnscrypt-proxy-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
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 22 --priority 1001Do not open port 53 with a blanket az vm open-port. Instead, add a scoped Network Security Group rule for UDP and TCP 53 that lists only your client subnets as the source (see Step 7).
First boot
On first boot, the image writes a per-instance informational note to /root/dnscrypt-proxy-info.txt, refreshes the signed resolver list into its cache, and starts dnscrypt-proxy. This completes within seconds. SSH in as azureuser and read the note:
sudo cat /root/dnscrypt-proxy-info.txtThe note records the version, the listen address, this VM's IP, the config path and the encrypted-only upstream policy. dnscrypt-proxy has no password, so the note holds no secret.
Confirm the service is running
dnscrypt-proxy.service is active, dnscrypt-proxy -version reports 2.1.18, and the service runs as the unprivileged dnscrypt-proxy user. ss confirms that it is listening on :53 for DNS over both UDP and TCP on all interfaces.
systemctl is-active dnscrypt-proxy.service /opt/dnscrypt-proxy/dnscrypt-proxy -version sudo ss -tulnp | grep ':53 'Resolve a name through the encrypted resolver
Send an ordinary DNS query to the resolver on the loopback address. dnscrypt-proxy forwards it to an encrypted upstream and returns the answer. DNS over TCP works too, and clients fall back to it for large responses.
dig +noall +answer @127.0.0.1 example.com A dig +tcp +noall +answer @127.0.0.1 cloudflare.com ABoth queries return normal A records. Your client sees plain DNS on port 53, while dnscrypt-proxy fetches the answer over an encrypted transport on your behalf.
Confirm the upstreams are encrypted
Encrypted upstreams are the property that matters for a privacy resolver. dnscrypt-proxy logs each live upstream and the protocol that it speaks (DNSCrypt or DoH) as it measures latency, and it picks the fastest. The -resolve subcommand shows a full diagnostic for a name, including whether the answer is DNSSEC validated.
sudo journalctl -u dnscrypt-proxy --no-pager | grep -E 'OK \(DNSCrypt\)|OK \(DoH\)|lowest initial latency' | tail -5 /opt/dnscrypt-proxy/dnscrypt-proxy -config /etc/dnscrypt-proxy/dnscrypt-proxy.toml -resolve example.com | grep -iE 'Resolver|Name servers|DNSSEC'Every upstream is OK (DNSCrypt) or OK (DoH), and never plain DNS. DNSSEC signed : yes confirms that the answer was cryptographically validated end to end.
Secure by default and restrict the Network Security Group
The shipped configuration only ever selects encrypted, DNSSEC-validating, no-log, non-filtering upstreams. Review the policy, then lock down access. dnscrypt-proxy has no built-in allow-from access control list, so the Network Security Group is your access control.
grep -E '^(listen_addresses|require_dnssec|require_nolog|require_nofilter|dnscrypt_servers|doh_servers) ' /etc/dnscrypt-proxy/dnscrypt-proxy.tomlIn the Azure Portal, add an inbound Network Security Group rule for UDP 53 and TCP 53 whose Source is your own client subnets (for example your VNet address space or a specific 10.0.0.0/24). Set the source to your admin IP for TCP 22. Never set the source of the port 53 rule to Any or 0.0.0.0/0. An internet-reachable resolver with no allow list is an open resolver and can be abused for amplification.
Point your clients at the resolver
When the Network Security Group allows your subnets, point your clients or your VNet's DNS setting at this VM's private IP on port 53. To make the whole virtual network use the resolver, set it as the VNet's custom DNS server:
# From your workstation, using the Azure CLI (VNET_RG / VNET_NAME are your VNet's): # az network vnet update -g <VNET_RG> -n <VNET_NAME> --dns-servers <this-vm-private-ip> # Then reboot (or re-apply DHCP on) the client VMs so they pick up the new resolver.
echo "Set your VNet custom DNS to this VM's private IP, or configure clients directly."Individual Linux clients can test against the resolver directly with dig @<this-vm-private-ip> example.com.
Choose specific upstreams or protocols
By default, dnscrypt-proxy selects automatically from all resolvers that match the encrypted, DNSSEC, no-log and no-filter requirements. To pin a specific set, uncomment and edit server_names in the config, then restart. To use only DNS over HTTPS (or only DNSCrypt), set the matching *_servers toggles.
# edit /etc/dnscrypt-proxy/dnscrypt-proxy.toml, for example:
# server_names = ['cloudflare', 'google', 'quad9-doh-ip4-port443-nofilter-pri']
# or restrict to a single protocol:
# dnscrypt_servers = false
# DoH only
# then apply the change:
#
sudo systemctl restart dnscrypt-proxy echo "See https://github.com/DNSCrypt/dnscrypt-proxy/wiki for the full server list and options."The configuration is validated on start. If there is a syntax error, the service fails to start and logs the reason, so check systemctl status dnscrypt-proxy after any edit.
Optional blocklists, allow lists and cloaking
dnscrypt-proxy ships with ready-to-edit example rule files in /etc/dnscrypt-proxy. Enable name blocklists, IP blocklists, cloaking (local overrides) or per-name forwarding by pointing the matching section of the config at a rules file.
ls /etc/dnscrypt-proxy/example-*.txtCopy an example to a working file (for example blocked-names.txt), reference it from the [blocked_names] section of the config, and restart. With these rules, you can filter ad or malware domains, pin internal names, or forward a private zone to an internal resolver, all without an external service.
Security recommendations
Scope the Network Security Group. Allow UDP 53 and TCP 53 only from the client subnets that you control. dnscrypt-proxy has no allow-from ACL, so the NSG is the only thing standing between your resolver and the internet.
Keep the encrypted-only upstream policy. Leave require_dnssec, require_nolog and require_nofilter set to true so that answers stay authentic, private and unfiltered.
Prefer trusted upstreams for sensitive networks. Pin server_names to operators that you trust, or enable Anonymized DNSCrypt or Oblivious DoH so that no single upstream sees both your IP and your queries.
Keep the OS patched. Unattended security upgrades remain enabled on the running VM.
Support and Licensing
dnscrypt-proxy is an open-source project distributed under the ISC License. This SecureAnyCloud image bundles the unmodified official dnscrypt-proxy release binary. SecureAnyCloud provides the packaging, the systemd hardening, the secure-by-default encrypted-only upstream policy, the per-instance first-boot automation, the paired deploy guide, and 24/7 support with a guaranteed 24-hour response SLA.
SecureAnyCloud is not affiliated with or endorsed by the dnscrypt-proxy project or its authors. dnscrypt-proxy is a mark of its respective owner and is used here only to identify the software.
Deploy on Azure
Find dnscrypt-proxy 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 enquiries.
Deploy on Azure
Launch dnscrypt-proxy 2.1.18 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
dnscrypt-proxy is a flexible DNS proxy that encrypts your DNS traffic. It accepts ordinary DNS queries on port 53 and forwards every one of them to a public upstream resolver over an encrypted transport, so your internet provider and any network between you and the resolver can no longer see or tamper with the names you look up.
This guide covers the deployment and configuration of dnscrypt-proxy on AWS, using SecureAnyCloud AWS Marketplace images. The image installs the official dnscrypt-proxy binary (a self-contained Go binary, pinned by SHA256 at build) and runs it under systemd as the unprivileged dnscrypt-proxy user. An encrypted resolver for your whole network is answering queries within minutes of launch. It listens on 0.0.0.0:53 over both UDP and TCP.
Secure by default: hardened upstreams. Upstream selection is restricted to encrypted resolvers that validate DNSSEC, keep no logs, and apply no filtering. They are chosen automatically by lowest latency from a cryptographically signed public resolver list. The supported encrypted protocols are DNSCrypt v2, DNS over HTTPS, Anonymized DNSCrypt and Oblivious DoH.
Secure by default: not an open resolver. dnscrypt-proxy has no login and no baked-in credential of any kind. It binds all interfaces so that it can serve a network, but it has no built-in allow-from access control list, so the AWS security group is your access control. Open UDP and TCP 53 only to the client subnets that you control, never to 0.0.0.0/0, or the instance becomes an open resolver.
What you get:
dnscrypt-proxy2.1.18 (official binary, pinned by SHA256 at build time), run under systemd as the unprivileged dnscrypt-proxy user (dnscrypt-proxy.service)- An encrypted DNS resolver on port 53 over both UDP and TCP, forwarding to DNSSEC-validating, no-log, non-filtering public upstreams over DNSCrypt v2 and DNS over HTTPS
- A hardened configuration at
/etc/dnscrypt-proxy/dnscrypt-proxy.toml(require_dnssec,require_nolog,require_nofilterall enabled, only encrypted upstream families) - A per-instance informational note written on first boot (it holds no credential, because dnscrypt-proxy has no login)
- Ready-to-edit example blocklist, allow list, cloaking and forwarding rule files in
/etc/dnscrypt-proxy/ - Unattended security upgrades left enabled so that the server keeps receiving patches
Prerequisites
Before you deploy, make sure you have:
- An active AWS account, an EC2 key pair, and a VPC and subnet in the target region
- A subscription to the dnscrypt-proxy listing on AWS Marketplace
- A security group allowing TCP 22 (admin) and, from the clients you intend to serve, UDP 53 and TCP 53 (DNS)
Recommended instance type: m5.large (2 vCPU, 8 GB RAM). DNS forwarding is very light, and busy resolvers can move to a larger instance type.
Launch from AWS Marketplace
Find dnscrypt-proxy on AWS Marketplace, published by SecureAnyCloud. Choose Continue to Subscribe, then Continue to Configuration, and then Continue to Launch.
Select the Ubuntu 24.04 delivery option, your instance type (m5.large), your key pair, and a security group. The security group must allow TCP 22 for administration, plus UDP 53 and TCP 53 from the client networks that you want to serve.
Important: Scope the port 53 rules to your own client subnets. dnscrypt-proxy has no built-in allow-from access control, so the security group is the only thing that prevents anyone on the internet from using the resolver. Never open UDP/TCP 53 to 0.0.0.0/0.
Connecting to your instance
SSH in with your EC2 key pair as the login user for the OS variant that you launched.
OS variant SSH login user Example
Ubuntu 24.04 ubuntu ssh -i your-key.pem ubuntu@<public-ip>
ssh -i your-key.pem ubuntu@<public-ip>Confirm the resolver is running
dnscrypt-proxy starts automatically at boot. Confirm that the service is active and that it is listening on port 53 over both UDP and TCP:
sudo systemctl status dnscrypt-proxy.service --no-pager | head -12sudo ss -tulnp | grep -E ':53 'You should see the service active (running) and both a udp and a tcp listener on 0.0.0.0:53, owned by the unprivileged dnscrypt-proxy process.
Resolve a name through the encrypted proxy
Send a DNS query to the resolver on the instance itself. The resolver fetches the answer from a public upstream over an encrypted transport:
dig +noall +answer @127.0.0.1 example.com AThe resolver answers DNS over TCP too, which clients use for large or truncated responses:
dig +tcp +noall +answer @127.0.0.1 example.com ABoth commands return the same A records, which shows that the resolver answers over UDP and TCP.
Confirm the upstream is encrypted
The service journal records which public upstreams responded and over which transport. Every entry is an encrypted DNSCrypt or DoH resolver:
sudo journalctl -u dnscrypt-proxy --no-pager | grep -oE '\[[a-z0-9.-]+\] OK \((DoH|DNSCrypt)\) - rtt: [0-9]+ms' | tail -8dnscrypt-proxy picks the upstream with the lowest latency automatically:
sudo journalctl -u dnscrypt-proxy --no-pager | grep -oE 'Server with the lowest initial latency: .*' | tail -1Review the hardened configuration
One plain text file defines the entire behaviour of dnscrypt-proxy. Confirm the shipped hardening: only DNSSEC-validating, no-log, non-filtering encrypted upstreams.
sudo grep -E '^(listen_addresses|require_dnssec|require_nolog|require_nofilter|dnscrypt_servers|doh_servers) =' /etc/dnscrypt-proxy/dnscrypt-proxy.tomlFirst boot writes a per-instance informational note. The note holds no credential, because dnscrypt-proxy has no login:
sudo ls -l /root/dnscrypt-proxy-info.txtPoint your clients at the resolver
Point your clients, or your VPC DHCP option set / instance DNS setting, at this instance's private IP on port 53. Then, in the AWS security group, open UDP 53 and TCP 53 only from the client subnets that you control.
To change upstreams, caching, local blocklists, allow lists, cloaking or forwarding rules, edit /etc/dnscrypt-proxy/dnscrypt-proxy.toml (example rule files are shipped alongside it) and reload the service:
sudo systemctl reload dnscrypt-proxySecurity notes
The security group is your access control. dnscrypt-proxy has no built-in allow-from list. Open UDP/TCP 53 only to your own client subnets, never to 0.0.0.0/0, or the instance becomes an open resolver that anyone can abuse.
No baked-in credential. This image ships no login or password of any kind. The per-instance info note at /root/dnscrypt-proxy-info.txt contains no secret.
Encrypted, DNSSEC-validated, no-log upstreams only. The shipped configuration accepts answers only from DNSSEC-validating, no-log, non-filtering resolvers that are reached over encrypted transports.
Keep the OS patched. Unattended security upgrades are left enabled.
Support
SecureAnyCloud provides 24/7 technical support for this dnscrypt-proxy product by email (sales@secureanycloud.com) and live chat. We help with upstream and protocol selection, scoping the port 53 security group rules to your client subnets, DNSSEC and no-log requirements, local blocklists, allow lists, cloaking and forwarding rules, caching, and dnscrypt-proxy version upgrades. Critical issues receive a one-hour average response time.
Deploy on AWS
Launch dnscrypt-proxy Encrypted DNS Proxy with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com