應用獲取客戶端IP小結

應用獲取客戶端IP的3種形式

  • 通過request.getRemoteAddr()
    這是最官方的獲取客戶端IP的方法,但當請求經過代理服務器後,這個方法返回的是代理服務器的IP. 所以我們線上通過這個方法取到的是nginx的IP: 127.0.0.1

     request.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_IP

    public 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。

相關資料

X-Forwarded-For

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章