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

From 0.8.3 (beta, free; function block-page of the catalogue; internal/blockpage). The request behind it: the people of a household did not understand that Warda blocked a page, which simply did not open. With the answer Block page (see Answers: "blocked_response": "page"; the null address stays the default, and a box that was already installed keeps its answer), a browser that asks a blocked site shows "Blocked by Warda" instead.

How. The DNS of Warda answers a blocked name with the address of the box on the network the query came from: A with its IPv4 address there (the addresses set by WARDA_ADVERTISE_ADDR first: a container whose own address is not the one the network reaches), AAAA with its IPv6 address there, or :: when it has none but a link-local one; the short TTL of the blocked answers (WARDA_BLOCKED_TTL, 10 seconds). The other types get an empty answer, as with the null address. The browser then asks the box for the page; the box recognises the name (by the Host of the request, or over HTTPS by the name of the TLS handshake, SNI) and answers the block page, whatever the path, never the interface, its API nor the redirection to HTTPS: a request for one of the names or addresses of the box goes to the interface as before. Apps that are not browsers simply fail, as with the null address.

What keeps the null address (or NXDOMAIN), whatever the mode:

  • the devices outside the home (the relay and its DoH): the box is not reachable at a home address from there;
  • the names of a confidential list: the category of child sexual abuse material and the lists of hashes — the page could not tell them, and the name must never be kept (below);
  • the category bypass, which always gets NXDOMAIN.

The page. HTTP status 403, in the language of the browser (Accept-Language; English, French, Spanish, German, Dutch, Italian, Portuguese; English otherwise): the name of the site, why in plain words (on a block list of this network; blocked by an administrator; outside the Internet hours; the service, or the category, blocked for this profile; a leak through DNS; a look-alike name; a spyware; a rebinding; the quarantine of the device; the data protection policy; the restricted mode of an object; a mining pool; the analysis service of Warda), and the time. Then, for the device the block was decided for: Ask for more time when the reason is the Internet hours (the page /ask of the box), Ask to unblock it when the unblock requests are available and the reason can be lifted by one (never a leak through DNS, a look-alike, a spyware, a rebinding, the quarantine, the hours, a mining pool); otherwise "A mistake? Tell the person who manages this network." And a link to the certificate page (below). The links lead to the plain HTTP listener of the box, at the address the request reached.

  • Never another member's data: the reason is shown only to the device (its address) the block was decided for; any other address gets the name, the time and "The reason is shown only on the device it was blocked for."
  • Nothing from elsewhere: one inline style allowed by its hash, no script, no image, no font, no frame, no form (Content-Security-Policy: default-src 'none'; style-src 'sha256-…'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'), Cache-Control: no-store, X-Frame-Options: DENY, Referrer-Policy: no-referrer, noindex.
  • Rate limited: 5 pages a second by address (burst 20), 429 beyond.
  • Only for the networks allowed to use the box (the same rule as the interface).

The memory of the blocks. To know the reason, the box keeps the last block decision by device and name: 10 minutes, 8,192 at most, the least recently used out but never a name blocked less than 5 minutes ago, in memory only (never on disk, never in a backup, gone at a restart), and only in the mode page. The box answers its own address only for a name it keeps in that memory: when the memory is full of recent blocks, a new block gets the null address instead (so a page cannot push its own name out and then reach the interface under that name — DNS rebinding). The answers of the mode page live 60 seconds at most, whatever the TTL of the blocked answers; each block page shown renews the name. A name not blocked within 10 minutes is no longer recognised, and the box answers it as any request (the interface, or 404). The names of the confidential lists (and a name blocked because its CNAME target is on one) are never kept and always get the null address.

The local certificate authority#

Over HTTPS, the browser checks the certificate of the site it asked; the box cannot present the real one. So the box has its own certificate authority: ECDSA P-256, valid 10 years, made on first use (when the mode page is chosen, or the certificate page opened), in the data directory, blockca/ (ca.crt, and ca.key readable by Warda only, 0600). For a name blocked lately, the HTTPS listener presents a certificate for that name, made on the fly and signed by this authority: valid 48 hours (made again a day before its end), 512 kept in memory (least recently used out), 10 made a second at most for all names (burst 30; beyond, the usual certificate of the box is presented). The authority signs only servers, only names (never an address, never another authority), and only the names blocked lately; the names of the box keep their own certificate.

  • Without the authority installed on a device, the browser shows its security alert first; once past it (when the browser allows it), the block page shows. Installed, the block page shows at once.
  • Never in a backup: the backups take only the files they name, and blockca/ is not one. A restored box makes a new authority, to install again on the devices; the key never leaves the box that made it.
  • In a pair of high availability, each box has its own authority (the configuration given to the secondary does not carry it): a device that may be answered by either installs both certificates (the certificate page of each box).
  • Make a new authority (Network → DNS services → Answers, administrators, after a confirmation; POST /api/v1/dns-services/block-authority/regenerate, written to the administration log as blockpage.authority): when the key may have been copied, or to start afresh. The devices that installed the old one show the alert again until they install the new one.

The page DNS services shows, under Answers, the SHA-256 fingerprint of the authority and the date it was made (or that it is made at the first use), a link to the certificate page, and Make a new authority. The dashboard says Block page on.

The certificate page#

http://warda/certificate (or the address of the box), no sign-in, linked from the block page; only for a request that names the box (its names, localhost, an address: never a name of another site pointed to it), from the networks allowed, rate limited as the block page. It gives:

  • the certificate of the authority (never its key) as warda-ca.crt (DER: Windows, Android, macOS), warda-ca.pem (Linux, Firefox) and warda-ca.mobileconfig, a profile for iPhone, iPad and Mac ("Warda — block page"; a new authority gives a new profile, the same one installed again replaces itself): GET /certificate/<file>;
  • its SHA-256 fingerprint, to compare with the one the device shows before trusting it, the date it was made and the end of its validity (GET /api/v1/certificate, JSON);
  • the steps for Windows (the store "Trusted Root Certification Authorities", used by Edge and Chrome), Mac (the profile, or Keychain Access, "Always Trust"), iPhone and iPad (the profile in Safari, then Settings → General → About → Certificate Trust Settings, full trust), Android ("CA certificate" in the settings; Chrome trusts it, many apps ignore the certificates added by the user), Linux (update-ca-certificates or update-ca-trust; Chrome and Chromium keep their own list there) and Firefox (its own store, on every system; or security.enterprise_roots.enabled on Windows and Mac), and how to remove it;
  • a plain warning: a device that installs it trusts every certificate this box makes; Warda makes them only for its block page and its key never leaves the box, but install it only on your own devices, only from the Warda of your home or organisation, and remove it when the device leaves the network.

The same steps are in the user guide, chapter 5.

Limits#

  • Ports 80 and 443 are required. Browsers ask the blocked sites on 80 and 443: when the web interface listens elsewhere (WARDA_HTTP_LISTEN :8080, WARDA_HTTPS_LISTEN :8443, beside a reverse proxy, see Run with Docker), they cannot reach the block page and show a connection error instead. The page DNS services says so, with the ports in use; with Docker, publish the ports 80 and 443 of the machine to those of Warda.
  • Sites with HSTS (the large sites, those preloaded in the browsers): without the authority installed, the browser shows its alert with no way past it; installed, the page shows. A site or an app that pins its certificate refuses it whatever.
  • Apps (not browsers) fail as with the null address: the page is for people at a browser. Many apps on Android ignore the certificates added by the user.
  • A browser with its own encrypted DNS, or a device whose DNS is not Warda, never asks Warda: it gets neither the block nor the page (see Encrypted DNS for the devices).
  • The page may come a few seconds late for a name the device asked just before it was blocked (the answer in its cache).

Privacy. The block decisions are kept in memory only, 10 minutes, bounded, for the device they were decided for; never the names of the confidential lists; nothing is written to the database (no change of the schema in 0.8.3), nothing sent to the online service. The key of the authority stays in the data directory and out of the backups. Allowed names: a name an administrator allows (My rules, for everyone or for a device: allowing always wins) is never blocked by a list — a downloaded list, a list of hashes, a list behind a CNAME, the reputation, a category (but the child sexual abuse material) — so it never gets the block page; a test proves it from 0.8.3.