Warda-DNSDocs Warda: from ward — to protect, guardian
v0.9.3

Encrypted DNS for the devices

Network → DNS services (GET /api/v1/dns-services, administrators) serves DNS over TLS (RFC 7858, port 853), over HTTPS (RFC 8484, path /dns-query on the HTTPS port of the interface) and over QUIC (RFC 9250, port 853 UDP), with the same answers, rules and clients (allowed ranges, people, journal) as DNS on port 53. The queries are counted by protocol.

The phones only accept the certificate of a public authority for the name they are given. PUT /api/v1/dns-services/certificate chooses how to get it:

Mode Name Certificate
warda (recommended) given by the online service of Warda: <10 letters>.warda-dns.net Let's Encrypt, DNS-01 challenge written by the service (cloud)
domain a name of the owner (dns.maison.example) Let's Encrypt, DNS-01 challenge written with a Cloudflare API token (Zone.DNS edit) or the keys of an OVH application (/domain/zone/*)
self any name made by Warda (ECDSA P-256, 2 years), signed by an authority of its own limited to that name, to trust on each device
import the first name of the certificate that is not a wildcard (a wildcard alone is refused) given with its key (PEM), renewed by its owner

In self mode, Warda makes an authority for the name of the box, then the server certificate it signs. That authority is what the Apple devices install as a root, so it can only vouch for the name of the box: critical name constraints allow that name (and its subdomains) alone and no IP address, it cannot sign another authority (MaxPathLen 0), and its key is discarded once the certificate is signed. A certificate made in self mode by an older version (its own authority, for any name) is made again when Warda starts: the profile must then be installed again on the Apple devices. For 60 days the page of the DNS services and the state of the services on the dashboard say so (remade in the certificate state and in services.encrypted).

The certificate, its key, the key of the ACME account and the key of the box at the online service are in tls/ of the data directory (owner only). A new certificate and its key are first written together to tls/dns.pending, then copied to dns.crt and dns.key: an install that a stop interrupts is finished at the next start, so the key never goes without its certificate. The certificate is obtained in the background (the page follows it) and renewed 30 days before its end (task certificate), or at once when a certificate made by Warda stands where one of an authority is wanted (a first try that failed). A certificate obtained in the background (a renewal, or a first one obtained on a retry after a failure) is served at once, as one obtained from the page, restarting the listeners when needed; a change of the name of the certificate drops the old name (Warda no longer answers it). The keys of a DNS provider are kept in the database and never shown again. Warda answers the name itself with its own address: it is never published, and nothing of the box but its key and its identifier goes to the online service.

The card of the certificate shows its state (valid; to renew, from 30 days before its end, tried twice a day; expired), when it was obtained (not_before), until when it is valid (not_after), from when it is renewed (renew_at), the last check of the renewal since the start (last_check: 10 minutes after the start, then every 12 hours) and the last request with its result (last_try, last_error).

The name given by the online service is random (10 characters, about 50 bits), not the identifier of the installation: every certificate of Let's Encrypt is published in the public logs of Certificate Transparency, so a name made of the identifier would publish it. The box is known to the service by a key of its own (ed25519, tls/cloud.key), the same at each renewal, so it keeps its name. When another mode is chosen, Warda gives the name back (DELETE /v1/boxes, signed, after a certificate being obtained, and not when the mode is the online service again meanwhile): the service forgets the identifier of the installation, and gives the name to no other box for a year; a box that stops coming is released by the service all the same (see cloud).

The first certificate turns the three protocols on; PUT /api/v1/dns-services/protocols chooses them. A change restarts Warda (a few seconds without names): DoT and DoQ are listened to, and DoH is served on the HTTPS port, which gives the certificate of the encrypted DNS to the clients that ask its name (SNI) and the certificate of the interface to the others (from 0.7.10 whether DNS over HTTPS is on or not, so that the interface is trusted at that name, see From HTTP to HTTPS; /dns-query answers DNS questions only while DNS over HTTPS is on). GET /api/v1/dns-services/profile gives a profile for iPhone, iPad and Mac (.mobileconfig, DNS over HTTPS, with the limited authority as a root when the certificate is made by Warda). DNS over QUIC drops the datagrams of the clients outside the allowed ranges before the handshake. Android takes the name in Private DNS, Windows 11 the address of the box and the DoH template, the browsers the DoH address. These addresses work on the network of the house only: an Android phone keeps its private DNS everywhere, and outside it gets no names at all with this one (the page and the guide say so). Outside the house, from 0.8.0, a device can use instead its own address of the protection outside the home, at the online service (on Android through an app, since Private DNS takes a name, not an address).

The page is in two groups: Encrypted DNS for your devices, two steps (1. Certificate: the identity, its name and its certificate; 2. Protocols and devices: the protocols, then the settings of each kind of device, Android, iPhone and iPad, Mac, Windows 11, Linux, the browsers, TV and consoles, each with a Guide link), then How Warda answers (DNSSEC, the answers, IPv6). A Guide link opens https://docs.warda-dns.com/<language>/link/dns-<kind>/ in a new tab: a stable link of the documentation site to the part of chapter 9 of the guide (docs site).

The probes (task probes, 90 seconds after the start then every 15 minutes, and POST /api/v1/system/probes at once): the certificate (present, in force, trusted by the public authorities for its name, or its own authority in self mode; warn when the renewal failed past its date), the online service of Warda when the box uses it for its name (GET /healthz, nothing sent), and each protocol served, asked for real as a device would: a connection to the box with the name of the certificate, the certificate checked, a question (the root, NS) and its answer (DoT with the framing of TCP, DoH by POST on /dns-query, DoQ on a QUIC stream). services.probes of GET /system gives, for cloud, certificate, dot, doh and doq: state (ok, warn, failed, off), detail (the error, without address), at and ms. The card Online services of the dashboard shows Certificate service, then a line for each protocol (since 0.6.9): DNS over TLS (DoT), DNS over HTTPS (DoH) and DNS over QUIC (DoQ), each Answering, Not answering (the error under it) or not used, with the age of its check (see Reports); each protocol on the page has Checked or Check failed with the error. The box asks itself, from inside: a probe says the protocol is served and answers, not that the devices reach it (a firewall or a router between them and the box is not seen; the Network check and the device itself tell that).