Nginx多級代理,獲取客戶端真實請求IP以及每級代理IP前端
如圖所示,每一級nginx裏的location配置裏須要加上對應的配置,最後一級nginx是直接到應用,測試時爲了方便,直接用echo模塊去測試,打印IP地址。nginx
原理分析:測試
只有客戶端直接請求到的那個nginx可以拿到客戶端的真實IP,因此第一級nginx配置了代理
proxy_set_header X-Real-IP $remote_addr;blog
這個配置就會將客戶端IP放到http的header裏,這樣到最後的應用裏能夠經過request.getHeader去拿到客戶端真實IP了遞歸
public String getRemoteIp() {
String ip = request.getHeader("X-Forwarded-For");
if (isEffective(ip) && ip.indexOf(",") > -1) {
String[] array = ip.split(",");
for (String str : array) {
if (isEffective(str)) {
ip = str;
break;
}
}
}
if (!isEffective(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (!isEffective(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (!isEffective(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (!isEffective(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (!isEffective(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
private boolean isEffective(String remoteAddr) {
if ((null != remoteAddr) && (!"".equals(remoteAddr.trim()))
&& (!"unknown".equalsIgnoreCase(remoteAddr.trim()))) {
return true;
}
return false;
}
如何拿到用戶從請求源頭到應用所通過的各個代理IP呢?
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
經過如上配置,將每級代理IP與$remote_addr用逗號分隔開ip
因此從上述狀況來看,總體的流程很清晰了:ssl
客戶端請求(172.23.11.251) -->172.23.26.130-->172.23.26.132-->172.23.26.133-->172.23.30.100(具體應用)rem
可是咱們發現上面IP貌似打印少了一個133的地址,咱們在100上修改下echo測試get
這裏打印出了133的地址
nginx的安裝包裏有一個http_realip_module模塊,在編譯的時候能夠編譯此模塊
./configure --prefix=/home/nginx/install --with-pcre=../pcre-8.36 --with-zlib=../zlib-1.2.8 --with-openssl=../openssl-1.0.2 --add-module=/root/nginx/echo-nginx-module-0.60 --with-http_realip_module && make && make install
新的配置以下:
set_real_ip_from 172.23.0.0/16; IP段,指定接收來自哪一個前端發送的 IP head 能夠是單個IP或者IP段
set_real_ip_from 192.168.1.1; 單個IP
real_ip_header X-Real-IP; IP head 的對應參數,默認便可,含義是客戶端真實IP從哪一個頭取?
real_ip_recursive on; 是否遞歸解析real_ip_header