!52 修改TcpVisitorHandler获取真实IP地址的方式

Merge pull request !52 from NichenFly/dev
This commit is contained in:
傲世孤尘
2023-12-09 14:35:26 +00:00
committed by Gitee
2 changed files with 38 additions and 4 deletions
@@ -1,5 +1,6 @@
package org.dromara.neutrinoproxy.core.util;
import cn.hutool.core.net.Ipv4Util;
import io.netty.channel.ChannelHandlerContext;
import java.net.InetSocketAddress;
@@ -15,4 +16,33 @@ public class IpUtil extends org.noear.solon.core.util.IpUtil {
return remoteAddress;
}
/**
* 工作原理为从http协议的header中找公网地址,此主要用于处理nginx转发时塞进去的真实IP的header,找不到返回null
* @param httpContent http协议文档内容
* @return 返回找到的第一个公网地址
*/
public static String getRealRemoteIp(String httpContent) {
String headerContent = httpContent.split("\r\n\r\n")[0];
String[] lines = headerContent.split("\r\n");
String firstLine = lines[0];
if (!(firstLine.endsWith("HTTP/1.1") || firstLine.endsWith("HTTP/1.0"))) {
return null;
}
for (int i = 1; i < lines.length; i++) {
String line = lines[i];
// 匹配有ipv4地址格式的header
if (!line.matches(".*(\\d+\\.){3}\\d+")) {
continue;
}
// 截取IP地址
String ip = line.substring(line.charAt(':'));
if (!Ipv4Util.isInnerIP(ip)) {
return ip;
}
}
return null;
}
}
@@ -77,7 +77,8 @@ public class HttpVisitorChannelHandler extends SimpleChannelInboundHandler<ByteB
// 用户连接到代理服务器时,设置用户连接不可读,等待代理后端服务器连接成功后再改变为可读状态
ctx.channel().config().setOption(ChannelOption.AUTO_READ, false);
String host = getHost(bytes);
String httpContent = new String(bytes);
String host = getHost(httpContent);
log.debug("HttpProxy host: {}", host);
if (StringUtils.isBlank(host)) {
ctx.channel().close();
@@ -98,7 +99,11 @@ public class HttpVisitorChannelHandler extends SimpleChannelInboundHandler<ByteB
}
// 判断IP是否在该端口绑定的安全组允许的规则内
if (!securityGroupService.judgeAllow(IpUtil.getRemoteIp(ctx), portMappingService.getSecurityGroupIdByMappingPort(serverPort))) {
String ip = IpUtil.getRealRemoteIp(httpContent);
if (ip == null) {
ip = IpUtil.getRemoteIp(ctx);
}
if (!securityGroupService.judgeAllow(ip, portMappingService.getSecurityGroupIdByMappingPort(serverPort))) {
// 不在安全组规则放行范围内
ctx.channel().close();
return;
@@ -167,8 +172,7 @@ public class HttpVisitorChannelHandler extends SimpleChannelInboundHandler<ByteB
ctx.close();
}
private String getHost(byte[] buf) {
String req = new String(buf);
private String getHost(String req) {
String[] lines = req.split("\r\n");
String firstLine = lines[0];
if (!(firstLine.endsWith("HTTP/1.1") || firstLine.endsWith("HTTP/1.0"))) {