我们使用logstash和grok过滤来预处理apache日志文件。
我们所有的机器都在负载均衡器后面,所以客户端IP会登录到“x-forwarded-for”头中。
我们的访问日志如下:

"18.32.120.32, 192.168.12.118" [07/Sep/2014:15:53:48 +0200] "GET /login HTTP/1.1" 200 137 "http://www.google.com" "Mozilla/5.0 (Windows NT 5.1; rv:32.0) Gecko/20100101 Firefox/32.0"
 "18.32.120.32, 88.32.240.21, 192.168.12.118" [07/Sep/2014:15:53:48 +0200] "GET /login HTTP/1.1" 200 137 "http://www.google.com" "Mozilla/5.0 (Windows NT 5.1; rv:32.0) Gecko/20100101 Firefox/32.0"

相应的apache日志记录指令如下所示:
LogFormat       "\"%{X-Forwarded-For}i\" %t %{Host}i \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"

如您所见,x-forwarded-for报头可以由1到3个IP地址组成,具体取决于接收请求的方式。
在logstash/grok模式中,我们将x-forwarded-for头解释为“quotedstring”:
CUSTOMLOG %{QUOTEDSTRING:xforwardedfor_header} \[%{HTTPDATE:time}\] %{HOSTNAME:host_header} \"(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})\" %{NUMBER:response} (?:%{NUMBER:bytes}|-) %{QUOTEDSTRING:http_referrer} %{QUOTEDSTRING:http_useragent}

如果我们尝试使用xforwardedfor_头字段上grok的geoip模块,地理分辨率将失败。模块不应该搜索并使用它遇到的第一个IP地址吗?
我们需要用另一种方式解释x-转发-输入吗?如果是,怎么做?
非常感谢。

最佳答案

查看geoip源代码,它确实增强了一个数组:

     ip = event[@source]
     ip = ip.first if ip.is_a? Array

所以这告诉我在xforwardedfor_头中没有数组——有一个逗号分隔的字符串……所以你只需要split它。
filter {
  split {
    field => xforwardedfor_header
    terminator => ','
  }
}

geoip过滤器修复问题之前执行此操作。

07-28 01:35
查看更多