diff --git a/google_secops_parser/README.md b/google_secops_parser/README.md new file mode 100644 index 0000000..8e9677a --- /dev/null +++ b/google_secops_parser/README.md @@ -0,0 +1,132 @@ +# Google SecOps Parser for parsedmarc + +A [Google Security Operations (Chronicle)](https://cloud.google.com/security/products/security-operations) custom parser for ingesting [parsedmarc](https://domainaware.github.io/parsedmarc/) syslog events into the Unified Data Model (UDM). + +## Overview + +parsedmarc sends DMARC aggregate reports, forensic reports, and SMTP TLS reports as JSON-formatted syslog messages. This parser transforms those JSON events into Google SecOps UDM events for threat detection and investigation. + +### Supported Report Types + +| Report Type | UDM Event Type | Description | +|---|---|---| +| DMARC Aggregate | `EMAIL_TRANSACTION` | Aggregate DMARC authentication results from reporting organizations | +| DMARC Forensic | `EMAIL_TRANSACTION` | Individual email authentication failure reports | +| SMTP TLS | `GENERIC_EVENT` | SMTP TLS session success/failure reports (RFC 8460) | + +## UDM Field Mappings + +### DMARC Aggregate Reports + +| parsedmarc Field | UDM Field | Notes | +|---|---|---| +| `source_ip_address` | `principal.ip` | IP address of the email source | +| `source_reverse_dns` | `principal.hostname` | Reverse DNS of source | +| `source_country` | `principal.location.country_or_region` | GeoIP country of source | +| `header_from` | `network.email.from` | From header domain | +| `envelope_from` | `network.email.mail_from` | Envelope sender | +| `envelope_to` | `network.email.to` | Envelope recipient | +| `domain` | `target.hostname` | Domain the report is about | +| `report_id` | `metadata.product_log_id` | Report identifier | +| `disposition` | `security_result.action` | `none`→`ALLOW`, `quarantine`→`QUARANTINE`, `reject`→`BLOCK` | +| `dmarc_aligned` | `additional.fields` | Whether DMARC passed | +| `spf_aligned` | `additional.fields` | Whether SPF was aligned | +| `dkim_aligned` | `additional.fields` | Whether DKIM was aligned | +| `org_name` | `additional.fields` | Reporting organization name | +| `count` | `additional.fields` | Number of messages | +| `p`, `sp`, `pct` | `additional.fields` | DMARC policy settings | +| `dkim_domains`, `dkim_results` | `additional.fields` | DKIM authentication details | +| `spf_domains`, `spf_results` | `additional.fields` | SPF authentication details | + +### DMARC Forensic Reports + +| parsedmarc Field | UDM Field | Notes | +|---|---|---| +| `source_ip_address` | `principal.ip` | IP address of the email source | +| `source_reverse_dns` | `principal.hostname` | Reverse DNS of source | +| `source_country` | `principal.location.country_or_region` | GeoIP country of source | +| `original_mail_from` | `network.email.from` | Original sender | +| `original_rcpt_to` | `network.email.to` | Original recipient | +| `subject` | `network.email.subject` | Email subject | +| `reported_domain` | `target.hostname` | Reported domain | +| `message_id` | `metadata.product_log_id` | Email message ID | +| `arrival_date_utc` | `metadata.event_timestamp` | Arrival timestamp (UTC) | +| `auth_failure` | `security_result.description` | Type of authentication failure | +| `feedback_type` | `additional.fields` | Feedback report type | +| `authentication_results` | `additional.fields` | Full authentication results string | +| `delivery_result` | `additional.fields` | Email delivery outcome | + +### SMTP TLS Reports + +| parsedmarc Field | UDM Field | Notes | +|---|---|---| +| `sending_mta_ip` | `principal.ip` | Sending MTA IP address | +| `receiving_ip` | `target.ip` | Receiving MTA IP address | +| `receiving_mx_hostname` | `target.hostname` | Receiving MX hostname | +| `report_id` | `metadata.product_log_id` | Report identifier | +| `organization_name` | `additional.fields` | Reporting organization | +| `policy_domain` | `additional.fields` | Policy domain | +| `policy_type` | `additional.fields` | TLS policy type | +| `successful_session_count` | `additional.fields` | Count of successful TLS sessions | +| `failed_session_count` | `additional.fields` | Count of failed TLS sessions | +| `result_type` | `additional.fields` | Failure result type | +| `failure_reason_code` | `additional.fields` | Failure reason code | + +## Installation + +### Prerequisites + +- A Google Security Operations (Chronicle) tenant +- parsedmarc configured to send syslog output (see [parsedmarc documentation](https://domainaware.github.io/parsedmarc/)) + +### Steps + +1. **Configure parsedmarc syslog output** in your `parsedmarc.ini`: + + ```ini + [syslog] + server = your-chronicle-forwarder.example.com + port = 514 + ``` + +2. **Create the log source** in Google SecOps: + - Navigate to **Settings** → **Feeds** → **Add New** + - Select **Syslog** as the source type + - Configure to listen for parsedmarc syslog messages + +3. **Upload the custom parser**: + - Navigate to **Settings** → **Parsers** + - Click **Create Custom Parser** + - Set the **Log Type** to match your feed configuration + - Paste the contents of `parsedmarc.conf` + - Click **Submit** + +4. **Validate** the parser using the Chronicle parser validation tool with sample parsedmarc JSON events. + +## Sample Log Events + +### Aggregate Report + +```json +{"xml_schema": "1.0", "org_name": "Example Inc", "org_email": "noreply@example.net", "report_id": "abc123", "begin_date": "2024-01-01 00:00:00", "end_date": "2024-01-01 23:59:59", "domain": "example.com", "adkim": "r", "aspf": "r", "p": "reject", "sp": "reject", "pct": "100", "fo": "0", "source_ip_address": "203.0.113.1", "source_country": "United States", "source_reverse_dns": "mail.example.org", "source_base_domain": "example.org", "count": 42, "spf_aligned": true, "dkim_aligned": true, "dmarc_aligned": true, "disposition": "none", "header_from": "example.com", "envelope_from": "example.com", "envelope_to": null, "dkim_domains": "example.com", "dkim_selectors": "selector1", "dkim_results": "pass", "spf_domains": "example.com", "spf_scopes": "mfrom", "spf_results": "pass"} +``` + +### Forensic Report + +```json +{"feedback_type": "auth-failure", "user_agent": "Lua/1.0", "version": "1.0", "original_mail_from": "sender@example.com", "original_rcpt_to": "recipient@example.org", "arrival_date": "Mon, 01 Jan 2024 12:00:00 +0000", "arrival_date_utc": "2024-01-01 12:00:00", "source_ip_address": "198.51.100.1", "source_country": "Germany", "source_reverse_dns": "mail.example.com", "source_base_domain": "example.com", "subject": "Test Email", "message_id": "", "authentication_results": "dmarc=fail (p=reject; dis=reject) header.from=example.com", "dkim_domain": "example.com", "delivery_result": "reject", "auth_failure": "dmarc", "reported_domain": "example.com", "authentication_mechanisms": "dmarc"} +``` + +### SMTP TLS Report + +```json +{"organization_name": "Example Inc", "begin_date": "2024-01-01 00:00:00", "end_date": "2024-01-01 23:59:59", "report_id": "tls-123", "policy_domain": "example.com", "policy_type": "sts", "policy_strings": "version: STSv1; mode: enforce", "mx_host_patterns": "*.mail.example.com", "successful_session_count": 1000, "failed_session_count": 5, "result_type": "certificate-expired", "sending_mta_ip": "203.0.113.10", "receiving_ip": "198.51.100.20", "receiving_mx_hostname": "mx.example.com", "receiving_mx_helo": "mx.example.com", "failure_reason_code": "X509_V_ERR_CERT_HAS_EXPIRED"} +``` + +## UDM Reference + +For the complete list of UDM fields, see the [Google SecOps UDM field list](https://cloud.google.com/chronicle/docs/reference/udm-field-list). + +## License + +This parser is part of the [parsedmarc](https://github.com/domainaware/parsedmarc) project and is distributed under the same license. diff --git a/google_secops_parser/parsedmarc.conf b/google_secops_parser/parsedmarc.conf new file mode 100644 index 0000000..4ef1a17 --- /dev/null +++ b/google_secops_parser/parsedmarc.conf @@ -0,0 +1,1058 @@ +filter { + + # ========================================================================== + # parsedmarc Google SecOps Parser + # + # Parses JSON syslog events produced by parsedmarc + # (https://domainaware.github.io/parsedmarc/) + # + # parsedmarc outputs three types of reports as single-line JSON via syslog: + # 1. DMARC Aggregate Reports (contains "header_from" and "dmarc_aligned") + # 2. DMARC Forensic Reports (contains "feedback_type") + # 3. SMTP TLS Reports (contains "policy_type") + # + # UDM Reference: + # https://cloud.google.com/chronicle/docs/reference/udm-field-list + # ========================================================================== + + # Initialize variables + mutate { + replace => { + "event_type" => "EMAIL_UNCATEGORIZED" + "report_type" => "" + } + } + + # Parse the JSON payload from the syslog message + json { + source => "message" + array_function => "split_columns" + on_error => "not_json" + } + + # Abort if not valid JSON + if [not_json] { + drop {} + } + + # -------------------------------------------------------------------------- + # Detect report type + # -------------------------------------------------------------------------- + + # Aggregate reports contain "header_from" and "dmarc_aligned" + if [header_from] != "" { + mutate { + replace => { + "report_type" => "aggregate" + } + } + } + + # Forensic reports contain "feedback_type" + if [feedback_type] != "" { + mutate { + replace => { + "report_type" => "forensic" + } + } + } + + # SMTP TLS reports contain "policy_type" + if [policy_type] != "" { + mutate { + replace => { + "report_type" => "smtp_tls" + } + } + } + + # ========================================================================== + # DMARC Aggregate Report Parsing + # ========================================================================== + if [report_type] == "aggregate" { + + mutate { + replace => { + "event_type" => "EMAIL_TRANSACTION" + } + } + + # -- metadata -- + if [report_id] != "" { + mutate { + replace => { + "event.idm.read_only_udm.metadata.product_log_id" => "%{report_id}" + } + } + } + + if [org_name] != "" { + mutate { + replace => { + "org_name_label.key" => "org_name" + "org_name_label.value.string_value" => "%{org_name}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "org_name_label" + } + } + } + + if [org_email] != "" { + mutate { + replace => { + "org_email_label.key" => "org_email" + "org_email_label.value.string_value" => "%{org_email}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "org_email_label" + } + } + } + + # -- timestamps -- + if [begin_date] != "" { + mutate { + replace => { + "begin_date_label.key" => "begin_date" + "begin_date_label.value.string_value" => "%{begin_date}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "begin_date_label" + } + } + } + + if [end_date] != "" { + mutate { + replace => { + "end_date_label.key" => "end_date" + "end_date_label.value.string_value" => "%{end_date}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "end_date_label" + } + } + } + + # -- principal (source of emails) -- + if [source_ip_address] != "" { + mutate { + merge => { + "event.idm.read_only_udm.principal.ip" => "source_ip_address" + } + on_error => "merge_ip_error" + } + } + + if [source_reverse_dns] != "" { + mutate { + replace => { + "event.idm.read_only_udm.principal.hostname" => "%{source_reverse_dns}" + } + } + } + + if [source_country] != "" { + mutate { + replace => { + "event.idm.read_only_udm.principal.location.country_or_region" => "%{source_country}" + } + } + } + + if [source_base_domain] != "" { + mutate { + replace => { + "src_base_domain_label.key" => "source_base_domain" + "src_base_domain_label.value.string_value" => "%{source_base_domain}" + } + merge => { + "event.idm.read_only_udm.principal.labels" => "src_base_domain_label" + } + } + } + + if [source_name] != "" { + mutate { + replace => { + "src_name_label.key" => "source_name" + "src_name_label.value.string_value" => "%{source_name}" + } + merge => { + "event.idm.read_only_udm.principal.labels" => "src_name_label" + } + } + } + + if [source_type] != "" { + mutate { + replace => { + "src_type_label.key" => "source_type" + "src_type_label.value.string_value" => "%{source_type}" + } + merge => { + "event.idm.read_only_udm.principal.labels" => "src_type_label" + } + } + } + + # -- email fields -- + if [header_from] != "" { + mutate { + replace => { + "event.idm.read_only_udm.network.email.from" => "%{header_from}" + } + } + } + + if [envelope_from] != "" { + mutate { + replace => { + "event.idm.read_only_udm.network.email.mail_from" => "%{envelope_from}" + } + } + } + + if [envelope_to] != "" { + mutate { + replace => { + "event.idm.read_only_udm.network.email.to" => "%{envelope_to}" + } + on_error => "envelope_to_error" + } + } + + # -- target (domain being reported on) -- + if [domain] != "" { + mutate { + replace => { + "event.idm.read_only_udm.target.hostname" => "%{domain}" + } + } + } + + # -- message count -- + if [count] != "" { + mutate { + replace => { + "count_label.key" => "count" + "count_label.value.string_value" => "%{count}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "count_label" + } + } + } + + # -- security results: DMARC alignment and disposition -- + mutate { + replace => { + "security_result_dmarc.category" => "POLICY_VIOLATION" + "security_result_dmarc.summary" => "DMARC Aggregate Report" + } + } + + # Map disposition to security_result.action + if [disposition] == "none" { + mutate { + replace => { + "security_result_dmarc.action" => "ALLOW" + } + } + } else if [disposition] == "quarantine" { + mutate { + replace => { + "security_result_dmarc.action" => "QUARANTINE" + } + } + } else if [disposition] == "reject" { + mutate { + replace => { + "security_result_dmarc.action" => "BLOCK" + } + } + } else { + mutate { + replace => { + "security_result_dmarc.action" => "UNKNOWN_ACTION" + } + } + } + + # Build description of alignment results + mutate { + replace => { + "security_result_dmarc.description" => "dmarc_aligned=%{dmarc_aligned} spf_aligned=%{spf_aligned} dkim_aligned=%{dkim_aligned} disposition=%{disposition}" + } + on_error => "desc_error" + } + + # DMARC aligned category + if [dmarc_aligned] == "True" or [dmarc_aligned] == "true" { + mutate { + replace => { + "security_result_dmarc.category" => "SOFTWARE_MALICIOUS" + } + } + # Override: Passed DMARC = no policy violation + mutate { + replace => { + "security_result_dmarc.category" => "NETWORK_CATEGORIZED_CONTENT" + } + } + } + + # Merge security_result + mutate { + merge => { + "event.idm.read_only_udm.security_result" => "security_result_dmarc" + } + } + + # -- DMARC policy fields -- + if [p] != "" { + mutate { + replace => { + "p_label.key" => "dmarc_policy" + "p_label.value.string_value" => "%{p}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "p_label" + } + } + } + + if [sp] != "" { + mutate { + replace => { + "sp_label.key" => "dmarc_sub_policy" + "sp_label.value.string_value" => "%{sp}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "sp_label" + } + } + } + + if [pct] != "" { + mutate { + replace => { + "pct_label.key" => "dmarc_pct" + "pct_label.value.string_value" => "%{pct}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "pct_label" + } + } + } + + if [adkim] != "" { + mutate { + replace => { + "adkim_label.key" => "dkim_alignment_mode" + "adkim_label.value.string_value" => "%{adkim}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "adkim_label" + } + } + } + + if [aspf] != "" { + mutate { + replace => { + "aspf_label.key" => "spf_alignment_mode" + "aspf_label.value.string_value" => "%{aspf}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "aspf_label" + } + } + } + + # -- alignment detail fields -- + if [dmarc_aligned] != "" { + mutate { + replace => { + "dmarc_aligned_label.key" => "dmarc_aligned" + "dmarc_aligned_label.value.string_value" => "%{dmarc_aligned}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "dmarc_aligned_label" + } + } + } + + if [spf_aligned] != "" { + mutate { + replace => { + "spf_aligned_label.key" => "spf_aligned" + "spf_aligned_label.value.string_value" => "%{spf_aligned}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "spf_aligned_label" + } + } + } + + if [dkim_aligned] != "" { + mutate { + replace => { + "dkim_aligned_label.key" => "dkim_aligned" + "dkim_aligned_label.value.string_value" => "%{dkim_aligned}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "dkim_aligned_label" + } + } + } + + if [disposition] != "" { + mutate { + replace => { + "disposition_label.key" => "disposition" + "disposition_label.value.string_value" => "%{disposition}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "disposition_label" + } + } + } + + # -- DKIM auth detail fields -- + if [dkim_domains] != "" { + mutate { + replace => { + "dkim_domains_label.key" => "dkim_domains" + "dkim_domains_label.value.string_value" => "%{dkim_domains}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "dkim_domains_label" + } + } + } + + if [dkim_selectors] != "" { + mutate { + replace => { + "dkim_selectors_label.key" => "dkim_selectors" + "dkim_selectors_label.value.string_value" => "%{dkim_selectors}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "dkim_selectors_label" + } + } + } + + if [dkim_results] != "" { + mutate { + replace => { + "dkim_results_label.key" => "dkim_results" + "dkim_results_label.value.string_value" => "%{dkim_results}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "dkim_results_label" + } + } + } + + # -- SPF auth detail fields -- + if [spf_domains] != "" { + mutate { + replace => { + "spf_domains_label.key" => "spf_domains" + "spf_domains_label.value.string_value" => "%{spf_domains}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "spf_domains_label" + } + } + } + + if [spf_scopes] != "" { + mutate { + replace => { + "spf_scopes_label.key" => "spf_scopes" + "spf_scopes_label.value.string_value" => "%{spf_scopes}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "spf_scopes_label" + } + } + } + + if [spf_results] != "" { + mutate { + replace => { + "spf_results_label.key" => "spf_results" + "spf_results_label.value.string_value" => "%{spf_results}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "spf_results_label" + } + } + } + + # -- policy override fields -- + if [policy_override_reasons] != "" and [policy_override_reasons] != "none" { + mutate { + replace => { + "override_label.key" => "policy_override_reasons" + "override_label.value.string_value" => "%{policy_override_reasons}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "override_label" + } + } + } + + if [policy_override_comments] != "" and [policy_override_comments] != "none" { + mutate { + replace => { + "override_comments_label.key" => "policy_override_comments" + "override_comments_label.value.string_value" => "%{policy_override_comments}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "override_comments_label" + } + } + } + } + + # ========================================================================== + # DMARC Forensic Report Parsing + # ========================================================================== + if [report_type] == "forensic" { + + mutate { + replace => { + "event_type" => "EMAIL_TRANSACTION" + } + } + + # -- metadata -- + if [message_id] != "" { + mutate { + replace => { + "event.idm.read_only_udm.metadata.product_log_id" => "%{message_id}" + } + } + } + + # -- timestamps -- + if [arrival_date_utc] != "" { + date { + match => ["arrival_date_utc", "yyyy-MM-dd HH:mm:ss"] + on_error => "date_parse_error" + } + } + + # -- principal (source of the email) -- + if [source_ip_address] != "" { + mutate { + merge => { + "event.idm.read_only_udm.principal.ip" => "source_ip_address" + } + on_error => "merge_forensic_ip_error" + } + } + + if [source_reverse_dns] != "" { + mutate { + replace => { + "event.idm.read_only_udm.principal.hostname" => "%{source_reverse_dns}" + } + } + } + + if [source_country] != "" { + mutate { + replace => { + "event.idm.read_only_udm.principal.location.country_or_region" => "%{source_country}" + } + } + } + + if [source_base_domain] != "" { + mutate { + replace => { + "fsrc_base_domain_label.key" => "source_base_domain" + "fsrc_base_domain_label.value.string_value" => "%{source_base_domain}" + } + merge => { + "event.idm.read_only_udm.principal.labels" => "fsrc_base_domain_label" + } + } + } + + if [source_name] != "" { + mutate { + replace => { + "fsrc_name_label.key" => "source_name" + "fsrc_name_label.value.string_value" => "%{source_name}" + } + merge => { + "event.idm.read_only_udm.principal.labels" => "fsrc_name_label" + } + } + } + + if [source_type] != "" { + mutate { + replace => { + "fsrc_type_label.key" => "source_type" + "fsrc_type_label.value.string_value" => "%{source_type}" + } + merge => { + "event.idm.read_only_udm.principal.labels" => "fsrc_type_label" + } + } + } + + # -- email fields -- + if [original_mail_from] != "" { + mutate { + replace => { + "event.idm.read_only_udm.network.email.from" => "%{original_mail_from}" + } + } + } + + if [original_rcpt_to] != "" { + mutate { + replace => { + "event.idm.read_only_udm.network.email.to" => "%{original_rcpt_to}" + } + on_error => "rcpt_to_error" + } + } + + if [subject] != "" { + mutate { + replace => { + "event.idm.read_only_udm.network.email.subject" => "%{subject}" + } + } + } + + # -- target (reported domain) -- + if [reported_domain] != "" { + mutate { + replace => { + "event.idm.read_only_udm.target.hostname" => "%{reported_domain}" + } + } + } + + # -- security result -- + mutate { + replace => { + "security_result_forensic.summary" => "DMARC Forensic Report" + } + } + + if [auth_failure] != "" { + mutate { + replace => { + "security_result_forensic.description" => "auth_failure=%{auth_failure}" + } + } + } + + if [delivery_result] != "" { + mutate { + replace => { + "delivery_result_label.key" => "delivery_result" + "delivery_result_label.value.string_value" => "%{delivery_result}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "delivery_result_label" + } + } + } + + # Map auth_failure to security_result.category + if [auth_failure] == "dmarc" { + mutate { + replace => { + "security_result_forensic.category" => "POLICY_VIOLATION" + "security_result_forensic.action" => "ALLOW" + } + } + } else if [auth_failure] == "spf" { + mutate { + replace => { + "security_result_forensic.category" => "POLICY_VIOLATION" + "security_result_forensic.action" => "ALLOW" + } + } + } else if [auth_failure] == "dkim" { + mutate { + replace => { + "security_result_forensic.category" => "POLICY_VIOLATION" + "security_result_forensic.action" => "ALLOW" + } + } + } else { + mutate { + replace => { + "security_result_forensic.category" => "POLICY_VIOLATION" + "security_result_forensic.action" => "UNKNOWN_ACTION" + } + } + } + + mutate { + merge => { + "event.idm.read_only_udm.security_result" => "security_result_forensic" + } + } + + # -- additional forensic fields -- + if [feedback_type] != "" { + mutate { + replace => { + "feedback_type_label.key" => "feedback_type" + "feedback_type_label.value.string_value" => "%{feedback_type}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "feedback_type_label" + } + } + } + + if [user_agent] != "" { + mutate { + replace => { + "user_agent_label.key" => "user_agent" + "user_agent_label.value.string_value" => "%{user_agent}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "user_agent_label" + } + } + } + + if [authentication_results] != "" { + mutate { + replace => { + "auth_results_label.key" => "authentication_results" + "auth_results_label.value.string_value" => "%{authentication_results}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "auth_results_label" + } + } + } + + if [authentication_mechanisms] != "" { + mutate { + replace => { + "auth_mechanisms_label.key" => "authentication_mechanisms" + "auth_mechanisms_label.value.string_value" => "%{authentication_mechanisms}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "auth_mechanisms_label" + } + } + } + + if [dkim_domain] != "" { + mutate { + replace => { + "f_dkim_domain_label.key" => "dkim_domain" + "f_dkim_domain_label.value.string_value" => "%{dkim_domain}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "f_dkim_domain_label" + } + } + } + + if [auth_failure] != "" { + mutate { + replace => { + "auth_failure_label.key" => "auth_failure" + "auth_failure_label.value.string_value" => "%{auth_failure}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "auth_failure_label" + } + } + } + + if [arrival_date] != "" { + mutate { + replace => { + "arrival_date_label.key" => "arrival_date" + "arrival_date_label.value.string_value" => "%{arrival_date}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "arrival_date_label" + } + } + } + } + + # ========================================================================== + # SMTP TLS Report Parsing + # ========================================================================== + if [report_type] == "smtp_tls" { + + mutate { + replace => { + "event_type" => "GENERIC_EVENT" + } + } + + # -- metadata -- + if [report_id] != "" { + mutate { + replace => { + "event.idm.read_only_udm.metadata.product_log_id" => "%{report_id}" + } + } + } + + if [organization_name] != "" { + mutate { + replace => { + "tls_org_label.key" => "organization_name" + "tls_org_label.value.string_value" => "%{organization_name}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "tls_org_label" + } + } + } + + # -- timestamps -- + if [begin_date] != "" { + mutate { + replace => { + "tls_begin_label.key" => "begin_date" + "tls_begin_label.value.string_value" => "%{begin_date}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "tls_begin_label" + } + } + } + + if [end_date] != "" { + mutate { + replace => { + "tls_end_label.key" => "end_date" + "tls_end_label.value.string_value" => "%{end_date}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "tls_end_label" + } + } + } + + # -- principal (sending MTA) -- + if [sending_mta_ip] != "" { + mutate { + merge => { + "event.idm.read_only_udm.principal.ip" => "sending_mta_ip" + } + on_error => "merge_tls_sending_ip_error" + } + } + + # -- target (receiving MTA) -- + if [receiving_ip] != "" { + mutate { + merge => { + "event.idm.read_only_udm.target.ip" => "receiving_ip" + } + on_error => "merge_tls_receiving_ip_error" + } + } + + if [receiving_mx_hostname] != "" { + mutate { + replace => { + "event.idm.read_only_udm.target.hostname" => "%{receiving_mx_hostname}" + } + } + } + + # -- policy fields -- + if [policy_domain] != "" { + mutate { + replace => { + "policy_domain_label.key" => "policy_domain" + "policy_domain_label.value.string_value" => "%{policy_domain}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "policy_domain_label" + } + } + } + + if [policy_type] != "" { + mutate { + replace => { + "policy_type_label.key" => "policy_type" + "policy_type_label.value.string_value" => "%{policy_type}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "policy_type_label" + } + } + } + + if [policy_strings] != "" { + mutate { + replace => { + "policy_strings_label.key" => "policy_strings" + "policy_strings_label.value.string_value" => "%{policy_strings}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "policy_strings_label" + } + } + } + + if [mx_host_patterns] != "" { + mutate { + replace => { + "mx_patterns_label.key" => "mx_host_patterns" + "mx_patterns_label.value.string_value" => "%{mx_host_patterns}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "mx_patterns_label" + } + } + } + + # -- session counts -- + if [successful_session_count] != "" { + mutate { + replace => { + "success_count_label.key" => "successful_session_count" + "success_count_label.value.string_value" => "%{successful_session_count}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "success_count_label" + } + } + } + + if [failed_session_count] != "" { + mutate { + replace => { + "failed_count_label.key" => "failed_session_count" + "failed_count_label.value.string_value" => "%{failed_session_count}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "failed_count_label" + } + } + } + + # -- failure details -- + if [result_type] != "" { + mutate { + replace => { + "result_type_label.key" => "result_type" + "result_type_label.value.string_value" => "%{result_type}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "result_type_label" + } + } + } + + if [receiving_mx_helo] != "" { + mutate { + replace => { + "mx_helo_label.key" => "receiving_mx_helo" + "mx_helo_label.value.string_value" => "%{receiving_mx_helo}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "mx_helo_label" + } + } + } + + if [additional_info_uri] != "" { + mutate { + replace => { + "info_uri_label.key" => "additional_info_uri" + "info_uri_label.value.string_value" => "%{additional_info_uri}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "info_uri_label" + } + } + } + + if [failure_reason_code] != "" { + mutate { + replace => { + "failure_code_label.key" => "failure_reason_code" + "failure_code_label.value.string_value" => "%{failure_reason_code}" + } + merge => { + "event.idm.read_only_udm.additional.fields" => "failure_code_label" + } + } + } + + # -- security result for TLS reports -- + mutate { + replace => { + "security_result_tls.summary" => "SMTP TLS Report" + } + } + + if [result_type] != "" { + mutate { + replace => { + "security_result_tls.description" => "result_type=%{result_type}" + "security_result_tls.action" => "UNKNOWN_ACTION" + } + } + } + + mutate { + merge => { + "event.idm.read_only_udm.security_result" => "security_result_tls" + } + } + } + + # ========================================================================== + # Common metadata fields + # ========================================================================== + mutate { + replace => { + "event.idm.read_only_udm.metadata.event_type" => "%{event_type}" + "event.idm.read_only_udm.metadata.vendor_name" => "parsedmarc" + "event.idm.read_only_udm.metadata.product_name" => "parsedmarc" + } + } + + if [report_type] != "" { + mutate { + replace => { + "event.idm.read_only_udm.metadata.product_event_type" => "%{report_type}" + } + } + } + + # ========================================================================== + # Output + # ========================================================================== + statedump {} + + mutate { + merge => { + "@output" => "event" + } + } +}