NginX Logstash의 다중 IP 관련 Grok 문제

NginX Logstash의 다중 IP 관련 Grok 문제

elb가 있고 nginx 레이어 앞에 광택 레이어가 있는 웹 서버에서 로깅하는 데 문제가 있습니다.

X-Forwarded-For에 대해 varnish가 올바르게 설정되었으며 올바른 'client.ip'가 기록되면서 로그가 정상적으로 전달됩니다.

그러나 nginx 로그는 요청의 전체 IP 목록과 함께 제공됩니다. 기본 grok 동작은 클라이언트 IP를 목록의 마지막으로 설정하는 것 같습니다. nginx 로그에 대한 내 client.ip 필드를 엉망으로 만드는 elb 및 varnish 서버. 올바른 클라이언트 IP는 목록의 첫 번째(또는 최소한 처음 몇 개)에 있어야 합니다.

예를 들면 다음과 같습니다.

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"

문제는 그런 결과를 처리하기 위해 grok을 조정할 수 없다는 것입니다. heroku grok 디버거는 이 쿼리와 내 grok에 대해 작동하지 않는 것 같습니다. 하지만 그들은 logstash에서 작동하고 있습니다. grok 실패에 태그를 지정하지 않습니다.

특정 부분을 디버깅하려고 시도했지만 쉼표로 구분된 IP 주소 목록이 있는 IP/IPORHOST에 필요한 작업을 수행하는 방법을 찾지 못했습니다. 어떤 IP를 사용해야 하는지 지정할 수 있어야 합니다. 즉. 목록의 첫 번째는 마지막이 아닌 client.ip여야 합니다.

내 nginx grok은 다음과 같습니다.

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}

해당 로그를 다룰 grok에 대한 아이디어가 있나요?

답변1

여전히 이 문제가 발생하는지 확실하지 않지만, 그렇다면 다음 방법을 따르세요.

다음 로그 형식을 고려하면:

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

지정한 grok 패턴은 해당 "$host" "$http_x_forwarded_for"부분의 추가를 고려하지 않습니다.

왜 grok이 실패하지 않는지 잘 모르겠지만 그래야 합니다.

어쨌든 이 패턴은 위의 로그 형식에서 작동합니다.

%{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}, .*)"

결과는 다음과 같습니다.

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    

이전보다 몇 가지 새로운 필드가 생겼습니다.

첫 번째("x_forward_for" => 1.144.97.102, 1.144.97.102, 1.144.97.102, 127.0.0.1, 172.31.26.59)는 마지막 따옴표 세트의 내용이거나 $http_x_forwarded_for로그 형식의 내용입니다.
두 번째("xff_clientip" => 1.144.97.102)는단지해당 목록의 첫 번째 IP는 요청의 실제 소스 IP로 변환되어야 합니다.

저라면 필터를 x_forwarded_for통해 필드 를 실행하여 mutate배열로 나눌 수도 있습니다.

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

답변2

마지막 부분의 경우 Anton Roslov의 솔루션은 "ip1, ip2" 및 "single-ip" 로그 줄만 일치하고 "ip1, ip2, ip3"은 일치하지 않습니다.
IMHO 같은 것

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

트릭을 수행해야합니다. 그냥 확인하는 중...

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

또는

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

당신이 선택한 패턴이 되어야 합니다. grokdebug.herokuapp.com에서 테스트되었습니다.

관련 정보