Syslog filters

Hi there, I want to capture Server: IPv4 information for log corellation.

I’m receiving syslog messages from(cisco) in the below format:

@timestamp: "2025-09-18T00:49:35.275360534Z"
dataSource: "89.115.123.60"
dataType: "syslog"
deviceTime: "2025-09-18T00:49:35.190678816Z"
host: "10.0.1.14"
id: "75ad06dc-c23c-49fb-aa1f-80763f0703f9"
logx:
syslog:
message: "<180>SSL Log: OPENVPN Server: 114.125.52.140:34025 Connection reset, restarting"

other examples of received syslog messages, TCP Allow

@timestamp: "2025-09-18T18:00:10.245304268Z"
dataSource: "89.115.123.60"
dataType: "syslog"
deviceTime: "2025-09-18T18:00:10.189365635Z"
host: "10.0.1.14"
id: "f6f7002b-bcef-4abd-bc4a-777afc7c0205"
logx:
syslog:
message: "<1>ALLOW TCP 78.125.62.116:57795 -> 89.115.123.60:3389 on ppp1"

Other examples, UDP allow

@timestamp: "2025-09-18T15:16:35.24806315Z"
dataSource: "89.115.123.60"
dataType: "syslog"
deviceTime: "2025-09-18T15:16:35.192144145Z"
host: "10.0.1.14"
id: "c4f281bc-0a31-4a7c-aa12-092312cb1fdc"
logx:
syslog:
message: "<1>ALLOW UDP 5.187.35.53:31158 -> 89.115.123.60:500 on ppp1"

other examples:

@timestamp: "2025-09-18T14:28:35.239062442Z"
dataSource: "89.115.123.60"
dataType: "syslog"
deviceTime: "2025-09-18T14:28:35.182411440Z"
host: "10.0.1.14"
id: "5bbadf85-4000-46fe-95bc-3cd1e0851040"
logx:
syslog:
message: "TCP 192.168.2.166:60966 -> 92.123.103.72:80 on eth0TCP 192.168.2.166:60967 -> 34.237.206.2:80 on eth0"

My filter is like below, I tried using dissect instead of grok without success.

The message is parsed as a single line and I can’t use IP addresses or other metadata to filter, please advise.

filter {
# Syslog filter, version 1.0.1

split {
 field => "message"
 terminator => "<utm-log-separator>"
}

#Looking for datasource generated by an agent and parse original message
if [message]=~/\[utm_stack_agent_ds=(.+)\]-(.+)/ {
  grok {
    match => {
     "message" => [ "\[utm_stack_agent_ds=%{DATA:dataSource}\]-%{GREEDYDATA:original_log_message}" ]
    }
  }
}
if [original_log_message] {
  mutate {
    update => { "message" => "%{[original_log_message]}" }
  }
}
#......................................................................#
#Generating dataSource field required by CurrelationRulesEngine
if ![dataSource] {
  mutate {
    add_field => { "dataSource" => "%{host}" }
  }
}
#......................................................................#
#Generating logx structure
if ![dataType] {
  mutate {
    add_field => {"dataType" => "syslog"}
    rename => ["message", "[logx][syslog][message]"]
  }
}
#Remove unwanted fields if the message not match with conditions
  mutate {
    remove_field => ["@version","original_log_message","headers"]
  }
}

To get the IP address from all four of those examples you could use

grok { match => { "message" => "%{IPV4:host1}:%{NUMBER:port1}( -> %{IPV4:host2}:%{NUMBER:port2})?" } }
1 Like

Thank you Badger, this was very helpful!

I was able to capture most of the metadata with the below filter(a bit modified to fit my needs)

<?>%{GREEDYDATA:Connect}? %{WORD:Protocol} %{IPV4:SourceIP}:%{NUMBER:SourcePort}( -> %{IPV4:DestIP}:%{NUMBER:DestPort}) on %{GREEDYDATA:Interface}"