71 lines
2.8 KiB
YAML
71 lines
2.8 KiB
YAML
filter: "evt.Parsed.program startsWith 'nginx'"
|
|
onsuccess: next_stage
|
|
name: crowdsecurity/nginx-logs
|
|
description: "Parse nginx access and error logs"
|
|
pattern_syntax:
|
|
NGCUSTOMUSER: '[a-zA-Z0-9\.\@\-\+_%]+'
|
|
nodes:
|
|
- grok:
|
|
pattern: '(%{IPORHOST:target_fqdn} )?%{IPORHOST:remote_addr} - %{NGCUSTOMUSER:remote_user}? \[%{HTTPDATE:time_local}\] "%{WORD:verb} %{DATA:request} HTTP/%{NUMBER:http_version}" %{NUMBER:status} %{NUMBER:body_bytes_sent} "%{NOTDQUOTE:http_referer}" "%{NOTDQUOTE:http_user_agent}"( %{NUMBER:request_length} %{NUMBER:request_time} \[%{DATA:proxy_upstream_name}\] \[%{DATA:proxy_alternative_upstream_name}\])?'
|
|
apply_on: message
|
|
statics:
|
|
- meta: log_type
|
|
value: http_access-log
|
|
- target: evt.StrTime
|
|
expression: evt.Parsed.time_local
|
|
- grok:
|
|
# and this one the error log
|
|
pattern: '(%{IPORHOST:target_fqdn} )?%{NGINXERRTIME:time} \[%{LOGLEVEL:loglevel}\] %{NONNEGINT:pid}#%{NONNEGINT:tid}: (\*%{NONNEGINT:cid} )?%{GREEDYDATA:message}, client: %{IPORHOST:remote_addr}, server: %{DATA:target_fqdn}, request: "%{WORD:verb} ([^/]+)?%{URIPATHPARAM:request}( HTTP/%{NUMBER:http_version})?", host: "%{IPORHOST}(:%{NONNEGINT})?"'
|
|
apply_on: message
|
|
statics:
|
|
- meta: log_type
|
|
value: http_error-log
|
|
- target: evt.StrTime
|
|
expression: evt.Parsed.time
|
|
pattern_syntax:
|
|
NO_DOUBLE_QUOTE: '[^"]+'
|
|
onsuccess: next_stage
|
|
nodes:
|
|
- filter: "evt.Parsed.message contains 'was not found in'"
|
|
pattern_syntax:
|
|
USER_NOT_FOUND: 'user "%{NO_DOUBLE_QUOTE:username}" was not found in "%{NO_DOUBLE_QUOTE}"'
|
|
grok:
|
|
pattern: '%{USER_NOT_FOUND}'
|
|
apply_on: message
|
|
statics:
|
|
- meta: sub_type
|
|
value: "auth_fail"
|
|
- meta: username
|
|
expression: evt.Parsed.username
|
|
- filter: "evt.Parsed.message contains 'password mismatch'"
|
|
pattern_syntax:
|
|
PASSWORD_MISMATCH: 'user "%{NO_DOUBLE_QUOTE:username}": password mismatch'
|
|
grok:
|
|
pattern: '%{PASSWORD_MISMATCH}'
|
|
apply_on: message
|
|
statics:
|
|
- meta: sub_type
|
|
value: "auth_fail"
|
|
- meta: username
|
|
expression: evt.Parsed.username
|
|
- filter: "evt.Parsed.message contains 'limiting requests, excess'"
|
|
statics:
|
|
- meta: sub_type
|
|
value: "req_limit_exceeded"
|
|
# these ones apply for both grok patterns
|
|
statics:
|
|
- meta: service
|
|
value: http
|
|
- meta: source_ip
|
|
expression: "evt.Parsed.remote_addr"
|
|
- meta: http_status
|
|
expression: "evt.Parsed.status"
|
|
- meta: http_path
|
|
expression: "evt.Parsed.request"
|
|
- meta: http_verb
|
|
expression: "evt.Parsed.verb"
|
|
- meta: http_user_agent
|
|
expression: "evt.Parsed.http_user_agent"
|
|
- meta: target_fqdn
|
|
expression: "evt.Parsed.target_fqdn"
|