---
description: Pipeline for normalizing Zeek ssl.log
processors:
- set:
    field: event.ingested
    value: '{{_ingest.timestamp}}'
- set:
    field: event.created
    value: '{{@timestamp}}'
- date:
    field: zeek.ssl.ts
    formats:
    - UNIX
    - ISO8601
- remove:
    field: zeek.ssl.ts
- date:
    if: ctx.tls?.server?.not_before != null
    field: tls.server.not_before
    target_field: tls.server.not_before
    formats:
      - UNIX
      - ISO8601
- date:
    if: ctx.tls?.server?.not_after != null
    field: tls.server.not_after
    target_field: tls.server.not_after
    formats:
      - UNIX
      - ISO8601
- geoip:
    field: destination.ip
    target_field: destination.geo
    ignore_missing: true
- geoip:
    field: source.ip
    target_field: source.geo
    ignore_missing: true
- geoip:
    database_file: GeoLite2-ASN.mmdb
    field: source.ip
    target_field: source.as
    properties:
    - asn
    - organization_name
    ignore_missing: true
- geoip:
    database_file: GeoLite2-ASN.mmdb
    field: destination.ip
    target_field: destination.as
    properties:
    - asn
    - organization_name
    ignore_missing: true
- rename:
    field: source.as.asn
    target_field: source.as.number
    ignore_missing: true
- rename:
    field: source.as.organization_name
    target_field: source.as.organization.name
    ignore_missing: true
- rename:
    field: destination.as.asn
    target_field: destination.as.number
    ignore_missing: true
- rename:
    field: destination.as.organization_name
    target_field: destination.as.organization.name
    ignore_missing: true
- remove:
    field: zeek.ssl.client.cert_chain_fuids
    if: ctx.zeek.ssl.client?.cert_chain_fuids?.length == 0
    ignore_missing: true
- gsub:
    field: zeek.ssl.issuer
    pattern: \\,
    replacement: ""
    ignore_missing: true
- kv:
    field: zeek.ssl.issuer
    field_split: ','
    value_split: '='
    target_field: zeek.ssl.server.issuer
    ignore_missing: true
- rename:
    field: zeek.ssl.issuer
    target_field: tls.server.issuer
    ignore_missing: true
- rename:
    field: zeek.ssl.server.issuer.C
    target_field: zeek.ssl.server.issuer.country
    ignore_missing: true
- set:
    field: tls.server.x509.issuer.country
    value: '{{zeek.ssl.server.issuer.country}}'
    ignore_empty_value: true
- rename:
    field: zeek.ssl.server.issuer.CN
    target_field: zeek.ssl.server.issuer.common_name
    ignore_missing: true
- set:
    field: tls.server.x509.issuer.common_name
    value: '{{zeek.ssl.server.issuer.common_name}}'
    ignore_empty_value: true
- rename:
    field: zeek.ssl.server.issuer.L
    target_field: zeek.ssl.server.issuer.locality
    ignore_missing: true
- set:
    field: tls.server.x509.issuer.locality
    value: '{{zeek.ssl.server.issuer.locality}}'
    ignore_empty_value: true
- rename:
    field: zeek.ssl.server.issuer.O
    target_field: zeek.ssl.server.issuer.organization
    ignore_missing: true
- set:
    field: tls.server.x509.issuer.organization
    value: '{{zeek.ssl.server.issuer.organization}}'
    ignore_empty_value: true
- rename:
    field: zeek.ssl.server.issuer.OU
    target_field: zeek.ssl.server.issuer.organizational_unit
    ignore_missing: true
- set:
    field: tls.server.x509.issuer.organizational_unit
    value: '{{zeek.ssl.server.issuer.organizational_unit}}'
    ignore_empty_value: true
- rename:
    field: zeek.ssl.server.issuer.ST
    target_field: zeek.ssl.server.issuer.state
    ignore_missing: true
- set:
    field: tls.server.x509.issuer.state_or_province
    value: '{{zeek.ssl.server.issuer.state}}'
    ignore_empty_value: true
- gsub:
    field: zeek.ssl.subject
    pattern: \\,
    replacement: ""
    ignore_missing: true
- kv:
    field: zeek.ssl.subject
    field_split: ','
    value_split: '='
    target_field: zeek.ssl.server.subject
    ignore_missing: true
- rename:
    field: zeek.ssl.subject
    target_field: tls.server.subject
    ignore_missing: true
- rename:
    field: zeek.ssl.server.subject.C
    target_field: zeek.ssl.server.subject.country
    ignore_missing: true
- set:
    field: tls.server.x509.subject.country
    value: '{{zeek.ssl.server.subject.country}}'
    ignore_empty_value: true
- rename:
    field: zeek.ssl.server.subject.CN
    target_field: zeek.ssl.server.subject.common_name
    ignore_missing: true
- set:
    field: tls.server.x509.subject.common_name
    value: '{{zeek.ssl.server.subject.common_name}}'
    ignore_empty_value: true
- rename:
    field: zeek.ssl.server.subject.L
    target_field: zeek.ssl.server.subject.locality
    ignore_missing: true
- set:
    field: tls.server.x509.subject.locality
    value: '{{zeek.ssl.server.subject.locality}}'
    ignore_empty_value: true
- rename:
    field: zeek.ssl.server.subject.O
    target_field: zeek.ssl.server.subject.organization
    ignore_missing: true
- set:
    field: tls.server.x509.subject.organization
    value: '{{zeek.ssl.server.subject.organization}}'
    ignore_empty_value: true
- rename:
    field: zeek.ssl.server.subject.OU
    target_field: zeek.ssl.server.subject.organizational_unit
    ignore_missing: true
- set:
    field: tls.server.x509.subject.organizational_unit
    value: '{{zeek.ssl.server.subject.organizational_unit}}'
    ignore_empty_value: true
- rename:
    field: zeek.ssl.server.subject.ST
    target_field: zeek.ssl.server.subject.state
    ignore_missing: true
- set:
    field: tls.server.x509.subject.state_or_province
    value: '{{zeek.ssl.server.subject.state}}'
    ignore_empty_value: true
- gsub:
    field: zeek.ssl.client_issuer
    pattern: \\,
    replacement: ""
    ignore_missing: true
- kv:
    field: zeek.ssl.client_issuer
    field_split: ','
    value_split: '='
    target_field: zeek.ssl.client.issuer
    ignore_missing: true
- rename:
    field: zeek.ssl.client_issuer
    target_field: tls.client.issuer
    ignore_missing: true
- rename:
    field: zeek.ssl.client.issuer.C
    target_field: zeek.ssl.client.issuer.country
    ignore_missing: true
- set:
    field: tls.client.x509.issuer.country
    value: '{{zeek.ssl.client.issuer.country}}'
    ignore_empty_value: true
- rename:
    field: zeek.ssl.client.issuer.CN
    target_field: zeek.ssl.client.issuer.common_name
    ignore_missing: true
- set:
    field: tls.client.x509.issuer.common_name
    value: '{{zeek.ssl.client.issuer.common_name}}'
    ignore_empty_value: true
- rename:
    field: zeek.ssl.client.issuer.L
    target_field: zeek.ssl.client.issuer.locality
    ignore_missing: true
- set:
    field: tls.client.x509.issuer.locality
    value: '{{zeek.ssl.client.issuer.locality}}'
    ignore_empty_value: true
- rename:
    field: zeek.ssl.client.issuer.O
    target_field: zeek.ssl.client.issuer.organization
    ignore_missing: true
- set:
    field: tls.client.x509.issuer.organization
    value: '{{zeek.ssl.client.issuer.organization}}'
    ignore_empty_value: true
- rename:
    field: zeek.ssl.client.issuer.OU
    target_field: zeek.ssl.client.issuer.organizational_unit
    ignore_missing: true
- set:
    field: tls.client.x509.issuer.organizational_unit
    value: '{{zeek.ssl.client.issuer.organizational_unit}}'
    ignore_empty_value: true
- rename:
    field: zeek.ssl.client.issuer.ST
    target_field: zeek.ssl.client.issuer.state
    ignore_missing: true
- set:
    field: tls.client.x509.issuer.state_or_province
    value: '{{zeek.ssl.client.issuer.state}}'
    ignore_empty_value: true
- gsub:
    field: zeek.ssl.client_subject
    pattern: \\,
    replacement: ""
    ignore_missing: true
- kv:
    field: zeek.ssl.client_subject
    field_split: ','
    value_split: '='
    target_field: zeek.ssl.client.subject
    ignore_missing: true
- remove:
    field: zeek.ssl.client_subject
    ignore_missing: true
- rename:
    field: zeek.ssl.client.subject.C
    target_field: zeek.ssl.client.subject.country
    ignore_missing: true
- set:
    field: tls.client.x509.subject.country
    value: '{{zeek.ssl.client.subject.country}}'
    ignore_empty_value: true
- rename:
    field: zeek.ssl.client.subject.CN
    target_field: zeek.ssl.client.subject.common_name
    ignore_missing: true
- set:
    field: tls.client.x509.subject.common_name
    value: '{{zeek.ssl.client.subject.common_name}}'
    ignore_empty_value: true
- rename:
    field: zeek.ssl.client.subject.L
    target_field: zeek.ssl.client.subject.locality
    ignore_missing: true
- set:
    field: tls.client.x509.subject.locality
    value: '{{zeek.ssl.client.subject.locality}}'
    ignore_empty_value: true
- rename:
    field: zeek.ssl.client.subject.O
    target_field: zeek.ssl.client.subject.organization
    ignore_missing: true
- set:
    field: tls.client.x509.subject.organization
    value: '{{zeek.ssl.client.subject.organization}}'
    ignore_empty_value: true
- rename:
    field: zeek.ssl.client.subject.OU
    target_field: zeek.ssl.client.subject.organizational_unit
    ignore_missing: true
- set:
    field: tls.client.x509.subject.organizational_unit
    value: '{{zeek.ssl.client.subject.organizational_unit}}'
    ignore_empty_value: true
- rename:
    field: zeek.ssl.client.subject.ST
    target_field: zeek.ssl.client.subject.state
    ignore_missing: true
- set:
    field: tls.client.x509.subject.state_or_province
    value: '{{zeek.ssl.client.subject.state}}'
    ignore_empty_value: true
- set:
    field: tls.cipher
    value: '{{zeek.ssl.cipher}}'
    if: ctx.zeek?.ssl?.cipher != null
- set:
    field: tls.curve
    value: '{{zeek.ssl.curve}}'
    if: ctx.zeek?.ssl?.curve != null
- convert:
    target_field: tls.established
    field: zeek.ssl.established
    type: boolean
    ignore_missing: true
- convert:
    target_field: tls.resumed
    field: zeek.ssl.resumed
    type: boolean
    ignore_missing: true
- script:
    lang: painless
    if: ctx.zeek?.ssl?.version != null
    source: >-
      def parts = ctx.zeek.ssl.version.splitOnToken("v");
      if (parts.length != 2) {
        return;
      }
      if (parts[0] == "SSL") {
        ctx.tls.version = parts[1] + ".0";
      } else {
        ctx.tls.version = parts[1].substring(0,1) + "." + parts[1].substring(1);
      }
      ctx.tls.version_protocol = parts[0].toLowerCase();
- append:
    field: related.ip
    value: "{{source.ip}}"
    if: "ctx?.source?.ip != null"
- append:
    field: related.ip
    value: "{{destination.ip}}"
    if: "ctx?.destination?.ip != null"
on_failure:
- set:
    field: error.message
    value: '{{ _ingest.on_failure_message }}'
