Improved exim parser

I just noticed my exim parser at /etc/crowdsec/parsers/s01-parse/exim-logs.yaml was not working well. Even if it was parsing a very default exim4 mainlog file.

I just want to share my current modified one (exim-logs.yaml)

onsuccess: next_stage
#debug: true
filter: "evt.Parsed.program == 'exim'"
name: crowdsecurity/exim-logs
description: "Parse exim logs"
pattern_syntax:
  NO_DOUBLE_QUOTE: '[^"]+'
  NO_END_BRACKET: '[^\]]+'
  NO_END_PAR: '[^\)]+'
  EXIM_AUTH: '(?:dovecot_)?(?:login|plain)'
  EXIM_SOURCE: '(?:%{HOSTNAME:source_dns} )?(?:\(%{NO_END_PAR:source_helo}\) )?\[%{IP:source_ip}\]'
  EXIM_OPT_DATE: '(:?%{EXIM_DATE:date} )?'
  EXIM_SOURCE_TLS: 'H=%{EXIM_SOURCE}(?::%{POSINT:source_port})? (:?X=%{NOTSPACE:tls_cipher} CV=(:?yes|no) )?'
nodes:
  - grok:
      pattern: '%{EXIM_OPT_DATE}%{EXIM_AUTH:exim_auth} authenticator failed for %{EXIM_SOURCE}:(?:%{POSINT:source_port}:)? 535 Incorrect authentication data \(set_id=%{NO_END_PAR:target_user}\)'
      apply_on: message
      statics:
        - meta: log_type
          value: exim_failed_auth
  - grok:
      pattern: '%{EXIM_OPT_DATE}%{EXIM_SOURCE_TLS}F=<%{EMAILADDRESS:source_user}> rejected RCPT <%{EMAILADDRESS:target_user}>: "JunkMail rejected - %{NOTSPACE} \[%{NO_END_BRACKET}\]:%{INT} is in an RBL: %{NO_DOUBLE_QUOTE:rbl_url}"'
      apply_on: message
      statics:
        - meta: log_type
          value: spam-attempt
        - meta: rbl_url
          expression: evt.Parsed.rbl_url
        - meta: source_user
          expression: evt.Parsed.source_user
  - grok:
      pattern: '%{EXIM_OPT_DATE}%{EXIM_SOURCE_TLS}F=<%{EMAILADDRESS:source_user}> rejected RCPT <%{EMAILADDRESS:target_user}>: Email blocked by %{HOSTNAME:rbl_url}'
      apply_on: message
      statics:
        - meta: log_type
          value: spam-attempt
        - meta: rbl_url
          expression: evt.Parsed.rbl_url
        - meta: source_user
          expression: evt.Parsed.source_user
  - grok:
      pattern: '%{EXIM_OPT_DATE}%{EXIM_SOURCE_TLS}F=<%{EMAILADDRESS:source_user}> rejected RCPT <%{EMAILADDRESS:target_user}>: No Such User Here'
      apply_on: message
      statics:
        - meta: log_type
          value: exim_failed_auth
        - meta: source_user
          expression: evt.Parsed.source_user
  - grok:
      pattern: '%{EXIM_OPT_DATE}%{EXIM_SOURCE_TLS}temporarily rejected connection in "%{NO_DOUBLE_QUOTE:acl}" ACL: "Host is ratelimited \(%{NO_END_PAR:rate_limit}\)'
      apply_on: message
      statics:
        - meta: log_type
          value: spam-attempt
  - grok:
      pattern: '%{EXIM_OPT_DATE}%{EXIM_SOURCE_TLS}sender verify fail for <%{EMAILADDRESS:source_user}>: The mail server does not recognize %{NOTSPACE} as a valid sender.'
      apply_on: message
      statics:
        - meta: log_type
          value: spam-attempt
        - meta: source_user
          expression: evt.Parsed.source_user
  - grok:
      pattern: '%{EXIM_OPT_DATE}%{EXIM_SOURCE_TLS}F=<%{EMAILADDRESS:source_user}> rejected RCPT <%{EMAILADDRESS:target_user}>: Sender verify failed'
      apply_on: message
      statics:
        - meta: log_type
          value: spam-attempt
        - meta: source_user
          expression: evt.Parsed.source_user
  - grok:
      pattern: '%{EXIM_OPT_DATE}%{EXIM_SOURCE_TLS}F=<%{EMAILADDRESS:source_user}> rejected RCPT <%{EMAILADDRESS:target_user}>: SMTP AUTH is required for message submission on port %{POSINT:target_port}'
      apply_on: message
      statics:
        - meta: log_type
          value: spam-attempt
        - meta: source_user
          expression: evt.Parsed.source_user
        - meta: target_port
          expression: evt.Parsed.target_port
  - grok:
      pattern: '%{EXIM_OPT_DATE}SMTP protocol error in "%{NO_DOUBLE_QUOTE:smtp_error}" H=%{EXIM_SOURCE} %{GREEDYDATA:error_detail}'
      apply_on: message
      statics:
        - meta: log_type
          value: exim_failed_auth
  - grok:
      pattern: '%{EXIM_OPT_DATE}H=%{EXIM_SOURCE} F=<%{EMAILADDRESS:source_user}> rejected RCPT <%{EMAILADDRESS:target_user}>: %{GREEDYDATA:reject_reason}'
      apply_on: message
      statics:
        - meta: log_type
          value: spam-attempt
        - meta: source_user
          expression: evt.Parsed.source_user
  - grok:
      pattern: '%{EXIM_OPT_DATE}rejected EHLO from %{HOSTNAME:source_dns} \[%{IP:source_ip}\]: %{GREEDYDATA:error_detail}'
      apply_on: message
      statics:
        - meta: log_type
          value: spam-attempt
  - grok:
      pattern: '%{EXIM_OPT_DATE}%{NOTSPACE:exim_id} H=%{EXIM_SOURCE} F=<%{EMAILADDRESS:source_user}> rejected after DATA: %{GREEDYDATA:reject_reason}'
      apply_on: message
      statics:
        - meta: log_type
          value: spam-attempt
        - meta: source_user
          expression: evt.Parsed.source_user
  - grok:
      pattern: '%{EXIM_OPT_DATE}SMTP syntax error in "%{NO_DOUBLE_QUOTE:smtp_error}" H=%{EXIM_SOURCE} %{GREEDYDATA:error_detail}'
      apply_on: message
      statics:
        - meta: log_type
          value: spam-attempt
  - grok:
      pattern: '%{EXIM_OPT_DATE}unexpected disconnection while reading SMTP command from %{EXIM_SOURCE} D=%{NOTSPACE:duration}'
      apply_on: message
      statics:
        - meta: log_type
          value: spam-attempt
  - grok:
      pattern: '%{EXIM_OPT_DATE}SMTP call from %{EXIM_SOURCE} dropped: %{GREEDYDATA:drop_reason}'
      apply_on: message
      statics:
        - meta: log_type
          value: spam-attempt
  - grok:
      pattern: '%{EXIM_OPT_DATE}TLS error on connection from %{EXIM_SOURCE} \(%{NO_END_PAR:tls_direction}\): %{GREEDYDATA:tls_error}'
      apply_on: message
      statics:
        - meta: log_type
          value: spam-attempt
statics:
  - meta: service
    value: exim
  - target: evt.StrTime
    expression: evt.Parsed.date
  - meta: source_ip
    expression: evt.Parsed.source_ip
  - meta: source_dns
    expression: evt.Parsed.source_dns
  - meta: source_helo
    expression: evt.Parsed.source_helo
  - meta: username
    expression: evt.Parsed.target_user

Cheers,

Matthijs