cscli parsers install crowdsecurity/caddy-logs
Parser for caddy logs. It expects the default key values for caddy logs.
You need to specify caddy config to enable logging in a file:
:80 {
# Set this path to your site's directory.
root * /usr/share/caddy
# Enable the static file server.
file_server
# Another common task is to set up a reverse proxy:
# reverse_proxy localhost:8080
# Or serve a PHP site through php-fpm:
# php_fastcgi localhost:9000
log {
output file /var/log/caddy/access.log
}
}
And then add in acquisition this :
---
filenames:
- /var/log/caddy/access.log
labels:
type: caddy
1filter: |2 evt.Parsed.program startsWith 'caddy' &&3 UnmarshalJSON(evt.Parsed.message, evt.Unmarshaled, 'caddy') in ['', nil] &&4 (evt.Unmarshaled.caddy.logger == nil || evt.Unmarshaled.caddy.logger != 'http.handlers.waf') &&5 evt.Unmarshaled.caddy.request != nil6onsuccess: next_stage7name: crowdsecurity/caddy-logs8description: "Parse caddy logs"9statics:10 - meta: log_type11 value: http_access-log12 - target: evt.StrTime13 expression: |14 Sprintf("%v", evt.Unmarshaled.caddy.ts) matches '^[0-9e\\.\\+]+$' ? int(evt.Unmarshaled.caddy.ts) : evt.Unmarshaled.caddy.ts15 - meta: service16 value: http17 ##Caddy now sets client_ip to the value of X-Forwarded-For if users sets trusted proxies18 - parsed: remote_ip19 expression: "evt.Unmarshaled.caddy.request.client_ip"20 - parsed: http_version21 expression: "Split(evt.Unmarshaled.caddy.request.proto, '/')[1]"22 - meta: source_ip23 expression: evt.Parsed.remote_ip24 - meta: http_status25 expression: "evt.Unmarshaled.caddy.status != nil ? int(evt.Unmarshaled.caddy.status) : nil" ## We still check if status is not nil because of downstream error26 - meta: http_path27 expression: "evt.Unmarshaled.caddy.request.uri"28 - parsed: request #Add for http-logs enricher29 expression: "evt.Unmarshaled.caddy.request.uri"30 - parsed: verb31 expression: "evt.Unmarshaled.caddy.request.method"32 - meta: http_verb33 expression: "evt.Unmarshaled.caddy.request.method"34 - parsed: http_user_agent35 expression: "get(evt.Unmarshaled.caddy.request.headers, 'User-Agent') != nil ? evt.Unmarshaled.caddy.request.headers['User-Agent'][0] : nil" ## We still check if useragent exists because of client may not send it36 - meta: http_user_agent37 expression: evt.Parsed.http_user_agent38 - meta: target_fqdn39 expression: "evt.Unmarshaled.caddy.request.host"40 - meta: sub_type41 expression: "evt.Meta.http_status == '401' && get(evt.Unmarshaled.caddy.resp_headers, 'Www-Authenticate') != nil && any(get(evt.Unmarshaled.caddy.resp_headers, 'Www-Authenticate'), { # startsWith 'Basic' }) ? 'auth_fail' : nil"4243