Version: 5.0.9
Date: 20 Nov 2024
This Splunk App for McAfee Web Gateway allows rapid insights and operational visibility into McAfee Web Gateway (MWG) and McAfee Web Gateway Cloud Service (WGCS) deployments. It provides field extraction and CIM field mapping using all available types of access logs (default and custom McAfee Web Gateway log, McAfee Web Gateway Cloud Service), facilitates fast incident response and troubleshooting. This app is designed for security administrators, CISOs, or security personnel dedicated to taking security seriously.
In 2022, McAfee Web Gateway (MWG) rebranded as SkyHigh Secure Web Gateway (SWG). The App and sourcetype will maintain the McAfee name for some time to preserve the old App ID.
List of abbreviations used in this document:
Abbreviation | Meaning |
---|---|
MWG | McAfee Web Gateway |
SWG | SkyHigh/Secure Web Gateway |
WGCS | McAfee/SkyHigh Web Gateway Cloud Service |
UF | Splunk Universal Forwarder |
Product Compatibility:
Product | Version(s) |
---|---|
Splunk Enterprise | 6.6+, 7.x, 8.x, 9.x |
Splunk Cloud | all versions, both Classic and Victoria |
Splunk CIM | 4.x, 5.x |
MWG/SWG | 7.6+, 8.x, 9.x, 10.x, 11.x, 12.x |
WGCS | API version 5-12 |
Currently there are 85 different charts and tables grouped into 22 views
Applications Applications by Hits Applications by Volume Top Blocked Applications by Hits Top Applications by Volume Top Applications by Hits Top Application Statistics Audit Failed Logins Activity by Action Activity by Source_Type Activity by User User Activity by Appliance Authentication Top IP by Failed Auth Top User-Agents by Failed Auth Top Destination Hosts by Failed Auth Top User-Agents + IPs by Failed Auth Top User-Agents + DestHost by Failed Auth Top IPs + DestHost by Failed Auth Top IPs + User-Agent + DestHost by Failed Auth Multiple Logins from diff IPs Multiple Usernames coming from a single IP Authentication Method Statistics Connections Long running transactions DNS Timechart DNS resolution time Timechart DNS resolution time distribution (including Cached) Timechart DNS resolution time distribution (excluding Cached) DNS distribution (1ms - 200ms) DNS distribution (all) Errors Error Analysis HTTP Timechart HTTP Method HTTP Method Statistics HTTP Request Headers Statistics HTTP Response Headers Statistics Easy Search Status Code Overview Web Usage by URL Category Web Usage by URL Category Area Graph Top User-Agents Users + IPs IP Addresses by Hits Graph Top Hosts by Hits Top Blocked Domains by Hits Top Rules by Hits Events Malware Malware Top Users by blocked Malware Media Types Media Types Top Media Types by Volume Top Media Types by Hits EXE Uploads/Downloads Macro Uploads/Downloads EXE and Macro Uploads/Downloads with Magic Bytes Mismatch Encrypted Files Network Top unreachable Servers Performance Connect to Server Latency Total Transaction Duration distribution Client-Side Latency DNS resolution Latency distribution Time in Externals Distribution Protocols Protocols by Hits Protocols by Hits (Percent) Protocols by Volume Protocols by Volume (Percent) Potential Risks Top SRC with high Ratio of High Risk Requests Unusual Ports Requests to IP Addresses CONNECT Requests to IP Addresses Very long URLs Very large request and response Headers Non-resolvable Domains, potential DGA (Domain Generation Algorithm) Rules Top Rules Block Rules Overview Top Block Rules Rule Complexity/Performance Slowest Rule Execution Time in Rule Engine Distribution Time in Rule Engine over Time Security Posture Content Scan is possible Ratio SSL SSL Versions by Hits (Server) SSL Versions by Hits (Client) SSL Ciphers by Hits (Server) SSL Ciphers by Hits (Client) SSL KeyExchangeBits by Hits (Server) SSL KeyExchangeBits by Hits (Client) SSL Ciphers (Server) SSL Versions (Server) Client Certificate Requested SSL-related blocks Expired Certificate Certificate Issuers Summary Requests / Block Ratio Traffic Overview Traffic Top Inbound Traffic by Source Top Inbound Traffic by Destination Top Outbound Traffic by Source Top Outbound Traffic by Destination Uploads Uploads URL Filter URL Categories Blocked by URL Filter or by Web Reputation Top URL Categories by Volume Top URL Categories by Hits Geolocation Stats High Risk Destinations Not categorized Domains - Chart Top not categorized Domains - Table User-Agents User-Agent Statistics
Instance | App for McAfee Web Gateway | Add-on for McAfee Web Gateway |
---|---|---|
Standalone (all-in-one) Splunk | + | - |
Splunk Cloud | + | - |
On-prem Search Head | + | - |
On-prem Indexer | - | + |
Syslog/Log Server with Universal Forwarder | - | + |
SkyHigh Logging Client | - | + |
If you upgrade from a version 4.x then read Upgrade from 4.x to 5.x
MWG can write logs to the hard disk or/and send them via Syslog. Splunk can read log files locally, get them via network input (Syslog or raw UDP/TCP steam) or get them from a UF that is installed on a log server or on MWG itself. All these methods combined produce many possible ways to get MWG logs into Splunk:
Method / Link to configuration example | Description | Real time |
---|---|---|
Local file monitor | Splunk is installed directly on MWG and monitors the log file folder | Yes, up to 30 sec delay |
Local UDP/TCP input | Splunk is installed directly on the MWG and gets log files sent using Syslog | yes |
Syslog UDP/TCP | MWG sends logs via UDP/TCP to syslog collector or directly to Splunk | yes |
Syslog TCP+TLS | MWG sends logs via TCP, encrypted with TLS, to syslog collector or directly to Splunk | yes |
UF | Install UF on MWG to monitor log file folder | yes, up to 30 sec delay |
Log pushing from MWG to a log server | Use pushing (FTP/FTPS/SCP/SFTP/HTTP/HTTPS) from MWG to a log server | no |
Log pulling from MWG | Pulling logs from MWG via API, scp or rsync | no |
Log pulling from SSE/WGCS | Pulling logs via SSE/WGCS API | no, up to several minutes delay |
Splunk Connect for Syslog (SC4S) | MWG sends events via UDP/TCP to SC4S, SC4S forward them to Splunk HEC | yes |
Installing UF directly on MWG and configuring UF to forward events to Splunk indexer is a recommended and most reliable method!
Further considerations:
Log Format | Sourcetype | # of MWG fields | # of CIM fields | Average log line length (HTTPS Scanner enabled) | Comment/Example |
---|---|---|---|---|---|
Custom Log (recommended) | mcafee:webgateway:custom | 50-100 | 50-100 | ~600-1800 Bytes | This custom modular log format allows for flexible addition or removal of logging fields as needed. It provides comprehensive Common Information Model (CIM) coverage and deep insights for analytics and rapid troubleshooting. Despite the significantly larger amount of provided information, the log size remains largely unchanged. In fact, this new format achieves up to 3 times higher information density compared to the default log format. Starting from version 5.0.0 of the app, an updated log format was introduced that provides significantly improved search (up to 30 times) and reporting (up to 100 times) performance by leveraging TERM and PREFIX directives: 2021-02-26 14:36:46 -0600 s=200 ac=allowed src=192.168.2.1 p=https m=GET d=safebrowsing.googleapis.com dp=443 bi=563 bo=4156 dur=38 rt=17 up="/v4/threatListUpdates" ua="FF86-10.0" c=it dip=142.250.185.n ckex=112 skex=112 cntx scc=1302 ssc=1302 sslcp=1.3 sslsp=1.3 sslicn="GTS CA 1O1,GlobalSign" sslcn="upload.video.google.com" crtdays=-52 mbmismatch ctmt0 rul="L" rnf=41 rne=104 srcp=62407 conrt=0 bfc=524 btc=4418 tunnel psrcip=192.168.2.1n psrcp=42550 rqv=2.0 rsv=2.0 r=0 tdns=0 tcon=0 tre=34 text=34 t=18.18.22.11.15 Old versions of the app (3.x and 4.x) provided a slightly different format, that doesn't allow TERM/PREFIX benefits: 2021-02-26 14:40:23 +0100 204 allowed 192.168.2.1 https GET example.com 443 775/58 88/1 up="/test" ua="FF86-10.0" a="Google" c="wa" dip=142.250.185.nn kex=112/112 cntx sccc=1302/1302 sslp=1.3/1.3 sslicn="GTS CA 1O1,GlobalSign" sslcn="example.com" crtdays=-66 ctmt0 rul="L" rn=13/44 srcp=63298 conrt=0 b=744/239 psrcip=192.168.2.1 psrcp=20010 piv=2.0/2.0 r=0 t=0/0/86/87/56/56/3/4/28 |
Minimal Log | mcafee:webgateway:minimal | 6 | 8 | ~45-55 Bytes | Minimal log format, contains only 6 most important fields: status, src, dest, bytes_in, category, reputation. There is no timestamp, DATETIME_CONFIG = CURRENT is used instead. This format allows you to get the most important statistics using the shortest possible event length and is intended for use with the Splunk Free license (500 MB/day, ~10.000.000 events/day) . 302 192.168.1.10 maps.google.com 667 cm -38 |
Default Access Log | mcafee:webgateway:default | 14 | 17 | ~700 Bytes | The default log format, which has a fixed structure, provides only a minimal subset of fields. Use it only if no MWG modification is possible. [26/Feb/2021:14:40:23 +0100] "" 192.168.2.1 200 "GET https://example.com/test&adk=1473563476 HTTP/2.0" "Web Ads" "Minimal Risk" "image/gif" 286 538 "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0" "" "0" "Google" |
Legacy log format for the Splunk App v.3.0.7 | MWGaccess3 | 26 | 27 | ~650 Bytes | Customized log format with a fixed structure, provides more fields than the default log, including some timings and transferred bytes. Wasteful information like the User-Agent string is shortened. Consider it obsolete. [26/Feb/2021:14:40:23 +0100] status="200/0" srcip="192.168.2.1" user="" profile="-" dstip="-" dhost="example.com" urlp="443" proto="HTTPS/https" mtd="GET" urlc="Web Ads" rep="0" mt="image/gif" mlwr="-" app="Google" bytes="538/539/289/286" ua="FF86.0-10.0" lat="0/0/59/434" rule="Last Rule" url="https://example.com/test&adk=1473563476" |
Modified legacy log derived from MWGaccess3 | mcafee:wg:kv | 26 | 27 | 650-850 Bytes | Modified MWGaccess3 log format with a fixed structure included with the Splunk Add-on for McAfee Web Gateway , provides more fields than the default log, including some timings and transferred bytes. Wasteful information like the User-Agent string is shortened. Added sha2 hash and a CN name of the SSL certificate, a Cache-Control header, file name, a reputation level. Consider it obsolete. [10/Mar/2024:15:16:52 +0100] status="200/0" srcip="192.168.2.1" dhost="web.de" destip="82.165.229.83" urlp="443" proto="HTTPS/https" mtd="GET" urlc="Portal Sites" rep="0" mt="text/html" bytes="69/189/345936/345564" ua="curl/8.4.0" lat="0/0/397/397" rule="Last Rule" url="https://web.de/" rep_level="Minimal Risk" cache_control="no-cache, no-store, must-revalidate" ssl_cert_sha2="12695b9b9d0c190b01674492fcf898f91ba85d996dbafe8651e1ac41482f5907" ssl_cert_name="*.web.de" |
Log Format | Sourcetype | # of MWG fields | # of CIM fields | Average log line length (HTTPS Scanner enabled) | Comment/Example |
---|---|---|---|---|---|
WGCS API version 5 | skyhigh:webgateway:csv or mcafee:webgateway:wgcs_v5 | 28 | 28 | ~300-400 Bytes |
"user_id","username","source_ip", |
WGCS API version 6 | skyhigh:webgateway:csv | 28 | 28 | ~300-400 Bytes | No new fields are introduced. All fields from versions 1 – 5 are downloaded. Starting with API version 6, an error message is sent with the response to a download request that has timed out. |
WGCS API version 7 | skyhigh:webgateway:csv | 34 | 28 | ~400-450 Bytes | All fields from versions 1 – 6 are downloaded, plus these fields:
pop_country_code referer ssl_scanned av_scanned_up av_scanned_down rbi |
WGCS API version 8 | skyhigh:webgateway:csv | 40 | 30 | ~400-500 Bytes |
All fields from versions 1 – 7 are downloaded, plus these fields:
dlp client_system_name filename pop_egress_ip pop_ingress_ip proxy_port |
WGCS API version 9 | skyhigh:webgateway:csv | 40 | 30 | ~450-600 Bytes | With this header, no new fields are added. All fields from versions 1 – 8 are downloaded. |
WGCS API version 10 | skyhigh:webgateway:csv | 40 | 30 | ~450-600 Bytes |
With this header, all fields from versions 1 – 9 are downloaded, plus these fields:
mw_probability discarded_host ssl_client_prot ssl_server_prot |
WGCS API version 11 | skyhigh:webgateway:csv | 41 | 30 | ~450-600 Bytes |
With this header, fields from versions 1 – 10 are downloaded, plus this field:
domain_fronting_url |
WGCS API version 12 | skyhigh:webgateway:csv | 41 | 30 | ~450-600 Bytes |
With this header, fields from versions 1 – 11 are downloaded, plus these fields:
Downloaded for firewall traffic: domain_name client_host_name host_os_name scp_policy_name process_exe_pathDownloaded for Private Access traffic: virus |
Extract the file Splunk_Log_XXXXXX.xml (where XXXXXX is the version) from the MWG folder of the application package.
Import Splunk_Log_XXXXXX.xml file in MWG into the Default Log Handler: Policies > Rule Sets > Log Handler, right click on "Default" and select Add > Rule Set from Library
In the new window that appears, click on the "Import from file" button, then choose the xml file and click OK.
click "Auto-Solve Conflicts..." > select "Solve by referring to existing objects" and click OK to import the RuleSet.
The Log configuration has a modular structure, you can choose to send just a preconfigured minimal set of fields or select any subset from available fields. The log ruleset contains several parts (see numbering on the next screenshot):
Here are most important modifications that you can do in additional Rulesets (block of RuleSets #3 on the previous screenshot).
Ruleset | Possible modifications |
---|---|
Splunk | Domains not to log - some domains can be excluded from logging completely. |
Set Timestamp | choose the right timestamp. The ISO format with a time zone is selected by default. Other options are ToGMT, ISO8601, unix epoch and ToWebReporter formats. If you change the timestamp format on MWG then you have to adjust the TIME_FORMAT setting in local/props.conf on Splunk Indexer. |
Client IP | Connection.IP property is used by default. Deselect it and select Client.IP if you have downstream proxies or loadbalancer between the client and MWG. |
URL Categories | add internal domains to "internal Domains" list to avoid them to being shown as "uncategorized" |
Headers | on MWG older than version 10.x some rules will be marked in red if they are not compatible - delete them or upgrade MWG to the newest 10.x version or later. |
TLS | disable this ruleset if HTTPS Scanner is not enabled |
- | To get the correct Rule statistics you must create one last ruleset with a rule named "Last Rule" which is applied to all cycles (Request, Response, Embedded). |
RuleSet Library | Opener, Hashes/Body, Malware, Media Type, Uploads - to get some of the required information, additional rules need to be placed in the corresponding Policy Rule Sets. If you skip this step, some tables and graphs will be empty. |
Instead of letting Splunk read local splunk.log, events can be sent to a local Splunk instance via a local network interface or even loopback interface, without writing events to the hard disk (i.e. "Write Splunk Log" Rule Set can be disabled).
MWG UI:
$ModLoad imuxsock # provides support for local system logging (e.g. via logger command) $ModLoad imklog # reads kernel messages (the same are read from journald) $WorkDirectory /var/lib/rsyslog $ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat $IncludeConfig /etc/rsyslog.d/*.conf $ActionName messages *.info;daemon.!=info;mail.none;authpriv.none;cron.none -/var/log/messages authpriv.* /var/log/secure mail.* -/var/log/maillog cron.* /var/log/cron *.emerg :omusrmsg:* uucp,news.crit /var/log/spooler local7.* /var/log/boot.log $template msg_only,"%msg:2:$%" if $programname == 'mwg' and $syslogfacility-text == 'daemon' and $syslogseverity-text == 'info' then @127.0.0.1:6514;msg_only
Splunk UI:
MWG UI:
$ModLoad imuxsock # provides support for local system logging (e.g. via logger command) $ModLoad imklog # reads kernel messages (the same are read from journald) $WorkDirectory /var/lib/rsyslog $ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat $IncludeConfig /etc/rsyslog.d/*.conf $ActionName messages *.info;daemon.!=info;mail.none;authpriv.none;cron.none -/var/log/messages authpriv.* /var/log/secure mail.* -/var/log/maillog cron.* /var/log/cron *.emerg :omusrmsg:* uucp,news.crit /var/log/spooler local7.* /var/log/boot.log $template msg_only,"%msg:2:$%" if $programname == 'mwg' and $syslogfacility-text == 'daemon' and $syslogseverity-text == 'info' then @@server:6514;msg_only
Splunk UI:
$DefaultNetstreamDriver gtls $DefaultNetstreamDriverCAFile /etc/rsyslog.d/certs/example.com.ca.pem $DefaultNetstreamDriverCertFile /etc/rsyslog.d/certs/mwg.example.com.pem $DefaultNetstreamDriverKeyFile /etc/rsyslog.d/certs/mwg.example.com.key #$ActionSendStreamDriverAuthMode x509/name $ActionSendStreamDriverAuthMode anon #$ActionSendStreamDriverPermittedPeer splunk.example.com $ActionSendStreamDriverMode 1For Splunk configuration and more details watch Configure a McAfee Web Gateway (MWG) syslog to send TLS-secured data to Splunk
# exclude both daemon.notice and daemon.info: *.info;mail.none;daemon.!=info;daemon.!=notice;authpriv.none;cron.none -/var/log/messages $ActionQueueFileName fwdRule1 $ActionQueueMaxDiskSpace 1g $ActionQueueSaveOnShutdown on $ActionQueueType LinkedList $ActionResumeRetryCount -1 # use the new expression format instead of "traditional" severity and facility based selectors, because an expression like daemon.info match all messages of specified priority and HIGHER that can leads to duplicated events if $programname == 'mwg' and $syslogfacility-text == 'daemon' and $syslogseverity-text == 'info' then @@syslog1 $ActionQueueFileName fwdRule2 $ActionQueueMaxDiskSpace 1g $ActionQueueSaveOnShutdown on $ActionQueueType LinkedList $ActionResumeRetryCount -1 if $programname == 'mwg' and $syslogfacility-text == 'daemon' and $syslogseverity-text == 'notice' then @@syslog2
[monitor:///opt/mwg/log/user-defined-logs/splunk.log/splunk.log] sourcetype = mcafee:webgateway:custom # index = proxy
[tcpout] defaultGroup=splunk [tcpout:splunk] server=splunk:9997
McAfee Web Gateway Cloud Service (WGCS) or SkyHigh SSE provides the log with a reduced set of fields, so only a subset of views will work properly.
There are several ways to pull SSE/WGCS logs:
When reading WGCS logs, use [monitor:// and not [batch://, because batch seems to delete logs too early. Use a separate Scheduled Task (schtasks /create /tn "Delete old SSE Logs" /tr "C:\scripts\delete_old_sse_logs.bat" /sc HOURLY ) to delete old logs, for example ForFiles /p C:\SSE_Logs /d -1 /c "cmd /c del /q @file"
An example of inputs.conf:
[monitor://C:\SSE_Logs] sourcetype = skyhigh:webgateway:csv # index = proxy crcSalt = <SOURCE>
HOWTO: SkyHigh Web Gateway Cloud (SSE) integration with Splunk Cloud - step by step configuration: https://www.youtube.com/watch?v=1vCbwz6uKB0
Recently, Splunk has started recommending the use of SC4S as a syslog collector. SC4S is built on syslog-ng and automatically recognizes MWG/SWG events if an event contains 'mwg: ' prefix. Therefore, the custom template 'msg_only' (that strip the syslog header) cannot be used. Apply the following steps to send events via SC4S:
# rewrite a sourcetype (mcafee:webgateway:custom, mcafee:webgateway:default, etc.) mcafee_wg,sourcetype,mcafee:webgateway:default # rewrite an index if required # mcafee_wg,index,proxy
SEDCMD-0_delete_syslog_prefix = s/^mwg: //
TRANSFORMS-0_delete_syslog_prefix = 0_delete_syslog_prefixlocal/transforms.conf:
[0_delete_syslog_prefix] REGEX = ^mwg: (.*) DEST_KEY = _raw FORMAT = $1
Best practices: disable journald completely as described in https://kcm.trellix.com/corporate/index?page=content&id=KB92256
McAfee Web Gateway is based on RedHat/CentOS 7 and inherits some settings that rate-limit syslog. Read https://www.ibm.com/support/pages/how-disable-rsyslog-rate-limiting and https://access.redhat.com/solutions/1417483 to modify or disable rate-limiting in /etc/rsyslog.conf (using MWG UI) and /etc/systemd/journal.conf .
rsyslog.conf (after "$ModLoad imjournal" line):$SystemLogRateLimitInterval 0 $SystemLogRateLimitBurst 0 $imjournalRatelimitInterval 0 $imjournalRatelimitBurst 0journal.conf:
RateLimitInterval=0 RateLimitBurst=0Instead of disabling rate-limiting completely, you can set it to an appropriate value depending on the expected peak request rate.
Use following configuration for syslog-ng (on receiving side):
network flags(no-parse) # https://axoflow.com/syslog-over-udp-kernel-syslog-ng-tuning-avoid-losing-messages/ so-rcvbuf(32MiB) # Sets the receive buffer size log-iw-size(250k) # Sets the size of the initial window for flow control log-fetch-limit(10k) # Sets the number of messages fetched from the source
Correct extraction of host field is very important. Unfortunately default methods of host extraction have some downsides:
To summarize it all: it is better to set a host value explicit and not rely on "heuristic" that can lead to several host values for the same machine. With Syslog use either local resolution with a hosts file and host_segement/host_regex on a syslog receiver or send a host name of MWG directly with an event and extract it during the ingestion. This allows the syslog header to be disabled directly on MWG by defining the "msg_only" rsyslog template as described in the Syslog UDP/TCP section:
props.conf:[mcafee:webgateway:custom] TRANSFORMS-extract_host_from_event = extract_host_from_eventtransforms.conf:
[extract_host_from_event] REGEX = \shost=(\S+) FORMAT = host::$1 DEST_KEY = MetaData:Host # LOOKAHEAD = 40960
The host field must be placed in the event before long fields like url path or url query, because these potentially long fields can "push" the host field outside of the first 4096 bytes/characters limit defined by the LOOKAHEAD property defined in transforms.conf, that specifies how far Splunk looks in the event for index-time fields. To activate the host field enable the preconfigured rule "Add host field" under Policy > Log Handler > Default > Splunk > Web Data Model.
Disabling the syslog header has several benefits:
To use TERM and PREFIX directives with strings that contain double hyphens (such as punycode domains like xn--bcher-kva.de), a custom segmenters.conf file needs to be applied on indexer:
local/props.conf:
SEGMENTATION = indexing_without_double_dash
local/segmenters.conf
[indexing_without_double_dash] [indexing_without_double_dash] # These are default MAJOR segmenters, but without "--" to allow TERM/PREFIX work with punycode domains (xn--bcher-kva.de) and strings with more than one dash (hp--community.force.com) # https://community.splunk.com/t5/Splunk-Search/TERM-and-PREFIX-cannot-find-string-with-two-dashes/td-p/679366 # https://ideas.splunk.com/ideas/EID-I-2226 # default: # MAJOR = [ ] < > ( ) { } | ! ; , ' " * \n \r \s \t & ? + %21 %26 %2526 %3B %7C %20 %2B %3D -- %2520 %5D %5B %3A %0A %2C %28 %29 MAJOR = [ ] < > ( ) { } | ! ; , ' " * \n \r \s \t & ? + %21 %26 %2526 %3B %7C %20 %2B %3D %2520 %5D %5B %3A %0A %2C %28 %29 # default values need to be explicitely specified: MINOR = / : = @ . - $ # % \\ _ INTERMEDIATE_MAJORS = false
Test:
An interactive configuration builder provides an easy way to prepare configuration snippets for both sending (Web Gateway) and receiving (rsyslog, syslog-ng, Splunk UF or indexer) sides.
Configuration parameter | Option(s) | Comment |
---|---|---|
Syslog destination (hostname or IP) | ||
Syslog destination port | ||
Syslog Transport (UDP/TCP) | OR | |
Strip a syslog header. | OR | Send a message only, without a syslog header (that includes a host name). The host name needs to be provided in the event itself (prefered, read Host extraction) or can be resolved on the receiver via rDNS. |
# rsyslog configuration, optimized for Web Gateway, for more info see https://proxy-test.com/Splunk_App_for_SkyHigh_Secure_Web_Gateway_README.html $MaxMessageSize 32k $SystemLogRateLimitInterval 0 $SystemLogRateLimitBurst 0 # use imuxsock instead of imjournal (see https://kcm.trellix.com/corporate/index?page=content&id=KB92256) $ModLoad imuxsock # provides support for local system logging (e.g. via logger command) $ModLoad imklog # reads kernel messages (the same are read from journald) $WorkDirectory /var/lib/rsyslog # Where to place auxiliary files $ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat # Use default timestamp format $template msg_only,"%msg:2:$%" # An alternative format, without a syslog header $IncludeConfig /etc/rsyslog.d/*.conf # Log anything (except Web Gateway access log and mail) of level info or higher. *.info;daemon.!=info;mail.none;authpriv.none;cron.none -/var/log/messages authpriv.* /var/log/secure mail.* -/var/log/maillog cron.* /var/log/cron *.emerg :omusrmsg:* uucp,news.crit /var/log/spooler local7.* /var/log/boot.log $ActionName messages $ActionQueueFileName WebGateway # unique name prefix for spool files $ActionQueueMaxDiskSpace 1g # 1gb space limit (use as much as possible) $ActionQueueSaveOnShutdown on # save messages to disk on shutdown $ActionQueueType LinkedList # run asynchronously $ActionResumeRetryCount -1 # infinite retries if host is down if $programname == 'mwg' and $syslogfacility-text == 'daemon' and $syslogseverity-text == 'info' then @syslogserver:514
# rsyslog input configuration optimized for receiving of syslog messages from Web Gateway # for more info see https://proxy-test.com/Splunk_App_for_SkyHigh_Secure_Web_Gateway_README.html module(load="imtcp") template (name="tpl_skyhigh_web_gateway" type="string" string="/opt/syslog/skyhigh_web_gateway/%FROMHOST%/%$year%-%$month%-%$day%.log") template (name="tpl_FormatMsgOnly" type="string" string="%rawmsg%\n") ruleset(name="rule_SkyHigh_Web_Gateway"){ action(type="omfile" dynaFile="tpl_skyhigh_web_gateway" fileGroup="splunk" dirGroup="splunk" dirCreateMode="0770" fileCreateMode="0660") stop } input(type="imtcp" port="514" ruleset="rule_SkyHigh_Web_Gateway")
# syslog-ng input configuration optimized for receiving of syslog messages from Web Gateway # for more info see https://proxy-test.com/Splunk_App_for_SkyHigh_Secure_Web_Gateway_README.html # https://axoflow.com/syslog-over-udp-kernel-syslog-ng-tuning-avoid-losing-messages/ source s_skyhigh_web_gateway { network( ip(0.0.0.0) port(514) transport("tcp") so-rcvbuf(32MiB) # Sets the receive buffer size log-iw-size(250k) # Sets the size of the initial window for flow control log-fetch-limit(10k) # Sets the number of messages fetched from the source flags(no-parse) ); }; destination d_skyhigh_web_gateway { file("/opt/syslog/skyhigh_web_gateway/$FULLHOST/$C_YEAR-$C_MONTH-$C_DAY.log" create-dirs(yes) flush-lines(0) dir-perm(0755) perm(0644) dir-owner("splunk") dir-group("splunk") owner("splunk") group("splunk") ); }; log { source(s_skyhigh_web_gateway); destination(d_skyhigh_web_gateway); };
# local/inputs.conf for UF/indexer with installed rsyslog/syslog-ng [monitor:///opt/syslog/skyhigh_web_gateway/*/*.log] sourcetype = mcafee:webgateway:custom # index = proxy # enable host_segment if rsyslog/syslog-ng used to extract a hostname of web gateway from a syslog header # host_segement = 4 # local/props.conf for HF or indexer [mcafee:webgateway:custom] TRANSFORMS-extract_host_from_event = extract_host_from_event # local/transforms.conf for HF or indexer [extract_host_from_event] REGEX = \shost=(\S+) FORMAT = host::$1 DEST_KEY = MetaData:Host
Starting from UF version 9.x a splunk forwarder runs with AmbientCapabilities=CAP_DAC_READ_SEARCH that allows the service to read any file on the system (incl. /etc/shadow etc.). https://docs.splunk.com/Documentation/Forwarder/latest/Forwarder/Installleastprivileged.
Important: The Linux ACLs are still being applied. However, the user "splunkfwd" will continue to encounter a "permission denied" error when attempting to access files that it is not allowed to read. On the other hand, the Splunk forwarder service, which runs as the "splunkfwd" user but with the "CAP_DAC_READ_SEARCH" capability, can read any file.
If this capability is too permissive, you can disable it in /etc/systemd/system/SplunkForwarder.service and configure UF read-only permissions using classic linux permissions:
Command | Comment |
---|---|
setfacl -m u:splunkfwd:rx /opt/mwg/log/user-defined-logs | Allow the user splunkfwd to read user-defined logs |
usermod -aG adm splunkfwd | Add the user splunkfwd to the adm group to allow read /var/log/messages and /var/log/secure |
usermod -aG mwg splunkfwd | Add the user splunkfwd to the mwg group to allow read various proxy logs and provides more permissions than the setfacl-method. |
In a high-security environment, you can consider avoiding direct connections between the UF and the deployment server. Instead, opt to push all configurations using alternative methods.
Check | Expected Result | Conditions/Causes | Comment |
---|---|---|---|
Timestamp and Timezone | Timestamp and timezone are correct, there are no "future" events | | eval diff=_indextime - _time | |
Index | Index is correct | Use a separate index for proxy events | |
Sourcetype | sourcetype is correct | ||
Host extraction | Host extraction is correct | Syslog | Don't rely on rDNS, it decreases performance and can fail. Hosts server1, SERVER1, server1.example.com, 10.20.30.nn can be the same host, but are different hosts from Splunk's point of view. |
Integrity | All events reach Splunk, no events are lost | Syslog, high log rate | useACK, rsyslog: disk queue |
Truncation | Long log lines aren't truncated | rsyslog: MaxMessageSize, syslog-ng: log_msg_size, syslog via UDP, Splunk: TRUNCATE | test-link |
Logging delay | Low logging delay | | eval diff=_indextime - _time | |
Log integrity in case of network interruption | Short network interruptions shouldn't lead to loss of events | useACK, rsyslog: disk queue | |
Secure transfer | Log transferred via TLS, Certificate validation, mTLS | ||
Multiline | There are no mulitline proxy events | ||
Duplicates | There are no duplicate events | ||
Parsing | All events parsed correctly, action/src/dest fields are always present | ||
Settings location | All settings are placed inside of MWG App or TA | Settings can be placed in a wrong app if GUI is used | Use btool to verify. |
You can access these and additional onboarding tips and checks using the Data Onboarding Checklist Splunk app avalible on the Splunkbase.
Why the new log format? Neither the default nor the previously used MWGaccess3 log formats provide enough information for SIEM to be useful. These legacy formats provide very limited information about downloading and uploading risky files. Many SIEM correlation rules will not work properly if a transferred file is embedded as a part of a composite object (zip, iso, docx, etc.) or has different/faked media-type header or extension.
The new log format provides the following use cases among many others:
The custom log format (mcafee:webgateway:custom) consists of several parts:
2021-02-26 14:36:46 -0600 200 allowed 192.168.2.1 https GET safebrowsing.googleapis.com 443 563/4156 38/17 up="/v4/threatListUpdates" ua="FF86-10.0" c="it" dip=142.250.185.n kex=112/112 cntx sccc=1302/1302 sslp=1.3/1.3 sslicn="GTS CA 1O1,GlobalSign" sslcn="upload.video.google.com" crtdays=-52 mbmismatch ctmt0 rul="L" rn=41/104 srcp=62407 conrt=0 b=524/4418 tunnel psrcip=192.168.2.1 psrcp=42550 piv=2.0/2.0 r=0 t=0/0/34/34/18/18/22/11/11
Starting from version 5.0.0 of the app, an updated log format was introduced that provides significantly improved search (up to 30 times) and reporting (up to 100 times) performance by leveraging TERM and PREFIX directives:
Search/reporting performance using normal search: |
|
Search/reporting performance using accelerated new log format und TERM/PREFIX: |
|
The change between version 4 and version 5 is essentially the addition of a field prefix to every value, enabling the use of the PREFIX directive. The new version of log is about 10-15% longer - consider that for a license usage:
2021-02-26 14:36:46 -0600 s=200 ac=allowed src=192.168.2.1 p=https m=GET d=safebrowsing.googleapis.com dp=443 bi=563 bo=4156 dur=38 rt=17 up="/v4/threatListUpdates" ua="FF86-10.0" c=it dip=142.250.185.n ckex=112 skex=112 cntx scc=1302 ssc=1302 sslcp=1.3 sslsp=1.3 sslicn="GTS CA 1O1,GlobalSign" sslcn="upload.video.google.com" crtdays=-52 mbmismatch ctmt0 rul="L" rnf=41 rne=104 srcp=62407 conrt=0 bfc=524 btc=4418 tunnel psrcip=192.168.2.1 psrcp=42550 rqv=2.0 rsv=2.0 r=0 tdns=0 tcon=0 tre=34 text=34 t=4.18.18.22.11
You can download a Cheat Sheet new log format with examples of usage: https://proxy-test.com/swg_cheatsheet.pdf
The app (version 5.+) supports both old and new format. If you want to speedup search and reporting and also greatly reduce a load on the search head it is recommended to configure new log format on the SWG.
Logging of URL fields: Instead of logging a URL as-is (ex. http://www.example.com/wp/3?id=4), MWG splits the URL into usable parts (url protocol, domain, url path, url query) which will be used on Splunk's end to rebuild the url. This saves lot of processing and produces better results, in particular:
Default settings exclude logging of the URL query string (portion of the url after the question mark "?"). Enable it in the Web Data Model ruleset if required. Note that logging the query string greatly increases the length of log lines, potentially bloating TSIDX and leading to compromised search performance, heightened storage needs, and increased license usage. Conversely, enabling query string logging proves beneficial in numerous scenarios. Choose to enable it for each request or selectively as needed.
An excerpt of the 100 most useful fields is provided below. MWG has about 900 properties that can be used for logging.
MWG field | CIM field | Comment | |||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Timestamp | - |
| |||||||||||||||||||||||||||
Connection.IP / Client.IP | src | Client.IP takes the value of X-Forwarded-For header | |||||||||||||||||||||||||||
Authentication.UserName | user | ||||||||||||||||||||||||||||
Message.TemplateName, Block.ID, Response.StatusCode, Protocol.FailureDescription, BytesFromServer, Command.Name, Action.Names | action | The action taken by the proxy: allowed, blocked, error or auth. Various MWG properties are used to calculate correct action field. | |||||||||||||||||||||||||||
URL | url | Don't enable it, Splunk build URL based on uri components | |||||||||||||||||||||||||||
URL.Categories | category | MWG will try to categorize URL retroactively even if URL Filter was skipped in the Policy Rule Sets. Add your internal domains to "internal Domains" list to avoid them be marked as "uncategorized" | |||||||||||||||||||||||||||
Header.Response.Get(Content-Type) MediaType.FromHeader | http_content_type | The content-type of the requested HTTP resource as reported by the web server (can be wrong, faked or missing) | |||||||||||||||||||||||||||
Header.Request.Get(User-Agent) | http_user_agent | A short string (FF68-10.0 for Firefox 68 on Windows 10) | |||||||||||||||||||||||||||
LastSentLastReceivedServer | response_time | FSFRS-LSFRS+LSLRS is used to calculate response_time that includes sending time | |||||||||||||||||||||||||||
Header.Request.Exists(Referer) | http_referrer | The HTTP referrer used in the request. The W3C specification and many implementations misspell this as http_referer. Use a FIELDALIAS to handle both key names. This field is disabled by default. | |||||||||||||||||||||||||||
URL.Domain of Header.Request.Exists(Referer) | http_referer_domain | The domain name contained within the HTTP referrer used in the request. Disabled by default. | |||||||||||||||||||||||||||
Response.StatusCode | status | The HTTP response code indicating the status of the proxy request. MWG doesn't distinguish between status sent by web server and status set by proxy, so this value can be misleading. Use action field to see what the proxy action was. | |||||||||||||||||||||||||||
URL.Protocol | - | http/https/ftp etc. Used to re-build url | |||||||||||||||||||||||||||
Command.Name | http_method | GET/POST/PUT/OPTIONS etc | |||||||||||||||||||||||||||
URL.Host | dest | The host of the requested resource | |||||||||||||||||||||||||||
URL.Port | dest_port | The port of the requested resource | |||||||||||||||||||||||||||
BytesToServer | bytes_out | The number of outbound bytes transferred | |||||||||||||||||||||||||||
BytesFromServer | bytes_in | The number of inbound bytes transferred | |||||||||||||||||||||||||||
TimeInTransaction | duration | The time taken by the proxy event, in milliseconds | |||||||||||||||||||||||||||
URL.Path | uri_path | The path of the resource served by the webserver or proxy | |||||||||||||||||||||||||||
URL.ParametersString | uri_query | Not enabled by default. You can enable it for all requests or selectively | |||||||||||||||||||||||||||
Application.Name | app | The application detected or hosted by the server/site such as WordPress, Splunk, or Facebook | |||||||||||||||||||||||||||
Cache.Status eq TCP_HIT | cached | Indicates whether the event data is cached or not. Not enabled by default. | |||||||||||||||||||||||||||
Header.Get(Cookie) | cookie | The cookie file recorded in the event. Not enabled by default. | |||||||||||||||||||||||||||
URL.Destination.IP | dest_ip | It is important to record the destination IP at the moment of the request. A hostname can be resolved to several IPs (think "moving target" CDN) so a DNS resolution a second later can lead to wrong result. Be aware that MWG can be unable to do DNS resolution by itself and it can be a different IP after all if MWG is behind upstream proxies. | |||||||||||||||||||||||||||
URL.Domain | url_domain | The domain name contained within the URL of the requested HTTP resource. It is extracted from hostname based on Public Suffix List | |||||||||||||||||||||||||||
Header.Request.GetAll | - | Returns a concatenated string of all the original request headers (separated by \r\n) as received from client. | |||||||||||||||||||||||||||
Header.Response.GetAll | - | Returns a concatenated string of all the original response headers (separated by \r\n) as received from server. | |||||||||||||||||||||||||||
Header.Request.Get(Via) | - | Via header in request | |||||||||||||||||||||||||||
Header.Response.Get(Via) | - | Via header in response | |||||||||||||||||||||||||||
Header.Response.Get(Location) | - | Location header in response | |||||||||||||||||||||||||||
Client.KeyExchangeBits | - | Normalized strength (symmetric) of the weakest link during the key exchange. Helps to detect outdated client software | |||||||||||||||||||||||||||
Server.KeyExchangeBits | - | Normalized strength (symmetric) of the weakest link during the key exchange. Helps to detect outdated servers which required special handling | |||||||||||||||||||||||||||
Server.Handshake.CertificateIsRequested | - | True, if the web server requests a client certificate (during the initial SSL handshake) [*] | |||||||||||||||||||||||||||
ClientContext.IsApplied | - | A clue if HTTPS Scanner is enabled for this request | |||||||||||||||||||||||||||
Server.Cipher | - | Description of cipher/algorithms between proxy and server (e.g. ECDHE-RSA-AES256-GCM-SHA384) | |||||||||||||||||||||||||||
Client.Cipher | - | Description of cipher/algorithms between client and proxy (e.g. ECDHE-RSA-AES256-GCM-SHA384) | |||||||||||||||||||||||||||
SSL.Server.Protocol | - | SSL/TLS protocol used between proxy and server (e.g. TLSv1.2 TLSv1.1 TLSv1.0 SSLv3.0 unknown). | |||||||||||||||||||||||||||
SSL.Client.Protocol | - | SSL/TLS protocol used between client and proxy (e.g. TLSv1.2 TLSv1.1 TLSv1.0 SSLv3.0 unknown) | |||||||||||||||||||||||||||
SSL.TransparentCNHandling | - | true for ssl connections where the CN is not known until the server handshake is done | |||||||||||||||||||||||||||
Server.CertificateChain.Issuer.CNs | ssl_issuer_common_name | The issuer common names of the certificate chain (bottom-up including the self-signed root CA, empty without certificate verification) [*] | |||||||||||||||||||||||||||
SSL.Server.Certificate.CN | ssl_subject_common_name | The common name of the server certificate [*] | |||||||||||||||||||||||||||
Server.Certificate.SHA2-256Digest | ssl_hash | The hex-encoded sha2-256 digest of the server certificate [*] | |||||||||||||||||||||||||||
Server.Certificate.AlternativeCNs | - | This list stores all alternative subject names stored in the server certificate's extensions section [*] | |||||||||||||||||||||||||||
Server.Certificate.DaysExpired | ssl_end_time | Stores how many days the server certificate is expired. Negative values mean that it is still valid [*] | |||||||||||||||||||||||||||
DNS.Lookup(URL.Host) | - | List of IP addresses of URL.Host if there are more than one. | |||||||||||||||||||||||||||
DNS.Lookup.Reverse(URL.Destination.IP) | - | List of hostnames for the destination IP. Very often it does not equal the requested hostname | |||||||||||||||||||||||||||
Body.NumberOfChildren | - | Number of embedded objects for archive or document [*] | |||||||||||||||||||||||||||
Body.NestedArchiveLevel | - | The current archive level, used to calculate the max level of the embedded object [*] | |||||||||||||||||||||||||||
IsCompositeObject | - | True, if current file is composite (archive or office document) [*] | |||||||||||||||||||||||||||
Body.IsEncryptedObject | - | True, if current object is encrypted | |||||||||||||||||||||||||||
Antimalware.Proactive.Probability | - | Malware probability value | |||||||||||||||||||||||||||
Antimalware.Infected | used for: file_name file_hash | True, if virus was found, false otherwise | |||||||||||||||||||||||||||
Antimalware.VirusNames | signature | List of names of found viruses | |||||||||||||||||||||||||||
Application.Reputation | - | reputation of the application | |||||||||||||||||||||||||||
Authentication.Method | authentication_method | authentication method (NTLM, Kerberos, etc.) | |||||||||||||||||||||||||||
Authentication.Realm | - | authentication realm (i.e. AD directory name) | |||||||||||||||||||||||||||
Authentication.UserGroups | - | User Groups, can be filtered with "Authentication UserGroups to log" list | |||||||||||||||||||||||||||
Authentication.FailureReason.Message | signature (?) | Human readable authentication failure reason description | |||||||||||||||||||||||||||
Authentication.Failed | action (in Authentication DM) | It is true if credentials were provided but the authentication has failed | |||||||||||||||||||||||||||
Cache.IsCacheable | - | True, if the response is cacheable and web cache is enabled | |||||||||||||||||||||||||||
Cache.Status | - | TCP_HIT for a web cache hit, TCP_MISS_RELOAD for a miss, TCP_MISS_VERIFY if the data in the cache was outdated, TCP_MISS_BYPASS for bypass based on I/O load | |||||||||||||||||||||||||||
Cache.IsFresh | - | True, if the response is validated or not read from web cache | |||||||||||||||||||||||||||
MagicBytesMismatch | - | True, if Mime Type from header doesn't match to detected Mime Type [*] | |||||||||||||||||||||||||||
EnsuredTypes | - | List of Mime Types detected by signatures (with high probability of detection) | |||||||||||||||||||||||||||
NotEnsuredTypes | - | List of Mime Types detected by signatures (with low probability of detection) | |||||||||||||||||||||||||||
IsMediaStream | - | Determine if current transaction is media stream | |||||||||||||||||||||||||||
StreamDetector.Probability | - | Probability value for media stream detection | |||||||||||||||||||||||||||
StreamDetector.MatchedRule | - | Returns name of matched streaming detection rule | |||||||||||||||||||||||||||
Rules.CurrentRule.Name | - | The name of the currently evaluated rule | |||||||||||||||||||||||||||
Rules.EvaluatedRules | - | List of all IDs of rules/rule sets, which have been evaluated | |||||||||||||||||||||||||||
Rules.FiredRules | - | List of all IDs of rules/rule sets, where the condition was true | |||||||||||||||||||||||||||
Proxy.IP | - | Stores the Webgateway IP | |||||||||||||||||||||||||||
Proxy.Port | - | Stores the Webgateway port | |||||||||||||||||||||||||||
Client.ProcessName | - | Stores the process name that initiated the connection, e.g. provided by MCP | |||||||||||||||||||||||||||
Client.SystemInfo | - | Client System Information (provided by MCP) | |||||||||||||||||||||||||||
DNS.Lookup.Reverse(client_ip) | src_ip | Hostname of the client | |||||||||||||||||||||||||||
Connection.Protocol | - | The protocol that the client uses to communicate with the proxy (HTTP, HTTPS, FTP, IFP, SSL, ICAP, XMPP, TCP or SOCKS) | |||||||||||||||||||||||||||
Connection.Port | src_port | Stores the port of the client | |||||||||||||||||||||||||||
Connection.RunTime | - | Connection run time (current time minus start time) in seconds | |||||||||||||||||||||||||||
BytesFromClient | - | Number of bytes received from the client for this request | |||||||||||||||||||||||||||
BytesToClient | - | Number of bytes sent to the client for this request | |||||||||||||||||||||||||||
Tunnel.Enabled | - | True, if a HTTP or HTTPS tunnel was enabled - the server response bypassed the response cycle | |||||||||||||||||||||||||||
Proxy.Outbound.IP | - | Stores the IP which is used as the Outbound Source IP by Webgateway when connecting to onward server | |||||||||||||||||||||||||||
Proxy.Outbound.Port | - | The port which is used as the source port by Webgateway when connecting to onward server | |||||||||||||||||||||||||||
ProtocolAndVersion | - | protocol and version of the request/response (HTTP/1.1, HTTP/2.0) | |||||||||||||||||||||||||||
Error.ID | - | ID of error | |||||||||||||||||||||||||||
Error.Message | - | Name of error | |||||||||||||||||||||||||||
URL.Reputation | - | Returns the web reputation value for the current URL. Range is from -127 to 127, where -127 means 'Minimal Risk' and 127 means 'High Risk'. | |||||||||||||||||||||||||||
URL.Geolocation | - | Returns the geolocation of the current URL. The geolocation is the code of the country in which the webserver is located, that hosts the requested resource. The country code is given in ISO 3166 notation. Note: The setting "Disable local GTI database" must be enabled in the URL Filter settings; otherwise this property is not filled. | |||||||||||||||||||||||||||
TimeInRuleEngine | - | Milliseconds currently spent in rule engine. If used in log handler, time consumed by the rule engine from start to the end of a transaction | |||||||||||||||||||||||||||
FirstSentFirstReceivedServer LastSentLastReceivedServer FirstReceivedFirstSentClient LastReceivedLastSentClient LastSentFirstReceivedServer | - | Time between first byte sent to server and first byte returned from server in milliseconds etc... | |||||||||||||||||||||||||||
HandleConnectToServer | - | Time to connect to a server in milliseconds | |||||||||||||||||||||||||||
ResolveHostNameViaDNS | - | Time to resolve a host name via DNS | |||||||||||||||||||||||||||
TimeInExternals | - | Milliseconds currently spent waiting for external responses, e.g. from AV scanner, domain controller for NTLM authentication or URL cloud categorization |
Audit logs (/opt/mwg/log/audit/audit.log) contains all changes and activity made by administator(s) using UI or REST interface. Audit events can be sent to Splunk using a UF or custom syslog configuration. Almost 70 actions are mapped to Authentication and Change CIM Data Models:
Action | action | change_type | object_category |
---|---|---|---|
ACTIVATE_LICENSE_FILE | modified | license | |
ADDED_ADMINROLE | added | AAA | role |
ADDED_APPLIANCE | added | appliance | |
ADDED_CONTENT | added | filesystem | config |
ADDED_GROUP_ROLE_MAPPING | added | AAA | role |
ADDED_RULES | added | config | |
ADDED_SYSTEM_FILES | added | filesystem | file |
ADDED_TEMPLATE_DIRECTORIES | added | filesystem | directory |
AUTHENTICATE_WITH_EXTERNAL_SERVER | success | ||
BACKUP_TRIGGERED | created | backup | |
CREATED_NEW_LIST | added | config | |
CREATED_NEW_RULE | added | config | |
CREATED_NEW_RULEGROUP | added | config | |
CREATED_NEW_SETTINGS | added | config | |
CREATED_NEW_USER | added | AAA | user |
CREATED_NEW_USER_DEFINED_PROPERTY | added | config | |
DASHBOARD_DATA_RESET | deleted | ||
DATE_CHANGED | modified | config | |
DELETED_ADMINROLE | deleted | AAA | role |
DELETED_APPLIANCE | deleted | appliance | |
DELETED_CONTENT | deleted | config | |
DELETED_LIST | deleted | config | |
DELETED_LOG_HANDLER | deleted | config | |
DELETED_RULE | deleted | config | |
DELETED_RULE_GROUP | deleted | config | |
DELETED_RULES | deleted | config | |
DELETED_SETTINGS | deleted | config | |
DELETED_TEMPLATE_DIRECTORIES | deleted | directory | |
DELETED_TEMPLATE_FILES | deleted | file | |
DELETED_USER | deleted | AAA | user |
DELETED_USER_DEFINED_PROPERTY | deleted | config | |
EXPORT_PRIVATE_KEY | read | config | |
FILE_DOWNLOAD | read | file | |
FILE_UPLOAD | added | filesystem | file |
FILES_DELETE | deleted | filesystem | file |
FORCED_USER_LOGOUT | logout | ||
JOINED_NTLM | modified | config | |
LEFT_NTLM | modified | config | |
MODIFIED_ADMINROLE | modified | role | |
MODIFIED_APPLIANCE_SETTINGS | modified | config | |
MODIFIED_CLUSTER_CONFIGURATION | modified | config | |
MODIFIED_CONTENT | modified | config | |
MODIFIED_CATALOG | modified | config | |
MODIFIED_GROUP_ROLE_MAPPING | modified | role | |
MODIFIED_LIST | modified | config | |
MODIFIED_NTLM | modified | config | |
MODIFIED_RULE | modified | config | |
MODIFIED_RULE_GROUP | modified | config | |
MODIFIED_SETTINGS | modified | config | |
MODIFIED_SYSTEM_FILES | modified | filesystem | file |
MODIFIED_TEMPLATE_FILES | modified | filesystem | file |
MODIFIED_USER | modified | AAA | user |
MODIFIED_USER_DEFINED_PROPERTY | modified | config | |
MOVED_RULE_GROUPS | modified | config | |
MOVED_RULES | modified | config | |
REORDERED_CONTENT | modified | config | |
RESTORE_FAILED | modified | config | |
RESTORE_STARTED | pending | config | |
RESTORE_SUCCEDED | modified | config | |
SAVING_FAILED | read | config | |
SYSTEM_LIST_UPDATE | modified | config | |
TRIGGER_ACTION | pending | config | |
USER_LOGIN | success | ||
USER_LOGIN_FAILED | failure | ||
USER_LOGOUT | logout | ||
USER_TIMED_OUT | timeout |
Audit.log can be sent to Splunk using either the UF or Syslog.
This method sends audit events "as is" - multiline, with all details.
inputs.conf:
[monitor:///opt/mwg/log/audit/audit*.log] #index=proxy_audit sourcetype=mcafee:webgateway:audit
This method sends audit events "as is" - multiline, with all details.
create a new file /etc/rsyslog.d/swg_audit_log.conf with following content:
module(load="imfile") # exclude this facility.severity in rsyslog.conf: local5.!=info input(type="imfile" File="/opt/mwg/log/audit/audit.log" Tag="swg_audit_log" Facility="local5" Severity="info") template(name="msg_only_udp" type="string" string="%msg%") # template(name="msg_only_tcp" type="string" string="%msg:2:$%") if $programname == "swg_audit_log" then { action(type="omfwd" Target="splunk.server" Port="10514" Protocol="udp" Template="msg_only_udp") }
This method produces one-line events (easier to read, but less details)
$template msg_only_udp,"%msg%" # An alternative format, without a syslog header, for UDP if $programname == 'mwg' and $syslogfacility-text == 'auth' and $syslogseverity-text == 'info' then @splunk-server:10514;msg_only_udp
/var/log/messages is a system log file that records various system messages and events
To send it using UF (recommended):
adm:x:4:mwgc,tomcat,splunk
[monitor:///var/log/messages*] # host = your_host # index = proxy sourcetype = linux_messages_syslog
To send it using syslog:
$template msg_only_udp,"%msg%" # An alternative format, without a syslog header, for UDP *.info;daemon.!=info;daemon.!=debug;daemon.!=notice;mail.none;authpriv.none;cron.none @splunk:10614;msg_only_udp
/var/log/secure is a system log file that contains security-related events and authentication information, for example:
pam_unix(sshd:session): session opened for user root by (uid=0) pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=10.1.2.3 user=root
To send it using UF (recommended):
adm:x:4:mwgc,tomcat,splunk
[monitor:///var/log/secure*] # host = your_host # index = proxy_audit sourcetype = linux_secure # sourcetype = mcafee:webgateway:secure
To send it using syslog:
$template msg_only_udp,"%msg%" # An alternative format, without a syslog header, for UDP authpriv.* @splunk:10714;msg_only_udp
An example of usage:
source="/var/log/secure" host="prx*" index="proxy" sourcetype="linux_secure" authentication fail* | rex "(?\d+) more authentication failures" | eval failure_count=if(isnotnull(failure_count),failure_count,1)| stats sum(failure_count) AS count values(host) AS host by process rhost user
The folder /opt/mwg/log/mwg-errors contains various types of logs:
Log name | Log type | Comment |
---|---|---|
mwg-core | text, single line | mwg-core logging |
mwg-coordinator | text, single line | mwg-coordinator logging |
mwg-ui | text, multi line | mwg-ui Tomcat logging |
mwg-logmanager | text, single line | mwg-logmanager logging |
mwg-uideserialization | text, single line | mwg-ui deserialization logging |
mwg-sysconfd | text, single line | mwg-sysconfd logging |
mwg-monitor | text, single line | mwg-monitor logging |
mwg-saas-connector | text, single line | mwg-saas connector logging |
*.bin | binary | cannot be parsed. Can be excluded, but the presence of such logs is also a good hint about potential issues. |
To send it using UF (recommended):
mwg:x:199:tomcat,splunk
[monitor:///opt/mwg/log/mwg-errors/mwg*log] sourcetype = mcafee:webgateway:mwg-errors # index = proxy_audit
To send it using syslog:
module(load="imfile") # exclude this facility.severity in rsyslog.conf: local6.!=info input(type="imfile" File="/opt/mwg/log/mwg-errors/mwg-co*.errors.log" #File="/opt/mwg/log/mwg-errors/mwg-core.errors.log" #File="/opt/mwg/log/mwg-errors/mwg-coordinator.errors.log" #File="/opt/mwg/log/mwg-errors/mwg-ui.errors.log" #File="/opt/mwg/log/mwg-errors/mwg-uideserialization.errors.log" #File="/opt/mwg/log/mwg-errors/mwg-logmanager.errors.log" #File="/opt/mwg/log/mwg-errors/mwg-sysconfd.errors.log" #File="/opt/mwg/log/mwg-errors/mwg-monitor.errors.log" #File="/opt/mwg/log/mwg-errors/mwg-saas-connector.errors.log" #File="/opt/mwg/log/mwg-errors/mwg-ui.errors.log" Tag="swg_mwg-errors_mwg-core_log" Facility="local6" Severity="info") template(name="msg_only_udp" type="string" string="%msg%") # template(name="msg_only_tcp" type="string" string="%msg:2:$%") if $programname == "swg_mwg-errors_mwg-core_log" then { action(type="omfwd" Target="splunk.server" Port="10524" # for mwg-ui log it is better to use tcp transport. For single-line events both udp and tcp will work Protocol="udp" Template="swg_mwg-errors_mwg-core_log") }
SSWG offers approximately 300 system properties and counters that can be collected from all appliances and analyzed. These include::
This statistic can be collected and sent along with an access log to Splunk. A scheduled rule engine trigger or a cron job can be used to perform a request to a non-existent domain called ‘reporting.test’. The monitoring data is sent to Splunk as part of the URL path, for example:
2024-03-09 16:21:04 +0100 s=403 ac=blocked src=255.255.255.255 p=http m=- d=reporting.test dp=80 bi=0 bo=0 dur=0 rt=0 up="/hostname_proxy24_ProxyIP_10.20.30.40_MWGVersion_12.2.5_MWGBuildNumber_47878___Lic336_CPULoad4_CPUIdle94_MemFree13645803520_MemUsed7259697152_...."
In an example above the proxy hostname is proxy24, the IP 10.20.30.40, the software version 12.2.5 and the build 47878, the remaining license 336 days and so on.
A pre-configured rule set is provided with the app package (located in the MWG folder). Consider it as a lightweight alternative for full-fledged monitoring with SNMP but without installing and configuring any software besides Splunk. This self-monitoring is especially useful for a PoC and quick troubleshooting.
A full list of all available counters can be viewed here: List of Counters.
The statistic counters can be sent from Web Gateway to Splunk every 60 seconds via the already configured mcafee:webgateway:custom sourcetype - no need to configure SNMP, configure firewall rules etc. The counters are sent along with other events in the same mcafee:webgateway:custom sourcetype. Following 3 steps are all that is needed to enable it:
The ruleset can be modified to include other counters as needed.
The self-monitoring will be extended in future versions, so check for updates if you find this feature useful.
You want to: | Action |
---|---|
complete setup |
|
use non-default index | Modify "index_and_sourcetype" macro to include an index (i.e. 'index=proxy AND sourcetype="mcafee:webgateway:custom"') |
improve search speed and speedup reporting | Upgrade to version 5.x and upgrate to the new log format, the app version 5.x supports all previous log formats and introduces a new format for faster searches (speedup up to 30 times) and faster reports (speedup up to 100 times). |
implement Common Information Model (CIM) | Install Splunk Common Information Model (CIM) App |
import new version of the Splunk Logging Ruleset but keep all modifications | Use a mwg_xml2txt and dump_logging_fields scripts to see differences between versions. |
build accelerated DM | Don't put a high variable strings like uri_path, uri_query, url in accelerated DM unless you really need them |
improve proxy performance, find causes of high latency | Check errors, web cache (should be disabled!), timers (esp. DNS) |
configure data retention | Configure frozenTimePeriodInSecs TBD |
implement some GDRP requirements | Check if personally indentifiable information (PII) should be removed, encrypted, obfuscated or masked. TBD |
investigate a breach/incident | Create a copy of all relevant events (also from other sources) to avoid aging it out. TBD |
implement a 4-eyes principle | It can be implemented either on the proxy side or using splunk. TBD |
mask/obfuscate some fields | It can be implemented either on the proxy side or using splunk. TBD |
send events to other destination besides splunk | Modify rsyslog.conf or use "Route and filter data". TBD |
customize or create own views and reports | Dashboard Customization |
add new fields | At first, check if a required field is already available. Send me an email, so I can include it in the log template. If the field is too specific, consider to create a new ruleset in the Splunk ruleset and put all new fields there - this step will greatly simplify an update/migration. To benefit from the PREFIX/TERM acceleration, if the value can't contain any major breakers, use key=value format. |
exclude some events from search | Create a macro to exclude some sources, destinations or user-agents and add it to a query |
exclude some events from logging | On MWG: Modify existing list "Domains not to log" or create own excluding rules |
improve search performance |
|
correctly log FTP/FTPoverHTTP connections | Due to the nature of FTP requests, the MWG events don't correctly reflect connection type. This requires more work, both on MWG and on Splunk side. TBD |
use TERM/PREFIX for fields with major breakers like User-Agent | Build a ua field on SWG without major breakers using String.ReplaceAllMatches( field, regex([^\w\-]+),"_") |
work with IPv6 addresses | TBD |
you have an idea how to improve this app or need support | Write an email to splunk |
Required fields: action, bytes_in, bytes_out, http_user_agent
Starting with the version 5 of the app, new accelerated views are introduced. They are based on tstats/TERM/PREFIX and provide significant speedup. They are only works with the new mcafee:webgateway:custom log. The new accelerated views have a plus-suffix (e.g. Summary+).
Easy search
This view provides most common searches based on user, src ip, dest, action and user-agent input.
Required fields: status, category, block_id url_domain, rule, action, bytes_in, bytes_out, http_user_agent, bytes_to_client, bytes_from_client, web_reputation, block_reason
This is just a raw splunk prompt with a prefilled `index_and_sourcetype` macro.
This is an accelerated (based on PREFIX) table of most important fields with a drilldown to a "normal" SPL search.
Required fields: action, bytes_in, bytes_out, http_user_agent, category, web_reputation, user, geolocation
Accelerated version of the URL Filter view
Required fields: action, bytes_in, bytes_out, bytes_from_client, bytes_to_client, url_domain
Accelerated version of the Traffic view
There can be several media types in a web transaction. For example when a user uploads a zip file that contains pictures, audio and executables, we'll see application/zip in the Request Cycle, various image/*, audio/* and application/executable in the embedded cycle of Request Cycle and text/html in the Response cycle. Which of them should be logged?
Additionally, if the server sends a wrong Content-Type header, we want to check it with MediaType.EnsuredTypes and report Magic Bytes Mismatch. Most web transactions are downloads, so it is common practice to log the content type of the response.
The logging ruleset supplied with the app has a "MediaType Watchlist" that can be used to track some potentially dangerous media types.
Magic Bytes Mismatch: the web server present a Content-Type header that doesn't match the content of the file. Example: http://www.csm-testcenter.org/download/media_type/video.html should produce following log entry: mbmismatch ct=text/html mte=video/mpeg
Required fields: action, bytes_in, bytes_out, http_user_agent, category, web_reputation, user, content_type, http_content_type, file_name, media_types_not_ensured, media_type_ensured, magic_bytes_mismatch
Required fields: action, http_user_agent, category, web_reputation, malware, bytes_in, url, malware_file_name, malware_file_hash, block_id
Required fields: action, bytes_in, bytes_out, http_proto_version, protocol, req_http_version, url_protocol,l resp_http_version, http_user_agent
Accelerated version of the Protocols view
Required fields: action, bytes_in, bytes_out, url_domain, connection_runtime, web_reputation, category, user, http_user_agent, url, dest_ip, dest_port, proxy_src_ip, proxy_src_port
Required fields: action, bytes_in, bytes_out, http_user_agent, user, app
Required fields: action, bytes_in, bytes_out, http_user_agent, user, web_reputation, web_reputation_risk, url_protocol, url_domain, bytes_to_client, bytes_from_client, status, status_category, rule, malware, malware_probability, file_name, file_hash, contains_macro, contains_exe, category, block_reason,, block_id
Accelerated version
Required fields: user, http_user_agent, t_dns, duration, t_externals, http_method, client_side_latency, bytes_out, bytes_in, t_lrlsc, t_connect, latency
Required fields: user, status, t_dns, status, duration, http_user_agent, action
Required fields: user, http_user_agent, status, action, authentication_method
Overview over Uploads. Requieres the copying of the Media Type Filter / Track Uploads ruleset from Splunk/RuleSet Library
Required fields: web_reputation, url, bytes_in, bytes_out, action, category, file_name, ensured_mediatypes, http_user_agent, content_type, action
Required fields: dest, dest_port, user, http_user_agent, url, http_method, web_reputation, action, url_domain, status, resp_headers_length, url_length, dest_ip, content_disposition, category, url_protocol, req_headers_length, error_template
Required fields: t_dns, user, http_user_agent, action
Statistics on DNS-over-HTTPS (DoH). To enable copy a RuleSet "DNS-over-HTTPS" from Policy > RuleSets > Log Handler > Splunk > RuleSet Library to RuleSet after HTTPS Scanner and Media Type Filter.
Required fields: user, http_user_agent, DoH, action
Required fields: t_rule_engine, user, http_user_agent, action, url, t_externals, rules_fired, rules_evaluated, duration, bytes_in, bytes_out
Required fields: user, http_user_agent, action, http_method, resp_headers, req_headers
The HTTP protocol can be used by malware to communicate with C&C, blending in the normal web traffic generated by benign applications like browsers. However, most enterprise security solutions don’t analyze all parts of the HTTP protocol and even if they do, only partial information can be logged: either a small subset of headers (like User-Agent, X-Forwarded-For, Referer, etc.) or header names must be configured explicitly to be logged. Neither of these methods allows logging of all or unknown headers.
Fortunately, the recent MWG/SWG versions close this security gap by allowing to log all HTTP headers. The rule based policy logic makes it possible to apply such deep logging on suspicious transactions only, significantly reducing log volume.
Possible use cases:
Enabling the collection of header information on the SWG side: Some headers like User-Agent, Content-Type, Referer, Content-Length, Content-Disposition are already logged, therefore use the Headers ruleset to log specific or all headers.
Warning: Be aware of potential issues when headers contain special characters like equal sign, quotes, "less than" character etc. that can break parsing and even introduce security vulnerabilities. If unsure, start with sanitized version, where all characters except [a-zA-Z0-9:_\.] are replaced.
Applying conditional criteria for header collection to specific transactions only: avoid enabling header logging without a clear purpose, as it can do more harm than provide benefits. Enable header logging for suspicious transactions that require investigation.
Log example with request header information: TBD
Working with a Header View: TBD
Next step: configure the response header collection
Required fields: user, http_user_agent, action, hrq_*, host_header, len_hrq_*
Required fields: user, http_user_agent, ssl_client_cipher, ssl_client_kex_bits, ssl_client_protocol, ssl_server_cipher, ssl_server_kex_bits, ssl_server_protocol
Required fields: url_protocol, user, tunnel_enabled, ssl_client_context_is_applied, http_user_agent, action
Required fields: user, ssl_subject_common_name, reverse_dns, http_user_agent, web_reputation, ssl_server_cert_chain_issuer_cns, ssl_subject_common_name, ssl_cert_days_expired, block_id, category, ssl_server_handshake_cert_requested, ssl_cert_valid_days
Required fields: url_protocol, url, status, protocol_failure_description, http_method, error_id, dest_port, bytes_in, bytes_out, block_id, action, web_reputation, error_template, error_message, t_lslrs, t_dns, t_connect, src_ip, src_port, dest_port, protocol_failure_description, http_user_agent, connection_runtime
Dashboard for logs in /opt/mwg/log/mwg-errors: mwg-core.errors.log, mwg-coordinator.errors.log etc.
Centralized monitoring of all your Web Gateway appliances. More details: Self-Monitoring
Requires the mcafee:webgateway:audit sourcetype.
Provides visual overview as a timeline about failed logins, changes, upload/downloads and other actions.
Requires Timeline visualization App https://classic.splunkbase.splunk.com/app/3120/
Show allowed transactions to risky sites (URL Category like Malicious Sites or Reputation in Medum- or High-Risk) or download of malware. This view requires the new log format (with s=200 src= dest=) introduced in the version 5.0.0.
Sometimes it is required to add own inputs elements, for example a dropdown list of indexes or group of hosts. This can be easily be done using sed. Each view (starting from the version 5.0.6) contains a placeholder line that can be used to insert your input element. In a following example we add an input element and modify search queries in SPL code to use a new token.
Prod Non-Prod `index_and_sourcetype_prod`
su - splunk # change to splunk user mkdir -p $SPLUNK_HOME/etc/apps/McAfeeWebGateway/local/data/ui/views # create a local folder cp $SPLUNK_HOME/etc/apps/McAfeeWebGateway/default/data/ui/views/*xml $SPLUNK_HOME/etc/apps/McAfeeWebGateway/local/data/ui/views # copy views from default to the local folder cd $SPLUNK_HOME/etc/apps/McAfeeWebGateway/local/data/ui/views # cd to the local folder
for file in *xml; do if [ "$file" != "mwg_errors.xml" ] && [ "$file" != "audit.xml" ] && [ "$file" != "audit_timeline.xml" ]; then sed -i '//r /tmp/textblock.txt' "$file" sed -i '/`index_and_sourcetype`/$index_and_sourcetype_macro$/g' $file fi done
If you just need to add the same text block for all views use this sed command instead:
for file in *xml; do sed -i '//r /tmp/textblock.txt' $file; done # add a textblock to each view
This App, documentation and MWG logging ruleset are licensed under Creative Commons BY-ND 3.0
It is possible to install syslog-ng (for example from EPEL) directly on MWG, for example for testing, but if you'll try to remove rsyslog it will break the dependencies, as mwg itself and other packages depend on rsyslog. You can follow the steps below, but be aware that it is not supported and can lead to various problems! See also https://www.syslog-ng.com/products/open-source-log-management/3rd-party-binaries.aspx and https://www.syslog-ng.com/community/b/blog/posts/installing-latest-syslog-ng-on-rhel-and-other-rpm-distributions
rpm -e --nodeps rsyslog ps aux|grep [r]syslog yum install https://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/s/syslog-ng-3.5.6-3.el7.x86_64.rpm \ https://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/i/ivykis-0.36.2-2.el7.x86_64.rpm \ https://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/e/eventlog-0.2.13-4.el7.x86_64.rpm systemctl enable syslog-ng --now systemctl status syslog-ng
The MWG Splunk Logging RuleSet is quite complex. Most customers modify it to accommodate their own needs. Use this script to find all modifications when importing a new version of the RuleSet.
Usage:
Step 1: convert XML to TXT and compare them
perl mwg_xml2txt.pl old_ruleset.xml > old_ruleset.txt
perl mwg_xml2txt.pl new_ruleset.xml > new_ruleset.txt
vimdiff old_ruleset.txt new_ruleset.txt
VIMDIFF will compare TXT files and highlight differences in lists and rules using color output. It can be a simple change, like a rule being enabled/disabled, but can also be a more complex modification - in this case use a Step 2 to do a direct XML comparison.
Tip: press zR inside of vimdiff to unfold all sections.
Step 2: Identify differences and optionally extract the corresponding XML section for comparisonAfter Step 1 you'll see similar output (see below). The [true] or [false] indicates if the rule is enabled or disabled. The short 6-char string after each line are first 6 chars of the md5 for the entire rule block, so even a small modification will be highlighted.
|
|
#!/usr/bin/perl use strict; use warnings; my $version = "0.3 17.Oct.2022 by PP"; use Digest::MD5 qw(md5_hex); # #
application/vnd.ms-excel.addin.macroEnabled.12 #MS Office 2007 Excel addin (macro-enabled) # # ##
# # # # # # ## # # # usage: # Step 1: convert XML to TXT and compare them # perl mwg_xml2txt.pl old_ruleset.xml > old_ruleset.txt # perl mwg_xml2txt.pl new_ruleset.xml > new_ruleset.txt # vimdiff old_ruleset.txt new_ruleset.txt # # VIMDIFF will compare TXT files and highlight differences in lists and rules using color output. It can be a simple enabled vs disabled, # but can be also a more complex modification - in this case use a Step 2 to do a direct XML comparison. # # Step 2: identify differences and optionally extract corresponding XML section for comparison # export a single rule from xml ruleset: # perl -0777 -e '$a=<>; ($rule)=$a=~m/(\QRuleName\E.*?<\/rule>)/ms; print "$rule"' ruleset_old.xml > rule_old.txt # perl -0777 -e '$a=<>; ($rule)=$a=~m/(\QRuleName\E.*?<\/rule>)/ms; print "$rule"' ruleset_new.xml > rule_new.txt # vimdiff rule_old.xml rule_new.xml my $line=1; my $xml = undef; open (my$fh, '<', $ARGV[0]) or die "cannot open file: $!"; { local $/=undef; $xml = <$fh>; } close $fh; my @lists=$xml=~m/ )/ms){ # map has other structure $list = $1; #print "$list_name\n$list\n\n"; my @entries = $list =~ m/ key="key"[^\n]+value="([^\n]+\n[^\n]+value="[^"]+)"/msg; s/([^"]+)".*\n.*"([^"]*)/$1 - $2/msg for @entries; # remove anything except key-value print "$list_name\n ".(join "\n ",sort @entries)."\n\n"; }elsif($xml =~/(
)/ms){ $list = $1; #print "$list_name\n$list\n\n"; my @entries = $list =~ m/
([^<]+)<\/entry>/msg; print "$list_name\n ".(join "\n ",sort @entries)."\n\n"; }else{ die "cannot find list" }; } while(<>){ #print "$line: $_"; $line++; next if / /; my($ruleid,$string,$offset,$name,$enabled,$rule_block)=(undef,undef,undef,undef,undef,undef); if(/^(\s*) )/ms; $rule_block =~ s/(id=")\d+"/$1XXX"/msg; $rule_block =~ s/(propertyId=")\d+"/$1XXX"/msg; $rule_block =~ s/(id="com\.scur\.type\.\w+\.)\d+"/$1XXX"/msg; $rule_block =~ s/(id="com\.scur\.type\.complex\.\w+\.)\d+"/$1XXX"/msg; $rule_block =~ s/(com\.scur\.engine\.\w+\.)\d+/$1XXX/msg; if(not defined $rule_block){die "Rule block not defined for $string"}; print "$offset $name [$enabled] ".substr((md5_hex($rule_block)),0,6)."\n" } }
Use the following script to output configured fields in the Splunk log handler. This is useful if you migrate to a new Logging ruleset and want to compare which fields are enabled in old and new ruleset.
Example of usage:
./dump_logging.pl 2023-10-26_13-10_Splunk.xml com.scur.engine.datetimefilter.datetime.toisostring s= ac= src= p= m= d= dp= bi= bo= dur= rt= up="" ua="" a="" c= ct="" u= ud= exe= macro= mbmismatch ctmt0 ctemt mte= mtne="" cl= contentdisp='' ckex= skex= ccert cntx scc= ssc= sslcp= sslsp= tcn sslsm= DoH="" emb= embl= rqcompst rscompst encrypt= file_watchlist="" mlwrp= malware="" malware_file_name="" malware_file_hash="" stream rul="" rul="" rnf= rne= crt= bfc= btc= tunnel rqv= rsv= uploads="" pfail="" tmplt="" errid= bid= r= geo= tdns= tcon= tre= text= t=.... LOGERR1 LOGERR2 LOGERR3com.scur.engine.stringfilter.string.replaceallmatches tl=
#!/usr/bin/perl use 5.010; use strict; use warnings; my $version = "0.3 26.Oct.2023 by PP"; # This script reads a single Logging RuleSet (exported from the SWG UI) and output a line with logging fields # USAGE: ./dump_logging_ruleset.pl LoggingRuleset.xml use XML::LibXML; use JSON; use Data::Dumper; use utf8; #use open ":std", ":encoding(UTF-8)"; binmode(STDIN, ":utf8"); binmode(STDOUT, ":utf8"); my $array_counter = -1; # -1 because it get incremented at start of the loop my $array_counter_list = -1; my $filename = $ARGV[0]; my %hash = (); my $result = undef; my $logline_id = undef; my $dom = XML::LibXML->load_xml(location => $filename); # get an IP of User-Defined.logLine foreach my $property( $dom->findnodes('/libraryContent/userDefinedPropertys/userDefinedProperty')){ if($property->findvalue('@name') eq "User-Defined.logLine"){ $logline_id = $property->findvalue('@id'); } } $result = walk_rules("/libraryContent/ruleGroup/rules/rule", 0, "top_rules"); $result = walk_rulesets("/libraryContent/ruleGroup/ruleGroups/ruleGroup"); sub walk_rules{ my $path = shift; my $ruleset_counter = shift; my $level = shift; $array_counter_list = -1; foreach my $rule ($dom->findnodes($path)) { if( $rule->findvalue('@enabled') eq "true" ){ $array_counter_list++; $hash{$level}[$ruleset_counter]{rules}[$array_counter_list]{"name"}= $rule->findvalue('@name'); # print all direct assigments of logline=xxx foreach my $p5 ($rule->findnodes('immediateActionContainers/setActionContainer[@propertyId='.$logline_id."]")){ my @nodes = $p5->findnodes('expressions/setExpression'); if( scalar @nodes eq 1 ){ print $p5->findvalue('expressions/setExpression/parameter/value/propertyInstance/@propertyId'); } } # print all fields (logline=logline+field= foreach my $p ($rule->findnodes('immediateActionContainers/setActionContainer[@propertyId='.$logline_id."]")){ foreach my $p2 ($p->findnodes('expressions/setExpression/parameter/value/propertyInstance[@propertyId='.$logline_id."]")){ foreach my $p3 ( $p2->findnodes('../../../../setExpression/parameter/value/stringValue')){ print $p3->findvalue('@value'); } } } } } } sub walk_rulesets{ my $path = shift; $array_counter = -1; foreach my $ruleGroup ($dom->findnodes($path)) { if( $ruleGroup->findvalue('@enabled') eq "true" ){ $array_counter++; my $ruleGroup_name = $ruleGroup->findvalue('@name'); my $ruleGroup_id = $ruleGroup->findvalue('@id'); $hash{rulesets}[$array_counter]{name}= $ruleGroup->findvalue('@name'); my $nested_path = $path.'[@id="'.$ruleGroup_id.'"]/rules/rule'; walk_rules($nested_path, $array_counter, "rulesets"); } } } #print Dumper %hash; #use utf8; #my $json = encode_json(\%hash); #my $json = JSON->new->utf8->pretty->encode(\%hash);
AMJobQueueLength AMLoad AMPrivateMemory AMUsed AMUsedPhys ApplHighRisk ApplicationMemoryUsage ApplMediumRisk ApplMinimalRisk ApplUnverified AuthNTLMCacheRequests AuthUserCacheRequests BlockedByAntiMalware BlockedByApplControl BlockedByDCC BlockedByDLPMatch BlockedByMATD BlockedByMediaFilter BlockedByURLFilter Categories CertExpired CertNameMismatch CertRevoked CertSelfSigned CertUnresolvable CertWildCardMatch ClientCount CloseWaits CloudEnc.DecryptionBytesAll CloudEnc.DecryptionErrorsAll CloudEnc.DecryptionHitsAll CloudEnc.EncryptionBytesAll CloudEnc.EncryptionErrorsAll CloudEnc.EncryptionHitsAll ConnectedSockets ConnectionsBlocked ConnectionsLegitimate CoordLoad CoordPrivateMemory CoordUsed CoordUsedPhys CoreLoad CorePrivateMemory CoreThreads CoreUsed CoreUsedPhys CPUIdle CPUIOWait CPULoad CPULoadRaw CPUSystem CPUUser DCCCalled DCCUncategorized DXLEventsReceived DXLEventsSent DXLRequestErrors DXLRequestsSent DXLServiceCalls DXLTraffic eDirectoryRequestProcTime eDirectoryRequests FilesystemUsage FirstSentFirstReceivedClient FirstSentFirstReceivedServer FtpBytesFromServer FtpBytesToServer FtpRequests FtpTraffic GTIFileRepCloudLookupDone GTIRequestSentToCloud HandleConnectToServer HarddiskUsage Http2BytesFromClient Http2BytesFromServer Http2BytesToClient Http2BytesToServer Http2Requests Http2Traffic HttpBytesFromClient HttpBytesFromServer HttpBytesToClient HttpBytesToServer HttpConnectionsFromClientPerCustomer HttpRequests HttpsBytesFromClient HttpsBytesFromServer HttpsBytesToClient HttpsBytesToServer HttpsRequests HttpsTraffic HttpTraffic ICAPClientActiveConnections ICAPReqmodRequests ICAPReqmodTraffic ICAPRespmodRequests ICAPRespmodTraffic IfpRequests KerberosRequests LastSentFirstReceivedServer LastSentLastReceivedClient LastSentLastReceivedServer LDAPRequestProcTime LDAPRequests LoadPerCPU MalwareDetected MATDInfected MATDRequests MATDScanTime MemConsumed MemFree MemMallocChunks MemMallocKBytesUsed MemMMBlocks MemMMBytesUsed MemoryUsage MemUsed MT.Archive MT.Audio MT.Database MT.Document MT.Executable MT.Image MT.Text MT.Video NetworkBytesReceived NetworkBytesSent NTLMAgentRequestProcTime NTLMAgentRequests NTLMRequestProcTime NTLMRequests OTPSendProcTime OTPSendRequests OTPVerifyProcTime OTPVerifyRequests PrivDecryptOK PrivEncryptOK PrivKeyOpDuration RADIUSRequestProcTime RADIUSRequests RawTCPTraffic RepHighRisk RepMediumRisk RepMinimalRisk RepUnverified ReputationNeutral ReputationSuspicious ReputationTrusted ReputationUnverified ResolveHostViaDNS SMCached SOCKSHTTPRequests SOCKSHTTPSRequests SOCKSHTTPSTraffic SOCKSHTTPTraffic SOCKSUDPConnections SOCKSUDPTraffic SOCKSUnFilteredRequests SOCKSUnFilteredTraffic SOCKSv4Requests SOCKSv4Traffic SOCKSv5Requests SOCKSv5Traffic SSLIssuedCertificate SSLSessionClientHit SSLSessionClientMiss SSLSessionServerHit SSLSessionServerMiss SSO.AllLogins SSO.IncorrectTokens StatDBSize SwapFree SwapUsed TCPProxyConnections TimeConsumedByGTIFileRepCloudLookup TimeConsumedByGTIFileRepCloudLookup_0000_25 TimeConsumedByGTIURLCloudLookup TimeConsumedByGTIURLCloudLookup_0000_25 TimeConsumedByGTIURLCloudLookup_0026_50 TimeConsumedByGTIURLCloudLookup_0051_75 TimeConsumedByGTIURLCloudLookup_0076_100 TimeConsumedByGTIURLCloudLookup_0101_150 TimeConsumedByGTIURLCloudLookup_0151_200 TimeConsumedByGTIURLCloudLookup_0201_250 TimeConsumedByGTIURLCloudLookup_2001_2500 TimeConsumedByGTIURLRating TimeConsumedByGTIURLRating_0000_25 TimeConsumedByGTIURLRating_0026_50 TimeConsumedByGTIURLRating_0051_75 TimeConsumedByGTIURLRating_0076_100 TimeConsumedByGTIURLRating_0101_150 TimeConsumedByGTIURLRating_0151_200 TimeConsumedByGTIURLRating_0201_250 TimeConsumedByGTIURLRating_2001_2500 TimeConsumedByGTIURLRatingSync TimeConsumedByGTIURLRatingSync_0000_25 TimeConsumedByRuleEngine TimeForRegex TimeForTransaction UserDBRequests WebCacheDiskUsage WebCacheHits WebCacheMisses WebCacheObjectsCount WebCacheReadNotCacheable WorkingQueueLength XmppClients XmppRequests XmppTraffic