AZiT

Parsing and enrichment is highlighted; its page is below.

Parsing and enrichment

Vector receives syslog over TLS and runs a short program for each line. pf lines are taken apart with one regular expression; SSH logins are recognised and classified; addresses get names.

What gets added#

  • The rule's name, from the label the firewall appends.
  • Network names for each interface, so a dashboard says "Trusted Wi-Fi", not vlan10.
  • Device names for internal addresses, from a CSV lookup table; an unknown internal address is named unknown, which makes strangers easy to spot.
  • Country and network owner for traffic from the internet, from GeoIP databases inside OpenSearch.
  • SSH logins on the firewall, as success or failure with user, source and the key's fingerprint.
  • The web server's requests, which arrive as JSON: status, path, user agent and TLS version, and the country and network owner of every visitor. Its SSH logins and sudo commands are recognised the same way.

In the configuration#

Vector transform, VRL
p, err = parse_regex(.message,
  r'rule (?P<rule>\d+)/\((?P<reason>[^)]+)\) (?P<action>pass|block) (?P<dir>in|out) on (?P<iface>\S+): (?P<src_ip>[\d.]+)\.?(?P<src_port>\d+)? > (?P<dst_ip>[\d.]+)\.?(?P<dst_port>\d+)?:')
if err == null {
  .event.action = p.action
  .source.ip = p.src_ip
  .destination.ip = p.dst_ip
  host, e = get_enrichment_table_record("hosts", {"ip": .source.ip})
  if e == null { .source.hostname = host.hostname }
}
  • Errors are values in VRL, so a line that does not match is kept and tagged instead of being dropped.