本文参考:https://www.jianshu.com/p/cc8d592582c9 感谢分享

Netty获取真实IP

netty想要获取客户端请求的IP有两种方法:

一、通过ChannelHandlerContext

String ip=connContext.getClientIP().replace("/","").split(":")[0];

如果使用了代理,这时获取到的IP是代理服务器的IP

二、通过nginx获取真实IP

nginx对TCP协议进行代理需要引入stream模块,并修改nginx配置:

stream{upstream tcpstream{server  10.1.11.67:10001 weight=1;}server{listen 80;proxy_connect_timeout 20s;proxy_timeout 1m;# 开启代理proxy_protocol on;proxy_pass tcpstream;}error_log logs/error.log;
}

proxy protocol是HAProxy的作者Willy Tarreau于2010年开发和设计的一个Internet协议,通过为tcp添加一个很小的头信息,来方便的传递客户端信息(协议栈、源IP、目的IP、源端口、目的端口等),在网络情况复杂又需要获取用户真实IP时非常有用。其本质是在三次握手结束后由代理在连接中插入了一个携带了原始连接四元组信息的数据包。

  • 目前 proxy protocol有两个版本,v1仅支持human-readable报头格式(ASCIII码),v2需同时支持human-readable和二进制格式,即需要兼容v1格式
  • proxy protocol的接收端必须在接收到完整有效的 proxy protocol 头部后才能开始处理连接数据。因此对于服务器的同一个监听端口,不存在兼容带proxy protocol包的连接和不带proxy protocol包的连接。如果服务器接收到的第一个数据包不符合proxy protocol的格式,那么服务器会直接终止连接。

    当三次握手成功后获取到的byte数据转成16进制为:
50524f58592054435034203132372e302e302e31203132372e302e302e312036303634322038300d0a

解析结果为:

PROXY TCP4 127.0.0.1 127.0.0.1 60642 80注意结果为PROXY TCP4 127.0.0.1 127.0.0.1 60642 80\r\n
所以上面会换行

解析代码

以上是解析只有一层代理的,如果两层代理得到的数据有是什么样的呢?

50524f585920544350342031302e312e31312e36362031302e312e31312e36382035333732382038300d0a50524f585920544350342031302e312e352e32372031302e312e31312e36362036353431312038300d0a

解析出来的结果是:

获取到数据PROXY TCP4 10.1.11.66 10.1.11.68 53728 80PROXY TCP4 10.1.5.27 10.1.11.66 65411 80

解析代码

public class MessageDecoder extends ByteToMessageDecoder {protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws Exception {log.info("收到数据:{},{}",ctx.channel().id(),ByteBufUtil.hexDump(buffer));if(buffer.readableBytes() < ProtocolDataHead.LENGTH){return;}//protocol headProtocolDataHead header = ProtocolDataHead.fromData(ByteBufUtil.getBytes(buffer,0,ProtocolDataHead.LENGTH));if(header.getStartMark().equals(ProtocolDataHead.STARTMARK)){//本公司业务代码,不展示} else if(header.getStartMark().equals(NginxIPConst.NGINX_IP_TWO)){if(buffer.readableBytes()<NginxIPConst.NGINX_IP_LENGTH){return;}String readData=ByteBufUtil.hexDump(buffer);log.info("收到nginx消息:{}",ByteBufUtil.hexDump(buffer));if(readData.indexOf(NginxIPConst.NGINX_IP_END)>0){byte[] nginxIP=new byte[readData.indexOf(NginxIPConst.NGINX_IP_END)/2+2];buffer.readBytes(nginxIP);NginxUtils.checkHead(ctx.channel().id().toString(),nginxIP);return;}else{buffer.clear();}}else{log.info("收到数据错误:{}",ByteBufUtil.hexDump(buffer));buffer.clear();return;}}
}
public class NginxUtils {private static ConcurrentHashMap<String,String> ipMap=new ConcurrentHashMap<>(1000);public static void checkHead(String channelId,byte[] bytes){String nginxIP=new String(bytes, Charset.forName("UTF-8"));log.info("获取到数据{}",nginxIP);String[] strs=nginxIP.split(" ");if(strs.length>2){ipMap.put(channelId,strs[2]);}}public static String getIp(String channelId){return ipMap.get(channelId);}public static String removeIp(String channelId){return ipMap.remove(channelId);}
}
public class NginxIPConst {//nginx透传ip最小长度public static final int NGINX_IP_LENGTH = 41;//nginx透传ip前两位数据public static final String NGINX_IP_TWO = "PR";//nginx结尾符public static final String NGINX_IP_END = "0d0a";
}

Netty获取真实IP相关推荐

  1. 老大说,网上这种获取真实IP地址的方法不对,我不信...

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:蔡永吉  来源:http://bit.ly/33H8RMm ...

  2. nodejs+nginx获取真实ip

    nodejs + nginx获取真实ip分为两部分: 第一.配置nginx: 第二.通过nodejs代码获取: 其他语言也是一样的,都是配置nginx之后,在http头里面获取"x-forw ...

  3. nginx 后端获取真实ip

    nginx前端配置 server { listen 80; server_name blog.jinchuang.org; access_log logs/blog.access.log; error ...

  4. nginx 日志格式设置 和 负载均衡下 获取真实ip

    log_format log 格式   '配置规则'; 日志格式设置: $remote_addr与$http_x_forwarded_for用以记录客户端的ip地址: $remote_user:用来记 ...

  5. php负载均衡如何获得真实ip,nginx负载均衡后端RS中获取真实ip

    nginx负载均衡后端RS中获取真实ip 前端proxy配置 #################### worker_processes  1; events { worker_connections ...

  6. 502 proxy error解决方法_老大说,网上这种获取真实IP地址的方法不对,我不信......

    作者:蔡永吉  来源:http://bit.ly/33H8RMm想必大家对这段代码并不陌生: public String getIpAddr(HttpServletRequest request) { ...

  7. spring cloud gateway获取真实ip以及跨服务器时路由转发的一些问题

    springCloud主版本Greenwitch SR2  gateway版本2.1.2 网上大多教程是添加如下一段代码,然后就可以在网关拿到真实路由ip而不是路由id 但是网上教程杂七杂八,我也不记 ...

  8. java获取真实ip的方法

    在网络中,如果不想被人监听,那么就需要获取 IP地址了,在电脑中我们可以使用到 ip地址获取工具,那么如何在 Java中获取真实的 IP地址呢? 1.首先我们需要先准备一台电脑,然后将电脑进行联网: ...

  9. Java获取真实Ip地址

    目录 一.工具类代码 二.ip伪造解决 一.工具类代码 /*** 获取Ip** @param request 请求*/public static String getIpRequest(HttpSer ...

最新文章

  1. 奖客富翁系统python_作业 2018-12-28 20.1 奖客富翁
  2. [转]MyBatis的foreach语句详解
  3. 绝对定位和浮动的区别和运用
  4. h5 在线语音识别接口
  5. IDL | 实验一、IDL编码与运行
  6. TensorFlow :HelloWorld
  7. 高中信息技术python教材内容_高中信息技术教材 掌控基础版
  8. SRE 到底是什么?
  9. Mac下7z格式文件解压
  10. java四大名著知乎_《西游记》是否被高估了?四大名著该如何排名?
  11. 分享几个IP获取地理位置的API接口
  12. 如何把canvas元素作为网站背景总结详解
  13. 详细Ubuntu系统下搭建Hadoop完全分布式
  14. 使用Visual Studio Code 进行Python编程(二)-print、if、for的用法
  15. 【百度点石(WSDM)】 Retention Rate of Baidu Hao Kan APP Users 小白经验分享
  16. 获取你想要的微信公众号推文的封面图
  17. 1.什么是bat文件
  18. django 压缩文件下载
  19. 利用Python对电商销售数据进行分析
  20. 如何设置敬业签定时提醒待办事项?

热门文章

  1. java判断总共天数_java判断两个时间相差得天数
  2. 学习编程第一章 `大数据应用` linux系统jdk安装
  3. python版本升级
  4. 统计信号处理知识点总结_概率论与数理统计之二维离散性随机变量及其分布的知识点总结...
  5. 查看自己电脑上的机器码教材
  6. 初学java 第一个java程序 坦克大战单机版
  7. python查看目录是否存在_如何检查Python中是否存在文件或目录
  8. if函数python_python pandas实现excel中的if 函数(一)
  9. SAAS应用灰度设计
  10. agc044 c Strange Dance