Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Traefik access logs parser #275

Merged
merged 3 commits into from
Dec 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions collections/crowdsecurity/traefik.md
@@ -0,0 +1,4 @@
A collection to defend traefik against common attacks (currently only directory enumeration over HTTP/S):
- traefik parser (supports CLF and JSON)
- directory enumeration scenario

12 changes: 12 additions & 0 deletions collections/crowdsecurity/traefik.yaml
@@ -0,0 +1,12 @@
parsers:
#generic post-parsing of http stuff
- crowdsecurity/traefik-logs
collections:
- crowdsecurity/traefik-bf
description: "traefik support: parser and directory enumeration scenario"
author: crowdsecurity
tags:
- traefik
- http
- bruteforce

1 change: 1 addition & 0 deletions parsers/s01-parse/crowdsecurity/traefik-logs.md
@@ -0,0 +1 @@
This traefik parser supports access logs in the Common Log Format ([defined here for Traefik](https://doc.traefik.io/traefik/observability/access-logs/#format)) and JSON formats.
59 changes: 59 additions & 0 deletions parsers/s01-parse/crowdsecurity/traefik-logs.yaml
@@ -0,0 +1,59 @@
# debug: true
filter: "evt.Parsed.program startsWith 'traefik'"
# onsuccess: next_stage
pattern_syntax:
TRAEFIK_ROUTER: '(%{USER}@%{URIHOST}|\-)'
TRAEFIK_SERVER_URL: '(%{URI}|\-)'
# for json just use TIMESTAMP_ISO8601
name: crowdsecurity/traefik-logs
description: "Parse Traefik access logs"

nodes:
- grok: # CLF parser
pattern: '%{NGINXACCESS} %{NUMBER:number_of_requests_received_since_traefik_started} "%{TRAEFIK_ROUTER:traefik_router_name}" "%{TRAEFIK_SERVER_URL:traefik_server_url}" %{NUMBER:request_duration_in_ms}ms'
apply_on: message
- grok:
pattern: '%{IPORHOST:remote_addr}'
expression: JsonExtract(evt.Line.Raw, "ClientAddr")
- grok:
pattern: '%{USERNAME:remote_user}'
expression: JsonExtract(evt.Line.Raw, "ClientUsername")
- grok:
pattern: '%{NUMBER:body_bytes_sent}'
expression: JsonExtract(evt.Line.Raw, "DownstreamContentSize")
- grok:
pattern: '%{NUMBER:request_duration_in_ms}'
expression: JsonExtract(evt.Line.Raw, "Duration")
- grok:
pattern: '%{TRAEFIK_ROUTER:traefik_router_name}'
expression: JsonExtract(evt.Line.Raw, "RouterName")
- grok:
pattern: '%{GREEDYDATA:timestamp}:'
expression: JsonExtract(evt.Line.Raw, "time")
- grok:
pattern: '%{WORD:method}:'
expression: JsonExtract(evt.Line.Raw, "RequestMethod")
- grok:
pattern: '%{URIPATHPARAM:request}:'
expression: JsonExtract(evt.Line.Raw, "RequestPath")
- grok:
pattern: 'HTTP/%{NUMBER:http_version}'
expression: JsonExtract(evt.Line.Raw, "RequestProtocol")
- grok:
pattern: '%{NUMBER:status}'
expression: JsonExtract(evt.Line.Raw, "DownstreamStatus")
- statics:
- meta: service
value: traefik
- meta: user
expression: "evt.Parsed.remote_user"
- meta: source_ip
expression: "evt.Parsed.remote_addr"

- filter: "evt.Parsed.status startsWith '4'" # 4XX status code (like 404, 401, etc.) -> invalid URI
onsuccess: next_stage
statics:
- meta: log_type
value: traefik_invalid_uri


5 changes: 5 additions & 0 deletions scenarios/crowdsecurity/traefik-bf.md
@@ -0,0 +1,5 @@
## Detect URI bruteforcing
Parameters:
- leakspeed: 10s
- capacity: 5
- blackhole: 5mins
13 changes: 13 additions & 0 deletions scenarios/crowdsecurity/traefik-bf.yaml
@@ -0,0 +1,13 @@
type: leaky
debug: true
name: crowdsecurity/traefik-bf
description: "Detect URI bruteforcing using traefik"
filter: evt.Meta.log_type == 'traefik_bad_request'
leakspeed: "10s"
capacity: 5
groupby: evt.Meta.source_ip
blackhole: 5m
labels:
service: http
type: bruteforce
remediation: true