flatrick / graylog2_iis

Configuration to get IIS logs into Graylog with each field extracted

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

graylog2_iis

Configuration to get IIS logs into Graylog2 using Graylog2 collector-sidecar (FileBeats), after which all fields are extracted from the message into searchable fields. In this example, the field log_timestamp is also converted from unmarked UTC to Europe/Stockholm.

Notes

This guide is written with IIS 10 in mind, so any older or newer versions of IIS might require some adaptation to work. For example, the field StreamID in the error-log refers to a HTTP/2.0 (SPDY) feature and HTTP/2.0 is an entirely new feature in IIS 10. I used the graylog-2.4.6-1.ova image while creating this guide.

Currently missing or not working

  • I haven't handled C:/Windows/System32/LogFiles/HTTPERR/*.log yet.
  • Since I've named some of the fields from the access-logs with generic names (PORT for s-port/server-port), when I'm now trying to add a GROK-pattern for the error-file I've found that I now need to rename the previous ones for it to make sense together.

Configure IIS to get the logs in the correct format

Set the correct formatting of the log-files:
%windir%\system32\inetsrv\appcmd.exe set config -section:system.applicationHost/sites -siteDefaults.logfile.logFormat:"W3C"

Add the necessary fields:
%windir%\system32\inetsrv\appcmd.exe set config -section:system.applicationHost/sites -siteDefaults.logfile.logExtFileFlags:Date,Time,ClientIP,UserName,SiteName,ComputerName,ServerIP,Method,UriStem,UriQuery,HttpStatus,Win32Status,BytesSent,BytesRecv,TimeTaken,ServerPort,UserAgent,Cookie,Referer,ProtocolVersion,Host,HttpSubStatus

If you wish to change the path to where the logs are stored, edit the command below and run it:
%windir%\system32\inetsrv\appcmd.exe set config -section:system.applicationHost/sites -siteDefaults.logfile.directory:"%SystemDrive%\inetpub\logs\LogFiles"

Graylog

Input

For this configuration to work, we'll need to setup a Beats-input. Select Beats and click Launch new input if you don't already have one you want to use. You will not need to enter any special configuration here to get it running, but keep track of what port the Input is listening on. You might need to set a bind_adress (what IP this Input will be listening on).

Manage extractors

If we want to create our extactor through the GUI, we will need events in our stream first. You can however import extractors before that if you have an export of the extractor you want to import.
Below, I've described how to do it both ways.

  • Before we can create our extractor, we need some events in our input, so return to this step when you have received your first message and then click Manage extractors.
    Then click on Get started to create the extractor described in the table below.
  • Or you can import the extractor by clicking on Actions and then Import extractors, then copy the JSON-formatted message below this table, then you don't have to wait until a message has been harvested/saved in Graylog/Elasticsearch.
Setting Choice
Extractor type Grok pattern
Named capture only If you don't want to recursively extract fields from GROK pattern and put the explicitly named captures into the message
Source field message
Grok pattern %{TIMESTAMP_ISO8601:log_timestamp} %{WORD:serviceName} %{SERVERNAME:serverName} %{IP:serverIP} %{WORD:method} %{URIPATH:uriStem} %{NOTSPACE:uriQuery} %{NUMBER:port;int} %{NOTSPACE:username} %{IPORHOST:clientIP} %{NOTSPACE:protocolVersion} %{NOTSPACE:userAgent} %{NOTSPACE:cookie} %{NOTSPACE:referer} %{NOTSPACE:requestHost} %{NUMBER:response;int} %{NUMBER:subresponse;int} %{NUMBER:win32response;int} %{NUMBER:bytesSent;int} %{NUMBER:bytesReceived;int} %{NUMBER:timetaken;int}
Condition Only attempt extraction if field matches regular expression
Field matches regular expression W3SVC
Extraction strategy Copy
Extractor title IIS-WC3 Full

The JSON-formatted importable extractor

{
  "extractors": [
    {
      "title": "IIS-WC3 Full",
      "extractor_type": "grok",
      "converters": [],
      "order": 0,
      "cursor_strategy": "copy",
      "source_field": "message",
      "target_field": "",
      "extractor_config": {
        "grok_pattern": "%{TIMESTAMP_ISO8601:log_timestamp} %{WORD:serviceName} %{SERVERNAME:serverName} %{IP:serverIP} %{WORD:method} %{URIPATH:uriStem} %{NOTSPACE:uriQuery} %{NUMBER:port;int} %{NOTSPACE:username} %{IPORHOST:clientIP} %{NOTSPACE:protocolVersion} %{NOTSPACE:userAgent} %{NOTSPACE:cookie} %{NOTSPACE:referer} %{NOTSPACE:requestHost} %{NUMBER:response;int} %{NUMBER:subresponse;int} %{NUMBER:win32response;int} %{NUMBER:bytesSent;int} %{NUMBER:bytesReceived;int} %{NUMBER:timetaken;int}",
        "named_captures_only": false
      },
      "condition_type": "string",
      "condition_value": "W3SVC"
    }
  ],
  "version": "2.4.6"
}

Collector

Beats Input

Setting Value
Path to logfile ['C:\inetpub\logs\LogFiles\*\*.log']
Encoding utf-8
Type of input file iis
Lines that you want Filebeat to exclude ['^#']

Pipelines

In this example, I'm using one rule in one stage;

  1. It first modifies the value log_timestamp so it's stored as a datetime object, which means it also contains the timezone
  2. Then I change the timezone to my local timezone to make it easier to read for possible alerts in the future and store it in log_timestamp
  3. Lastly, using the corrected log_timestamp as a source I set the field timestamp to be the same but in UTC.

If I don't do the last step, timestamp will be referring to when Filebeat sent the event to Graylog and not when it actually happened. Since IIS can wait a while before writing to it's logfile, this means that the timestamp we get would always be slightly incorrect (and/or if Filebeat for whatever reason wasn't running for a while, all of the new events that it'll send will have the same timestamp for all events, even though the events could be from different days).

Set correct time for log_timestamp and timestamp

For this rule to work, Pipeline Processor must run after Message Filter Chain (edit this under System - Configuration by pressing Update below the table showing the current order and move Pipeline Processor to after Message Filter Chain

This rule will

  • read all messages that are of type iis and contains the field log_timestamp
  • parse the field log_timestamp to add it's correct timezone (UTC)
  • save the field with "Europe/Stockholm" as timezone in the format: yyyy-MM-dd HH:mm:ss +0100 (non-DST, +0200 when DST is in effect)
  • save the correct timestamp in the field timestamp as well to improve searching/indexing instead of storing time of ingestion by Filebeat
rule "Set correct IIS log_timestamp and timestamp"
when
	contains(
            value: to_string($message.type), 
            search: "iis",
            ignore_case: true)
	AND has_field(field: "log_timestamp")
then
	let set_timezone = parse_date(
				value: to_string($message.log_timestamp),
				pattern: "yyyy-MM-dd HH:mm:ss",
				timezone: "UTC");
	let correct_timestamp = format_date(
					value: set_timezone,
					format: "yyyy-MM-dd HH:mm:ss Z",
					timezone: "Europe/Stockholm");
	set_field("log_timestamp", correct_timestamp);
	set_field("timestamp", set_timezone);
end

Info

By adding the keyword ;int at the end of grok-patterns, we're telling Graylog that this field is to be stored as integers, without this hint, it'll most certainly store it as a string and then statistics won't work on those fields.

Comparison of the two different log-files for IIS

  • #Fields: date time s-sitename s-computername s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs-version cs(User-Agent) cs(Cookie) cs(Referer) cs-host sc-status sc-substatus sc-win32-status sc-bytes cs-bytes time-taken
  • #Fields: date time c-ip c-port s-ip s-port cs-version cs-method cs-uri streamid sc-status s-siteid s-reason s-queuename

Access-log (Extended W3C)

Swedish name Field-name according to logfile GROK
Datum date (date+time is handled by the rule below)
Tid time %{TIMESTAMP_ISO8601:log_timestamp}
Servicenamn s-sitename %{WORD:S-SiteName}
Servernamn s-computername %{HOSTNAME:S-ComputerName}
IP-adress för server s-ip %{IPORHOST:S-IP}
Metod cs-method %{WORD:CS-Method}
URI-stam cs-uri-stem %{URIPATH:CS-URI-Stem}
URI-fråga cs-uri-query %{NOTSPACE:CS-URI-Query}
Server-port s-port %{NUMBER:S-Port;int}
Användarnamn cs-username %{NOTSPACE:CS-Username}
IP-adress för klient c-ip %{IPORHOST:C-IP}
Protokollversion cs-version %{NOTSPACE:CS-Version}
Användaragent cs(User-Agent) %{NOTSPACE:CS-UserAgent}
Cookie cs(Cookie) %{NOTSPACE:CS-Cookie}
Referenssida cs(Referer) %{NOTSPACE:CS-Referer}
Värd cs-host %{NOTSPACE:CS-Host}
Protokollstatus sc-status %{NUMBER:SC-Status;int}
Understatus för protokoll sc-substatus %{NUMBER:SC-SubStatus;int}
Win32-Status sc-win32-status %{NUMBER:SC-Win32-Status;int}
Skickade bytes sc-bytes %{NUMBER:SC-Bytes;int}
Mottagna bytes cs-bytes %{NUMBER:CS-Bytes;int}
Tidsåtgång time-taken %{NUMBER:Time-Taken;int}

Error logs

Swedish name Fieldname GROK
date time %{TIMESTAMP_ISO8601:log_timestamp}
c-ip %{IPORHOST:clientIP}
c-port %{NUMBER:port;int}
s-ip %{IP:serverIP}
s-port %{NUMBER:port;int}
cs-version %{NOTSPACE:CS-Version}
cs-method %{WORD:method}
cs-uri %{URI:URI}
streamid ?
sc-status %{NUMBER:SC-Status;int}
s-siteid ?
s-reason ?
s-queuename ?

About

Configuration to get IIS logs into Graylog with each field extracted

License:GNU Lesser General Public License v3.0