DoT in Turris Omnia for connecting Android (Private DNS option) over Wireguard

I use Wireguard to route the traffic from my mobile phone to my router. How could I enable DoT on turris Omnia to be able to activate Private DNS on Android.

Not quire sure what you are asking. You want the TO resolver instance to act as DoT server for the Android peer as Private DNS provider (DoT)?

That might be quite extensive to achieve since the Android option (Private DNS provider) does not accept IP addresses but (resolvable) hostnames only.
Also you would need to configure the TO resolver instance as DoT server, with certificates and all.
Plus once the Android gets disconnected from the WG tunnel the Android device will loose DNS resolution until either the WG tunnel is restored or a another DNS provider is set.

There are other ways however to utilize the TO resolver instance from the client. Assuming that

  • access to the resolver instance on the TO (kresd ?) is not inhibited by firewall rules or resolver access rules
  • the resolver instance on the TO is utilizing DoT with public upstream servers

there are at least two potential ways:

  1. set the IP of the resolver that runs on the TO as DNS server in the WG app on the Android device


  1. with a firewall port forward rule on the TO force all DNS queries that egress port 53 on the WG interface to the resolver on the TO - this works via UCI | LuCI for IPv4 only and requires manual scripting for IPv6

I think you meant the Android feature where the auto-configured IP address for DNS server gets auto-upgraded to TLS (opportunistically, i.e. without checking server’s identity). There are two steps, in any order:

  1. get the DNS to Turris. Maybe you have this already. Anyway, I’m no expert on this one, but I’ve seen at least one success story for wireguard here on the forum. Perhaps just note that the resolver on Turris listens on all addresses, so you most likely want the address from the wireguard subnet.
  2. make Turris serve DoT. Add custom config line:
    net.listen({'', '::'}, 853, { kind = 'tls' })


  • I had thought about making this default; perhaps we will do that in future, say, using the same cert as the https service.
  • With just the line above you get an ephemeral self-signed certificate. That should be sufficient for Android’s auto-upgrade, but you might e.g. want some Let’s Encrypt instead… in kresd config that would be just adding another simple line.
  • The path downstream (from kresd to clients) is completely independent of the path upstream. If you want TLS there (as well), some basic options are provided by the Foris/DNS tab already (“Forwarding”).

Not sure where that can be set in Android or how that WG implementation in Android.

As for private DNS mode one can set an upstream server

It requires a DNS hostname (implemented by G to get around dual IP stack implementation) in the TLS certificate. Not sure whether/how Android’s CA bundle deals with self-signed or LE signed certificates for local domain names

Te be clear, I’ve been writing about the “Automatic” option the whole time.

But then you cannot leverage the resolver instance on the TO since as far I am aware automatic does not just upgrade to TLS opportunistically but also sets the G upstream server (conveniently) for DNS queries and which is not impacted by the DNS server that can be set in the WG settings on the Android peer.

I believe this default/automatic mode normally keeps the IP address for DNS that Android got from DHCP (and probes it on port 853). Still, I don’t really know how it interacts with “VPNs”, etc.

1 Like

Turned automatic on with Android 9 client and run a tcpdump on the port that connects to the TO and the Android client instantly switched DNS queries to on port 853, effectively bypassing (hijacking) the DNS settings provided through DHCP from the router.

This not widely known and neither well documented.

However, Android may have probed first the DNS server provided through DHCP from the router, and since DoT not being implemented with the local resolver instance on the router the TLS probe failed and Android then turned to their own upstream DNS server.

On a side note - G also enforces a secondary DNS server ( in addition to the the one propagated from upstream DHCP.

I use a DoT from the list in foris.
Let’s encrypt is currently no solution for me.
I wish to use the DNS from my router because it should resolve also host names from my network.
May in a later time I try to set-up a Pi hole on Turris Omnia, so I need my phone using the DNS from the router.

in which section of /etc/config/resolver would you put net.listen({‘’, ‘::’}, 853, { kind = ‘tls’ }) ?

This pertains to

and is not relevant to what you want achieve.

That line goes into a separate file – and the link I provided shows the rest.

Thanks. Did it that way. I thought it was wrong because setup Private DNS tells me connection not possible.

/etc/kresd/custom.conf contains now
net.listen({'', '::'}, 853, { kind = 'tls' })
and /etc/config/resolver
`option include_config '/etc/kresd/custom.conf'`

Yes, that sounds correct to me.

What do you mean? (Where have you seen that?)

If I enter the hostname from the router in Android in the Option “Private DNS provider hostname”,
below the “Enter hstname of DNS” entry I get this feedback.

Ah, I see. That’s a name to verify TLS certs against, like in https://hostname . This “Let’s Encrypt route” is more secure but more difficult to set up.

What happens when set to automatic instead?

How could I verify that Android use my router if I set it to Automatic?

Probably only with packet inspection (tcpdump) on the router port where the traffic from the Android client is entering the router.
Or, if kresd provides logging facilities for client requests.

Verbose logging in kresd does contain that. It’s actually too verbose for most purposes, so it might be harder to find what you need. Still, that only shows what goes to kresd, not e.g. whether also something goes to… so tcpdump is the surest way (there it’s hard to inspect inside of TLS, of course, but that shouldn’t be needed here).

packet capture supports that probing

and switching to G’s upstream server once the probe fails