Hello,
I’m brand new to crowdsec. I’ve got a simple host on where haproxy, zoneminder, and of course ssh are in use. There is existing functionality for haproxy and ssh. However, for zoneminder, I need to parse its web_php.log file in crowdsec for user authentication errors (i.e., bruteforce, etc.).
I’ve setup the test environment, and gone through the documentation. I think I’m very close, but not fully grokking a few things. Here’s what I’ve got setup so far:
- added this in acquis.yml
filenames:
- /path/to/zoneminderm/web_php.log
labels:
type: web_php
- set this up for my custom parser (and used https://grokdebug.herokuapp.com/ to validate):
filter: 1 == 1
debug: true
onsuccess: next_stage
name: webphp_parser
description: parser for zoneminder web_php.log
grok:
#our grok pattern : capture .*
pattern: ^%{DATE}[- ]%{TIME}\s(%{WORD:logname})\[.*\[(%{IP:srcIP})\]\s\[%{GREEDYDATA:message}"\]
#the field to which we apply the grok pattern : the log message itself
apply_on: message
statics:
- parsed: web_php
value: yes
- added this file for my scenario
type: leaky
name: web_php/bad_logins
description: "Detect multiple bad loginsfrom a single ip"
#filter: "evt.Parsed.program == 'web_php'"
filter: 1 == 1
groupby: "evt.Meta.srcIP"
distinct: "evt.Meta.username"
capacity: 3
leakspeed: "10s"
blackhole: 5m
labels:
service: web_php
type: web_php
remediation: true
Here are some example lines of text from web_php.log:
01/06/22 09:26:11.688105 web_php[21].ERR [99.1.1.1] [Could not retrieve user testuser details] at /usr/share/zoneminder/www/includes/auth.php line 313
01/06/22 09:26:13.280121 web_php[23].ERR [99.1.1.1] [Could not retrieve user testuser details] at /usr/share/zoneminder/www/includes/auth.php line 313
01/06/22 09:26:15.117434 web_php[258].ERR [99.1.1.1] [Could not retrieve user testuser details] at /usr/share/zoneminder/www/includes/auth.php line 313
01/06/22 09:27:39.843338 web_php[688].ERR [99.1.1.1] [Login denied for user "validuser"] at /usr/share/zoneminder/www/includes/auth.php line 313
01/06/22 09:27:41.568784 web_php[25].ERR [99.1.1.1] [Login denied for user "validuser"] at /usr/share/zoneminder/www/includes/auth.php line 313
Here is my cscli metrics output:
root@zm:/etc/crowdsec/parsers# cscli metrics
INFO[06-01-2022 01:40:21 PM] Acquisition Metrics:
+-----------------------------------------------------+------------+--------------+----------------+------------------------+
| SOURCE | LINES READ | LINES PARSED | LINES UNPARSED | LINES POURED TO BUCKET |
+-----------------------------------------------------+------------+--------------+----------------+------------------------+
| file:/path/to/zoneminderm/web_php.log | 9 | - | 9 | - |
| file:/var/log/auth.log | 430 | - | 430 | - |
| file:/var/log/haproxy.log | 311 | - | 311 | - |
| file:/var/log/syslog | 323 | - | 323 | - |
| journalctl:journalctl-_SYSTEMD_UNIT=apache2.service | 2 | - | 2 | - |
+-----------------------------------------------------+------------+--------------+----------------+------------------------+
INFO[06-01-2022 01:40:21 PM] Parser Metrics:
+---------------+------+--------+----------+
| PARSERS | HITS | PARSED | UNPARSED |
+---------------+------+--------+----------+
| webphp_parser | 1075 | - | 1075 |
+---------------+------+--------+----------+
INFO[06-01-2022 01:40:21 PM] Local Api Metrics:
+----------------------+--------+------+
| ROUTE | METHOD | HITS |
+----------------------+--------+------+
| /v1/decisions/stream | GET | 2521 |
| /v1/watchers/login | POST | 4 |
+----------------------+--------+------+
INFO[06-01-2022 01:40:21 PM] Local Api Bouncers Metrics:
+----------------------------+----------------------+--------+------+
| BOUNCER | ROUTE | METHOD | HITS |
+----------------------------+----------------------+--------+------+
| FirewallBouncer-1641340869 | /v1/decisions/stream | GET | 1260 |
| crowdsec-custom-bouncer | /v1/decisions/stream | GET | 1261 |
+----------------------------+----------------------+--------+------+
And getting a fair amount of errors in /var/log/crowdsec.log:
time="06-01-2022 13:39:01" level=debug msg="Event leaving node : ko" id=shy-waterfall name=webphp_parser stage=s01-parse
time="06-01-2022 13:39:01" level=debug msg="(shy-waterfall) target field 'message' doesn't exist in map[]" id=shy-waterfall name=webphp_parser stage=s01-parse
time="06-01-2022 13:39:01" level=debug msg="+ Grok '^%{DA...' didn't return data on ''" id=shy-waterfall name=webphp_parser stage=s01-parse
Here are some questions I have:
-
In my parser, I’m not fully understanding the filter item. I had thought in the testing environment, I’d identified being able to set type type to
web_php
and then use this for a filter:"evt.Parsed.program == 'web_php'"
. However, this does not work. I’ve not found doco that shows what all of the evt.* variables are, nor to what they are mapped. Does this exist somewhere? How would I fix the filter line for my parser? -
In the crowdsec.log file, it’s failing to parse, even though I am able to parse in my test environment (including my filter line working). Example from test environment is below. What am I missing here?
INFO[06-01-2022 13:48:40] reading web_php3.log at once type="file://web_php3.log"
DEBU[06-01-2022 13:48:40] eval(evt.Parsed.program == 'web_php') = TRUE id=cool-frog name=webphp_parser stage=s01-parse
DEBU[06-01-2022 13:48:40] eval variables: id=cool-frog name=webphp_parser stage=s01-parse
DEBU[06-01-2022 13:48:40] evt.Parsed.program = 'web_php' id=cool-frog name=webphp_parser stage=s01-parse
DEBU[06-01-2022 13:48:40] + Grok '^%{DA...' returned 3 entries to merge in Parsed id=cool-frog name=webphp_parser stage=s01-parse
DEBU[06-01-2022 13:48:40] .Parsed['logname'] = 'web_php' id=cool-frog name=webphp_parser stage=s01-parse
DEBU[06-01-2022 13:48:40] .Parsed['srcIP'] = '110.201.0.1' id=cool-frog name=webphp_parser stage=s01-parse
DEBU[06-01-2022 13:48:40] .Parsed['message'] = 'Login denied for user "hoodswoods' id=cool-frog name=webphp_parser stage=s01-parse
DEBU[06-01-2022 13:48:40] + Processing 1 statics id=cool-frog name=webphp_parser stage=s01-parse
DEBU[06-01-2022 13:48:40] .Parsed[web_php] = 'yes' id=cool-frog name=webphp_parser stage=s01-parse
DEBU[06-01-2022 13:48:40] Event leaving node : ok id=cool-frog name=webphp_parser stage=s01-parse
- Do I have the right setup going here - i.e., write a parser and scenario config, and then use the crowdsec-custom-bouncer for decisions?
Thanks in advance!
-Matt