我在從我的網站伺服器進行日誌記錄時遇到了問題,該伺服器有一個 elb,然後在 nginx 層前面有一個清漆層。
清漆已為 X-Forwarded-For 設定正確,並且日誌正常通過,並記錄了正確的“client.ip”。
但是,nginx 日誌會在請求中包含完整的 IP 清單。預設的 grok 行為似乎將客戶端 IP 設定為清單中的最後一個,即。 elb 和 varnish 伺服器,這會弄亂我的 nginx 日誌的 client.ip 欄位。正確的客戶端 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 ie 中工作。不標記 grok 失敗。
我已經嘗試調試特定部分,但我還沒有找到一種方法來使用 IP/IPORHOST 執行我需要的操作,其中有一個以逗號分隔的 IP 位址清單。我需要能夠指定它應該使用哪個IP。 IE。清單中的第一個應該是 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」。
恕我直言,類似的東西
(?<x_forwarded_for>%{IP:clientip}(?:, [^,]+)*)
應該可以解決問題。只是檢查...
... \"(?:%{DATA:user_agent}|-)\" \"(?<x_forwarded_for>%{IP:clientip}(?:, [^,]+)*)?|-\"
或者
... \"(?:%{DATA:user_agent}|-)\" \"(-|(?<x_forwarded_for>%{IP:clientip}(?:, [^,]+)*)?)\ 」
應該是您選擇的模式。在 grokdebug.herokuapp.com 中測試。