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 asblockpage.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) andwarda-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-certificatesorupdate-ca-trust; Chrome and Chromium keep their own list there) and Firefox (its own store, on every system; orsecurity.enterprise_roots.enabledon 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.