Router guide
dnscrypt-proxy on OpenWrt: the dnscrypt-proxy2 Package and dnsmasq
Running dnscrypt-proxy on OpenWrt is the most efficient way to protect a whole household: one install on the router, and every phone, television and console that takes its DNS from DHCP is covered without any setting on the device. The router keeps dnsmasq for DHCP and local names, and simply forwards the actual lookups to the proxy.
Which package manager your release uses
OpenWrt changed package managers with 25.12. Its release notes explain that the project moved from opkg to apk, the Alpine Package Keeper, because the OpenWrt fork of opkg is no longer maintained, and that the command-line arguments differ. The current point release is 25.12.6 from 18 October 2026, while 24.10 and earlier still ship opkg.
The package name is the same on both: dnscrypt-proxy2. The master branch of the OpenWrt packages feed builds release 2.1.20, but the wiki points out that updates are at the maintainer’s discretion, so a stable release may carry an older build than GitHub. Check the installed version before reporting a bug, because a problem may already be fixed upstream.
Installing dnscrypt-proxy on OpenWrt from the command line
Log in over SSH as root and run the block that matches your release. The two uci lines add 127.0.0.53 as an upstream server for dnsmasq, commit the change and restart it. From that moment the router’s own resolver sends every query it cannot answer from local data through the proxy.
# OpenWrt 25.12 and later
apk update
apk add dnscrypt-proxy2
# OpenWrt 24.10 and earlier
opkg update
opkg install dnscrypt-proxy2
# both
uci add_list dhcp.@dnsmasq[0].server='127.0.0.53'
uci commit dhcp
/etc/init.d/dnsmasq restart
The package does a good part of the configuration for you, which is the main reason to prefer it over a manual binary install. Its build recipe copies the project’s example file to /etc/dnscrypt-proxy2/dnscrypt-proxy.toml, rewrites listen_addresses to ['127.0.0.53:53'] so the proxy never collides with dnsmasq on port 53, enables a blocked-names.txt list, and installs an init script at /etc/init.d/dnscrypt-proxy.
Installing dnscrypt-proxy2 in LuCI
- Open System, Software, and click Update lists.
- Type
dnscrypt-proxy2into the Filter box and install the package. - Go to Network, DHCP and DNS, Forwards, and add
127.0.0.53under DNS Forwards. - Click Save & Apply.
- Restart
dnsmasqunder System, Startup.
LuCI covers installation and forwarding, but the proxy’s own options still live in the TOML file, which is edited over SSH with vi or copied off and back with scp. Restart with /etc/init.d/dnscrypt-proxy restart after each change. Picking resolvers and relays is easier off the router: the route builder produces a block you can paste in.
Closing the leaks
Only do this after the proxy resolves correctly, because it switches off the provider’s DNS. In /etc/config/dhcp, option noresolv '1' stops dnsmasq from reading upstream servers from resolv.conf, option localuse '1' makes the router itself use dnsmasq, and option cachesize '0' avoids caching twice, since the proxy’s cache is the better one.
config dnsmasq
option noresolv '1'
option localuse '1'
option cachesize '0'
Some devices ignore DHCP and query hard-coded servers. The wiki’s firewall recipe adds a DNAT redirect that catches any LAN packet to port 53 and sends it to the router, plus a rule rejecting DNS over TLS on TCP 853, and optionally option peerdns '0' on the WAN interface so provider addresses are never learned. Reload with /etc/init.d/firewall reload.
That still leaves devices with built-in DNS over HTTPS, which looks like ordinary web traffic. For advanced users the wiki points to the banIP package, which ships a DoH blocklist. One caveat matters: add the DoH servers the proxy itself uses to the banIP allowlist, or the router blocks its own upstream and resolution stops.
The clock needs attention as well. Certificate checks fail when the time is wrong, and a router without a battery-backed clock cannot fetch the time without DNS. The wiki’s answer is to list NTP servers by IP address in /etc/config/system, for example Google’s 216.239.35.0 and Cloudflare’s 162.159.200.123, then restart sysntpd.
Verifying dnscrypt-proxy on OpenWrt
Three checks cover the setup. On the router, dnscrypt-proxy -resolve google.com reports which resolver answered, and that address must not belong to your provider. Then cat /etc/resolv.conf should show nameserver 127.0.0.1, which is dnsmasq, once localuse is enabled. Finally, run the outside queries from the DNS leak check on a LAN device.
dnscrypt-proxy -resolve google.com
cat /etc/resolv.conf
logread -l 100 | grep dnsmasq
Before the next firmware upgrade, protect the work. In System, Backup / Flash Firmware, open the Configuration tab and add /etc/dnscrypt-proxy2/ to the list, or append the same line to /etc/sysupgrade.conf. Without it, the edited TOML file and any custom blocklist disappear with the old image, and the router quietly falls back to defaults.
Troubleshooting
- Nothing resolves after enabling
noresolv: the proxy is not running; start it and checklogread. - Handshake errors right after boot: the clock is wrong; add NTP servers by IP or set
cert_ignore_timestamp = truewhen using only DNSCrypt servers. - Log full of “possible DNS-rebind attack detected”: a filtering resolver returns
0.0.0.0; move rebinding protection into the proxy and setoption rebind_protection '0'fordnsmasq. - Query log shows no device addresses: expected, because
dnsmasqforwards; enablelogqueriesindnsmasqto see them.
The last point changes how you read the logs from dnscrypt-proxy on OpenWrt. Since every query arrives from dnsmasq, the proxy cannot tell which device asked. The wiki suggests option logqueries '1' with a logfacility path in /etc/config/dhcp, written to external storage, because flash memory has limited write cycles. Category-based blocking is covered on the filtering page.
Frequently asked questions
Do I use opkg or apk?
It depends on the release. OpenWrt 25.12 moved from opkg to apk, the Alpine Package Keeper, because the OpenWrt opkg fork is no longer maintained. On 25.12 run apk update and apk add dnscrypt-proxy2. Releases before it, such as 24.10, still use opkg update and opkg install with the same package name.
Why 127.0.0.53 and not port 53 on the router address?
dnsmasq already owns port 53 on the router because it answers DHCP clients. The package therefore rewrites listen_addresses to 127.0.0.53:53, a separate loopback address, and dnsmasq forwards to it. Clients keep asking the router as before and never need to know the proxy exists. The uci commands or the LuCI Forwards tab add that forwarding entry.
Where is the configuration file on the router?
The package installs it as /etc/dnscrypt-proxy2/dnscrypt-proxy.toml, next to a blocked-names.txt list it enables by default. Edit it over SSH, restart with /etc/init.d/dnscrypt-proxy restart, and add the folder to the backup list so a firmware upgrade keeps your changes. Without that entry, the edited file and any custom blocklist vanish with the old image.
Why does DNS fail after a reboot until the clock is set?
Certificate checks need the correct time, and routers without a battery-backed clock boot with the wrong one. NTP then needs DNS to resolve its servers, which needs the proxy, which needs the time. Listing NTP servers by IP address breaks the loop, or cert_ignore_timestamp helps when only DNSCrypt servers are used.