location /gameExchange {
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://gameExchange;
proxy_set_header Host $http_host;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_connect_timeout 4; #nginx跟后端服务器连接超时时间(代理连接超时)
#proxy_read_timeout 4; #连接成功后,后端服务器响应时间(代理接收超时)
}
nginx log 格式:
log_format main '$remote_addr [$time_local] request_time[$request_time] upto $upstream_addr,'
'upresponse_time[$upstream_response_time], "$request" $status $body_bytes_sent '
'"$http_user_agent"';
nginx 中如上配置,查看access.log发现$remote_addr打印出来都是内网地址
java 程序获取真实IP代码如下:
public static String getRequestIP(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip ==null || ip.length() ==0 ||"unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip ==null || ip.length() ==0 ||"unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip ==null || ip.length() ==0 ||"unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
//多次反向代理,取第一个IP地址
if (ip !=null && ip.length() >15) {
if (ip.indexOf(",") >0) {
ip = ip.substring(0, ip.indexOf(","));
}
}
return ip;
}
调用无法获取真实的IP
解决办法: 把$remote_addr替换成$http_x_forwarded_for
location /gameExchange {
proxy_set_header X-Real-IP $http_x_forwarded_for;
proxy_pass http://gameExchange;
proxy_set_header Host $http_host;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_connect_timeout 4; #nginx跟后端服务器连接超时时间(代理连接超时)
#proxy_read_timeout 4; #连接成功后,后端服务器响应时间(代理接收超时)
}
log_format main '$http_x_forwarded_for [$time_local] request_time[$request_time] upto $upstream_addr,'
'upresponse_time[$upstream_response_time], "$request" $status $body_bytes_sent '
'"$http_user_agent"';
原因:nginx层前面还经过层F5负载均衡,
其中$http_x_forwarded_for就是nginx接受到的http request header中的X-Forwarded-For的值
$remote_addr是直接与nginx通信的那台主机的ip。nginx层前面还经过层F5负载均衡,所以$remote_addr的地址成了内网地址