From e1566fec7bcd48d5511fc91db2dd8f6d784a1835 Mon Sep 17 00:00:00 2001 From: Miska Husgafvel Date: Wed, 8 Oct 2025 14:51:07 +0300 Subject: [PATCH 1/6] Fix CAS auditlog filename Currently filename does not include protocols, so change the filename pattern. --- cas-pipeline.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cas-pipeline.conf b/cas-pipeline.conf index 4b5b571..cd8e524 100644 --- a/cas-pipeline.conf +++ b/cas-pipeline.conf @@ -5,7 +5,7 @@ input { file { # Use a generic path for the log file. Update this to your specific log file location. - path => "/var/log/cas/*_service_*_idp_audit.log" + path => "/var/log/cas/*_audit.log" start_position => "beginning" # The sincedb_path is set to /dev/null for testing. For production, # consider setting a relative path, e.g., "./.sincedb_cas-audit". From 4526639d1e03a7f83c2b1f15c5fbf83c23fdceee Mon Sep 17 00:00:00 2001 From: Miska Husgafvel Date: Wed, 8 Oct 2025 14:52:09 +0300 Subject: [PATCH 2/6] Fix removing unnecessary header lines Remove extra ANSI escape codes Remove double escape from digit fields --- cas-pipeline.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cas-pipeline.conf b/cas-pipeline.conf index cd8e524..c55d990 100644 --- a/cas-pipeline.conf +++ b/cas-pipeline.conf @@ -25,8 +25,8 @@ filter { # The first gsub removes ANSI escape codes, which are sometimes present in the logs. # The second gsub removes the leading header line for each audit trail record. gsub => [ - "message", "\e\[(\d+;)*\d+m", "", - "message", "^\s*20\d{2}-\d{2}-\d{2} \d{2}:\d{2}:\\d{2},\\d{3} INFO.*Audit trail record BEGIN\n=============================================================\n", "" + "message", "(\e\[m)?\e\[(\d+;)*\d+m", "", + "message", "^\s*20\d{2}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3} INFO.*Audit trail record BEGIN\n=============================================================\n", "" ] } From da95efe839f149f560f0d84b5a71ab7b30189ed0 Mon Sep 17 00:00:00 2001 From: Miska Husgafvel Date: Wed, 8 Oct 2025 14:54:28 +0300 Subject: [PATCH 3/6] Remove duplicated === line --- cas-pipeline.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cas-pipeline.conf b/cas-pipeline.conf index c55d990..86c6d27 100644 --- a/cas-pipeline.conf +++ b/cas-pipeline.conf @@ -34,7 +34,7 @@ filter { # This pattern is designed to extract key fields from the audit trail body. grok { match => { - "message" => "=============================================================\nWHEN: %{TIMESTAMP_ISO8601:timestamp}\nWHO: %{DATA:subject}\nWHAT: %{GREEDYDATA:what}\nACTION: %{WORD:action}\nCLIENT_IP: %{IP:ip_address}\nSERVER_IP: %{IP:server_ip}" + "message" => "WHEN: %{TIMESTAMP_ISO8601:timestamp}\nWHO: %{DATA:subject}\nWHAT: %{GREEDYDATA:what}\nACTION: %{WORD:action}\nCLIENT_IP: %{DATA:ip_address}\nSERVER_IP: %{DATA:server_ip}" } } From f3e5dc884cd5adc0348fd257dde108cfc1cfd92c Mon Sep 17 00:00:00 2001 From: Miska Husgafvel Date: Wed, 8 Oct 2025 14:55:52 +0300 Subject: [PATCH 4/6] Use the default GeoIP databases Logstash geoip plugin does not include GeoLite2-Country.mmdb by default, so use the default databases --- cas-pipeline.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cas-pipeline.conf b/cas-pipeline.conf index 86c6d27..e996998 100644 --- a/cas-pipeline.conf +++ b/cas-pipeline.conf @@ -174,7 +174,7 @@ filter { target => "geoip" # Use a generic path for the GeoLite2 database. Logstash usually looks in its own 'data' directory. # Replace this with the actual path to your database file if the generic path fails. - database => "GeoLite2-Country.mmdb" + #database => "GeoLite2-Country.mmdb" fields => ["country_name", "country_code2"] } } From cf12a3743ec057efb7a5b032535efff35b4fc928 Mon Sep 17 00:00:00 2001 From: Miska Husgafvel Date: Wed, 8 Oct 2025 14:56:58 +0300 Subject: [PATCH 5/6] Fix GeoIP result structure and field names --- cas-pipeline.conf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cas-pipeline.conf b/cas-pipeline.conf index e996998..89df716 100644 --- a/cas-pipeline.conf +++ b/cas-pipeline.conf @@ -236,9 +236,9 @@ filter { acct["context"] = event.get("context") end - if event.get("[geoip][country_name]") && event.get("[geoip][country_code2]") - acct["geoip_country"] = event.get("[geoip][country_name]") - acct["geoip_country_code"] = event.get("[geoip][country_code2]") + if event.get("[geoip][geo][country_name]") && event.get("[geoip][geo][country_iso_code]") + acct["geoip_country"] = event.get("[geoip][geo][country_name]") + acct["geoip_country_code"] = event.get("[geoip][geo][country_iso_code]") end event.set("accounting", acct) From 6272b696a592837103ab62fae67bcbc511b83335 Mon Sep 17 00:00:00 2001 From: Miska Husgafvel Date: Wed, 8 Oct 2025 14:58:46 +0300 Subject: [PATCH 6/6] Add a best effort guess for destination / object values for several actions --- cas-pipeline.conf | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/cas-pipeline.conf b/cas-pipeline.conf index 89df716..d23b3a0 100644 --- a/cas-pipeline.conf +++ b/cas-pipeline.conf @@ -167,6 +167,17 @@ filter { } } + # Make a best effort guess for destination system / object value + if [action] in [ "DELEGATED_CLIENT_SUCCESS", "SERVICE_TICKET_CREATED", "SERVICE_TICKET_VALIDATE_SUCCESS", "OAUTH2_USER_PROFILE_CREATED", "OAUTH2_ACCESS_TOKEN_REQUEST_CREATED", "SAML2_RESPONSE_CREATED" ] { + # Extract the service URI and use it for both the object and destination_system + grok { + # Extract the service URI being at the end of the line + # by matching both the trailing comma and the final curly bracket. + match => { "what" => "service=%{URI:destination_system}(?:,|})" } + add_field => { "object" => "%{destination_system}" } + } + } + # The geoip filter enriches the event with geographical information based on the IP address. if [ip_address] { geoip {