spot public and internal brutes
vi /etc/fluent-bit/custom_parsers.conf
#
# parse sshguard journal
#
# impossible to register parser if using source.ip directly
# impossible to register parser if using source.ip_range directly
# double quotes there are
[PARSER]
Name sshguard_attack
Format regex
Regex ^Attack from "(?<src_ip>[^ ]+)" on service .*$
# CIDR and double quotes there are
[PARSER]
Name sshguard_block_range
Format regex
Regex ^Blocking "(?<src_ip_range>[^ ]+)" for [0-9]+ secs .*$
# CIDR and double quotes there are
[PARSER]
Name sshguard_block
Format regex
Regex ^Blocking "(?<src_ip>[^ /]+)/32" for [0-9]+ secs .*$
# seen without CIDR
[PARSER]
Name sshguard_unblock
Format regex
Regex ^(?<src_ip>[^:]+): unblocking after .*$
vi /etc/fluent-bit/fluent-bit.conf
[SERVICE]
...
parsers_file custom_parsers.conf
@INCLUDE flb_brutes.conf
vi /etc/fluent-bit/flb_brutes.conf
#
# spot public and internal brutes
#
# change:
# destination.ip
# destination.geo.name
# sensor
#
[INPUT]
name systemd
systemd_filter _SYSTEMD_UNIT=sshguard.service
read_from_tail on
tag sshguard
# https://docs.fluentbit.io/manual/pipeline/filters/parser
# https://docs.fluentbit.io/manual/pipeline/parsers/regular-expression
[FILTER]
name parser
match sshguard
key_name MESSAGE
parser sshguard_attack
Preserve_Key true
Reserve_Data true
[FILTER]
name parser
match sshguard
key_name MESSAGE
parser sshguard_block
Preserve_Key true
Reserve_Data true
[FILTER]
name parser
match sshguard
key_name MESSAGE
parser sshguard_unblock
Preserve_Key true
Reserve_Data true
# this is a workaround - impossible to register parsers if using source.ip source.ip_range directly
[FILTER]
name modify
match sshguard
condition key_value_matches src_ip [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+
rename src_ip source.ip
[FILTER]
name geoip2
match sshguard
database /etc/fluent-bit/GeoLite2-City.mmdb
lookup_key source.ip
record source.geo.city_name source.ip %{city.names.ru}
record source.geo.country_name source.ip %{country.names.ru}
record lat source.ip %{location.latitude}
record lon source.ip %{location.longitude}
log_level error
# catch lat lon (lat comes first)
[FILTER]
name nest
match sshguard
operation nest
wildcard l*
nest_under source.geo.location
[FILTER]
name modify
match sshguard
# assume 1/10 of a MB just to get a Map Line
add source.bytes 100000
add destination.bytes 100000
add destination.geo.name HOSTNAME
add destination.ip PUBLIC-IP
add lat 55.7386
add lon 37.6068
add destination.geo.city_name Москва
add destination.geo.country_name Россия
[FILTER]
name nest
match sshguard
operation nest
wildcard l*
nest_under destination.geo.location
[FILTER]
name modify
match sshguard
add sensor sshguard@HOSTNAME
#[OUTPUT]
# name file
# match sshguard
# path /var/log
# file fluent-bit.brutes.log