NXLog Docs

Collect logs from Windows Event Forwarding

Windows Event Forwarding (WEF) is a service available on Windows that forwards logs from Windows Event Log to a remote server. This built-in functionality avoids the need to install an agent on each Windows host and the administrative tasks related to deploying and managing third-party software across your network. However, you must understand that this minimalist approach lacks some essential functionality NXLog can provide, such as parsing and filtering logs.

In addition, WEF inherits the limitations of Windows Event Log, such as collecting logs based on ETW Providers. Many more log sources exist on a Windows system than WEF can provide. Nevertheless, it might be a viable option when a log collection agent cannot be installed on the host for whatever reason.

A WEF setup consists of two roles: the Windows Event Collector (WEC), also known as a Subscription Manager, is the server configured to receive logs, and the WEF client, from which the host event logs 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 logs to the WEC using a Group Policy Object (GPO). This is the most flexible and scalable method because it allows you to collect logs from different sources without managing a list of client machines.

  • Pull, or collector-initiated, where the WEC is configured with a list of hosts from which to collect logs. This is useful when you only need to monitor a small number of hosts.

WEF subscription
Figure 1. Components of a Windows Event Forwarding setup

NXLog can collect logs forwarded by Windows Event Forwarding in two ways; by using the im_wseventing module to act as a WEC or by using the im_msvistalog module to collect forwarded events from a Windows server configured as a WEC.

Configuring NXLog as a Windows Event Collector

NXLog can assume the role of a WEC by configuring the im_wseventing module to receive logs from WEF clients using the push method. This gives you the benefit of configuring your WEC on any supported platform, 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 mainly on your environment.

Windows Event Forwarding with Kerberos authentication

Kerberos authentication can be used when NXLog is installed on a host in an Active Directory (AD) environment. 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.

Using WEF with Kerberos authentication
Figure 2. NXLog as a Windows Event Collector using Kerberos authentication

For a step-by-step guide on configuring NXLog with Kerberos, see Using Kerberos authentication in the NXLog Enterprise Edition Reference Manual.

Windows Event Forwarding with certificate-based authentication (HTTPS)

Certificate-based authentication is ideal for collecting logs from Windows servers that do not belong to any Active Directory domain. When using HTTPS, X509 certificates must be generated for the WEC and WEF clients. Windows Remote Management and event forwarding also need to be configured on each client. The configuration can be done manually or automated using a script, such as the one available in our public git repository.

Using WEF with HTTPS
Figure 3. NXLog as a Windows Event Collector using HTTPS

For a step-by-step guide on configuring NXLog with certificate-based authentication, see Using HTTPS certificate-based authentication in the NXLog Enterprise Edition Reference Manual.

NXLog WEC configuration

The example below demonstrates configuring NXLog as a WEC when using Kerberos authentication. For more configuration examples, see the Examples in the im_wseventing documentation.

Example 1. Receiving WEF logs with NXLog’s im_wseventing module

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 base logs, but the first collects additional file system auditing events.

The list of base events being collected is inspired by Microsoft’s recommendation on how to Use Windows Event Forwarding to help with intrusion detection.

nxlog.conf
<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 logs 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 logs to it, follow the steps below.

Prerequisites
  • Communication between WEF clients and the collector is done over WinRM. Ensure the Windows Remote Management (WS-Management) service is running and configured to start automatically on the collector.

  • WEF uses the Network Service account to send events to the collector. This account cannot access the Security event log or other custom logs by default. Add the Network Service account to the Event Log Readers group on WEF clients or through group policy to give it access. See Forwarding events from the Security log for more information.

Configure the subscription manager
  1. On the Windows server that will act as the event collector, open Event Viewer (eventvwr.msc).

  2. Right-click on Subscriptions and then Create Subscription…​.

  3. If the Windows Event Collector service is not running, you will be asked if you want to start the service. Click Yes.

    Windows Event Collector Service

  4. Enter a subscription name and description.

  5. For Destination log, select Forwarded Events.

    Windows Event Collector Subscription Configuration

  6. 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.

  7. 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.

    Windows Event Collector Subscription Events Filter

  8. Click the OK button to close the Query Filter dialog.

  9. Click on the Advanced…​ button.

  10. For Event Delivery Optimization, select Minimize Latency to ensure the collector receives events as soon as possible.

  11. For Protocol, select HTTP to use Kerberos authentication or HTTPS to use certificate-based authentication.

    Windows Event Collector Subscription Advanced Settings

  12. If you chose Collector initiated for the 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 must configure WEF clients to forward their logs to the collector. This is usually done through a domain Group Policy Object (GPO) on a server with the Group Policy Management feature installed:

  1. Open Server Manager and go to Tools > Group Policy Management.

  2. From the Group Policy Management MMC, expand Forest:[name] > Domains and select your domain name.

  3. Right-click on the relevant group policy and select Edit…​.

  4. Navigate to Computer Configuration > Policies > Administrative Templates > Windows Components > Event Forwarding.

  5. Open and enable the Configure target Subscription Manager setting.

  6. Click Show…​ beside the Subscription Managers option.

    Windows Event Forwarding policy

  7. Add subscription manager settings in the format:

    Server=http://<wec_fqdn>:5985/wsman/SubscriptionManager/WEC,Refresh=<interval_in_seconds>

    Windows Event Forwarding policy SubscriptionManagers

    The main Subscription Manager properties window contains a Help pane that describes the syntax for this setting, including the required format for HTTPS.

  8. Click OK and Apply to save the policy settings.

The example below demonstrates configuring NXLog to collect logs from a native Windows Event Collector.

Example 2. Collecting WEF logs with the im_msvistalog module

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 logs but can be changed according to the destination configured in the subscription.

nxlog.conf
<Input forwarded_events>
    Module    im_msvistalog
    <QueryXML>
        <QueryList>
            <Query Id="0" Path="ForwardedEvents">
                <Select Path="ForwardedEvents">*</Select>
            </Query>
        </QueryList>
    </QueryXML>
</Input>
Disclaimer

While we endeavor to keep the information in this topic up to date and correct, NXLog makes no representations or warranties of any kind, express or implied about the completeness, accuracy, reliability, suitability, or availability of the content represented here. We update our screenshots and instructions on a best-effort basis.

The accurateness of the content was tested and proved to be working in our lab environment at the time of the last revision with the following software versions:

Microsoft Windows Server 2022 Standard
Linux Mint 21.1 Vera base: Ubuntu 22.04 (Jammy Jellyfish)
NXLog version 5.7.7898

Last revision: 29 March 2023