[Tutorial] [No CLI] Configuring DNS over TLS with LuCI using Stubby and Dnsmasq

I recently decided to implement DNS over TLS and found that many tutorials were not oriented to those who are less tech savvy. This is a simple approach which allows you to do all configuration in LuCI without any CLI commands. I have to give credit to https://candrews.integralblue.com/2018/08/dns-over-tls-on-openwrt-18-06/, as that is where I got my setup instructions from, and just figured out how to do them in LuCI


  • This setup expects you to use Cloudflare's DNS resolvers. If you want to use an alternative such as Google DNS, you will have to use some CLI.
  • This tutorial is based on the latest master branch commit as of 2018-01-10. The steps may be similar for different versions or setups, but are not guaranteed. Most likely these steps are going to be the same for 18.06.1, but I don't quite remember the differences in LuCI.


  1. Log into LuCI at, go to System -> Software, and hit the Update Lists button.
  2. Filter down to find the package called "stubby", and click the Install button. For OpenWrt 18.06.1 users, also install "ca-certificates" and "ca-bundle". This is needed due to a missed dependency on the stubby package. Newer versions of OpenWrt corrected this.
  3. Go to System -> Startup, find stubby, and click the Start button. Also set stubby to "Enabled" on this same screen.
  4. Under Network -> DHCP and DNS, click the "Resolv and Hosts Files" tab, and put a check mark next to "Ignore resolve file". Press Save & Apply.
  5. Under Network -> DHCP and DNS, click the "General Settings" tab, set the "DNS forwardings" list to 0::1#5453 and
  6. Go to System -> Startup, find "dnsmasq" and click "Restart".

Your done! To verify everything is working, open a new tab in your internet browser and try to go to some websites you don't normally go to. You can also go to https://www.cloudflare.com/ssl/encrypted-sni/ and press "Check My Browser". You should see green check marks for "Secure DNS" and "DNSSEC".

Edit 2021-03-13:
Removed step to set custom DNS servers on WAN and WAN6 due to the research from @open.nya, @jbrossard, and @thekiefs. Thanks!


It is not working: Stubby produces following error:

Could not schedule query: None of the configured upstreams could be used to send queries on the specified transports

As a result I have no internet connection.
I am using OpenWrt 18.06.1 r7258-5eb055306f / LuCI openwrt-18.06 branch (git-18.228.31946-f64b152)

Thats not good. I will do a fresh install of 18.06.1 when I get home from work today to test. In the meantime, in DHCP and DNS you can change from the localhost resolver to your favorite DNS resolver, or under your WAN and WAN6 interfaces, recheck "Use DNS servers advertised by peer".

Sorry for any inconveniences and I'll keep you updated on what I find.

Alright I looked into this more. Looking at https://github.com/openwrt/packages/issues/6682, the dependencies for 18.06.1 r7258 are not correct for stubby. Can you also install "ca-certificates" through System -> Software? If that doesn't fix it, can you also install "ca-bundle"?

You may need to restart stubby/dnsmasq after installing.

Thank you very much Ajkay. Ca-Bundle did the trick.

One more thing I noticed: I am using chromecast. It is still using google-public-dns-a.google.com:53. I restarted chromecast, did not help.
Maybe I should not ask it in your thread, instead opening a new one....

Glad to see that it is working!

In regards to your Chromecast, looks like they are hard coded to use Google DNS. Two ideas on what you can try - either build iptable rules to block Google's DNS (and hoping they fall back to honor your systems DNS), or static route them back to your default gateway. Not sure either will work though, so a new thread may be a good idea.

You can rewrite the DNS queries with a little work. Do something along the lines of the following in firewall.user:

iptables -t nat -N DNSFILTER

iptables -t nat -A DNSFILTER -m mac --mac-source <chromecast-mac-address> -j DNAT --to-destination <my-dns-server-ip-address>

iptables -t nat -I prerouting_lan_rule -p tcp -m tcp --dport 53 -j DNSFILTER
iptables -t nat -I prerouting_lan_rule -p udp -m udp --dport 53 -j DNSFILTER

Just remember that when you test this that on the LAN side the DNS query will still have the google dns servers as their destination address as the rewrite hasn't occurred yet - so you'll have to packet trace on the WAN side to verify that this is working.


Unfortunately I am a noob when it comes to ACL.
logread writes following error message:

daemon.err uhttpd[722]: Parse error (invalid command) at line 127, byte 1
daemon.err uhttpd[722]: Error: Failed to load /etc/config/firewall

Did you replace the '<text>' with IP addresses and mac-addresses ? (don't include the angle brackets themselves).

If you want to make things really simple you can just do the following:

iptables -t nat -N DNSFILTER

iptables -t nat -A DNSFILTER -j DNAT --to-destination <my-dns-server-ip-address>

iptables -t nat -I prerouting_lan_rule -p tcp -m tcp --dport 53 -j DNSFILTER
iptables -t nat -I prerouting_lan_rule -p udp -m udp --dport 53 -j DNSFILTER

Which will rewrite DNS queries for every device - as it is not mac specific - to force them to use your DNS server (probably the router IP in this case).

If you are going to go down this road, it's probably worth going through the iptables man page at some point, it's not terribly difficult to understand and it'll give an idea as to the capabilities of what else you may be able to do: https://linux.die.net/man/8/iptables

Thx cbz. Yes I did change it without brackets etc. I am going to dive deeper with your provided link.

Okay - something else occurred to me. These are not changes you apply to /etc/config/firewall. These rules go in /etc/firewall.user.

They are effectively a set of standalone commands to iptables - applied after the /etc/config/firewall script has been interpreted and used to set up the openwrt firewall.

Maybe they're should be one more better luci client

Step five breaks Dynamic DNS because the router can't resolve addresses. Drill in the router can't resolve anything. Also, I don't know why that step is necessary because after step 4 /etc/resolv.conf simply points to the router's loopback address.

The problem may be that step four is missing some information. From ReadMe:

  1. Unselect the "Use DNS servers advertised by peer" checkbox
  2. Enter in the "Use custom DNS servers" dialogue box.
  3. Repeat the above steps for the WAN6 interface, but use the address 0::1 instead of

If I do the above I can check "Ignore resolve file" and DDNS still works.

Thanks for finding this and digging into an answer! I will update the original post when I am home later tonight or tomorrow.

Where is it specified that it should use Cloudflare's nameservers?

And later, is there a way I can verify it uses for lookups, preferably without tcpdump?

/etc/config/stubby is setup out of the box to use the Cloudflare nameservers.

Verify at https://www.cloudflare.com/ssl/encrypted-sni/

1 Like

the wiki it's pretty comprehensive and clean now


This makes the internet connection broken after an OpenWRT firmware update. It seems that I need to restore the DNS setting to download "Stubby" (because of broken connection I could not download it), and then go through the whole procedure again.

Since DNS over HTTPS seems to be a popular feature now, I hope OpenWRT would come with this feature out-of-the-box without the need of all these procedure.


I thought the same thing and was fully reconfiguring after every update. All you have to do to is reset the interfaces by checking Use DNS servers advertised by peers for each to be able to resolve.. then opkg update, install stubby, and redo the interface settings (uncheck Use DNS servers advertised by peers for wan and wan6, and input the respective custom dns servers and 0::1)

You don't have to go through all the steps.. hope that helps

1 Like