[fix] 添加客户端渗透服务端

This commit is contained in:
wujiawei
2024-09-18 22:03:31 +08:00
parent 2166a1eee6
commit 138752e56d
20 changed files with 689 additions and 104 deletions

View File

@ -45,6 +45,15 @@ public class HeartbeatClientConfiguration {
public ClientHandleDistributeSingleClientMessageTypeAdvanced handleDistributeSingleClientMessageTypeAdvanced() {
return new ClientHandleDistributeSingleClientMessageTypeAdvanced();
}
/**
* 处理 客户端渗透服务端数据传输通道连接成功
*
* @return ClientHandleDistributeClientTransferServerPermeateChannelConnectionSuccessfulTypeAdvanced
*/
@Bean
public ClientHandleDistributeClientTransferServerPermeateChannelConnectionSuccessfulTypeAdvanced clientHandleDistributeClientTransferServerPermeateChannelConnectionSuccessfulTypeAdvanced() {
return new ClientHandleDistributeClientTransferServerPermeateChannelConnectionSuccessfulTypeAdvanced();
}
@Bean
public ClientHandleDistributeSingleClientRealCloseVisitorTypeAdvanced handleDistributeSingleClientRealCloseVisitorTypeAdvanced() {

View File

@ -0,0 +1,53 @@
package org.framework.lazy.cloud.network.heartbeat.client.netty;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.Accessors;
import org.framework.lazy.cloud.network.heartbeat.client.config.NettyClientProperties;
import org.framework.lazy.cloud.network.heartbeat.common.InternalNetworkPermeate;
import org.framework.lazy.cloud.network.heartbeat.common.adapter.ChannelFlowAdapter;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.HandleChannelTypeAdvanced;
import java.util.List;
@Builder
@Accessors(chain = true)
@Data
public class InternalNetworkPermeateServerVisitor implements InternalNetworkPermeate {
/**
* 目标地址
*/
private String targetIp;
/**
* 目标端口
*/
private Integer targetPort;
/**
* 访问端口
*/
private Integer visitorPort;
/**
* 流量适配器
*/
private ChannelFlowAdapter channelFlowAdapter;
/**
* 服务端地址信息
*/
private NettyClientProperties nettyClientProperties;
/**
* 通道处理器
*/
private List<HandleChannelTypeAdvanced> handleChannelTypeAdvancedList;
/**
* 访客ID
*/
private String visitorId;
}

View File

@ -0,0 +1,43 @@
package org.framework.lazy.cloud.network.heartbeat.client.netty.advanced;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.client.netty.handler.NettyClientPermeateServerVisitorHandler;
import org.framework.lazy.cloud.network.heartbeat.client.netty.socket.NettyClientTransferServerSocket;
import org.framework.lazy.cloud.network.heartbeat.common.NettyProxyMsg;
import org.framework.lazy.cloud.network.heartbeat.common.NettyRealIdContext;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.client.AbstractHandleDistributeClientTransferServerPermeateChannelConnectionSuccessfulTypeAdvanced;
import org.framework.lazy.cloud.network.heartbeat.common.enums.MessageTypeEnums;
/**
* 客户端渗透服务端数据传输通道连接成功
* @see NettyClientTransferServerSocket
* @see NettyClientPermeateServerVisitorHandler
*
* @see MessageTypeEnums#DISTRIBUTE_CLIENT_TRANSFER_SERVER_PERMEATE_CHANNEL_CONNECTION_SUCCESSFUL
*/
@Slf4j
public class ClientHandleDistributeClientTransferServerPermeateChannelConnectionSuccessfulTypeAdvanced extends AbstractHandleDistributeClientTransferServerPermeateChannelConnectionSuccessfulTypeAdvanced<NettyProxyMsg> {
/**
* 处理当前数据
*
* @param channel 当前通道
* @param nettyProxyMsg 通道数据
*/
@Override
public void doHandler(Channel channel, NettyProxyMsg nettyProxyMsg) {
// 连接成功 开启自动读取写
byte[] msgVisitorId = nettyProxyMsg.getVisitorId();
String visitorId = new String(msgVisitorId);
Channel visitor = NettyRealIdContext.getReal(visitorId);
visitor.config().setOption(ChannelOption.AUTO_READ, true);
}
}

View File

@ -5,18 +5,17 @@ import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import org.framework.lazy.cloud.network.heartbeat.client.netty.handler.NettyClientVisitorHandler;
import org.framework.lazy.cloud.network.heartbeat.common.InternalNetworkPenetrationRealClient;
import org.framework.lazy.cloud.network.heartbeat.common.adapter.ChannelFlowAdapter;
import org.framework.lazy.cloud.network.heartbeat.client.netty.InternalNetworkPermeateServerVisitor;
import org.framework.lazy.cloud.network.heartbeat.client.netty.handler.NettyClientPermeateServerVisitorHandler;
import org.framework.lazy.cloud.network.heartbeat.common.filter.DebugChannelInitializer;
public class NettyClientVisitorFilter extends DebugChannelInitializer<SocketChannel> {
private final InternalNetworkPenetrationRealClient internalNetworkPenetrationRealClient;
private final ChannelFlowAdapter channelFlowAdapter;
public class NettyClientPermeateServerVisitorFilter extends DebugChannelInitializer<SocketChannel> {
private final InternalNetworkPermeateServerVisitor internalNetworkPermeateServerVisitor;
public NettyClientPermeateServerVisitorFilter(InternalNetworkPermeateServerVisitor internalNetworkPermeateServerVisitor) {
this.internalNetworkPermeateServerVisitor = internalNetworkPermeateServerVisitor;
public NettyClientVisitorFilter(InternalNetworkPenetrationRealClient internalNetworkPenetrationRealClient, ChannelFlowAdapter channelFlowAdapter) {
this.internalNetworkPenetrationRealClient = internalNetworkPenetrationRealClient;
this.channelFlowAdapter = channelFlowAdapter;
}
/**
@ -32,6 +31,6 @@ public class NettyClientVisitorFilter extends DebugChannelInitializer<SocketChan
protected void initChannel0(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new ChannelDuplexHandler());
pipeline.addLast(new NettyClientVisitorHandler(internalNetworkPenetrationRealClient, channelFlowAdapter));
pipeline.addLast(new NettyClientPermeateServerVisitorHandler(internalNetworkPermeateServerVisitor));
}
}

View File

@ -0,0 +1,43 @@
package org.framework.lazy.cloud.network.heartbeat.client.netty.filter;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import org.framework.lazy.cloud.network.heartbeat.client.netty.handler.NettyClientPermeateTransferHandler;
import org.framework.lazy.cloud.network.heartbeat.client.netty.handler.NettyClientVisitorRealHandler;
import org.framework.lazy.cloud.network.heartbeat.common.adapter.ChannelTypeAdapter;
import org.framework.lazy.cloud.network.heartbeat.common.decoder.NettyProxyMsgDecoder;
import org.framework.lazy.cloud.network.heartbeat.common.encoder.NettyProxyMsgEncoder;
import org.framework.lazy.cloud.network.heartbeat.common.filter.DebugChannelInitializer;
/**
* netty 客户端渗透通信通道
*/
public class NettyClientPermeateTransferFilter extends DebugChannelInitializer<SocketChannel> {
private final ChannelTypeAdapter channelTypeAdapter;
public NettyClientPermeateTransferFilter(ChannelTypeAdapter channelTypeAdapter) {
this.channelTypeAdapter = channelTypeAdapter;
}
/**
* This method will be called once the {@link Channel} was registered. After the method returns this instance
* will be removed from the {@link ChannelPipeline} of the {@link Channel}.
*
* @param ch the {@link Channel} which was registered.
* @throws Exception is thrown if an error occurs. In that case it will be handled by
* {@link #exceptionCaught(ChannelHandlerContext, Throwable)} which will by default connectionClose
* the {@link Channel}.
*/
@Override
protected void initChannel0(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
// // 解码、编码
// pipeline.addLast(new NettyProxyMsgDecoder(Integer.MAX_VALUE, 0, 4, -4, 0));
// pipeline.addLast(new NettMsgEncoder());
pipeline.addLast(new NettyProxyMsgDecoder(Integer.MAX_VALUE, 0, 4, -4, 0));
pipeline.addLast(new NettyProxyMsgEncoder());
pipeline.addLast(new NettyClientPermeateTransferHandler(channelTypeAdapter));
}
}

View File

@ -8,24 +8,37 @@ import io.netty.channel.ChannelOption;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.common.*;
import org.framework.lazy.cloud.network.heartbeat.common.adapter.ChannelFlowAdapter;
import org.framework.lazy.cloud.network.heartbeat.client.netty.InternalNetworkPermeateServerVisitor;
import org.framework.lazy.cloud.network.heartbeat.client.netty.advanced.ClientHandleDistributeClientTransferServerPermeateChannelConnectionSuccessfulTypeAdvanced;
import org.framework.lazy.cloud.network.heartbeat.client.netty.socket.NettyClientTransferServerSocket;
import org.framework.lazy.cloud.network.heartbeat.common.MessageType;
import org.framework.lazy.cloud.network.heartbeat.common.NettyCommunicationIdContext;
import org.framework.lazy.cloud.network.heartbeat.common.NettyProxyMsg;
import org.framework.lazy.cloud.network.heartbeat.common.NettyRealIdContext;
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
import org.wu.framework.core.utils.ObjectUtils;
import java.util.UUID;
@Slf4j
public class NettyClientVisitorHandler extends SimpleChannelInboundHandler<ByteBuf> {
private final InternalNetworkPenetrationRealClient internalNetworkPenetrationRealClient;
private final ChannelFlowAdapter channelFlowAdapter;// 流量适配器
public class NettyClientPermeateServerVisitorHandler extends SimpleChannelInboundHandler<ByteBuf> {
private final InternalNetworkPermeateServerVisitor internalNetworkPermeateServerVisitor;
// private final ChannelFlowAdapter channelFlowAdapter;// 流量适配器
// private final NettyChannelPool nettyChannelPool = new DefaultNettyChannelPool(10);
public NettyClientVisitorHandler(InternalNetworkPenetrationRealClient internalNetworkPenetrationRealClient, ChannelFlowAdapter channelFlowAdapter) {
this.internalNetworkPenetrationRealClient = internalNetworkPenetrationRealClient;
this.channelFlowAdapter = channelFlowAdapter;
public NettyClientPermeateServerVisitorHandler(InternalNetworkPermeateServerVisitor internalNetworkPermeateServerVisitor) {
this.internalNetworkPermeateServerVisitor = internalNetworkPermeateServerVisitor;
// this.channelFlowAdapter = channelFlowAdapter;
}
/**
* @param ctx
* @throws Exception
* @see NettyClientTransferServerSocket
* @see ClientHandleDistributeClientTransferServerPermeateChannelConnectionSuccessfulTypeAdvanced
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
// 访客连接上代理服务器了
@ -36,41 +49,16 @@ public class NettyClientVisitorHandler extends SimpleChannelInboundHandler<ByteB
// 生成访客ID
String visitorId = UUID.randomUUID().toString();
String clientId = internalNetworkPenetrationRealClient.getClientId();
Integer visitorPort = internalNetworkPenetrationRealClient.getVisitorPort();
String clientTargetIp = internalNetworkPenetrationRealClient.getClientTargetIp();
Integer clientTargetPort = internalNetworkPenetrationRealClient.getClientTargetPort();
// 绑定访客真实通道
NettyRealIdContext.pushReal(visitorChannel, visitorId);
// 当前通道绑定访客ID
ChannelAttributeKeyUtils.buildVisitorId(visitorChannel, visitorId);
ChannelAttributeKeyUtils.buildClientId(visitorChannel, clientId);
NettyProxyMsg nettyProxyMsg = new NettyProxyMsg();
nettyProxyMsg.setType(MessageType.DISTRIBUTE_SINGLE_CLIENT_REAL_CONNECT);
nettyProxyMsg.setClientId(clientId);
nettyProxyMsg.setVisitorPort(visitorPort);
nettyProxyMsg.setClientTargetIp(clientTargetIp);
nettyProxyMsg.setClientTargetPort(clientTargetPort);
nettyProxyMsg.setVisitorId(visitorId);
internalNetworkPermeateServerVisitor.setVisitorId(visitorId);
// 判断是否有可用的通道 如果没有创建新的通道
// Channel transferChannel = nettyChannelPool.availableChannel(visitorId);
// if (transferChannel == null) {
// 客户端心跳通道
ChannelContext.ClientChannel clientChannel = ChannelContext.get(clientId);
if (clientChannel != null) {
log.info("通过客户端:{},获取通道而后创建连接", clientId);
Channel channel = clientChannel.getChannel();
channel.writeAndFlush(nettyProxyMsg);
} else {
log.error("客户端:【{}】已经下线无法通过客户端ID获取客户端通道", clientId);
}
// }
// 等待访客ID传输到客户端后绑定客户端真实服务后开启
// 创建访客连接服务端通道
NettyClientTransferServerSocket.buildTransferServer(internalNetworkPermeateServerVisitor);
log.info("服务端访客端口连接成功了");
super.channelActive(ctx);
}
@ -80,32 +68,20 @@ public class NettyClientVisitorHandler extends SimpleChannelInboundHandler<ByteB
// 访客通道
Channel visitorChannel = ctx.channel();
String clientId = internalNetworkPenetrationRealClient.getClientId();
String clientTargetIp = internalNetworkPenetrationRealClient.getClientTargetIp();
Integer clientTargetPort = internalNetworkPenetrationRealClient.getClientTargetPort();
Integer visitorPort = internalNetworkPenetrationRealClient.getVisitorPort();
String visitorId = ChannelAttributeKeyUtils.getVisitorId(visitorChannel);
if (StringUtil.isNullOrEmpty(clientId)) {
return;
}
Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(visitorChannel);
byte[] bytes = new byte[buf.readableBytes()];
buf.readBytes(bytes);
// 获取客户端通道而后进行数据下发
log.debug("【服务端】访客端口成功接收数据:{}", new String(bytes));
// 使用访客的通信通道
Channel visitorCommunicationChannel = NettyCommunicationIdContext.getVisitor(visitorId);
// 绑定数据流量
ChannelAttributeKeyUtils.buildInFlow(visitorCommunicationChannel, bytes.length);
NettyProxyMsg nettyProxyMsg = new NettyProxyMsg();
nettyProxyMsg.setType(MessageType.DISTRIBUTE_CLIENT_TRANSFER);
nettyProxyMsg.setClientId(clientId);
nettyProxyMsg.setClientTargetIp(clientTargetIp);
nettyProxyMsg.setClientTargetPort(clientTargetPort);
nettyProxyMsg.setVisitorPort(visitorPort);
nettyProxyMsg.setType(MessageType.REPORT_CLIENT_TRANSFER);
nettyProxyMsg.setVisitorId(visitorId);
nettyProxyMsg.setData(bytes);
visitorCommunicationChannel.writeAndFlush(nettyProxyMsg);
nextChannel.writeAndFlush(nettyProxyMsg);
// 处理访客流量
// ServerChannelFlow serverChannelFlow = ServerChannelFlow
// .builder()
@ -120,23 +96,25 @@ public class NettyClientVisitorHandler extends SimpleChannelInboundHandler<ByteB
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
String visitorId = ChannelAttributeKeyUtils.getVisitorId(ctx.channel());
String clientId = ChannelAttributeKeyUtils.getClientId(ctx.channel());
Channel channel = ctx.channel();
String visitorId = ChannelAttributeKeyUtils.getVisitorId(channel);
String clientId = ChannelAttributeKeyUtils.getClientId(channel);
if (StringUtil.isNullOrEmpty(visitorId)) {
super.channelInactive(ctx);
return;
}
Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(channel);
// 通信通道自动读写打开 然后关闭通信通道
Channel visitorChannel = NettyCommunicationIdContext.getVisitor(visitorId);
if (visitorChannel != null && visitorChannel.isActive()) {
visitorChannel.config().setOption(ChannelOption.AUTO_READ, true);
if (nextChannel != null && nextChannel.isActive()) {
nextChannel.config().setOption(ChannelOption.AUTO_READ, true);
// 通知服务端 关闭访问通道真实通道
NettyProxyMsg myMsg = new NettyProxyMsg();
myMsg.setType(MessageType.DISTRIBUTE_SINGLE_CLIENT_REAL_CLOSE_VISITOR);
myMsg.setVisitorId(visitorId);
visitorChannel.writeAndFlush(myMsg);
nextChannel.writeAndFlush(myMsg);
}
// 关闭 访客通信通道访客真实通道
NettyRealIdContext.clear(visitorId);

View File

@ -0,0 +1,79 @@
package org.framework.lazy.cloud.network.heartbeat.client.netty.handler;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOption;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.common.ChannelContext;
import org.framework.lazy.cloud.network.heartbeat.common.MessageType;
import org.framework.lazy.cloud.network.heartbeat.common.NettyProxyMsg;
import org.framework.lazy.cloud.network.heartbeat.common.NettyRealIdContext;
import org.framework.lazy.cloud.network.heartbeat.common.adapter.ChannelTypeAdapter;
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
import org.wu.framework.core.utils.ObjectUtils;
/**
* 客户端访客通信通道 处理器
*/
@Slf4j
public class NettyClientPermeateTransferHandler extends SimpleChannelInboundHandler<NettyProxyMsg> {
private final ChannelTypeAdapter channelTypeAdapter;
public NettyClientPermeateTransferHandler(ChannelTypeAdapter channelTypeAdapter) {
this.channelTypeAdapter = channelTypeAdapter;
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
}
@Override
public void channelRead0(ChannelHandlerContext ctx, NettyProxyMsg nettyProxyMsg) throws Exception {
Channel channel = ctx.channel();
channelTypeAdapter.handler(channel, nettyProxyMsg);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
String clientId = ChannelAttributeKeyUtils.getClientId(ctx.channel());
String visitorId = ChannelAttributeKeyUtils.getVisitorId(ctx.channel());
// 关闭访客
ChannelContext.ClientChannel clientChannel = ChannelContext.get(clientId);
if (clientChannel != null) {
Channel channel = clientChannel.getChannel();
// 上报关闭这个客户端的访客通道
NettyProxyMsg closeVisitorMsg = new NettyProxyMsg();
closeVisitorMsg.setType(MessageType.REPORT_SINGLE_CLIENT_CLOSE_VISITOR);
closeVisitorMsg.setVisitorId(visitorId);
channel.writeAndFlush(closeVisitorMsg);
}
super.channelInactive(ctx);
}
@Override
public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
// 处理客户端本地真实通道问题
String visitorId = ChannelAttributeKeyUtils.getVisitorId(ctx.channel());
if(ObjectUtils.isEmpty(visitorId)) {
super.channelWritabilityChanged(ctx);
return;
}
Channel realChannel = NettyRealIdContext.getReal(visitorId);
if (realChannel != null) {
log.debug("visitorId:{} transfer AUTO_READ:{} ",visitorId,ctx.channel().isWritable());
realChannel.config().setOption(ChannelOption.AUTO_READ, ctx.channel().isWritable());
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
super.exceptionCaught(ctx, cause);
}
}

View File

@ -6,8 +6,9 @@ import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.client.netty.filter.NettyClientVisitorFilter;
import org.framework.lazy.cloud.network.heartbeat.common.InternalNetworkPenetrationRealClient;
import org.framework.lazy.cloud.network.heartbeat.client.config.NettyClientProperties;
import org.framework.lazy.cloud.network.heartbeat.client.netty.InternalNetworkPermeateServerVisitor;
import org.framework.lazy.cloud.network.heartbeat.client.netty.filter.NettyClientPermeateServerVisitorFilter;
import org.framework.lazy.cloud.network.heartbeat.common.NettyClientVisitorContext;
import org.framework.lazy.cloud.network.heartbeat.common.NettyVisitorPortContext;
import org.framework.lazy.cloud.network.heartbeat.common.adapter.ChannelFlowAdapter;
@ -15,7 +16,7 @@ import org.framework.lazy.cloud.network.heartbeat.common.adapter.ChannelFlowAdap
import java.io.IOException;
/**
* 内网穿透客户端端访客通道
* 内网穿透 客户端渗透服务端通道
*
* @see NettyVisitorPortContext
* @see NettyClientVisitorContext
@ -24,20 +25,20 @@ import java.io.IOException;
public class NettyClientPermeateServerVisitorSocket {
private final EventLoopGroup bossGroup = new NioEventLoopGroup();
private final EventLoopGroup workerGroup = new NioEventLoopGroup();
private final NettyClientVisitorFilter nettyClientVisitorFilter;
private final NettyClientPermeateServerVisitorFilter nettyClientPermeateServerVisitorFilter;
@Getter
private final String clientId;
@Getter
private final int visitorPort;
public NettyClientPermeateServerVisitorSocket(NettyClientVisitorFilter nettyClientVisitorFilter, String clientId, int visitorPort) {
this.nettyClientVisitorFilter = nettyClientVisitorFilter;
public NettyClientPermeateServerVisitorSocket(NettyClientPermeateServerVisitorFilter nettyClientPermeateServerVisitorFilter, String clientId, int visitorPort) {
this.nettyClientPermeateServerVisitorFilter = nettyClientPermeateServerVisitorFilter;
this.clientId = clientId;
this.visitorPort = visitorPort;
}
/**
* 启动服务代理
* 启动客户端本地端口渗透到服务端端口
*
* @throws Exception
*/
@ -64,7 +65,7 @@ public class NettyClientPermeateServerVisitorSocket {
.childOption(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(1024 * 1024, 1024 * 1024 * 2))
.childHandler(nettyClientVisitorFilter);
.childHandler(nettyClientPermeateServerVisitorFilter);
ChannelFuture sync = bootstrap.bind(visitorPort).sync();
sync.addListener((ChannelFutureListener) future -> {
if (future.isSuccess()) {
@ -137,6 +138,10 @@ public class NettyClientPermeateServerVisitorSocket {
* 流量适配器
*/
private ChannelFlowAdapter channelFlowAdapter;
/**
* 服务端地址信息
*/
private NettyClientProperties nettyClientProperties;
public static NettyVisitorSocketBuilder builder() {
return new NettyVisitorSocketBuilder();
@ -196,6 +201,16 @@ public class NettyClientPermeateServerVisitorSocket {
this.channelFlowAdapter = channelFlowAdapter;
return this;
}
/**
* 服务端地址信息
*
* @param nettyClientProperties 客户服务端地址配置属性
* @return 返回当前对象
*/
public NettyVisitorSocketBuilder builderNettyClientProperties(NettyClientProperties nettyClientProperties) {
this.nettyClientProperties = nettyClientProperties;
return this;
}
/**
* 绑定访客ID
@ -209,9 +224,6 @@ public class NettyClientPermeateServerVisitorSocket {
}
public NettyClientPermeateServerVisitorSocket build() {
if (clientId == null) {
throw new IllegalArgumentException("clientId must not null");
}
if (clientTargetIp == null) {
throw new IllegalArgumentException("clientTargetIp must not null");
}
@ -221,15 +233,15 @@ public class NettyClientPermeateServerVisitorSocket {
if (visitorPort == null) {
throw new IllegalArgumentException("visitorPort must not null");
}
InternalNetworkPenetrationRealClient internalNetworkPenetrationRealClient = InternalNetworkPenetrationRealClient
InternalNetworkPermeateServerVisitor internalNetworkPermeateServerVisitor = InternalNetworkPermeateServerVisitor
.builder()
.clientId(clientId)
.clientTargetIp(clientTargetIp)
.clientTargetPort(clientTargetPort)
.targetIp(clientTargetIp)
.targetPort(clientTargetPort)
.visitorPort(visitorPort)
.visitorId(visitorId).build();
.build();
NettyClientVisitorFilter visitorFilter = new NettyClientVisitorFilter(internalNetworkPenetrationRealClient, channelFlowAdapter);
NettyClientPermeateServerVisitorFilter visitorFilter = new NettyClientPermeateServerVisitorFilter();
return new NettyClientPermeateServerVisitorSocket(visitorFilter, clientId, visitorPort);
}

View File

@ -0,0 +1,112 @@
package org.framework.lazy.cloud.network.heartbeat.client.netty.socket;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.client.config.NettyClientProperties;
import org.framework.lazy.cloud.network.heartbeat.client.netty.InternalNetworkPermeateServerVisitor;
import org.framework.lazy.cloud.network.heartbeat.client.netty.filter.NettyClientPermeateTransferFilter;
import org.framework.lazy.cloud.network.heartbeat.common.MessageType;
import org.framework.lazy.cloud.network.heartbeat.common.NettyCommunicationIdContext;
import org.framework.lazy.cloud.network.heartbeat.common.NettyProxyMsg;
import org.framework.lazy.cloud.network.heartbeat.common.NettyRealIdContext;
import org.framework.lazy.cloud.network.heartbeat.common.adapter.ChannelTypeAdapter;
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
import java.util.concurrent.TimeUnit;
/**
* 客户端渗透服务端传输通道
*/
@Slf4j
public class NettyClientTransferServerSocket {
static EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
/**
* 连接服务端通信通道
*/
public static void buildTransferServer(InternalNetworkPermeateServerVisitor internalNetworkPermeateServerVisitor) {
newTransferConnect2Server(internalNetworkPermeateServerVisitor);
}
/**
* 连接服务端通信通道
* <p>
* internalNetworkPermeateServerVisitor
*/
protected static void newTransferConnect2Server(InternalNetworkPermeateServerVisitor internalNetworkPermeateServerVisitor) {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(eventLoopGroup)
.channel(NioSocketChannel.class)
.option(ChannelOption.SO_KEEPALIVE, true)
// 设置读缓冲区为2M
.option(ChannelOption.SO_RCVBUF, 2048 * 1024)
// 设置写缓冲区为1M
.option(ChannelOption.SO_SNDBUF, 1024 * 1024)
// .option(ChannelOption.TCP_NODELAY, false)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1000 * 60)//连接超时时间设置为 60 秒
// .option(ChannelOption.SO_BACKLOG, 256)//务端接受连接的队列长度 默认128
// .option(ChannelOption.RCVBUF_ALLOCATOR, new NettyRecvByteBufAllocator(1024 * 1024))//用于Channel分配接受Buffer的分配器 默认AdaptiveRecvByteBufAllocator.DEFAULT
.option(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(1024 * 1024, 1024 * 1024 * 2))
.handler(new NettyClientPermeateTransferFilter(new ChannelTypeAdapter(internalNetworkPermeateServerVisitor.getHandleChannelTypeAdvancedList())))
;
NettyClientProperties nettyClientProperties = internalNetworkPermeateServerVisitor.getNettyClientProperties();
String inetHost = nettyClientProperties.getInetHost();
int inetPort = nettyClientProperties.getInetPort();
// local client id
String clientId = nettyClientProperties.getClientId();
String targetIp = internalNetworkPermeateServerVisitor.getTargetIp();
Integer targetPort = internalNetworkPermeateServerVisitor.getTargetPort();
String visitorId = internalNetworkPermeateServerVisitor.getVisitorId();
Integer visitorPort = internalNetworkPermeateServerVisitor.getVisitorPort();
// 客户端新建访客通道 连接服务端IP:{},连接服务端端口:{}
log.info("Client creates a new visitor channel to connect to server IP: {}, connecting to server port: {}", inetHost, inetPort);
ChannelFuture future = bootstrap.connect(inetHost, inetPort);
// 使用的客户端ID:{}
log.info("Client ID used: {}", clientId);
future.addListener((ChannelFutureListener) futureListener -> {
Channel channel = futureListener.channel();
if (futureListener.isSuccess()) {
NettyProxyMsg myMsg = new NettyProxyMsg();
myMsg.setType(MessageType.REPORT_CLIENT_TRANSFER_SERVER_PERMEATE_CHANNEL_CONNECTION_SUCCESSFUL);
myMsg.setClientId(clientId);
myMsg.setVisitorPort(visitorPort);
myMsg.setClientTargetIp(targetIp);
myMsg.setClientTargetPort(targetPort);
myMsg.setVisitorId(visitorId);
channel.writeAndFlush(myMsg);
// 绑定客户端真实通信通道
NettyCommunicationIdContext.pushVisitor(channel, visitorId);
ChannelAttributeKeyUtils.buildVisitorId(channel, visitorId);
ChannelAttributeKeyUtils.buildClientId(channel, clientId);
// 传输通道打开后自动读取
Channel visitor = NettyRealIdContext.getReal(visitorId);
ChannelAttributeKeyUtils.buildNextChannel(visitor, channel);
ChannelAttributeKeyUtils.buildNextChannel(channel, visitor);
} else {
log.info("每隔2s重连....");
// 离线
channel.eventLoop().schedule(() -> {
newTransferConnect2Server(internalNetworkPermeateServerVisitor);
}, 2, TimeUnit.SECONDS);
}
});
}
}