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