Configuración de Elasticsearch Ingest node y Filebeat para indexación de logs de Microsoft Internet Information Services (IIS).

La configuración tratada en este artículo es para el envió directo de Logs de IIs mediante Filebeat a servidores de Elasticsearch en modo “ingest”, sin intermediarios. Si usas Logstash te puede ser de utilidad la Template usada así como el filtro GROK empleado en el Pipeline para ES Ingest Node pero la configuración será diferente.

Requisitos

Necesitamos primero Elasticsearch y Kibana funcionando (instalado y conectado a ES). Vamos a configurar Filebeat en el servidor Windows con IIS y el pipeline y template necesarios para Indexar los logs de IIS.

Configuración requerida para IIS

En IIS necesitamos solamente configurar para todos los logs que usen el formato W3C y que guarde todos los campos (se deben seleccionar todos). Es muy importante configurarlo de esta manera ya que toda la configuración expuesta en este artículo se basa en esa configuración de los logs de IIS.

Atención Se adjunta al final del artículo un zip con todos ficheros de configuración de este artículo. Mejor no hagas copy / paste del artículo que los carga el diablo.

Algunas operaciones básicas que es necesario conocer

Podemos ver los indices existentes en Elasticsearch con:

[root@es5 ~]# curl 'localhost:9200/_cat/indices?v'
health status index   uuid                   pri rep docs.count docs.deleted store.size pri.store.si                     ze
yellow open   .kibana cy6tNq1gTUWkPOs7Lu4FFg   1   1          1            0      3.1kb          3.1                     kb

Podemos borrar un índice:

curl -XDELETE 'http://localhost:9200/index_name-*/'

p.e. Borrar los indices “filebeat” (ficheros filebeat-*)

curl -XDELETE 'http://localhost:9200/filebeat-*/'

Ver todos los Pipelines configurados en Elasticsearch desde la consola de Kibana DEV Tools.

GET _ingest/pipeline/*

Eliminar un pipeline desde la consola de Kibana DEV Tools.

DELETE _ingest/pipeline/pipeline-name

Eliminar los indices de esta manera no está recomendado en un entorno de producción. Es mejor usar una herramienta como Curator. En instalaciones de test/lab puedes usarlo.

Pipeline de Internet Information server para Elasticsearch Ingest node

Necesitamos tener definido un Pipeline para trasladar las entradas de logs de IIS a “campos” en Elasticsearch. Si estamos usando Logstash (en lugar de ES Ingest Nodes) no necesitarás un Pipeline sino una configuración especifica para Logstash que no es objeto de este artículo. En cualquier caso el filtro GROK que se usa en este Pipeline te puede ser de mucha utilidad.

Debemos crear un Pipeline “iis_w3c” desde la consola de Kibana DEV Tools.

PUT _ingest/pipeline/iis_w3c
{
  "description": "iis_w3c",
  "processors": [
    {
      "grok": {
        "field": "message",
        "patterns": ["%{TIMESTAMP_ISO8601:date_time} %{WORD:s_sitename} %{HOSTNAME:s_computername} %{IP:s_ip} %{WORD:cs_method} %{URIPATH:cs_uri_stem} %{NOTSPACE:cs_uri_query} %{NUMBER:s_port} %{NOTSPACE:cs_username} %{IPORHOST:c_ip} %{NOTSPACE:cs_version} %{NOTSPACE:cs_user_agent} %{NOTSPACE:cs_cookie} %{NOTSPACE:cs_referer} %{NOTSPACE:cs_host} %{NUMBER:sc_status} %{NUMBER:sc_substatus} %{NUMBER:sc_win32_status} %{NUMBER:sc_bytes} %{NUMBER:cs_bytes} %{NUMBER:time_taken}"]
      }
    },
    {
      "date": {
        "field": "date_time",
        "formats": [ "yyyy-MM-dd HH:mm:ss" ]
      }
    }   
  ],
  "on_failure" : [
    {
      "set" : {
        "field" : "_index",
        "value" : "failed-{{ _index }}"
      }
    }
  ]
}

Podemos ver los pipelines presentes en nuestro ES con:

GET _ingest/pipeline/*

Atención En el pipeline se define un Indice “failed-*” que se creará en caso de que las líneas de log que se Indexan no hagan “match” con la expresión regular de GROK. De esta forma evitamos que Filebeat pare o descarte el envió de logs con el formato correcto a Elasticsearch.

Probando el filtro GROK para IIS de nuestro Pipeline

Podemos probar el filtro GROK encargado de trasladar los campos e log a campos reales en ES. Lo podemos hacer directamente desde la consola de Kibana DEV Tools. Puedes cambiar el campo “message” por una línea real del log de tu IIS.

POST _ingest/pipeline/_simulate
{
  "pipeline" :
  {
  "description": "tets_iis",
  "processors": [
    {
      "grok": {
        "field": "message",
        "patterns": ["%{TIMESTAMP_ISO8601:log_timestamp} %{WORD:serviceName} %{HOSTNAME:virtual_host} %{IP:serverIP} %{WORD:method} %{URIPATH:uriStem} %{NOTSPACE:uriQuery} %{NUMBER:port} %{NOTSPACE:username} %{IPORHOST:clientIP} %{NOTSPACE:protocolVersion} %{NOTSPACE:userAgent} %{NOTSPACE:cookie} %{NOTSPACE:referer} %{NOTSPACE:requestHost} %{NUMBER:response} %{NUMBER:subresponse} %{NUMBER:win32response} %{NUMBER:bytesSent} %{NUMBER:bytesReceived} %{NUMBER:timetaken}"]
      }
    }]},
  "docs": [
    {
      "_index": "index",
      "_type": "type",
      "_id": "id",
      "_source": {
        "message": "2017-04-06 08:15:38 W3SVC1 server-iis8 10.10.48.91 GET /sga/pepito.html - 80 - 10.10.45.43 HTTP/1.1 Mozilla/5.0+(Windows+NT+10.0;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/57.0.2987.133+Safari/537.36 ROUTEID1=.server-001;+ROUTEID2=.server-002 https://www.fulanito.com/sga/pepito.html www.fulanito.com 200 0 0 51340 637 15"
      }
    }
  ]
}

El resultado será una respuesta del Elasticsearch con todos los campos correctamente identificados.

{
  "docs": [
    {
      "doc": {
        "_index": "index",
        "_type": "type",
        "_id": "id",
        "_source": {
          "log_timestamp": "2017-04-06 08:15:38",
          "referer": "https://www.fulanito.com/sga/pepito.html",
          "win32response": "0",
          "requestHost": "www.fulanito.com",
          "timetaken": "15",
          "clientIP": "10.10.45.43",
          "serverIP": "10.10.48.91",
          "protocolVersion": "HTTP/1.1",
          "virtual_host": "server-iis8",
          "method": "GET",
          "cookie": "ROUTEID1=.server-001;+ROUTEID2=.server-002",
          "uriStem": "/sga/pepito.html",
          "userAgent": "Mozilla/5.0+(Windows+NT+10.0;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/57.0.2987.133+Safari/537.36",
          "bytesSent": "51340",
          "message": "2017-04-06 08:15:38 W3SVC1 server-iis8 10.10.48.91 GET /sga/pepito.html - 80 - 10.10.45.43 HTTP/1.1 Mozilla/5.0+(Windows+NT+10.0;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/57.0.2987.133+Safari/537.36 ROUTEID1=.server-001;+ROUTEID2=.server-002 https://www.fulanito.com/sga/pepito.html www.fulanito.com 200 0 0 51340 637 15",
          "serviceName": "W3SVC1",
          "bytesReceived": "637",
          "uriQuery": "-",
          "port": "80",
          "response": "200",
          "subresponse": "0",
          "username": "-"
        },
        "_ingest": {
          "timestamp": "2017-05-17T14:05:32.641Z"
        }
      }
    }
  ]
}

Probando el Pipeline para IIS

Podemos también probar nuestro pipeline “iis_w3c” ya definido en ES directamente.

POST _ingest/pipeline/iis_w3c/_simulate
{
  "docs": [
    {
      "_index": "index",
      "_type": "type",
      "_id": "id",
      "_source": {
        "message": "2017-04-06 08:15:38 W3SVC1 server-iis8 10.10.48.91 GET /sga/pepito.html - 80 - 10.10.45.43 HTTP/1.1 Mozilla/5.0+(Windows+NT+10.0;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/57.0.2987.133+Safari/537.36 ROUTEID1=.server-001;+ROUTEID2=.server-002 https://www.fulanito.com/sga/pepito.html www.fulanito.com 200 0 0 51340 637 15"
      }
    }
  ]
}

Con idéntico resultado que el test previo del filtro grok

Filebeat template for Internet Information Server logs.

Ahora necesitamos un Template para los logs de IIS. El Template contempla la creación del campo necesario @timestamp, las direcciones IP con el campo tipo IP y algunos campos numéricos como tal. Todos los campos de texto serán de tipo “keyword” excepto el de message que será analizado. La plantilla está hecha a partir de una original de Filebeat. Con esta definición creará los campos en ES del tipo apropiado.

Podemos cargar el Template desde la consola de DEV Tools de Kibana, mediante curl o desde el agente Filebeat directamente. Optamos por hacerlo desde consola de S.O. con la utilidad “curl”. De esta forma creamos primero el fichero json con la definición del Template y luego lo cargamos.

El fichero iis_access.template.json sería:

{
  "mappings": {
    "_default_": {
      "_all": {
        "norms": false
      },
      "_meta": {
        "version": "5.3.1"
      },
      "dynamic_templates": [
        {
          "strings_as_keyword": {
            "mapping": {
              "ignore_above": 1024,
              "type": "keyword"
            },
            "match_mapping_type": "string"
          }
        }
      ],
      "properties": {
        "@timestamp": {
          "type": "date"
        },
        "c_ip": {
          "type": "ip"
        },
        "s_ip": {
          "type": "ip"
        },
        "sc_bytes": {
          "type": "integer"
        },
        "cs_bytes": {
          "type": "integer"
        },
        "time_taken": {
          "type": "integer"
        },
        "beat": {
          "properties": {
            "hostname": {
              "ignore_above": 1024,
              "type": "keyword"
            },
            "name": {
              "ignore_above": 1024,
              "type": "keyword"
            },
            "version": {
              "ignore_above": 1024,
              "type": "keyword"
            }
          }
        },
        "input_type": {
          "ignore_above": 1024,
          "type": "keyword"
        },
        "message": {
          "norms": false,
          "type": "text"
        },
        "offset": {
          "type": "long"
        },
        "source": {
          "ignore_above": 1024,
          "type": "keyword"
        },
        "tags": {
          "ignore_above": 1024,
          "type": "keyword"
        },
        "type": {
          "ignore_above": 1024,
          "type": "keyword"
        }
      }
    }
  },
  "order": 0,
  "settings": {
    "index.refresh_interval": "5s"
  },
  "template": "iis_access-*"
}

Con este fichero desde la shell del servidor de Elasticsearch ejecutamos

curl -XPUT 'http://localhost:9200/_template/iis_access' -d@./iis_access.template.json

Obtendremos una respuesta: {"acknowledged":true}

Podemos ver que existe el Template en ES.

curl -XGET 'http://localhost:9200/_template/iis_access?pretty'

Configuración de Filebeat en el servidor de IIS

Instalamos Filebeat y paramos el servicio de Filebeat de momento. Localizamos el fichero de configuración “filebeat.yml” y lo modificamos

filebeat.prospectors:
- input_type: log
  paths:
    - C:\inetpub\logs\LogFiles\*\*
  exclude_lines: ['#']

output.elasticsearch:
  hosts: ["stg-elasticsearch-c02-0001:9200"]
  index: "iis_access-%{+yyyy.MM.dd}"
  pipeline: iis_w3c
  template.enabled: false
  template.name: "iis_access"
  • En paths configuramos todos los directorios (con patterns)de logs a indexar.
  • Es necesario excluir líneas que comienzan con ‘#’. IIS comienza cada nuevo log con líneas de comentario.
  • En la sección de ES pondremos el host al que mandaremos los log.
  • Es necesario especificar el Pipeline previamente creado para que lo use.
  • Que no use templates locales (puede estar el fichero json en el directorio de configuración y cargarlo al iniciar Filebet)
  • Nombre del Template a usar (iis_access) para realizar los mapeos de los campos.

Inicia el servicio de Filebeat y verifica que inicia correctamente. Ahora lo primero será revisar el log de filebeat para ver si hay problemas

El log “filebeat.log” nos dirá algo como (si todo va bien):

2017-05-17T14:04:32+02:00 INFO States Loaded from registrar: 3
2017-05-17T14:04:32+02:00 INFO Loading Prospectors: 1
2017-05-17T14:04:32+02:00 INFO Prospector with previous states loaded: 0
2017-05-17T14:04:32+02:00 INFO Starting prospector of type: log; id: 12363095216683313965
2017-05-17T14:04:32+02:00 INFO Loading and starting Prospectors completed. Enabled prospectors: 1
2017-05-17T14:04:32+02:00 INFO Starting Registrar
2017-05-17T14:04:32+02:00 INFO Start sending events to output
2017-05-17T14:04:32+02:00 INFO Starting spooler: spool_size: 2048; idle_timeout: 5s
2017-05-17T14:04:32+02:00 INFO Harvester started for file: C:\inetpub\logs\LogFiles\....
2017-05-17T14:04:32+02:00 INFO Connected to Elasticsearch version 5.4.0

Revisar que se ha creado el Index “iis_access-*” en Elasticsearh

[root@es5 files]#  curl 'localhost:9200/_cat/indices?v'
health status index    uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open  .kibana   cy6tNq1gTUWkPOs7Lu4FFg   1   1          1            0     12.9kb         12.9kb
yellow open  iis_access-2017.05.17 uHc5ipPJRU--R9cvF6h_IQ   5   1         87            0    180.9kb        180.9kb

Configurar el “Index Pattern” en Kibana

En Kibana tenemos que configurar un nuevo “Index pattern” para ver los datos de los índices de IIS. En la sección de “Management” configuramos dicho “Index Pattern” añadiendo en el campo “Index name or pattern” el valor “iis_access-*”. Tabulamos para que nos descubra en el campo “Time-field name” nuestro “@timestamp” y aceptamos.

Elasticsearch IIS create Index pattern

Ahora podemos ir a la pestaña de “Discover” y revisar los campos disponibles de nuestro nuevo índice para realizar búsquedas y/o gráficas desde “Visualize”.
Elasticsearch IIS Index fields

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Comment moderation is enabled. Your comment may take some time to appear.