應用獲取客戶端IP的3種形式
-
通過request.getRemoteAddr()
這是最官方的獲取客戶端IP的方法,但當請求經過代理服務器後,這個方法返回的是代理服務器的IP. 所以我們線上通過這個方法取到的是nginx的IP: 127.0.0.1request.getRemoteAddr()
-
通過X-Forwarded-For http頭
X-Forwarded-For 不是在http協議裏定義的,所以request的默認實現是不用X-Forwarded-For取IP的。最早是由Squid的開發引入的。 請求經過代理服務器後,代理服務器會把客戶端IP和自己的IP放在X-Forwarded-For頭中,並與逗號隔開。也就是說每經過一個代理服務器,這個頭中會多加一個IP。 Web程序通過獲取這個HTTP頭來取得客戶端的IP。 這是目前我們獲取客戶端IP的方法。也有一些代碼服務器會用ORIG_CLIENT_IPpublic static String getRemoteIp(HttpServletRequest request) { String ip = null; if (request.getHeader("ORIG_CLIENT_IP") != null) { ip = request.getHeader("ORIG_CLIENT_IP"); } if (ip == null && request.getHeader("x-forwarded-for") != null) { ip = request.getHeader("x-forwarded-for"); if (ip != null) { ip = ip.split("\\s*,\\s*")[0]; } } if (ip == null) { ip = request.getRemoteAddr(); } return ip; }
-
通過程序來獲取
並不是所有的代理服務器都會加X-Forwarded-For這個HTTP頭。所以爲了獲取客戶端真實的IP,有些網站會通過插件等形式來更準確的獲取客戶端IP。
webx中取客戶端IP
-
爲什麼在webx中還是能通過request.getRemoteAddr()取到代理過的客戶端IP?
在Webx中,當配置了ResourcesFilter後,在ResourcesFilter中會把request包裝一下,並在包裝類中重寫了getRemoteAddr方法。重寫後會加上從x-forwarded-for中取IP。
線上應用取不到IP的故障原因分析。
-
PE在改nginx時沒有加x-forwarded-for的頭,導致應用取不到客戶端IP,取出來的是nginx代理機的IP,即127.0.0.1。 同時應用有對同一IP發送郵件數有限制,最後導致郵件發不出去。
-
當故障發生後,爲什麼內網綁轉發平臺無法重現問題?
內網綁轉發平臺後發出的請求,已經經過了代理服務器,並且該代理服務器已經爲請求加上了x-forwarded-for的頭,所以就算應用的nginx上沒有加,應用取到的IP也不會是127.0.0.1。(雖然通過抓包工具看到轉發平臺加在x-forwarded-for頭裏的IP並不是真正客戶端IP)
通過CSP引流模式做壓測時,取客戶端IP會受影響嗎?
- CSP引渡壓測只是通過proxy_pass把流量導到目標機上。而客戶端IP只和x-forwarded-for頭有關,所以引流壓測不會影響取客戶端IP。