diff --git a/docs/sources/vendor/Citrix/netscaler.md b/docs/sources/vendor/Citrix/netscaler.md index a758992eff..1f14a51d9a 100644 --- a/docs/sources/vendor/Citrix/netscaler.md +++ b/docs/sources/vendor/Citrix/netscaler.md @@ -7,27 +7,33 @@ ## Links -| Ref | Link | -|----------------|---------------------------------------------------------------------------------------------------------| -| Splunk Add-on | | +| Ref | Link | +|----------------|-----------------------------------------------------------------------------------------------------| +| Splunk Add-on | | | Product Manual | | ## Sourcetypes -| sourcetype | notes | -|----------------|---------------------------------------------------------------------------------------------------------| -| citrix:netscaler:syslog | None | -| citrix:netscaler:appfw | None | -| citrix:netscaler:appfw:cef | None | +| sourcetype | notes | +|----------------------------|-------| +| citrix:netscaler:syslog | None | +| citrix:netscaler:appfw | None | +| citrix:netscaler:appfw:cef | None | ## Sourcetype and Index Configuration -| key | sourcetype | index | notes | -|----------------|----------------|----------------|----------------| -| citrix_netscaler | citrix:netscaler:syslog | netfw | none | -| citrix_netscaler | citrix:netscaler:appfw | netfw | none | -| citrix_netscaler | citrix:netscaler:appfw:cef | netfw | none | +| key | sourcetype | index | notes | +|------------------|----------------------------|-------|-------| +| citrix_netscaler | citrix:netscaler:syslog | netfw | none | +| citrix_netscaler | citrix:netscaler:appfw | netfw | none | +| citrix_netscaler | citrix:netscaler:appfw:cef | netfw | none | ## Source Setup and Configuration -* Follow vendor configuration steps per Product Manual above. Ensure the data format selected is "DDMMYYYY" +* Follow vendor configuration steps per Product Manual above. + +## Options + +| Variable | default | description | +|--------------------------------------------|--------------|-----------------------------------------------------------------------------------------------| +| `SC4S_IGNORE_MMDD_LEGACY_CITRIX_NETSCALER` | empty string | (empty/yes) Set to "yes" for parsing the date in format `dd/mm/yyyy` instead of `mm/dd/yyyy`. | diff --git a/package/enterprise/etc/conf.d/conflib/almost-syslog/app-almost-syslog-citrix_netscaler.conf b/package/enterprise/etc/conf.d/conflib/almost-syslog/app-almost-syslog-citrix_netscaler.conf index 0408a0ff77..a5316cc179 100644 --- a/package/enterprise/etc/conf.d/conflib/almost-syslog/app-almost-syslog-citrix_netscaler.conf +++ b/package/enterprise/etc/conf.d/conflib/almost-syslog/app-almost-syslog-citrix_netscaler.conf @@ -10,7 +10,7 @@ block parser app-almost-syslog-citrix_netscaler() { parser { regexp-parser( prefix(".tmp.") - patterns('^(?\<\d+>) (?(?\d\d)\/\d\d\/\d\d\d\d:\d\d:\d\d:\d\d ?(?\w+))? (?[^ ]+) (?[A-Z\-0-9]+ : .*)') + patterns('^(?\<\d+\>) (?(?\d\d)\/\d\d\/\d\d\d\d:\d\d:\d\d:\d\d ?(?\w+))? (?[^ ]+) (?[A-Z\-0-9]+ : .*)') ); }; parser { @@ -19,11 +19,12 @@ block parser app-almost-syslog-citrix_netscaler() { ); }; + if { - filter { "${.tmp.tspart1}" eq "$R_DAY"}; + filter { "`SC4S_IGNORE_MMDD_LEGACY_CITRIX_NETSCALER`" eq "yes" or "${.tmp.tspart1}" eq "${DAY}"}; parser { date-parser-nofilter( - format('%d/%m/%Y:%H:%M:%S %z','%d/%m/%Y:%H:%M:%S') + format('%d/%m/%Y:%H:%M:%S %z','%d/%m/%Y:%H:%M:%S','%d/%m/%Y:%H:%M:%S %Z') template("${.tmp.timestamp}") ); }; diff --git a/package/etc/conf.d/conflib/almost-syslog/app-almost-syslog-citrix_netscaler.conf b/package/etc/conf.d/conflib/almost-syslog/app-almost-syslog-citrix_netscaler.conf index 0408a0ff77..a5316cc179 100644 --- a/package/etc/conf.d/conflib/almost-syslog/app-almost-syslog-citrix_netscaler.conf +++ b/package/etc/conf.d/conflib/almost-syslog/app-almost-syslog-citrix_netscaler.conf @@ -10,7 +10,7 @@ block parser app-almost-syslog-citrix_netscaler() { parser { regexp-parser( prefix(".tmp.") - patterns('^(?\<\d+>) (?(?\d\d)\/\d\d\/\d\d\d\d:\d\d:\d\d:\d\d ?(?\w+))? (?[^ ]+) (?[A-Z\-0-9]+ : .*)') + patterns('^(?\<\d+\>) (?(?\d\d)\/\d\d\/\d\d\d\d:\d\d:\d\d:\d\d ?(?\w+))? (?[^ ]+) (?[A-Z\-0-9]+ : .*)') ); }; parser { @@ -19,11 +19,12 @@ block parser app-almost-syslog-citrix_netscaler() { ); }; + if { - filter { "${.tmp.tspart1}" eq "$R_DAY"}; + filter { "`SC4S_IGNORE_MMDD_LEGACY_CITRIX_NETSCALER`" eq "yes" or "${.tmp.tspart1}" eq "${DAY}"}; parser { date-parser-nofilter( - format('%d/%m/%Y:%H:%M:%S %z','%d/%m/%Y:%H:%M:%S') + format('%d/%m/%Y:%H:%M:%S %z','%d/%m/%Y:%H:%M:%S','%d/%m/%Y:%H:%M:%S %Z') template("${.tmp.timestamp}") ); }; diff --git a/package/lite/etc/addons/citrix/app-almost-syslog-citrix_netscaler.conf b/package/lite/etc/addons/citrix/app-almost-syslog-citrix_netscaler.conf index 0408a0ff77..a5316cc179 100644 --- a/package/lite/etc/addons/citrix/app-almost-syslog-citrix_netscaler.conf +++ b/package/lite/etc/addons/citrix/app-almost-syslog-citrix_netscaler.conf @@ -10,7 +10,7 @@ block parser app-almost-syslog-citrix_netscaler() { parser { regexp-parser( prefix(".tmp.") - patterns('^(?\<\d+>) (?(?\d\d)\/\d\d\/\d\d\d\d:\d\d:\d\d:\d\d ?(?\w+))? (?[^ ]+) (?[A-Z\-0-9]+ : .*)') + patterns('^(?\<\d+\>) (?(?\d\d)\/\d\d\/\d\d\d\d:\d\d:\d\d:\d\d ?(?\w+))? (?[^ ]+) (?[A-Z\-0-9]+ : .*)') ); }; parser { @@ -19,11 +19,12 @@ block parser app-almost-syslog-citrix_netscaler() { ); }; + if { - filter { "${.tmp.tspart1}" eq "$R_DAY"}; + filter { "`SC4S_IGNORE_MMDD_LEGACY_CITRIX_NETSCALER`" eq "yes" or "${.tmp.tspart1}" eq "${DAY}"}; parser { date-parser-nofilter( - format('%d/%m/%Y:%H:%M:%S %z','%d/%m/%Y:%H:%M:%S') + format('%d/%m/%Y:%H:%M:%S %z','%d/%m/%Y:%H:%M:%S','%d/%m/%Y:%H:%M:%S %Z') template("${.tmp.timestamp}") ); }; diff --git a/tests/test_citrix_netscaler.py b/tests/test_citrix_netscaler.py index b7e6413298..ef6f661c6d 100644 --- a/tests/test_citrix_netscaler.py +++ b/tests/test_citrix_netscaler.py @@ -4,6 +4,9 @@ # license that can be found in the LICENSE-BSD2 file or at # https://opensource.org/licenses/BSD-2-Clause import datetime +import os +from unittest.mock import patch + import shortuuid import pytz import pytest @@ -28,7 +31,7 @@ def test_citrix_netscaler(record_property, setup_splunk, setup_sc4s, get_pid): _, bsd, time, _, _, tzname, epoch = time_operations(dt) # Tune time functions - time = dt.strftime("%d/%m/%Y:%H:%M:%S") + time = dt.strftime("%m/%d/%Y:%H:%M:%S") epoch = epoch[:-7] mt = env.from_string( @@ -91,6 +94,49 @@ def test_citrix_netscaler_sdx( assert result_count == 1 +# <134> 05/08/2025:03:13:15 GMT DC-NS02 0-PPE-0 : default TCP CONN_TERMINATE 1874124822 0 : Source 10.x.x.x:47990 - Destination 10.x.x.x:80 - Start Time 26/03/2025:21:13:15 GMT - End Time 26/03/2025:21:13:15 GMT - Total_bytes_send 1 - Total_bytes_recv 1 +@pytest.mark.addons("citrix") +@patch.dict( + os.environ, + { + "SC4S_IGNORE_MMDD_LEGACY_CITRIX_NETSCALER": "yes", + }, + clear=False +) +def test_citrix_netscaler_new_date_format( + record_property, setup_splunk, setup_sc4s, get_pid +): + host = f"test-ctitrixns-host-{shortuuid.ShortUUID().random(length=5).lower()}-{shortuuid.ShortUUID().random(length=5).lower()}" + pid = get_pid + + dt = datetime.datetime.now(datetime.timezone.utc) + _, bsd, time, _, _, tzname, epoch = time_operations(dt) + + # Tune time functions + time = dt.strftime("%d/%m/%Y:%H:%M:%S") + epoch = epoch[:-7] + + mt = env.from_string( + "{{ mark }} {{ time }} GMT {{ host }} 0-PPE-0 : default TCP CONN_TERMINATE 1874124822 0 : Source 10.x.x.x:47990 - Destination 10.x.x.x:80 - Start Time 26/03/2025:21:13:15 GMT - End Time 26/03/2025:21:13:15 GMT - Total_bytes_send 1 - Total_bytes_recv 1\n" + ) + message = mt.render( + mark="<134>", bsd=bsd, time=time, tzname=tzname, host=host, pid=pid + ) + + sendsingle(message, setup_sc4s[0], setup_sc4s[1][514]) + + st = env.from_string( + 'search _time={{ epoch }} index=netfw host={{ host }} sourcetype="citrix:netscaler:syslog"' + ) + search = st.render(epoch=epoch, host=host, pid=pid) + + result_count, _ = splunk_single(setup_splunk, search) + + record_property("host", host) + record_property("resultCount", result_count) + record_property("message", message) + + assert result_count == 1 # [289]: AAA Message : In receive_ldap_user_search_event: ldap_first_entry returned null, user ssgconfig not found @pytest.mark.addons("citrix")