Skip to content

Conversation

@ook
Copy link

@ook ook commented Jan 7, 2026

Description

Handles Traefik multilayer routing. Fix #1628

Checklist

  • I have read the contributing guide
  • I have tested my changes locally
  • For new parsers or scenarios, tests have been added
  • I have run the hub linter and no issues were reported (see contributing guide)
  • Automated tests are passing
  • AI was used to generate any/all content of this PR

@ook ook marked this pull request as ready for review January 7, 2026 17:27
@LaurenceJJones
Copy link
Member

LaurenceJJones commented Jan 8, 2026

Personally I wouldnt alter the traefik router as that is the format of the router itself (it used in the position but we can get and set proper meta data of parent and child for alert purposes) and would move this to the CLF itself.

Mind if I take over and update it?

however, thinking back now it might break some peoples whitelists that match a full string so we probably need to keep the same naming.

@ook
Copy link
Author

ook commented Jan 8, 2026

Mind if I take over and update it?

Please, do! I only wanted to help other traefik multilayer routers enthusiasts to continue using Crowdsec :)

@LaurenceJJones
Copy link
Member

LaurenceJJones commented Jan 8, 2026

Mind if I take over and update it?

Please, do! I only wanted to help other traefik multilayer routers enthusiasts to continue using Crowdsec :)

question do you know if the json logs adds this as a new property or the RouterName key embeds both?

also test is parent and leaf is child?

@ook
Copy link
Author

ook commented Jan 8, 2026

test is root and leaf is child/leaf. Please note that it can exists intermediates layers, so potentially N layers.
I don’t know for json logs, but I’ll build a test setup to check that for you.

@ook
Copy link
Author

ook commented Jan 8, 2026

@LaurenceJJones here your answer https://github.com/cults/crowdsec-traefik-multilayer-logs you can play with this.
The json output:

traefik-1  | {"ClientAddr":"192.168.65.1:29366","ClientHost":"192.168.65.1","ClientPort":"29366","ClientUsername":"-","DownstreamContentSize":364,"DownstreamStatus":200,"Duration":2001375,"OriginContentSize":364,"OriginDuration":1935291,"OriginStatus":200,"Overhead":66084,"RequestAddr":"whoami.localhost","RequestContentSize":0,"RequestCount":1,"RequestHost":"whoami.localhost","RequestMethod":"GET","RequestPath":"/","RequestPort":"-","RequestProtocol":"HTTP/1.1","RequestScheme":"http","RetryAttempts":0,"RouterName":"root@file -\u003e intermediate1@file -\u003e intermediate2@file -\u003e leaf@file","ServiceAddr":"whoami:80","ServiceName":"whoami@file","ServiceURL":"http://whoami:80","StartLocal":"2026-01-08T14:19:15.980170592Z","StartUTC":"2026-01-08T14:19:15.980170592Z","entryPointName":"web","level":"info","msg":"","time":"2026-01-08T14:19:15Z"}

And more visually:
image

…ermediate/Leaf routers

- Parse Traefik's multi-layer routing chains (X levels of routers)
- Extract root router (first in chain), intermediate routers (middle), and leaf router (last)
- Use Traefik's official terminology: Root → Intermediate → Leaf
- Ensure consistent behavior between CLF and JSON log formats
- Add test cases for extended router chains (4 routers)
- Provide full chain in traefik_router_name_full for both formats
- Expose breakdown via meta fields: traefik_router_name_root, traefik_router_name_intermediate, traefik_router_name_leaf

Signed-off-by: Laurence <[email protected]>
…low blank routers

- Set traefik_router_name_root to empty string for single/standalone routers
- Only populate root when there's an actual hierarchy (leaf exists)
- Update TRAEFIK_ROUTER pattern to accept blank values ("-")
@LaurenceJJones
Copy link
Member

LaurenceJJones commented Jan 8, 2026

Okay think I got it in a space, where I am happy 😅

this allow us to parse additional properties that might be useful for alert context debugging / false positive. You can see the generated asserts for the meta information basically

root: entry
intermediate: any router between root and leaf
leaf: last

@ook
Copy link
Author

ook commented Jan 8, 2026

Congrats! Even I foresee the different root / leaf values for routers will be YAGNI (after all, crowdsec bouncer is always a middleware, so already inside the router chain: we already know in which kind of router we’re in), I like your implementation. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Traefik parser can’t handle Multi layer routing logs

2 participants