Skip to content

BunkerWeb Integration

duggytuxy edited this page Aug 25, 2026 · 8 revisions

BunkerWeb Integration

Status: Version-specific Documentation baseline: v4.03.2

This page defines the SysWarden side of the BunkerWeb integration and migration fence. It does not claim that any plugin release has completed its external end-to-end matrix. Use only a partner version whose release notes explicitly name compatibility with this frozen contract.

Integration boundary

The BunkerWeb scheduler can use SysWarden's authenticated HA API to:

  • push temporary Layer 7 bans into Linux nftables;
  • withdraw only provenance records owned by the same claimed source and observed peer scope;
  • read bounded blocklist, whitelist, status and telemetry data;
  • migrate its own durable historical static submissions to provenance-aware ownership without inferring ownership from effective peer state.

The plugin uses only the HTTPS HA API. It must not edit SysWarden files, invoke the local CLI or access a local process socket. Source-owned temporary records are sent directly to every declared peer; SysWarden nodes do not relay them transitively.

The local TUI is unrelated to this integration. It opens no listening socket. The current product contains no browser terminal or remote PTY service and owns no TCP 62027 listener or firewall permission.

Prerequisites

  • The exact v4.03.2 candidate on every participating SysWarden node.
  • A compatible BunkerWeb plugin candidate.
  • Console or out-of-band recovery access.
  • TCP 62026 reachability on a dedicated management network.
  • A high-entropy bearer token delivered through a protected secret channel.
  • Exact member endpoints and an operator-approved inbound peer scope.
  • Authenticated distribution of every SysWarden public HA certificate or CA.
  • One operator-provided inventory containing every cluster member and every external legacy writer that can still submit historical static state.
  • A durable BunkerWeb record of the historical static addresses it submitted to each exact peer.

An omitted peer or writer invalidates the migration campaign. The integrator must never manufacture membership from what one peer happens to report.

Enable the SysWarden API

Configure the HA listener and partner extensions:

[integrations.ha]
enabled = true
peer_ips = ["172.30.0.0/29"]
peer_port = 62026
token = "replace-with-a-random-shared-secret"

[integrations.bunkerweb]
enabled = true

An exact IP can authorize inbound requests and serve as an outbound SysWarden peer. A CIDR authorizes inbound clients only and is never converted into an outbound destination. The bearer token remains mandatory.

Validate and apply the reviewed configuration:

sudo syswarden config validate
sudo syswarden reload

Activation must fail when HA is disabled, the token is empty or whitespace-padded, or the peer list is empty or invalid.

TLS and authentication

Every /ha/sync, /ha/status and /ha/telemetry request requires TLS 1.3 and Authorization: Bearer. An empty server token prevents the listener from starting.

The persistent server identity is stored at:

  • /var/lib/syswarden/ha/server.crt
  • /var/lib/syswarden/ha/server.key

Never copy server.key to a client. Transfer only the public certificate or CA through a trusted channel and verify its SHA-256 fingerprint:

openssl x509 -in /var/lib/syswarden/ha/server.crt -noout -fingerprint -sha256

Do not enable an insecure TLS bypass in production. A certificate identity change invalidates the current manifest and resets every partner observation window.

Dialect selection

For one exact peer and one serialized cycle, issue one authenticated GET /ha/status. Use the enriched dialect only when both sync_ttl and sync_provenance are present. If either capability is missing, partial, malformed or unavailable, stop the enriched handoff for that peer. Never relax TLS or bearer authentication and never mix historical and enriched bodies in one request.

Historical static submission uses:

{"ips":["198.51.100.25","203.0.113.0/28"]}

An enriched temporary submission can use:

{
  "bans": [
    {
      "ip": "198.51.100.25",
      "ttl": 3600,
      "reason": "Layer 7 detection",
      "source": "bunkerweb"
    }
  ]
}

The enriched contract accepts no more than 500 records per request. TTL is an integer from 1 to 2,592,000 seconds. IP and CIDR values must be canonical, source is bounded approved ASCII and reason is bounded printable UTF-8. Unknown fields, duplicate keys and mixed forms fail closed.

Separate ownership stores

Historical static entries and provenance ledger entries are distinct stores:

  • POST {"ips": [...]} creates historical static state;
  • DELETE {"ips": [...]} explicitly removes historical static entries;
  • POST {"bans": [...]} creates provenance-aware state;
  • DELETE {"bans": [...]} removes provenance ledger entries only;
  • deleting a provenance record never implicitly deletes a historical static entry;
  • deleting one peer never cascades into another peer.

The BunkerWeb cleanup set comes only from its durable, peer-specific registry of addresses it previously submitted historically. It must never infer ownership from GET /ha/sync, provenance pagination, another peer or an effective union. This prevents deletion of operator, WAAP or second-producer ownership.

A claim remains retained until one complete observation finds the address absent from every declared peer and absent from BunkerWeb. An unavailable peer does not count as absence. Membership changes reset every observation window.

Operator activation manifest

One trusted operator control host creates one strict, canonical manifest from a complete inventory. The manifest contains exact member endpoints, live TLS leaf fingerprints, external legacy-writer identifiers, one random epoch, membership_sha256 and legacy_writer_inventory_sha256.

sudo syswarden ha-fence manifest create \
  --inventory /root/syswarden-ha-inventory.json \
  --output /root/syswarden-ha-manifest.json \
  --assert-complete
sudo syswarden ha-fence manifest verify \
  --manifest /root/syswarden-ha-manifest.json
sudo syswarden ha-fence engage \
  --manifest /root/syswarden-ha-manifest.json

The operator distributes that exact protected manifest to every member and to the integrator. The integrator does not submit cluster membership or writer state through another API. A member, endpoint, certificate or writer change requires a new manifest.

Dynamic fence proof

The capability native_sync_fence_v1 announces schema support only. It is not proof that the node is fenced or drained.

For every manifest member, send a unique 32-byte base64url challenge in X-SysWarden-HA-Challenge and obtain one fresh authenticated GET /ha/status. Accept proof only when all conditions hold in the same response:

  • native_sync_fence.state is active_drained;
  • the returned challenge equals the request challenge;
  • the live TLS leaf fingerprint equals the manifest member pin;
  • epoch equals the manifest epoch;
  • membership_sha256 equals the manifest membership digest;
  • legacy_writer_inventory_sha256 equals the manifest writer digest;
  • the X-SysWarden-HA-Fence-Condition response header equals the JSON condition value;
  • server instance, generation and condition remain stable for the observation.

The integrator treats the epoch and both digest values as opaque, case-sensitive strings. It compares them for exact equality with the operator-provided manifest and does not recalculate either digest or reimplement SysWarden canonicalization.

An unreachable member, partial view, invalid challenge echo, changed certificate, changed server instance, changed generation, changed membership, blind interval or reappearing address resets the campaign observation.

Condition-bound cleanup

Every DELETE {"ips": [...]} migration request carries the exact observed condition:

X-SysWarden-HA-Fence-Condition: <condition>

While the fence is active and drained:

The outcomes are fail-closed: a missing condition receives HTTP 428, a malformed condition receives HTTP 400 and a stale condition receives HTTP 412. Each rejection performs no mutation.

Request condition Result Mutation
Missing HTTP 428 None
Malformed HTTP 400 None
Stale or changed HTTP 412 None
Exact current condition Normal authenticated request processing Peer-scoped only

HTTP 412 means the fence moved. Stop the cleanup, obtain a new all-member proof and require an operator decision. Do not retry blindly.

A one-hour continuous absence window is additional evidence only. It is never proof of drain and never permits claim release from an incomplete view. The window must cover every declared peer, and a reappearance resets the timer and must be logged.

Fence release

Release requires the unchanged activation manifest and durable terminal closure evidence for every external legacy writer:

sudo syswarden ha-fence release \
  --manifest /root/syswarden-ha-manifest.json \
  --writer-closure /root/syswarden-ha-writer-closure.json

No queued historical write may become eligible after release. Use ha-fence recover with the same manifest after an interrupted engagement. Never reuse a retired epoch or reconstruct a manifest from peer output.

Partner settings

The compatible plugin documentation is authoritative for final names. The current design uses these settings:

Setting Purpose
SYSWARDEN_PEERS Complete SysWarden peer list
SYSWARDEN_API_TOKEN Bearer token delivered as a secret
SYSWARDEN_CA_BUNDLE Trusted CA or certificate bundle
SYSWARDEN_SSL_FINGERPRINT Explicit SHA-256 leaf pin
SYSWARDEN_ENFORCEMENT Partner audit or enforcing mode
SYSWARDEN_BAN_CHUNK_SIZE Request batch size, never above 500
SYSWARDEN_BAN_MAX_ITEMS Per-pass safety limit
SYSWARDEN_BAN_SCOPE_FILTER BunkerWeb services whose bans are propagated
SYSWARDEN_BAN_MIN_TTL Minimum TTL eligible for propagation
USE_SYSWARDEN_BLOCKLIST Enable downloaded blocklist use
USE_SYSWARDEN_WHITELIST Enable downloaded whitelist use

Start in audit mode, inspect scheduler requests and live status responses, then enable only approved directions.

Verification and release gate

An isolated end-to-end campaign must verify:

  1. unauthenticated and untrusted TLS requests fail;
  2. dialect selection uses exactly one status request per peer cycle;
  3. temporary provenance expiry and owner-scoped withdrawal converge;
  4. operator and second-source entries survive partner cycles;
  5. historical cleanup comes only from the durable per-peer partner registry;
  6. a peer outage freezes progress and membership change resets observations;
  7. challenge, condition, epoch and opaque digest comparisons fail closed;
  8. HTTP 428, 400 and 412 perform no mutation;
  9. a resurrection is detected and deleted again under operator control;
  10. fence release requires closure for every declared writer.

Before the v4.03.2 freeze, the BunkerWeb partner must provide written confirmation against the exact frozen contract. Publication remains blocked if there is unexplained partner-attributable static residue, lost ownership, partial membership or missing writer closure.

Return to the deployment tutorial for package and operator procedures.