chadtmiller.com/knotless
git that lives in your Atmosphere account
The proxy holds knotless.page's certificate, and serve answers its sites
MergedThis adds an optional knotless.page block to the proxy. With KNOTLESS_PAGES_DOMAIN set, setup.sh builds Caddy with the Cloudflare DNS module, serves the apex and *. on one certificate, and passes the domain to serve as --pages-domain. I read the deploy changes (setup.sh, deploy.sh, docker-compose.yml, deploy.yml, local.env.example). I found nothing that must change.
- The token goes over ssh stdin into a file created under
umask 077, so it never shows in the process list. - A run with no domain falls back to stock
caddy:2and removes the Dockerfile. - An empty
--pages-domain ""is filtered toNoneinknotless-serve/src/lib.rs:1362, so the compose default is safe. - The compose heredoc is now unquoted so
$CADDYexpands. Nothing else in it contains$, so that is safe.
I did not read the other files in the diff (the knotless-serve and knotless crates, tests, docs, changeset). The diff is much larger than the description, and they look like the base branch's pages work, outside what this pull describes.
The unpinned module and the lack of a host run are both stated in the body. Run setup.sh against the host once feature/pages deploys.
Since my approval at b0f8c32, this pull has only had the pages/serve merge added, and that merge changes three things:
knotless/src/jetstream.rsaddsnsid::SITEto the collections the firehose keeps, so the index sees site records. This matches theindex.sitetest and the doc comment.knotless/src/site.rsswapswith_context(|| format!(..))for.context(format!(..)). It behaves the same. It builds the message eagerly, but only on the error path, so it costs nothing that matters.knotless-serve/src/index.rsis rustfmt reflow of a test.
I found nothing that must change. The deploy changes I reviewed before are unchanged. The unpinned module and the missing host run are still the open points the body states, so run setup.sh against the host once feature/pages deploys.
Since my approval at 14c0e37, the pull has added one test: the_firehose_keeps_every_indexed_collection in knotless-serve/src/lib.rs. It checks that every collection in indexed_collections() passes knotless::jetstream::knotless, so a collection can't be backfilled but dropped by the live firehose. Both functions exist with the signatures the test uses, and the assertion is sound. I found nothing that must change. The deploy changes are as before. The unpinned module and the missing host run are still the open points the body states, so run setup.sh against the host once feature/pages deploys.
Since my approval at 9d5f0c7, the pull has added hardening for the sites work. I found nothing that must change.
- SHA-256 check:
knotless::release::valid_sha256accepts only 64 lowercase hex digits.Siteschecks it before joining the hash into the kept-files path, andIndex::putdrops a site record with a bad hash. That closes a path-traversal hole through the record'ssha256. The index change moves the filter into SQL (INSERT … SELECT … WHERE ?5). It keeps the old behaviour of skipping non-sites and space records. The new test covers a traversal-style hash. - Backslash and control characters: a name containing
\or a control character now returns missing. Before, it could be redirected to/\evil, which a browser reads as another host. The integration test covers/%5Cevil.example. - Tests: the
pathhelper now returnsOption, andhandlein the owner test is the local closure. Both compile as written.
The checks are still queued, so I haven't seen them pass. The deploy changes are as before. The unpinned module and the missing host run are still the open points the body states, so run setup.sh against the host once feature/pages deploys.
What changes
deploy/setup.sh, givenKNOTLESS_PAGES_DOMAIN, sets the proxy up for repositories' sites. With it set, the script:caddy-dns/cloudflaremodule, from a Dockerfile in/etc/knotless-proxy;knotless.page, *.knotless.pageblock, whose one certificate comes from the DNS challenge, proxying to serve;KNOTLESS_PAGES_DNS_TOKEN, sent over ssh stdin so the host's process list never shows it, and keeps it in a0600/etc/knotless-proxy/cloudflare.env.The token is given once, like
run.env,triage.envandreview.envare: a run without it keeps the file there, and with no file at all the run stops and says the token is needed once.deploy.ymlsetsKNOTLESS_PAGES_DOMAIN: knotless.page, whichdeploy.shwrites to.envand the compose file passes to serve as--pages-domain. It's empty, and so off, when unset.The
deploy/README.mdproxy section andlocal.env.exampledescribe both.Why
A wildcard certificate can only come from the DNS challenge, which stock Caddy can't answer. The zone's token is scoped to knotless.page alone, and is the one in hetzner-infra's edge stack, which already made the zone's apex and
*records.Each step converges, as the rest of
setup.shdoes. A rerun writes the same Caddyfile, Dockerfile and compose file.up -d --buildbuilds the image once and from cache after, so a run that changes nothing recreates nothing. Without the domain, the proxy goes back to stockcaddy:2and the Dockerfile is removed.How it was checked
bash -non both scripts. Not run against the host yet: that'sdeploy/setup.shwith the token indeploy/local.env, once this lands on main with the rest of feature/pages.Shortcomings
Nothing serves knotless.page until feature/pages reaches main and deploys. The module is unpinned, built from
caddy:2-builderas stock Caddy iscaddy:2.🤖 Generated with Claude Code