問題背景:html
在使用nginx服務器NginxA 來反向代理服務 WebAPIA,WebAPIA中要獲取ClientIP,結果獲取到的IP爲NginxA的, 因而引出瞭如下的一連串概念。。。java
首先使用XFF來解決proxy中的ClientIP的記錄,同時具體瞭解一下正向與反向的區別。最後介紹正向代理Squid。nginx
XFF:X-Forwarded-For。用於記錄代理信息的,每通過一級代理(匿名代理除外),代理服務器都會把此次請求的來源IP追加在X-Forwarded-For。第一個則爲真實客戶端的地址。web
EG:收到一個來自4.4.4.4的請求,header包含這樣一行服務器
X-Forwarded-For: 1.1.1.1, 2.2.2.2, 3.3.3.3
表示請求由1.1.1.1發出,通過三層代理,第一層是2.2.2.2,第二層是3.3.3.3,而本次請求的來源IP4.4.4.4是第三層代理網絡
代碼片斷:java獲取客戶端真實IPui
public class HttpInfoReader { /** * 獲取當前網絡ip * @param request * @return */ public String getClientIPAddress(HttpServletRequest request){ String ipAddress = request.getHeader("x-forwarded-for"); if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getHeader("Proxy-Client-IP"); } if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getHeader("WL-Proxy-Client-IP"); } if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getRemoteAddr(); if(ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")){ //根據網卡取本機配置的IP InetAddress inet=null; try { inet = InetAddress.getLocalHost(); } catch (UnknownHostException e) { e.printStackTrace(); } ipAddress= inet.getHostAddress(); } } //對於經過多個代理的狀況,第一個IP爲客戶端真實IP,多個IP按照','分割 if(ipAddress!=null && ipAddress.length()>15){ //"***.***.***.***".length() = 15 if(ipAddress.indexOf(",")>0){ ipAddress = ipAddress.substring(0,ipAddress.indexOf(",")); } } return ipAddress; } }
Ref:.net
Ref:代理
Squid是一種用來緩衝Internet數據的軟件。它是這樣實現其功能的,接受來自人們須要下載的目標(object)的請求並適當地處理這些請求。也就是說,若是一我的想下載一web頁面,他請求Squid爲他取得這個頁面。Squid隨之鏈接到遠程服務器(好比:http://squid.nlanr.net/)並向這個頁面發出請求。而後,Squid顯式地彙集數據到客戶端機器,並且同時複製一份。當下一次有人須要同一頁面時,Squid能夠簡單地從磁盤中讀到它,那樣數據迅即就會傳輸到客戶機上。當前的Squid能夠處理HTTP,FTP,GOPHER,SSL和WAIS等協議。但它不能處理如POP,NNTP,RealAudio以及其它類型的東西。code