Citrix Web App Firewall
editCitrix Web App Firewall
editVersion |
1.16.1 (View all) |
Compatible Kibana version(s) |
8.11.0 or higher |
Supported Serverless project types |
Security |
Subscription level |
Basic |
Level of support |
Elastic |
The Citrix Web App Firewall prevents security breaches, data loss, and possible unauthorized modifications to websites that access sensitive business or customer information. It does so by filtering both requests and responses, examining them for evidence of malicious activity, and blocking requests that exhibit such activity. Your site is protected not only from common types of attacks, but also from new, as yet unknown attacks. In addition to protecting web servers and websites from unauthorized access, the Web App Firewall protects against vulnerabilities in legacy CGI code or scripts, web frameworks, web server software, and other underlying operating systems.
Compatibility
editThis integration has been tested against samples obtained from Citrix ADC 13.1 and NetScaler 10.0 documentation.
Configuration
editEnabling the integration in Elastic
edit- In Kibana go to Management > Integrations.
- In "Search for integrations" search bar type Citrix.
- Click on "Citrix Web App Firewall" integration from the search results.
- Click on Add Citrix Web App Firewall button to add the integration.
Citrix WAF Dashboard Configuration
editIt is recommended to configure the application firewall to enable CEF-formatted logs.
- Navigate to Security the NetScaler GUI.
- Click Application Firewall node.
- Select Change Engine Settings.
- Enable CEF Logging.
Syslog
editThe Citrix WAF GUI can be used to configure syslog servers and WAF message types to be sent to the syslog servers. Refer to How to Send Application Firewall Messages to a Separate Syslog Server and How to Send NetScaler Application Firewall Logs to Syslog Server and NS.log for details.
Configure the Citrix WAF integration
editSyslog
editDepending on the syslog server setup in your environment check one/more of the following options "Collect syslog from Citrix WAF via UDP", "Collect syslog from Citrix WAF via TCP", "Collect syslog from Citrix WAF via file".
Enter the values for syslog host and port OR file path based on the chosen configuration options.
Log Events
editEnable to collect Citrix WAF log events for all the applications configured for the chosen log stream.
Logs
editSyslog
editThe citrix_waf.log
dataset provides events from the configured syslog server. All Citrix WAF syslog specific fields are available in the citrix
field group.
Example
An example event for log
looks as following:
{ "@timestamp": "2012-12-18T21:46:17.000Z", "agent": { "ephemeral_id": "9153862d-f83f-4bd1-bbc9-c3ff3d96e726", "id": "e30119bc-b47d-4e56-86e3-4a9683305c6e", "name": "docker-fleet-agent", "type": "filebeat", "version": "8.2.3" }, "citrix": { "cef_format": true, "cef_version": "0", "detail": "CEF:0|Citrix|NetScaler|NS10.0|APPFW|APPFW_STARTURL|6|src=175.16.199.1 spt=54711 method=GET request=http://vpx247.example.net/FFC/login_post.html?abc\\=def msg=Disallow Illegal URL. cn1=465 cn2=535 cs1=profile1 cs2=PPE0 cs3=IliG4Dxp1SjOhKVRDVBXmqvAaIcA000 cs4=ALERT cs5=2012 act=not blocked", "device_event_class_id": "APPFW", "device_product": "NetScaler", "device_vendor": "Citrix", "device_version": "NS10.0", "facility": "local0", "name": "APPFW_STARTURL", "ppe_id": "PPE0", "priority": "info", "profile_name": "profile1", "session_id": "IliG4Dxp1SjOhKVRDVBXmqvAaIcA000", "severity": "ALERT" }, "client": { "geo": { "city_name": "London", "continent_name": "Europe", "country_iso_code": "GB", "country_name": "United Kingdom", "location": { "lat": 51.5142, "lon": -0.0931 }, "region_iso_code": "GB-ENG", "region_name": "England" }, "ip": "81.2.69.144" }, "data_stream": { "dataset": "citrix_waf.log", "namespace": "ep", "type": "logs" }, "ecs": { "version": "8.11.0" }, "elastic_agent": { "id": "e30119bc-b47d-4e56-86e3-4a9683305c6e", "snapshot": false, "version": "8.2.3" }, "event": { "action": "not blocked", "agent_id_status": "verified", "dataset": "citrix_waf.log", "id": "465", "ingested": "2022-07-12T00:06:17Z", "original": "Dec 18 21:46:17 <local0.info> 81.2.69.144 CEF:0|Citrix|NetScaler|NS10.0|APPFW|APPFW_STARTURL|6|src=175.16.199.1 spt=54711 method=GET request=http://vpx247.example.net/FFC/login_post.html?abc\\=def msg=Disallow Illegal URL. cn1=465 cn2=535 cs1=profile1 cs2=PPE0 cs3=IliG4Dxp1SjOhKVRDVBXmqvAaIcA000 cs4=ALERT cs5=2012 act=not blocked", "severity": 6, "timezone": "+00:00" }, "http": { "request": { "id": "535", "method": "GET" } }, "input": { "type": "tcp" }, "log": { "source": { "address": "172.22.0.4:41588" } }, "message": "Disallow Illegal URL.", "source": { "geo": { "city_name": "Changchun", "continent_name": "Asia", "country_iso_code": "CN", "country_name": "China", "location": { "lat": 43.88, "lon": 125.3228 }, "region_iso_code": "CN-22", "region_name": "Jilin Sheng" }, "ip": "175.16.199.1", "port": 54711 }, "tags": [ "preserve_original_event", "citrix_waf", "forwarded" ], "url": { "domain": "vpx247.example.net", "extension": "html", "original": "http://vpx247.example.net/FFC/login_post.html?abc\\=def", "path": "/FFC/login_post.html", "query": "abc\\=def", "scheme": "http" } }
Exported fields
Field | Description | Type |
---|---|---|
@timestamp |
Date/time when the event originated. This is the date/time extracted from the event, typically representing when the event was generated by the source. If the event source has no original timestamp, this value is typically populated by the first time the event was received by the pipeline. Required field for all events. |
date |
citrix.cef_format |
Whether the logging is in Citrix CEF format. |
boolean |
citrix.cef_version |
The CEF format version used in the logs. |
keyword |
citrix.default_class |
Whether the event class was the default. |
boolean |
citrix.detail |
The CEF or Citrix Native format details for the event. |
keyword |
citrix.device_event_class_id |
The ID of the event class. |
keyword |
citrix.device_product |
The model of the appliance. |
keyword |
citrix.device_vendor |
The name of the vendor for the device. |
keyword |
citrix.device_version |
The version of the device. |
keyword |
citrix.extended |
Additional data associated with the event. |
flattened |
citrix.facility |
The logging facility. |
keyword |
citrix.host |
The name of the host receiving the logs. |
keyword |
citrix.name |
The name of the security check. |
keyword |
citrix.ppe_id |
Packet Processing Engine ID. |
keyword |
citrix.priority |
The logging priority. |
keyword |
citrix.profile_name |
The name of the profile that raised the event. |
keyword |
citrix.session_id |
The ID for the session. |
keyword |
citrix.severity |
The severity of the event. |
keyword |
citrix.signature_violation_category |
The category that the violation is grouped into. |
keyword |
client.address |
Some event client addresses are defined ambiguously. The event will sometimes list an IP, a domain or a unix socket. You should always store the raw address in the |
keyword |
client.as.number |
Unique number allocated to the autonomous system. The autonomous system number (ASN) uniquely identifies each network on the Internet. |
long |
client.as.organization.name |
Organization name. |
keyword |
client.as.organization.name.text |
Multi-field of |
match_only_text |
client.domain |
The domain name of the client system. This value may be a host name, a fully qualified domain name, or another host naming format. The value may derive from the original event or be added from enrichment. |
keyword |
client.geo.city_name |
City name. |
keyword |
client.geo.continent_name |
Name of the continent. |
keyword |
client.geo.country_iso_code |
Country ISO code. |
keyword |
client.geo.country_name |
Country name. |
keyword |
client.geo.location |
Longitude and latitude. |
geo_point |
client.geo.region_iso_code |
Region ISO code. |
keyword |
client.geo.region_name |
Region name. |
keyword |
client.ip |
IP address of the client (IPv4 or IPv6). |
ip |
client.port |
Port of the client. |
long |
client.user.name |
Short name or login of the user. |
keyword |
client.user.name.text |
Multi-field of |
match_only_text |
cloud.account.id |
The cloud account or organization id used to identify different entities in a multi-tenant environment. Examples: AWS account id, Google Cloud ORG Id, or other unique identifier. |
keyword |
cloud.availability_zone |
Availability zone in which this host is running. |
keyword |
cloud.image.id |
Image ID for the cloud instance. |
keyword |
cloud.instance.id |
Instance ID of the host machine. |
keyword |
cloud.instance.name |
Instance name of the host machine. |
keyword |
cloud.machine.type |
Machine type of the host machine. |
keyword |
cloud.project.id |
Name of the project in Google Cloud. |
keyword |
cloud.provider |
Name of the cloud provider. Example values are aws, azure, gcp, or digitalocean. |
keyword |
cloud.region |
Region in which this host is running. |
keyword |
container.id |
Unique container id. |
keyword |
container.image.name |
Name of the image the container was built on. |
keyword |
container.labels |
Image labels. |
object |
container.name |
Container name. |
keyword |
data_stream.dataset |
Data stream dataset. |
constant_keyword |
data_stream.namespace |
Data stream namespace. |
constant_keyword |
data_stream.type |
Data stream type. |
constant_keyword |
ecs.version |
ECS version this event conforms to. |
keyword |
error.message |
Error message. |
match_only_text |
event.category |
This is one of four ECS Categorization Fields, and indicates the second level in the ECS category hierarchy. |
keyword |
event.code |
Identification code for this event, if one exists. Some event sources use event codes to identify messages unambiguously, regardless of message language or wording adjustments over time. An example of this is the Windows Event ID. |
keyword |
event.created |
|
date |
event.dataset |
Event dataset |
constant_keyword |
event.duration |
Duration of the event in nanoseconds. If |
long |
event.end |
|
date |
event.ingested |
Timestamp when an event arrived in the central data store. This is different from |
date |
event.kind |
This is one of four ECS Categorization Fields, and indicates the highest level in the ECS category hierarchy. |
keyword |
event.module |
Event module |
constant_keyword |
event.provider |
Source of the event. Event transports such as Syslog or the Windows Event Log typically mention the source of an event. It can be the name of the software that generated the event (e.g. Sysmon, httpd), or of a subsystem of the operating system (kernel, Microsoft-Windows-Security-Auditing). |
keyword |
event.severity |
The numeric severity of the event according to your event source. What the different severity values mean can be different between sources and use cases. It’s up to the implementer to make sure severities are consistent across events from the same source. The Syslog severity belongs in |
long |
event.start |
|
date |
event.timezone |
This field should be populated when the event’s timestamp does not include timezone information already (e.g. default Syslog timestamps). It’s optional otherwise. Acceptable timezone formats are: a canonical ID (e.g. "Europe/Amsterdam"), abbreviated (e.g. "EST") or an HH:mm differential (e.g. "-05:00"). |
keyword |
event.type |
This is one of four ECS Categorization Fields, and indicates the third level in the ECS category hierarchy. |
keyword |
file.path |
Full path to the file, including the file name. It should include the drive letter, when appropriate. |
keyword |
file.path.text |
Multi-field of |
match_only_text |
host.architecture |
Operating system architecture. |
keyword |
host.containerized |
If the host is a container. |
boolean |
host.domain |
Name of the domain of which the host is a member. For example, on Windows this could be the host’s Active Directory domain or NetBIOS domain name. For Linux this could be the domain of the host’s LDAP provider. |
keyword |
host.hostname |
Hostname of the host. It normally contains what the |
keyword |
host.id |
Unique host id. As hostname is not always unique, use values that are meaningful in your environment. Example: The current usage of |
keyword |
host.ip |
Host ip addresses. |
ip |
host.mac |
Host mac addresses. |
keyword |
host.name |
Name of the host. It can contain what |
keyword |
host.os.build |
OS build information. |
keyword |
host.os.codename |
OS codename, if any. |
keyword |
host.os.family |
OS family (such as redhat, debian, freebsd, windows). |
keyword |
host.os.kernel |
Operating system kernel version as a raw string. |
keyword |
host.os.name |
Operating system name, without the version. |
keyword |
host.os.name.text |
Multi-field of |
text |
host.os.platform |
Operating system platform (such centos, ubuntu, windows). |
keyword |
host.os.version |
Operating system version as a raw string. |
keyword |
host.type |
Type of host. For Cloud providers this can be the machine type like |
keyword |
http.request.id |
A unique identifier for each HTTP request to correlate logs between clients and servers in transactions. The id may be contained in a non-standard HTTP header, such as |
keyword |
http.request.method |
HTTP request method. The value should retain its casing from the original event. For example, |
keyword |
input.type |
Input type. |
keyword |
labels |
Custom key/value pairs. Can be used to add meta information to events. Should not contain nested objects. All values are stored as keyword. Example: |
object |
log.file.path |
Full path to the log file this event came from, including the file name. It should include the drive letter, when appropriate. If the event wasn’t read from a log file, do not populate this field. |
keyword |
log.level |
Original log level of the log event. If the source of the event provides a log level or textual severity, this is the one that goes in |
keyword |
log.offset |
Offset of the entry in the log file. |
long |
log.source.address |
Source address from which the log event was read / sent from. |
keyword |
message |
For log events the message field contains the log message, optimized for viewing in a log viewer. For structured logs without an original message field, other fields can be concatenated to form a human-readable summary of the event. If multiple messages exist, they can be combined into one message. |
match_only_text |
network.bytes |
Total bytes transferred in both directions. If |
long |
network.community_id |
A hash of source and destination IPs and ports, as well as the protocol used in a communication. This is a tool-agnostic standard to identify flows. Learn more at https://github.com/corelight/community-id-spec. |
keyword |
network.direction |
Direction of the network traffic. When mapping events from a host-based monitoring context, populate this field from the host’s point of view, using the values "ingress" or "egress". When mapping events from a network or perimeter-based monitoring context, populate this field from the point of view of the network perimeter, using the values "inbound", "outbound", "internal" or "external". Note that "internal" is not crossing perimeter boundaries, and is meant to describe communication between two hosts within the perimeter. Note also that "external" is meant to describe traffic between two hosts that are external to the perimeter. This could for example be useful for ISPs or VPN service providers. |
keyword |
network.iana_number |
IANA Protocol Number (https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml). Standardized list of protocols. This aligns well with NetFlow and sFlow related logs which use the IANA Protocol Number. |
keyword |
network.inner |
Network.inner fields are added in addition to network.vlan fields to describe the innermost VLAN when q-in-q VLAN tagging is present. Allowed fields include vlan.id and vlan.name. Inner vlan fields are typically used when sending traffic with multiple 802.1q encapsulations to a network sensor (e.g. Zeek, Wireshark.) |
group |
network.inner.vlan.id |
VLAN ID as reported by the observer. |
keyword |
network.inner.vlan.name |
Optional VLAN name as reported by the observer. |
keyword |
network.protocol |
In the OSI Model this would be the Application Layer protocol. For example, |
keyword |
network.transport |
Same as network.iana_number, but instead using the Keyword name of the transport layer (udp, tcp, ipv6-icmp, etc.) The field value must be normalized to lowercase for querying. |
keyword |
network.type |
In the OSI Model this would be the Network Layer. ipv4, ipv6, ipsec, pim, etc The field value must be normalized to lowercase for querying. |
keyword |
observer.egress.interface.name |
Interface name as reported by the system. |
keyword |
observer.egress.zone |
Network zone of outbound traffic as reported by the observer to categorize the destination area of egress traffic, e.g. Internal, External, DMZ, HR, Legal, etc. |
keyword |
observer.hostname |
Hostname of the observer. |
keyword |
observer.ingress.interface.name |
Interface name as reported by the system. |
keyword |
observer.ingress.zone |
Network zone of incoming traffic as reported by the observer to categorize the source area of ingress traffic. e.g. internal, External, DMZ, HR, Legal, etc. |
keyword |
observer.ip |
IP addresses of the observer. |
ip |
observer.name |
Custom name of the observer. This is a name that can be given to an observer. This can be helpful for example if multiple firewalls of the same model are used in an organization. If no custom name is needed, the field can be left empty. |
keyword |
observer.product |
The product name of the observer. |
keyword |
observer.type |
The type of the observer the data is coming from. There is no predefined list of observer types. Some examples are |
keyword |
observer.vendor |
Vendor name of the observer. |
keyword |
observer.version |
Observer version. |
keyword |
process.name |
Process name. Sometimes called program name or similar. |
keyword |
process.name.text |
Multi-field of |
match_only_text |
process.pid |
Process id. |
long |
related.hosts |
All hostnames or other host identifiers seen on your event. Example identifiers include FQDNs, domain names, workstation names, or aliases. |
keyword |
related.ip |
All of the IPs seen on your event. |
ip |
related.user |
All the user names or other user identifiers seen on the event. |
keyword |
server.address |
Some event server addresses are defined ambiguously. The event will sometimes list an IP, a domain or a unix socket. You should always store the raw address in the |
keyword |
server.domain |
The domain name of the server system. This value may be a host name, a fully qualified domain name, or another host naming format. The value may derive from the original event or be added from enrichment. |
keyword |
server.ip |
IP address of the server (IPv4 or IPv6). |
ip |
server.port |
Port of the server. |
long |
server.user.name |
Short name or login of the user. |
keyword |
server.user.name.text |
Multi-field of |
match_only_text |
source.address |
Some event source addresses are defined ambiguously. The event will sometimes list an IP, a domain or a unix socket. You should always store the raw address in the |
keyword |
source.as.number |
Unique number allocated to the autonomous system. The autonomous system number (ASN) uniquely identifies each network on the Internet. |
long |
source.as.organization.name |
Organization name. |
keyword |
source.as.organization.name.text |
Multi-field of |
match_only_text |
source.bytes |
Bytes sent from the source to the destination. |
long |
source.domain |
The domain name of the source system. This value may be a host name, a fully qualified domain name, or another host naming format. The value may derive from the original event or be added from enrichment. |
keyword |
source.geo.city_name |
City name. |
keyword |
source.geo.continent_name |
Name of the continent. |
keyword |
source.geo.country_iso_code |
Country ISO code. |
keyword |
source.geo.country_name |
Country name. |
keyword |
source.geo.location |
Longitude and latitude. |
geo_point |
source.geo.region_iso_code |
Region ISO code. |
keyword |
source.geo.region_name |
Region name. |
keyword |
source.ip |
IP address of the source (IPv4 or IPv6). |
ip |
source.nat.ip |
Translated ip of source based NAT sessions (e.g. internal client to internet) Typically connections traversing load balancers, firewalls, or routers. |
ip |
source.nat.port |
Translated port of source based NAT sessions. (e.g. internal client to internet) Typically used with load balancers, firewalls, or routers. |
long |
source.port |
Port of the source. |
long |
source.user.domain |
Name of the directory the user is a member of. For example, an LDAP or Active Directory domain name. |
keyword |
source.user.group.name |
Name of the group. |
keyword |
source.user.name |
Short name or login of the user. |
keyword |
source.user.name.text |
Multi-field of |
match_only_text |
tags |
List of keywords used to tag each event. |
keyword |
url.domain |
Domain of the url, such as "http://www.elastic.co[www.elastic.co]". In some cases a URL may refer to an IP and/or port directly, without a domain name. In this case, the IP address would go to the |
keyword |
url.extension |
The field contains the file extension from the original request url, excluding the leading dot. The file extension is only set if it exists, as not every url has a file extension. The leading period must not be included. For example, the value must be "png", not ".png". Note that when the file name has multiple extensions (example.tar.gz), only the last one should be captured ("gz", not "tar.gz"). |
keyword |
url.fragment |
Portion of the url after the |
keyword |
url.full |
If full URLs are important to your use case, they should be stored in |
wildcard |
url.full.text |
Multi-field of |
match_only_text |
url.original |
Unmodified original url as seen in the event source. Note that in network monitoring, the observed URL may be a full URL, whereas in access logs, the URL is often just represented as a path. This field is meant to represent the URL as it was observed, complete or not. |
wildcard |
url.original.text |
Multi-field of |
match_only_text |
url.password |
Password of the request. |
keyword |
url.path |
Path of the request, such as "/search". |
wildcard |
url.port |
Port of the request, such as 443. |
long |
url.query |
The query field describes the query string of the request, such as "q=elasticsearch". The |
keyword |
url.registered_domain |
The highest registered url domain, stripped of the subdomain. For example, the registered domain for "foo.example.com" is "example.com". This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last two labels will not work well for TLDs such as "co.uk". |
keyword |
url.scheme |
Scheme of the request, such as "https". Note: The |
keyword |
url.subdomain |
The subdomain portion of a fully qualified domain name includes all of the names except the host name under the registered_domain. In a partially qualified domain, or if the the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain. For example the subdomain portion of "http://www.east.mydomain.co.uk[www.east.mydomain.co.uk]" is "east". If the domain has multiple levels of subdomain, such as "sub2.sub1.example.com", the subdomain field should contain "sub2.sub1", with no trailing period. |
keyword |
url.top_level_domain |
The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is "com". This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last label will not work well for effective TLDs such as "co.uk". |
keyword |
url.username |
Username of the request. |
keyword |
user.email |
User email address. |
keyword |
user.name |
Short name or login of the user. |
keyword |
user.name.text |
Multi-field of |
match_only_text |
Changelog
editChangelog
Version | Details | Kibana version(s) |
---|---|---|
1.16.1 |
Bug fix (View pull request) |
8.11.0 or higher |
1.16.0 |
Enhancement (View pull request) |
8.11.0 or higher |
1.15.0 |
Enhancement (View pull request) |
8.3.0 or higher |
1.14.0 |
Enhancement (View pull request) |
8.3.0 or higher |
1.13.2 |
Enhancement (View pull request) |
8.3.0 or higher |
1.13.1 |
Bug fix (View pull request) |
8.3.0 or higher |
1.13.0 |
Enhancement (View pull request) |
8.3.0 or higher |
1.12.0 |
Enhancement (View pull request) |
8.3.0 or higher |
1.11.1 |
Bug fix (View pull request) |
8.3.0 or higher |
1.11.0 |
Enhancement (View pull request) |
8.3.0 or higher |
1.10.0 |
Enhancement (View pull request) |
8.3.0 or higher |
1.9.0 |
Enhancement (View pull request) |
8.3.0 or higher |
1.8.0 |
Enhancement (View pull request) |
8.3.0 or higher |
1.7.0 |
Enhancement (View pull request) |
8.3.0 or higher |
1.6.0 |
Enhancement (View pull request) |
8.3.0 or higher |
1.5.0 |
Enhancement (View pull request) |
8.3.0 or higher |
1.4.0 |
Enhancement (View pull request) |
8.3.0 or higher |
1.3.1 |
Enhancement (View pull request) |
8.3.0 or higher |
1.3.0 |
Enhancement (View pull request) |
8.3.0 or higher |
1.2.0 |
Enhancement (View pull request) |
8.3.0 or higher |
1.1.2 |
Bug fix (View pull request) |
8.3.0 or higher |
1.1.1 |
Enhancement (View pull request) |
8.3.0 or higher |
1.1.0 |
Enhancement (View pull request) |
8.3.0 or higher |
1.0.0 |
Enhancement (View pull request) Bug fix (View pull request) Bug fix (View pull request) |
8.3.0 or higher |
0.1.1 |
Bug fix (View pull request) |
— |
0.1.0 |
Enhancement (View pull request) |
— |