Problema de Grok con varias IP en NginX Logstash

Problema de Grok con varias IP en NginX Logstash

Tengo un problema al iniciar sesión desde mis servidores web, que tienen una capa elb y luego una capa de barniz delante de la capa nginx.

El barniz está configurado correctamente para X-Forwarded-For y los registros llegan normalmente con el 'client.ip' correcto registrado.

sin embargo, los registros de nginx llegan con una lista completa de IP en la solicitud. el comportamiento predeterminado de grok parece establecer la IP del cliente en el último lugar de la lista, es decir. los servidores elb y barniz, lo que estropea mi campo client.ip para los registros de nginx. la IP del cliente correcta debe ser la primera (o al menos las primeras) de la lista.

Aquí tienes un ejemplo:

172.31.7.219 - - [28/Sep/2015:12:39:56 +1000] "GET /api/filter/14928/content?api_key=apikey&site=website HTTP/1.1" 403 101 "-" "-" "my.website.com" "1.144.97.102, 1.144.97.102, 1.144.97.102, 127.0.0.1, 172.31.26.59"

El problema es que no he podido modificar Grok para manejar tal resultado, el depurador Heroku Grok no parece funcionar para esta consulta y mi Grok, pero están trabajando en logstash, es decir. No etiquetar el error de Grok.

Intenté depurar las partes específicas pero no encontré una manera de hacer lo que necesito con IP/IPORHOST donde hay una lista de direcciones IP separadas por comas. Necesito poder especificar qué IP debería usar. es decir. el primero en la lista debe ser client.ip, no el último.

mi nginx grok es:

NGINXACCESS %{IP:clientip} %{NGUSER:ident} %{NGUSER:auth} \[%{HTTPDATE:timestamp}\] "%{WORD:verb} %{DATA:request} HTTP/%{NUMBER:httpversion}" %{NUMBER:response} (?:%{NUMBER:bytes}|-) (?:"(?:%{URI:referrer}|-)"|%{QS:referrer})(?:;|) %{QS:agent}

¿Alguna idea sobre grok para cubrir ese registro?

Respuesta1

No estoy seguro de si todavía tienes este problema, pero si es así, esto es lo que funcionará para ti.

Dado este formato de registro:

log_format custom '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$host" "$http_x_forwarded_for"';

el patrón grok que ha especificado no tiene en cuenta la adición de la "$host" "$http_x_forwarded_for"porción.

No estoy seguro de por qué tu asimilación no falla, pero debería hacerlo.

En cualquier caso, este patrón funcionará con el formato de registro anterior:

%{IP:clientip} %{NOTSPACE:ident} %{NOTSPACE:auth} \[%{HTTPDATE:timestamp}\] "%{WORD:verb} %{DATA:request} HTTP/%{NUMBER:httpversion}" %{NUMBER:response} (?:%{NUMBER:bytes}|-) (?:"(?:%{URI:referrer}|-)"|%{QS:referrer})(?:;|) %{QS:agent} "%{NOTSPACE:host}" "(?<x_forwarded_for>%{IP:xff_clientip}, .*)"

Y resultados en los siguientes campos

httpversion      1.1
request          /api/filter/14928/content?api_key=apikey&site=website
timestamp        28/Sep/2015:12:39:56·+1000
auth             -
host             my.website.com
agent            "-"
x_forwarded_for    1.144.97.102,·1.144.97.102,·1.144.97.102,·127.0.0.1,·172.31.26.59
clientip         172.31.7.219
bytes            101
response         403
xff_clientip     1.144.97.102
ident            -
port    
verb             GET
referrer    

Tenga en cuenta que tiene un par de campos nuevos de los que habría tenido antes.

El primero ("x_forward_for" => 1.144.97.102, 1.144.97.102, 1.144.97.102, 127.0.0.1, 172.31.26.59) es el contenido del último conjunto de comillas, o $http_x_forwarded_fordel formato de registro.
El segundo ("xff_clientip" => 1.144.97.102) esjustola primera IP en esa lista, que debería traducirse a la IP de origen real de la solicitud.

Si fuera yo, también pasaría el x_forwarded_forcampo por un mutatefiltro para dividirlo en una matriz:

mutate {
  split  => { "x_forwarded_for" => ", " }
}

Respuesta2

Para la última parte, la solución de Anton Roslov solo coincidiría con las líneas de registro "ip1, ip2" y "single-ip", pero no con "ip1, ip2, ip3".
En mi humilde opinión, algo así como

(?<x_forwarded_for>%{IP:clientip}(?:, [^,]+)*)

debería funcionar. Solo revisando...

... \"(?:%{DATA:user_agent}|-)\" \"(?<x_forwarded_for>%{IP:clientip}(?:, [^,]+)*)?|-\"

o

... \"(?:%{DATA:user_agent}|-)\" \"(-|(?<x_forwarded_for>%{IP:clientip}(?:, [^,]+)*)?)\ "

debería ser tu patrón de elección. Probado en grokdebug.herokuapp.com.

información relacionada