Automatically chooses the best encrypted DNS transport for OpenWrt.
DoTorDoH uses stubby (DoT) and https_dns_proxy (DoH) to transparently switch
between DNS-over-TLS (DoT) and DNS-over-HTTPS (DoH) depending on network
conditions. On networks where outbound TCP/853 is blocked, it automatically
falls back to DoH. After a WAN interface change, it checks upstream reachability
and selects DoT when TCP/853 is reachable; otherwise, it uses DoH.
- Automatic DoT/DoH detection
- Automatic switching without restarting the router
- Minimal dependencies
- Built for OpenWrt
- Ensures only the router's DNS is advertised to clients
The default configuration uses Cloudflare DNS.
Clone the repository:
git clone https://github.com/stldo/dotordoh
cd dotordohBuild the standalone command:
./bundle.shInstall the bundled command on the router as root:
./dist/dotordoh installInstallation configures the shield, refreshes active WAN interfaces, and enables and starts the dotordoh service.
The bundler requires Zsh and can be invoked from any working directory. It
creates dist/dotordoh for OpenWrt's ash. Imports are included once, with
each command checking its own direct and transitive requirements.
dotordoh [COMMAND] [OPTIONS]
Available commands:
| Command | Description |
|---|---|
install |
Install and initialize DoTorDoH |
monitor |
Automatically switch between DoT and DoH |
shield |
Advertise router DNS on IPv4 and IPv6 |
Starts the resolver and evaluates DoT availability. It first checks for upstream reachability over TCP port 53, then checks whether TCP port 853 is reachable.
DoTorDoH uses DoT when it is reachable and otherwise switches to DoH. The decision runs once during application boot and whenever a WAN interface change with internet connectivity is detected.
Example:
dotordoh monitorConfigures the local OpenWrt DNS services to forward all client queries through the local resolver instance, overwriting WISP, ISP, and other DNS configurations.
- Disables PeerDNS on WAN interfaces
- Configures dnsmasq to advertise the router as the DNS server
- Enables DHCPv6
- Enables Router Advertisements
- Advertises the router's ULA through RDNSS
Example:
dotordoh shieldWaits until the local resolver instance is ready to accept DNS queries. It repeatedly queries the local resolver until it becomes available, then exits successfully. If the resolver does not become ready within the timeout period, the command exits with an error.
Example:
dotordoh shield -wConfiguration can be customized through .env.
Example:
LOCAL_PORT=5453
MONITOR_REACHABILITY_ATTEMPTS=12
MONITOR_REACHABILITY_DELAY=5
DOH_DOMAIN="cloudflare-dns.com"
DOH_PATH="/dns-query"
DOT_DOMAIN="1dot1dot1dot1.cloudflare-dns.com"
LAN_INTERFACE="lan"
WAN_INTERFACES="wan wan6"Configure dnsmasq to forward client DNS queries to the local DoT/DoH resolver.
The forwarding port must match LOCAL_PORT:
uci set dhcp.@dnsmasq[0].noresolv='1'
uci delete dhcp.@dnsmasq[0].server
uci add_list dhcp.@dnsmasq[0].server='127.0.0.1#5453'
uci commit dhcp
/etc/init.d/dnsmasq restartIf LOCAL_PORT is changed, use the same port in the dnsmasq server value.
The resolver services listen on IPv4 loopback, so do not add ::1#5453 unless
you have separately configured them to listen on IPv6 loopback.
Automatic mode first checks whether any configured upstream can be reached on TCP port 53. If upstream reachability is available, it checks whether a TCP connection to a configured DoT endpoint (port 853) can be established. If reachable, DoT is used; otherwise, it falls back to DoH (port 443).
Mode selection runs:
- Once during application boot
- When a WAN interface change with internet connectivity is detected (e.g. connecting to a new Wi-Fi or cable network)
After each WAN interface change, the monitor retries the reachability check for a short, bounded period while the connection is coming up. If reachability is not established, it waits for the next WAN interface change.
Network/interface changes that do not result in an available internet connection do not trigger the decision logic.
- GNU netcat
- https-dns-proxy
- Stubby
apk add https-dns-proxy netcat stubby
The project relies on other standard OpenWrt utilities, including:
- awk
- dnsmasq
- flock
- ifup
- ip
- jsonfilter
- nslookup
- sleep
- ubus
- uci
For commercial licensing, inquiries can be submitted via stldo.com.
Copyright (C) 2026-present stldo