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_for
del 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_for
campo por un mutate
filtro 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.