Windows Event Forwarding
Windows Event Forwarding (WEF) is a service available on Windows that forwards events from Windows Event Log to a remote server. This built-in functionality avoids not only the need to install an agent on each Windows host, but also the administrative tasks related to deploying and managing third-party software across your network. However, it should be emphasized that this minimalist approach lacks some very important functionality that NXLog can provide, such as parsing and filtering.
A WEF setup consists of two roles: the Windows Event Collector (WEC), also known as a Subscription Manager, which is the server configured to receive events, and the WEF client, from which the host events are collected. The link between the two is called a subscription and can be one of the following:
-
Push, or source-initiated subscription, where WEF clients are configured to forward their events to the WEC using a Group Policy Object (GPO). This is the most flexible and scalable method because it allows you to collect events from different sources without having to manage a list of client machines.
-
Pull, or collector-initiated, where the WEC is configured with a list of hosts from which events should be collected. This is useful when you only need to monitor a small number of hosts.

NXLog can collect forwarded events in two ways; by using the im_wseventing module to act as a WEC itself, or by using the im_msvistalog module to collect forwarded events from a Windows server that is configured as a WEC.
Configuring NXLog as a WEC
NXLog can assume the role of a WEC by configuring the im_wseventing module to receive events from WEF clients using the push method. This gives you the benefit of configuring your WEC on any of the supported platforms, including GNU/Linux systems, thus eliminating the Windows-only platform requirement.
Authentication between the WEC and WEF clients requires either Kerberos or HTTPS. Since NXLog supports both, deciding which one to use depends largely on your environment.
Using Kerberos authentication
Kerberos authentication can be used when NXLog is installed on a GNU/Linux host in an environment where Active Directory (AD) is available. In this setup, a Kerberos client that can authenticate with AD needs to be configured on the host where NXLog is installed. WEF clients joined with the domain are then configured to forward their events to NXLog using a GPO.

For a step-by-step guide on how to configure NXLog with Kerberos authentication, see Configuring Kerberos authentication for use with WEF clients in the NXLog Enterprise Edition Reference Manual.
Using certificate-based authentication (HTTPS)
Certificate-based authentication can be used in any environment. However, it is ideal for collecting events from Windows servers that do not belong to any Active Directory domain. In this setup, X509 certificates need to be generated for the WEC and WEF clients. Windows Remote Management and event forwarding then need to be configured on each client. This can be done manually, or it can be automated using a script, such as the one available in our public git repository.

For a step-by-step guide on how to configure NXLog with certificate-based authentication, see Configuring WEF to use HTTPS in the NXLog Enterprise Edition Reference Manual.
NXLog configuration
The example below demonstrates how to configure NXLog as a WEC when using Kerberos authentication. For more configuration examples, see the Examples in the im_wseventing documentation.
This configuration specifies two QueryXML directives, one for WEF client hostnames starting with filesrv
, and another for all other clients.
Both queries collect the same set of base events, but the first query collects additional events related to file system auditing.
The list of base events being collected is inspired by the Microsoft recommendation on how to Use Windows Event Forwarding to help with intrusion detection.
<Input wec_server>
Module im_wseventing
Address http://<nxlog_host_name>:5985/wsman
ListenAddr 0.0.0.0
Port 5985
# Subscription event query for file servers
<QueryXML>
<Computer>filesrv*</Computer>
<QueryList>
<Query Id="0" Path="Microsoft-Windows-TaskScheduler/Operational">
<!-- 106: Task scheduler Task Registered -->
<!-- 141: Task Registration Deleted -->
<!-- 142: Task Deleted -->
<Select Path="Microsoft-Windows-TaskScheduler/Operational">*[
System[Provider[@Name='Microsoft-Windows-TaskScheduler'] and
(EventID=106 or EventID=141 or EventID=142 )]]</Select>
<Select Path="System">*[System[Provider[
@Name='Microsoft-Windows-TaskScheduler'] and (EventID=106 or
EventID=141 or EventID=142 )]]</Select>
</Query>
<Query Id="1" Path="System">
<!-- 12: The operating system started -->
<!-- 13: The operating system is shutting down -->
<!-- 4608: Windows is starting up -->
<Select Path="System">*[System[Provider[
@Name='Microsoft-Windows-Kernel-General'] and
(EventID=12 or EventID=13)]]</Select>
<Select Path="Security">*[System[(EventID=4608)]]</Select>
</Query>
<Query Id="2" Path="System">
<!-- 7000: Service Install -->
<!-- 7045: Service start failure -->
<!-- 4697: New service -->
<Select Path="System">*[System[Provider[
@Name='Service Control Manager'] and (EventID = 7000 or
EventID=7045)]]</Select>
<Select Path="Security">*[System[(EventID=4697)]]</Select>
</Query>
<Query Id="3" Path="Security">
<!-- 4616: System time change -->
<Select Path="Security">*[System[(EventID=4616)]]</Select>
</Query>
<Query Id="4" Path="System">
<!-- Event log service events -->
<Select Path="System">*[System[Provider[
@Name='Microsoft-Windows-Eventlog']]]</Select>
</Query>
<Query Id="5" Path="Security">
<!-- Event log service events specific to Security channel -->
<Select Path="Security">*[System[Provider[
@Name='Microsoft-Windows-Eventlog']]]</Select>
</Query>
<Query Id="6" Path="Security">
<!-- 1102: Security Log cleared events -->
<!-- 1100: EventLog Service shutdown -->
<Select Path="Security">*[System[(EventID=1102 or
EventID = 1100)]]</Select>
</Query>
<Query Id="7" Path="System">
<!-- 104: Other Log cleared events -->
<Select Path="System">*[System[(EventID=104)]]</Select>
</Query>
<Query Id="8" Path="Security">
<!-- Local logons without network or service events -->
<Select Path="Security">*[System[(EventID=4624)]] and
(*[EventData[Data[@Name="LogonType"]!="3"]]) and
(*[EventData[Data[@Name="LogonType"]!="5"]])</Select>
</Query>
<Query Id="9" Path="Security">
<!-- 4647: User initiated logoff -->
<Select Path="Security">*[System[(EventID=4647)]]</Select>
</Query>
<Query Id="10" Path="Security">
<!-- 4625: An account failed to Log on -->
<Select Path="Security">*[System[(EventID=4625)]] and
(*[EventData[Data[@Name="LogonType"]!="2"]]) </Select>
</Query>
<Query Id="11" Path="Application">
<!-- WER events for application crashes only -->
<Select Path="Application">*[System[Provider[
@Name='Windows Error Reporting']]] and
(*[EventData[Data[3] ="APPCRASH"]])</Select>
</Query>
<Query Id="12" Path="Security">
<!-- 4624: Service logon events if the user account
isn't LocalSystem, NetworkService, LocalService -->
<Select Path="Security">*[System[(EventID=4624)]] and
(*[EventData[Data[@Name="LogonType"]="5"]]) and
(*[EventData[Data[@Name="TargetUserSid"] != "S-1-5-18"]]) and
(*[EventData[Data[@Name="TargetUserSid"] != "S-1-5-19"]]) and
(*[EventData[Data[@Name="TargetUserSid"] != "S-1-5-20"]])</Select>
</Query>
<Query Id="13" Path="Security">
<!-- 4720: New user account created -->
<!-- 4722: User account enabled -->
<!-- 4725: User account disabled -->
<!-- 4726: User account deleted -->
<Select Path="Security">*[System[(EventID=4720 or EventID=4722
or EventID=4725 or EventID=4726)]]</Select>
</Query>
<Query Id="14" Path="Security">
<!-- Network share object access without IPC$ and
Netlogon shares -->
<Select Path="Security">*[System[(EventID=5140)]] and
(*[EventData[Data[@Name="ShareName"]!="\\*\IPC$"]]) and
(*[EventData[Data[@Name="ShareName"]!="\\*\NetLogon"]])</Select>
</Query>
<Query Id="15" Path="Security">
<!-- 5142: Network share created -->
<!-- 5144: Network share deleted -->
<Select Path="Security">*[System[(EventID=5142 or
EventID=5144)]]</Select>
</Query>
<Query Id="16" Path="Security">
<!-- 4715: The audit policy (SACL) on an object was changed. -->
<!-- 4817: Auditing settings on object were changed. -->
<!-- 4656: A handle to an object was requested. -->
<!-- 4658: The handle to an object was closed. -->
<!-- 4660: An object was deleted. -->
<!-- 4663: An attempt was made to access an object. -->
<!-- 4664: An attempt was made to create a hard link. -->
<!-- 4670: Permissions on an object were changed. -->
<Select Path="Security">*[System[(EventID=4715 or EventID=4817
or EventID=4656 or EventID=4658 or EventID=4660 or EventID=4663
or EventID=4670)]]</Select>
</Query>
</QueryList>
</QueryXML>
# Subscription event query for all other servers
<QueryXML>
<QueryList>
<Query Id="0" Path="Microsoft-Windows-TaskScheduler/Operational">
<!-- 106: Task scheduler Task Registered -->
<!-- 141: Task Registration Deleted -->
<!-- 142: Task Deleted -->
<Select Path="Microsoft-Windows-TaskScheduler/Operational">*[
System[Provider[@Name='Microsoft-Windows-TaskScheduler'] and
(EventID=106 or EventID=141 or EventID=142 )]]</Select>
<Select Path="System">*[System[Provider[
@Name='Microsoft-Windows-TaskScheduler'] and (EventID=106 or
EventID=141 or EventID=142 )]]</Select>
</Query>
<Query Id="1" Path="System">
<!-- 12: The operating system started -->
<!-- 13: The operating system is shutting down -->
<!-- 4608: Windows is starting up -->
<Select Path="System">*[System[Provider[
@Name='Microsoft-Windows-Kernel-General'] and
(EventID=12 or EventID=13)]]</Select>
<Select Path="Security">*[System[(EventID=4608)]]</Select>
</Query>
<Query Id="2" Path="System">
<!-- 7000: Service Install -->
<!-- 7045: Service start failure -->
<!-- 4697: New service -->
<Select Path="System">*[System[Provider[
@Name='Service Control Manager'] and (EventID = 7000 or
EventID=7045)]]</Select>
<Select Path="Security">*[System[(EventID=4697)]]</Select>
</Query>
<Query Id="3" Path="Security">
<!-- 4616: System time change -->
<Select Path="Security">*[System[(EventID=4616)]]</Select>
</Query>
<Query Id="4" Path="System">
<!-- Event log service events -->
<Select Path="System">*[System[Provider[
@Name='Microsoft-Windows-Eventlog']]]</Select>
</Query>
<Query Id="5" Path="Security">
<!-- Event log service events specific to Security channel -->
<Select Path="Security">*[System[Provider[
@Name='Microsoft-Windows-Eventlog']]]</Select>
</Query>
<Query Id="6" Path="Security">
<!-- 1102: Security Log cleared events -->
<!-- 1100: EventLog Service shutdown -->
<Select Path="Security">*[System[(EventID=1102 or
EventID = 1100)]]</Select>
</Query>
<Query Id="7" Path="System">
<!-- 104: Other Log cleared events -->
<Select Path="System">*[System[(EventID=104)]]</Select>
</Query>
<Query Id="8" Path="Security">
<!-- Local logons without network or service events -->
<Select Path="Security">*[System[(EventID=4624)]] and
(*[EventData[Data[@Name="LogonType"]!="3"]]) and
(*[EventData[Data[@Name="LogonType"]!="5"]])</Select>
</Query>
<Query Id="9" Path="Security">
<!-- 4647: User initiated logoff -->
<Select Path="Security">*[System[(EventID=4647)]]</Select>
</Query>
<Query Id="10" Path="Security">
<!-- 4625: An account failed to Log on -->
<Select Path="Security">*[System[(EventID=4625)]] and
(*[EventData[Data[@Name="LogonType"]!="2"]]) </Select>
</Query>
<Query Id="11" Path="Application">
<!-- WER events for application crashes only -->
<Select Path="Application">*[System[Provider[
@Name='Windows Error Reporting']]] and
(*[EventData[Data[3] ="APPCRASH"]])</Select>
</Query>
<Query Id="12" Path="Security">
<!-- 4624: Service logon events if the user account
isn't LocalSystem, NetworkService, LocalService -->
<Select Path="Security">*[System[(EventID=4624)]] and
(*[EventData[Data[@Name="LogonType"]="5"]]) and
(*[EventData[Data[@Name="TargetUserSid"] != "S-1-5-18"]]) and
(*[EventData[Data[@Name="TargetUserSid"] != "S-1-5-19"]]) and
(*[EventData[Data[@Name="TargetUserSid"] != "S-1-5-20"]])</Select>
</Query>
<Query Id="13" Path="Security">
<!-- 4720: New user account created -->
<!-- 4722: User account enabled -->
<!-- 4725: User account disabled -->
<!-- 4726: User account deleted -->
<Select Path="Security">*[System[(EventID=4720 or EventID=4722
or EventID=4725 or EventID=4726)]]</Select>
</Query>
</QueryList>
</QueryXML>
</Input>
The value specified in the <Computer> tag of QueryXML is case-sensitive.
|
Configuring NXLog to collect forwarded events
NXLog can collect forwarded events from a native Windows Event Collector using the im_msvistalog input module. To create a subscription on a Windows server and configure WEF clients to forward events to it, follow the steps below.
- Prerequisites
-
-
Communication between WEF clients and the collector is done over WinRM. Make sure that the Windows Remote Management (WS-Management) service is running and configured to automatically start on the collector.
-
WEF uses the Network Service account to send events to the collector. By default, this account does not have access to the Security event log or other custom logs. To give it access, add the Network Service account to the Event Log Readers local group on WEF clients or through group policy. See Forwarding events from the Security log for more information.
-
- Configure the subscription manager
-
-
On the Windows server that will act as the event collector, open Event Viewer (eventvwr.msc).
-
Right-click on Subscriptions and then Create Subscription….
-
If the Windows Event Collector service is not running you will be asked if you want to start the service. Click Yes.
-
Enter a subscription name and description.
-
For Destination log, select Forwarded Events.
-
Choose the subscription type you would like to configure, either Collector initiated or Source computer initiated, then click on the respective button to select the hosts, to which this subscription should apply.
-
Click on the Select Events… button and choose the events that should be collected. You can filter by log type or source and by a list of event IDs to be included or excluded.
-
Click the OK button to close the Query Filter dialog.
-
Click on the Advanced… button.
-
For Event Delivery Optimization, select Minimize Latency to ensure the collector receives events as soon as possible.
-
For Protocol, select HTTP to use Kerberos authentication or HTTPS to use certificate-based authentication.
-
If you chose Collector initiated for subscription type, you will also be asked to specify the user account that will be used to collect events from the remote hosts.
-
- Configure WEF clients
-
If you created a Source computer initiated subscription, you will need to configure WEF clients to forward their events to the collector. This is usually done through a domain Group Policy Object (GPO) on a server with the Group Policy Management feature installed:
-
Open Server Manager and go to Tools > Group Policy Management.
-
From the Group Policy Management MMC, expand Forest:[name] > Domains and select your domain name.
-
Right-click on the relevant group policy and select Edit….
-
Navigate to Computer Configuration > Policies > Administrative Templates > Windows Components > Event Forwarding.
-
Open and enable the Configure target Subscription Manger setting.
-
Click Show… beside the Subscription Mangers option.
-
Add subscription manager settings in the format:
Server=http://<wec_fqdn>:5985/wsman/SubscriptionManager/WEC,Refresh=<interval_in_seconds>
The main Subscription Manager properties window contains a Help pane that describes the syntax for this setting, including the required format for HTTPS.
-
Click OK and Apply to save the policy settings.
-
NXLog configuration
The example below demonstrates how to configure NXLog to collect events from a native Windows Event Collector.
This configuration uses the im_msvistalog module to collect all events from the dedicated Forwarded Events log. This log is commonly used as the destination for forwarded events, but can be changed according to the destination configured in the subscription.
<Input forwarded_events>
Module im_msvistalog
<QueryXML>
<QueryList>
<Query Id="0" Path="ForwardedEvents">
<Select Path="ForwardedEvents">*</Select>
</Query>
</QueryList>
</QueryXML>
</Input>