Conversation
* feat(sharry): add Sharry collection with parser and bruteforce detection - Add sharry-logs parser for authentication failures - Add sharry-bf scenario (5 failures in 20s -> 1m ban) - Add collection, parser, and scenario documentation - Add test log samples - Detects: Authentication attempt failure for username X from ip Y * test(sharry): add parser and scenario tests - Add sharry-logs parser tests with assertions - Add sharry-bf scenario tests with 5 authentication failures - Tests verify correct field extraction and scenario triggering * fix(sharry): fix timestamp parsing and scenario capacity - Add timezone support to parser (UTC+11 for Sharry logs) - Add StrTimeFormat with timezone offset handling - Reduce scenario capacity from 5 to 4 (5 events need capacity 4 to overflow) - Update test assertions to expect +11:00 timezone format Fixes test failures where: 1. Timestamps weren't being parsed correctly (was defaulting to 1970) 2. Scenario wasn't triggering (needed 6 events with capacity 5, only had 5) * fix(sharry): use UTC timezone instead of hardcoded +1100 Replace hardcoded +1100 timezone offset with +0000 (UTC) since Sharry logs don't include timezone information. This follows the standard approach for logs without explicit timezone data. * Update blockers meta * Update blockers meta * chore(blockers): update cs-routeros-bouncer logo (#1867) The project replaced its brand mark. The logo carried here was the original teal shield-with-a-router drawing, two designs out of date. The replacement is the current mark: four lanes meeting a rail, three crossing and one stopping at it, in CrowdSec's indigo. Rendered at 256x256 from the same source SVG and the same palette tokens as every other asset the project ships, so it cannot drift from the site and the release artwork. Also 64x smaller: 1,072 bytes against 65,239. * Update blockers meta * Bump cryptography from 48.0.1 to 50.0.0 (#1856) Bumps [cryptography](https://github.com/pyca/cryptography) from 48.0.1 to 50.0.0. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](pyca/cryptography@48.0.1...50.0.0) --- updated-dependencies: - dependency-name: cryptography dependency-version: 50.0.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Update blockers meta --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: GitHub Action <action@github.com> Co-authored-by: José M. Requena Plens <jmrplens@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Manuel Sabban <github@sabban.eu>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR introduces Hub support for Sharry by adding a dedicated parser, a brute-force detection scenario, a collection wiring them together, and hubtest fixtures to validate parsing + scenario triggering.
Changes:
- Add
plague-doctor/sharry-logsparser and documentation to extract failed-auth events and key metadata. - Add
plague-doctor/sharry-bfleaky-bucket scenario + documentation, and bundle parser+scenario in a newplague-doctor/sharrycollection. - Add
.tests/hubtest fixtures for both the parser and the scenario (plus unrelated updates touv.lockandblockers/list.json).
Reviewed changes
Copilot reviewed 11 out of 16 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
uv.lock |
Updates cryptography lock entry/version (appears unrelated to Sharry support). |
scenarios/plague-doctor/sharry-bf.yaml |
New leaky-bucket scenario detecting Sharry brute-force attempts. |
scenarios/plague-doctor/sharry-bf.md |
Scenario documentation. |
parsers/s01-parse/plague-doctor/sharry-logs.yaml |
New parser to extract Sharry failed-auth events and set metadata for scenarios. |
parsers/s01-parse/plague-doctor/sharry-logs.md |
Parser documentation + acquisition template. |
collections/plague-doctor/sharry.yaml |
New collection wiring the Sharry parser + scenario. |
collections/plague-doctor/sharry.md |
Collection documentation + acquisition template. |
blockers/list.json |
Updates embedded logo for cs-routeros-bouncer (appears unrelated to Sharry support). |
.tests/sharry-logs/sharry.log |
Parser test log sample for Sharry. |
.tests/sharry-logs/parser.assert |
Expected parser + enrich output for Sharry sample log. |
.tests/sharry-logs/config.yaml |
Hubtest config for the Sharry parser test. |
.tests/sharry-bf/sharry.log |
Scenario test log sample (5 failed attempts). |
.tests/sharry-bf/scenario.assert |
Expected overflow/assertions for the Sharry brute-force scenario. |
.tests/sharry-bf/parser.assert |
(Empty) placeholder parser assertions for scenario test. |
.tests/sharry-bf/config.yaml |
Hubtest config for the Sharry scenario test. |
Suppressed comments (7)
.tests/sharry-logs/parser.assert:27
- This assertion file embeds the same public/WAN IP used in the test logs. After switching the log sample to a reserved documentation IP (e.g. 192.0.2.0/24), the expected parsed/meta source_ip and message values here need to be updated to match.
results["s01-parse"]["plague-doctor/sharry-logs"][0].Evt.Parsed["message"] == "2026.02.12 12:50:22:0000 [io-comp...] [INFO ] sharry.restserver.routes.LoginRoutes.makeResponse:232 - Authentication attempt failure for username Thgg from ip 1.136.110.240"
.tests/sharry-logs/parser.assert:40
- This assertion file embeds the same public/WAN IP used in the test logs. After switching the log sample to a reserved documentation IP (e.g. 192.0.2.0/24), the expected parsed/meta source_ip and message values here need to be updated to match.
results["s01-parse"]["plague-doctor/sharry-logs"][1].Evt.Parsed["message"] == "2026.02.12 12:50:25:0000 [io-comp...] [INFO ] sharry.restserver.routes.LoginRoutes.makeResponse:232 - Authentication attempt failure for username Thgg from ip 1.136.110.240"
.tests/sharry-logs/parser.assert:55
- This assertion file embeds the same public/WAN IP used in the test logs. After switching the log sample to a reserved documentation IP (e.g. 192.0.2.0/24), the expected parsed/meta source_ip and message values here need to be updated to match.
results["s02-enrich"]["crowdsecurity/dateparse-enrich"][0].Evt.Parsed["message"] == "2026.02.12 12:50:22:0000 [io-comp...] [INFO ] sharry.restserver.routes.LoginRoutes.makeResponse:232 - Authentication attempt failure for username Thgg from ip 1.136.110.240"
.tests/sharry-logs/parser.assert:69
- This assertion file embeds the same public/WAN IP used in the test logs. After switching the log sample to a reserved documentation IP (e.g. 192.0.2.0/24), the expected parsed/meta source_ip and message values here need to be updated to match.
results["s02-enrich"]["crowdsecurity/dateparse-enrich"][1].Evt.Parsed["message"] == "2026.02.12 12:50:25:0000 [io-comp...] [INFO ] sharry.restserver.routes.LoginRoutes.makeResponse:232 - Authentication attempt failure for username Thgg from ip 1.136.110.240"
.tests/sharry-bf/scenario.assert:20
- This scenario assertion embeds the same public/WAN IP used in the test logs. After switching the log sample to a reserved documentation IP (e.g. 192.0.2.0/24), update the expected source_ip meta values here to match.
results[0].Overflow.Alert.Events[0].GetMeta("source_ip") == "1.136.110.240"
results[0].Overflow.Alert.Events[0].GetMeta("timestamp") == "2026-02-12T12:50:22+11:00"
results[0].Overflow.Alert.Events[0].GetMeta("username") == "Thgg"
results[0].Overflow.Alert.Events[1].GetMeta("datasource_path") == "sharry.log"
results[0].Overflow.Alert.Events[1].GetMeta("datasource_type") == "file"
results[0].Overflow.Alert.Events[1].GetMeta("log_type") == "sharry_failed_auth"
results[0].Overflow.Alert.Events[1].GetMeta("service") == "sharry"
results[0].Overflow.Alert.Events[1].GetMeta("source_ip") == "1.136.110.240"
results[0].Overflow.Alert.Events[1].GetMeta("timestamp") == "2026-02-12T12:50:25+11:00"
results[0].Overflow.Alert.Events[1].GetMeta("username") == "Thgg"
.tests/sharry-bf/scenario.assert:34
- This scenario assertion embeds the same public/WAN IP used in the test logs. After switching the log sample to a reserved documentation IP (e.g. 192.0.2.0/24), update the expected source_ip meta values here to match.
results[0].Overflow.Alert.Events[2].GetMeta("source_ip") == "1.136.110.240"
results[0].Overflow.Alert.Events[2].GetMeta("timestamp") == "2026-02-12T12:50:27+11:00"
results[0].Overflow.Alert.Events[2].GetMeta("username") == "Thgg"
results[0].Overflow.Alert.Events[3].GetMeta("datasource_path") == "sharry.log"
results[0].Overflow.Alert.Events[3].GetMeta("datasource_type") == "file"
results[0].Overflow.Alert.Events[3].GetMeta("log_type") == "sharry_failed_auth"
results[0].Overflow.Alert.Events[3].GetMeta("service") == "sharry"
results[0].Overflow.Alert.Events[3].GetMeta("source_ip") == "1.136.110.240"
results[0].Overflow.Alert.Events[3].GetMeta("timestamp") == "2026-02-12T12:50:29+11:00"
results[0].Overflow.Alert.Events[3].GetMeta("username") == "Thgg"
.tests/sharry-bf/scenario.assert:40
- This scenario assertion embeds the same public/WAN IP used in the test logs. After switching the log sample to a reserved documentation IP (e.g. 192.0.2.0/24), update the expected source_ip meta value here to match.
results[0].Overflow.Alert.Events[4].GetMeta("source_ip") == "1.136.110.240"
results[0].Overflow.Alert.Events[4].GetMeta("timestamp") == "2026-02-12T12:50:31+11:00"
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
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.
fix small typo for eventually merging sharry support.
Description
Checklist