Repository navigation
Conversation
Member
Author
Live IP reputation via the HAProxy peers protocolReplaced the map-file approach for individual-IP reputation with the HAProxy peers protocol (as implemented in What changed
Validated against real HAProxy (
|
Add a per-level difficulty knob (leading-zero bits, default 16, range 1-255) advertised to the client via a fixed-width "d" field, and a new pow-worker challenge type that must be solved inside a Web Worker. An unset difficulty falls back to the historic 16-bit target so directly-built configs are never zero-work.
Strip the port from the Host header for cookie identity, trusted-domain matching and the cookie Domain attribute (#46). Receive the client session id over SPOE and log it. Log a keyed hash of the source IP instead of the plaintext address.
…ooks Detect missing browser capabilities and show actionable advisories; show and send a per-page session id (ena@<uuid>); render a ban-countdown screen (type 3); solve the pow-worker challenge in an inlined Web Worker; add a VITE_HOOKS system to customise the page without forking (#26); fix the cookie-warning element id.
Global/per-IP rate limits and a challenge-endpoint anti-bruteforce ban with a countdown page; tarpit library/scraper User-Agents; reputation/ASN/VPN/Tor/Cloudflare maps with an onion/I2P bypass; keyed IP hashing in logs; an alternative UA/endpoint filtering example config (#19).
Fetch public feeds (Cloudflare ranges, Tor exit list) and write the HAProxy map/ACL files atomically. Runs once or on an interval.
Drive headless Chrome against the running stack to verify the client bundle actually solves a challenge and reaches the backend (#9). Wired into the CI e2e job; kept in a separate module so chromedp stays out of the main module.
A self-contained, JS-free help page under docs/ plus a Pages deploy workflow; document the new config knobs and operations; an optional CrowdSec integration scaffold.
haproxy-go's peers package only receives stick-table updates; this adds the sending side (handshake, table definitions, entry updates, sync + heartbeat) so an external process can push entries into a running HAProxy's stick-tables live. Entry data is marshalled by hand because EntryUpdate.Marshal mis-encodes it upstream.
Individual-IP reputation (Tor exit nodes, banlists) is now pushed into HAProxy st_reputation stick-tables live over the peers protocol instead of being written to map files that need a reload. CIDR/range feeds (Cloudflare, ASN, VPN) stay as map/ACL files since stick-tables cannot do prefix matching. haproxy.cfg gains a peers section + reputation tables and consults the gpt0 tag; docker-compose runs feedupdater as the peer.
v0.1.1 includes the fix for EntryUpdate.Marshal's data encoding, so peerserver no longer needs to hand-marshal entry updates. Verified against real HAProxy: 1382 entries synced and a banned source silent-dropped.
fionera
force-pushed
the
feat/gandalf-features
branch
from
July 10, 2026 14:24
2b39b25 to
98a8a51
Compare
Member
Author
|
The omnibus branch has been rebased onto the current Core challenge behavior
Frontend and supportability
HAProxy policy
Live reputation
Verification
The custom peers-protocol implementation was replaced by HAProxy’s supported atomic Runtime API. The nonfunctional CrowdSec starting-point scaffold was intentionally not carried into these PRs; a real CrowdSec integration should be implemented and tested as a follow-up. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Implements a broad bot-blocker feature set on top of Berghain (modelled on the "Gandalf" spec), while keeping the core design intact: Berghain stays stateless (all runtime state lives in HAProxy stick-tables/maps), the Go hot path stays zero-allocation, and HAProxy owns policy while Berghain remains a pure SPOE function. Also closes four open issues.
What's included
Challenge engine (Go + web)
dfield; the server enforces its own level's difficulty.pow-workerchallenge type — same PoW, must be solved in a Web Worker (inlined into the single-file bundle).ena@<uuid>), and a ban-countdown screen.HAProxy policy (stateless)
HashSource+ HAProxy).cmd/feedupdatertool.Docs & ops
docs/+ a GitHub Pages workflow.Closes
haproxy-ua-filtering.cfg+ maps).VITE_HOOKS) so branding/behaviour can live in a separate repo without forkingweb/.Domain, and the HAProxy onion bypass).Verification
go build/test/vet+staticcheckclean; the Go hot path stays 0 allocs/op.npm run lint+npm run build(bothdefaultandnative-cryptomodes, single-file output).haproxy -cvalid for both example configs.feedupdaterunit-tested and confirmed against live feeds.Notes
tune.bufsizeis raised to 32k.gpt-5.5code review was run over the branch; its three findings (a zero-difficulty fail-open, the onion-port bypass gap, and a CI e2e that could pass without exercising the stack) are fixed in this PR.