【fix】新增本地socks代理服务端

This commit is contained in:
wujiawei
2025-05-03 22:36:21 +08:00
parent f0fd22ccd4
commit b7f099d3a4
28 changed files with 1185 additions and 5 deletions

View File

@ -5,6 +5,9 @@ import org.framework.lazy.cloud.network.heartbeat.common.adapter.ChannelFlowAdap
import org.framework.lazy.cloud.network.heartbeat.server.netty.permeate.tcp.advanced.*;
import org.framework.lazy.cloud.network.heartbeat.server.netty.permeate.udp.advanced.*;
import org.framework.lazy.cloud.network.heartbeat.server.netty.proxy.http.advanced.*;
import org.framework.lazy.cloud.network.heartbeat.server.netty.proxy.socks.advanced.ServerHandleSocksReportClientProxyServerConnectTransferTypeAdvanced;
import org.framework.lazy.cloud.network.heartbeat.server.netty.proxy.socks.advanced.ServerHandleSocksReportClientProxyServerTransferCloseTypeAdvanced;
import org.framework.lazy.cloud.network.heartbeat.server.netty.proxy.socks.advanced.ServerHandleSocksReportClientProxyServerTransferRequestTypeAdvanced;
import org.framework.lazy.cloud.network.heartbeat.server.properties.ServerNodeProperties;
import org.framework.lazy.cloud.network.heartbeat.server.standalone.application.*;
import org.springframework.beans.factory.config.BeanDefinition;
@ -248,4 +251,20 @@ public class ServerAutoConfiguration {
return new ServerHandleHttpReportServerProxyClientTransferCloseTypeAdvanced();
}
}
@Configuration
static class ServerSocksProxyConfiguration{
@Bean
public ServerHandleSocksReportClientProxyServerConnectTransferTypeAdvanced serverHandleSocksReportClientProxyServerConnectTransferTypeAdvanced(){
return new ServerHandleSocksReportClientProxyServerConnectTransferTypeAdvanced();
}
@Bean
public ServerHandleSocksReportClientProxyServerTransferCloseTypeAdvanced serverHandleSocksReportClientProxyServerTransferCloseTypeAdvanced(){
return new ServerHandleSocksReportClientProxyServerTransferCloseTypeAdvanced();
}
@Bean
public ServerHandleSocksReportClientProxyServerTransferRequestTypeAdvanced serverHandleSocksReportClientProxyServerTransferRequestTypeAdvanced(){
return new ServerHandleSocksReportClientProxyServerTransferRequestTypeAdvanced();
}
}
}

View File

@ -0,0 +1,101 @@
package org.framework.lazy.cloud.network.heartbeat.server.netty.proxy.socks.advanced;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.socksx.v5.DefaultSocks5CommandResponse;
import io.netty.handler.codec.socksx.v5.Socks5AddressType;
import io.netty.handler.codec.socksx.v5.Socks5CommandStatus;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.common.NettyTransferChannelContext;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyChannelContext;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.proxy.socket.server.AbstractHandleSocksReportClientProxyServerConnectionTransferTypeAdvanced;
import org.framework.lazy.cloud.network.heartbeat.common.constant.ProxyMessageType;
import org.framework.lazy.cloud.network.heartbeat.common.decoder.TransferDecoder;
import org.framework.lazy.cloud.network.heartbeat.common.factory.EventLoopGroupFactory;
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
import org.framework.lazy.cloud.network.heartbeat.server.netty.proxy.socks.handler.NettySocksClientProxyServerRealHandler;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Role;
import org.springframework.stereotype.Component;
import java.net.InetSocketAddress;
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@Slf4j
@Component
public class ServerHandleSocksReportClientProxyServerConnectTransferTypeAdvanced
extends AbstractHandleSocksReportClientProxyServerConnectionTransferTypeAdvanced<NettyProxyMsg> {
/**
* 处理当前数据
*
* @param nettyChannelContext 当前通道
* @param nettyProxyMsg 通道数据
*/
@Override
public void doHandler(NettyChannelContext nettyChannelContext, NettyProxyMsg nettyProxyMsg) {
Channel transferChannel = nettyChannelContext.channel();
String host = nettyProxyMsg.getTargetIpString();
Integer port = Integer.parseInt(nettyProxyMsg.getTargetPortString());
byte[] data = nettyProxyMsg.getData();
byte[] visitorId = nettyProxyMsg.getVisitorId();
byte[] clientId = nettyProxyMsg.getClientId();
String msgVisitorId = new String(visitorId);
ChannelAttributeKeyUtils.buildClientId(transferChannel, clientId);
ChannelAttributeKeyUtils.buildVisitorId(transferChannel, msgVisitorId);
NettyTransferChannelContext.pushVisitor(transferChannel, msgVisitorId);
Socks5AddressType socks5AddressType = Socks5AddressType.valueOf(data[0]);
// 创建真实代理链接
EventLoopGroup group = EventLoopGroupFactory.createClientWorkGroup();
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new TransferDecoder(Integer.MAX_VALUE, 1024 * 1024 * 10));
ch.pipeline().addLast(new NettySocksClientProxyServerRealHandler());
}
});
log.info("准备连接目标服务器ip = {},port = {}", host, port);
ChannelFuture f = b.connect(new InetSocketAddress(host, port));
f.addListener((ChannelFutureListener) future -> {
Channel realChannel = future.channel();
if (future.isSuccess()) {
log.info("目标服务器连接成功");
// 通道相互绑定
ChannelAttributeKeyUtils.buildNextChannel(transferChannel, realChannel);
ChannelAttributeKeyUtils.buildNextChannel(realChannel, transferChannel);
// 传输通道连接成功下发
NettyProxyMsg transferNettyProxyMsg = new NettyProxyMsg();
transferNettyProxyMsg.setType(ProxyMessageType.SOCKS_DISTRIBUTE_CLIENT_PROXY_SERVER_TRANSFER_CONNECTION_SUCCESS_);
transferChannel.writeAndFlush(transferNettyProxyMsg);
} else {
log.error("连接目标服务器失败,address={},port={}", host, port);
DefaultSocks5CommandResponse commandResponse = new DefaultSocks5CommandResponse(Socks5CommandStatus.FAILURE, socks5AddressType);
transferChannel.writeAndFlush(commandResponse);
realChannel.close();
}
});
// TODO 下发 连接真实服务成功、客户端可以采集数据了
}
}

View File

@ -0,0 +1,36 @@
package org.framework.lazy.cloud.network.heartbeat.server.netty.proxy.socks.advanced;
import io.netty.channel.*;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyChannelContext;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.proxy.socket.server.AbstractHandleSocksReportClientProxyServerTransferCloseTypeAdvanced;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Role;
import org.springframework.stereotype.Component;
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@Slf4j
@Component
public class ServerHandleSocksReportClientProxyServerTransferCloseTypeAdvanced
extends AbstractHandleSocksReportClientProxyServerTransferCloseTypeAdvanced<NettyProxyMsg> {
/**
* 处理当前数据
*
* @param nettyChannelContext 当前通道
* @param nettyProxyMsg 通道数据
*/
@Override
public void doHandler(NettyChannelContext nettyChannelContext, NettyProxyMsg nettyProxyMsg) {
Channel transferChannel = nettyChannelContext.channel();
}
}

View File

@ -0,0 +1,48 @@
package org.framework.lazy.cloud.network.heartbeat.server.netty.proxy.socks.advanced;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyChannelContext;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.proxy.socket.server.AbstractHandleSocksReportClientProxyServerTransferRequestTypeAdvanced;
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
import org.framework.lazy.cloud.network.heartbeat.server.netty.proxy.socks.handler.NettySocksClientProxyServerRealHandler;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Role;
import org.springframework.stereotype.Component;
import org.wu.framework.core.utils.ObjectUtils;
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@Slf4j
@Component
public class ServerHandleSocksReportClientProxyServerTransferRequestTypeAdvanced
extends AbstractHandleSocksReportClientProxyServerTransferRequestTypeAdvanced<NettyProxyMsg> {
/**
* 处理当前数据
*
* @param nettyChannelContext 当前通道
* @param nettyProxyMsg 通道数据
* @see NettySocksClientProxyServerRealHandler
*/
@Override
public void doHandler(NettyChannelContext nettyChannelContext, NettyProxyMsg nettyProxyMsg) {
Channel transferChannel = nettyChannelContext.channel();
// 目标通道
Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(transferChannel);
// 目标数据发送
if (ObjectUtils.isNotEmpty(nextChannel) && nextChannel.isActive()) {
ByteBuf buf = nextChannel.config().getAllocator().buffer(nettyProxyMsg.getData().length);
buf.writeBytes(nettyProxyMsg.getData());
nextChannel.writeAndFlush(buf);
} else {
log.error("当前目标通道已经关闭或者不存在");
}
}
}

View File

@ -0,0 +1,68 @@
package org.framework.lazy.cloud.network.heartbeat.server.netty.proxy.socks.handler;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.ReferenceCountUtil;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.common.NettyByteBuf;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
import org.framework.lazy.cloud.network.heartbeat.common.constant.ProxyMessageType;
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
@Slf4j
public class NettySocksClientProxyServerRealHandler extends SimpleChannelInboundHandler<NettyByteBuf> {
@Override
public void channelActive(ChannelHandlerContext ctx) {
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER);
}
@Override
public void channelRead0(ChannelHandlerContext ctx, NettyByteBuf nettyByteBuf) throws Exception {
log.trace("开始写回客户端数据");
// 结果下发
Channel channel = ctx.channel();
byte[] bytes = nettyByteBuf.getData();
log.debug("bytes.length:{}", bytes.length);
log.debug("客户端socks代理服务端接收服务端真实服务数据:{}", new String(bytes));
Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(channel);
if (nextChannel.isActive()) {
// 将数据返回给客户端
NettyProxyMsg nettyProxyMsgResponse = new NettyProxyMsg();
nettyProxyMsgResponse.setType(ProxyMessageType.SOCKS_DISTRIBUTE_CLIENT_PROXY_SERVER_TRANSFER_RESPONSE_);
nettyProxyMsgResponse.setData(bytes);
nextChannel.writeAndFlush(nettyProxyMsgResponse);
} else {
log.info("释放内存");
ReferenceCountUtil.release(nettyByteBuf);
}
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
log.trace("代理服务器和目标服务器的连接已经断开,即将断开客户端和代理服务器的连接");
Channel channel = ctx.channel();
Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(channel);
if (nextChannel.isActive()) {
// 下发关闭请求
NettyProxyMsg nettyProxyMsgClose = new NettyProxyMsg();
nettyProxyMsgClose.setType(ProxyMessageType.SOCKS_DISTRIBUTE_CLIENT_PROXY_SERVER_TRANSFER_CLOSE_);
nextChannel.writeAndFlush(nettyProxyMsgClose);
nextChannel.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
log.error("NettySocksClientProxyServerRealHandler exception", cause);
ctx.close();
}
}