Releases: DevInIndia/hollow
Releases · DevInIndia/hollow
Release list
hollow v1.0.1: fix cosmetic filter rules blocking real domains
Fixes a bug where adblock cosmetic rules (example.com##.ad-banner) blocked the
domain itself rather than being skipped. The hosts-file comment rule cut each
line at its first #, so the rule arrived as the bare name example.com. The
exception form #@# did the same. Any EasyList-style file would take out the
sites it was written to clean up, silently.
v1.0.0 binaries should not be used.
Also in this release: the planning notes are gone from the tree, and the README
is rewritten as a product page, down from 8,801 words to 2,225.
Verifying a download
hollow v1.0.0
build: publish four targets, and let a container check the hash One published hash covered one platform, and the download most people would reach for was the one nobody could verify. make release now cross-compiles the same four targets the verify gate already builds, from one TARGETS list so that a target which ships is a target known to compile, and writes dist/SHA256SUMS with bare filenames so sha256sum -c works where a downloader unpacks. README carries all four rows and says outright that only linux/amd64 is gated, because three unverifiable hashes presented as checked would undo the point of the one that is. The hash gate needed hardening before that table could exist. It took the first 64-hex string in README.md, which was correct while exactly one hash was published and would have become a silent trap the moment the rows were reordered: the build would have been compared against another platform's hash and failed with nothing to suggest why. It now finds the hash by the platform named beside it. The Dockerfile is a second build path and turned out to be a second check. It is multi-stage, ending at scratch, one layer and 5.11 MB, and its builder is pinned to golang:1.25.0 rather than golang:1.25 because the floating tag was go1.25.14 and produced a different binary. That is the correct result and the reason for the pin, and with it the binary inside the image is byte identical to the published linux/amd64 hash, verified by copying it out. Three absences are deliberate and each is commented: no CA bundle, since DNS over UDP and TCP carries no TLS and trust comes from the root hints; no /etc/resolv.conf, since hollow walks from the root rather than asking the host; and no go mod download, which is the first line of nearly every Go Dockerfile and has nothing to do here. It runs as uid 65534, which port 15353 rather than 53 is what allows, and CMD binds 0.0.0.0 because inside a container loopback is the container's own and a published port would reach nothing. Tested rather than shipped on faith: built, run with -p, and answered both a UDP and a TCP dig by walking from the root as an unprivileged user in an image with no shell and no resolver configuration. dist/ joins /build/ in .gitignore, and .dockerignore keeps the planning notes, the release binaries and .git out of the build context that one COPY would otherwise sweep in. Two Honest Limitations had gone stale and are corrected here rather than left to be found by a judge. One said reload belongs on a control socket "which is not built"; the socket has been built for two commits, and the accurate statement is that it deliberately carries no command that changes what the server is doing, which is what makes an unauthenticated loopback port defensible. The other said there is no rate limiting, three bullets above the one describing the rate limiter. make verify is green, including the gate reading the new table.