diff --git a/website/demo/.gitignore b/website/demo/.gitignore new file mode 100644 index 0000000..c213cb1 --- /dev/null +++ b/website/demo/.gitignore @@ -0,0 +1,5 @@ +node_modules/ +__pycache__/ +shots/ +screenshots.html +.cookies diff --git a/website/demo/README.md b/website/demo/README.md new file mode 100644 index 0000000..28082fc --- /dev/null +++ b/website/demo/README.md @@ -0,0 +1,81 @@ +# Screenshot demo + +A synthetic household that produces the admin screenshots in `../src/assets/screenshots/`. Six devices on a docker LAN send real DNS traffic through the published nxdns image, real public blocklists decide what is blocked, and the bulk of the traffic is then spread over the previous 24 hours so the Overview shows a believable day. Nothing here is real household data, and no device carries a person's name. + +| Device | Address | Group | +| --- | --- | --- | +| nxdns | 192.168.50.2 | — | +| Living room TV | 192.168.50.41 | default | +| iPhone | 192.168.50.52 | default | +| Pixel | 192.168.50.53 | default | +| Kids' phone | 192.168.50.54 | kids (safe search, gambling and NSFW lists) | +| Desktop PC | 192.168.50.20 | default | +| MacBook Air | 192.168.50.21 | default | + +The LAN is 192.168.50.0/24 because the machine that first ran this uses 192.168.1.0/24 for its real network. The admin UI is on , password `nxdns-demo`. Upstreams are Cloudflare DoH with Quad9 DoT as failover; Quad9's DoH endpoint requires HTTP/2, which nxdns does not speak. + +Run every command from this directory. It needs docker, Node.js and Python 3. + +## Generate the household + +`NXDNS_IMAGE` picks the image; it defaults to the version the committed screenshots show. Set it to the release the new screenshots are for. + +```sh +NXDNS_IMAGE=git.mial.net/mokhtar/nxdns: ./start.sh +``` + +Wait until `/api/blocklists` reports all four lists loaded. Then shrink the cache for the compressed bulk run, so the cache-hit share stays near what a real day produces, and send the bulk traffic: + +```sh +curl -s -c .cookies -H 'content-type: application/json' -d '{"password":"nxdns-demo"}' http://127.0.0.1:18080/api/auth/login +curl -s -b .cookies -X PUT -H 'content-type: application/json' -d '{"cache":{"size":48}}' http://127.0.0.1:18080/api/settings +./devices.sh bulk +``` + +The bulk run sends about 18,000 queries. Wait until all six device containers have exited, then restore the cache and rewrite the history while nxdns is stopped. `check_coherence.py` runs the repository's projection oracle and must print no `FAIL`: + +```sh +curl -s -b .cookies -X PUT -H 'content-type: application/json' -d '{"cache":{"size":10000}}' http://127.0.0.1:18080/api/settings +docker stop nxdemo-nxdns +./db.sh /gen/rewrite_history.py /data +./db.sh /gen/check_coherence.py /data +docker start nxdemo-nxdns +./devices.sh live +``` + +`gen/check_profiles.py` prints each device profile's expected blocked share through `/api/lookup`. Use it when you change `gen/profiles.py`. + +## Produce a Diagnostics episode + +Cut the primary DoH upstream off inside nxdns's network namespace, wait about two minutes, and restore it. nxdns opens an "Upstream failing" episode and closes it on its own after the routes come back. Check that the addresses are still the ones `cloudflare-dns.com` resolves to. + +```sh +docker run --rm --net container:nxdemo-nxdns --cap-add NET_ADMIN python:3-alpine ip route add blackhole 104.16.248.249/32 +docker run --rm --net container:nxdemo-nxdns --cap-add NET_ADMIN python:3-alpine ip route add blackhole 104.16.249.249/32 +docker run --rm --net container:nxdemo-nxdns --cap-add NET_ADMIN python:3-alpine ip route del blackhole 104.16.248.249/32 +docker run --rm --net container:nxdemo-nxdns --cap-add NET_ADMIN python:3-alpine ip route del blackhole 104.16.249.249/32 +``` + +## Take the screenshots + +The first time, install the pinned Playwright and its browser: + +```sh +npm ci +npx playwright install chromium +``` + +Then shoot all five pages in light and dark at 1440×900, 2× scale, and build a contact sheet to review them: + +```sh +node gen/shoot.mjs shots "$(./db.sh /gen/blocked_query_id.py /data)" +python3 -I gen/contact_sheet.py shots screenshots.html +``` + +Review the sheet before anything replaces the files in `../src/assets/screenshots/`. + +## Tear down + +```sh +./teardown.sh +``` diff --git a/website/demo/db.sh b/website/demo/db.sh new file mode 100755 index 0000000..51957c3 --- /dev/null +++ b/website/demo/db.sh @@ -0,0 +1,8 @@ +#!/bin/sh +# usage: db.sh /gen/