Repository navigation
Add a CRS observation disable action with a persistent pre-change snapshot - #78
Merged
Merged
Conversation
…pshot The WAF page could enable CRS observation but never turn it off. The daemon gains a DISABLE verb that removes the observation policy, acquisition entry, and bouncer marker, then restarts CrowdSec and waits for health, restoring the configuration on failure. Both verbs now write a snapshot of the CrowdSec configuration tree and bouncer file under /var/lib/npmplus/crs-control/snapshot before touching anything; it survives the run as the known-good instance for manual recovery, and the uninstaller removes it with the helper's other state. The GUI button toggles with the observation state, the route is admin-only and shares the control rate limit and audit trail, and the Hub rule package is left installed but inert so disabling never involves Hub surgery.
Only the defaults matrix runs the --enable-crs safe-update step that the round trip depends on; in the alternate matrix observation was never enabled, the daemon's accepted no-op left no snapshot to assert about, and the step failed.
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.
What
The CrowdSec → WAF page could turn CRS observation on but never off. This adds the disable action end to end, mirroring the enable path's transactional design:
DISABLEsocket verb. It removes the observation policy file, thenpmplus/crs-observeacquisition entry, and theNPMPLUS_CRS_MODEmarker from the bouncer config, then config-tests (crowdsec -t), restarts CrowdSec, and waits for health. Any failure restores the enabled configuration and reportsfailed; a failed restore reportsrollback-failed. A disable while idle is an accepted no-op, and the same 5-minute cooldown applies. The Hub rule package is left installed but inert — removing it would be Hub surgery with no behavioral gain.ENABLEandDISABLEnow copy the CrowdSec config tree and the bouncer file to/var/lib/npmplus/crs-control/snapshot/before touching anything. It survives a successful run (last known-good instance) and a failed rollback (manual recovery), instead of the enable path's old temp-dir snapshot that vanished with the process. Uninstall removes it along with the helper's other state.DELETE /api/crowdsec/crs— admin-only, audited before acting (actiondisable-requested), sharing the enable route's rate-limit bucket and reason mapping (busy/unsupported → 409, cooldown → 429). The shared request path incrs-control.jsis factored out.Why
Requested after the enable button shipped: once observation was on there was no supported way back to the pre-CRS detection behavior short of hand-editing host files, and any future regression in the change path had no on-host fallback instance to recover from.
Verification
tests/crs-control.py: 16/16 in CI-replica docker — disable round trip restores the exact pre-observation acquisition and keeps a snapshot; failed disable restores the enabled state and keeps the cooldown; snapshot survives a failed recovery; idempotent no-op and unsupported-state refusals; socket verb pins.pnpm test(226 tests) in CI-replica docker, including the newcrs-disable.test.js(own process so the shared rate bucket doesn't shift api.test.js's enable boundary) — 403/401/cross-origin guards, audit-before-act, 500 on audit failure without reaching the host, 429 at the bucket limit.