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

This commit is contained in:
wujiawei
2025-05-04 13:35:09 +08:00
parent 24fe9e4bc9
commit 7af14b4251
23 changed files with 852 additions and 29 deletions

View File

@ -388,8 +388,8 @@ public class ClientAutoConfiguration {
@Configuration
static class SocksProxyConfiguration {
@Bean
public NettySocketProtocolHandleSocketClientProxyServerTypeAdvanced nettySocketProtocolHandleSocketClientProxyServerTypeAdvanced() {
return new NettySocketProtocolHandleSocketClientProxyServerTypeAdvanced();
public NettySocketProtocolHandleSocketClientProxyServerStartTypeAdvanced nettySocketProtocolHandleSocketClientProxyServerTypeAdvanced() {
return new NettySocketProtocolHandleSocketClientProxyServerStartTypeAdvanced();
}
@Bean

View File

@ -0,0 +1,48 @@
package org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks;
import io.netty.handler.codec.socksx.v5.Socks5AddressType;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.framework.lazy.cloud.network.heartbeat.client.config.NettyClientProperties;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.HandleChannelTypeAdvanced;
import java.util.List;
/**
* 客户端代理服务端配置信息
*/
@NoArgsConstructor
@Data
public class NettySocksClientProxyClient {
/**
* 目标地址
*/
private String targetIp;
/**
* 目标端口
*/
private Integer targetPort;
/**
* 服务端地址信息
*/
private NettyClientProperties nettyClientProperties;
/**
* 通道处理器
*/
private List<HandleChannelTypeAdvanced> handleChannelTypeAdvancedList;
/**
* 是否是ssl
*/
private boolean isSsl;
/**
* 地址类型
*/
private Socks5AddressType socks5AddressType;
}

View File

@ -0,0 +1,27 @@
package org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.advanced;
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.socks.client.AbstractHandleSocksDistributeClientProxyClientConnectionTransferFailTypeAdvanced;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.proxy.socks.client.AbstractHandleSocksDistributeClientProxyServerConnectionTransferFailTypeAdvanced;
@Slf4j
public class ClientHandleDistributeSocksClientProxyClientConnectionTransferFailAdvanced extends
AbstractHandleSocksDistributeClientProxyClientConnectionTransferFailTypeAdvanced<NettyProxyMsg> {
/**
* 处理当前数据
*
* @param nettyChannelContext 当前通道
* @param nettyProxyMsg 通道数据
*/
@Override
protected void doHandler(NettyChannelContext nettyChannelContext, NettyProxyMsg nettyProxyMsg) {
// 传输通道关闭
}
}

View File

@ -0,0 +1,52 @@
package org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.advanced;
import io.netty.channel.Channel;
import io.netty.handler.codec.socksx.v5.DefaultSocks5CommandResponse;
import io.netty.handler.codec.socksx.v5.Socks5AddressType;
import io.netty.handler.codec.socksx.v5.Socks5CommandRequestDecoder;
import io.netty.handler.codec.socksx.v5.Socks5CommandStatus;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.handler.NettyClientProxyServerVisitorInboundHandler;
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.socks.client.AbstractHandleSocksDistributeClientProxyClientConnectionTransferSuccessTypeAdvanced;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.proxy.socks.client.AbstractHandleSocksDistributeClientProxyServerConnectionTransferSuccessTypeAdvanced;
import org.framework.lazy.cloud.network.heartbeat.common.decoder.TransferDecoder;
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
import org.framework.lazy.cloud.network.heartbeat.protocol.handler.NettySocks5CommandRequestHandler;
@Slf4j
public class ClientHandleDistributeSocksClientProxyClientConnectionTransferSuccessfulAdvanced extends
AbstractHandleSocksDistributeClientProxyClientConnectionTransferSuccessTypeAdvanced<NettyProxyMsg> {
/**
* 处理当前数据
*
* @param nettyChannelContext 当前通道
* @param nettyProxyMsg 通道数据
*/
@Override
protected void doHandler(NettyChannelContext nettyChannelContext, NettyProxyMsg nettyProxyMsg) {
// 传输通道
Channel transferChannel = nettyChannelContext.channel();
// 根据传输通道获取代理通道
Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(transferChannel);
Byte socks5AddressTypeByte = ChannelAttributeKeyUtils.getSocks5AddressType(nextChannel);
Socks5AddressType socks5AddressType = Socks5AddressType.valueOf(socks5AddressTypeByte);
//添加客户端转发请求到服务端的Handler
// TODO bug fix
nextChannel.pipeline().addLast(new TransferDecoder(Integer.MAX_VALUE, 1024 * 1024*10));
// 请求数据开始上报
nextChannel.pipeline().addLast(new NettyClientProxyServerVisitorInboundHandler(transferChannel));
DefaultSocks5CommandResponse commandResponse =
new DefaultSocks5CommandResponse(Socks5CommandStatus.SUCCESS, socks5AddressType);
nextChannel.writeAndFlush(commandResponse);
nextChannel.pipeline().remove(NettySocks5CommandRequestHandler.class);
nextChannel.pipeline().remove(Socks5CommandRequestDecoder.class);
}
}

View File

@ -0,0 +1,32 @@
package org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.advanced;
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.socks.client.AbstractHandleSocksDistributeClientProxyClientTransferCloseTypeAdvanced;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.proxy.socks.client.AbstractHandleSocksDistributeClientProxyServerTransferCloseTypeAdvanced;
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
@Slf4j
public class ClientHandleDistributeSocksClientProxyClientTransferCloseAdvanced extends
AbstractHandleSocksDistributeClientProxyClientTransferCloseTypeAdvanced<NettyProxyMsg> {
/**
* 处理当前数据
*
* @param nettyChannelContext 当前通道
* @param nettyProxyMsg 通道数据
*/
@Override
protected void doHandler(NettyChannelContext nettyChannelContext, NettyProxyMsg nettyProxyMsg) {
Channel channel = nettyChannelContext.channel();
// 关闭传输通道
Channel proxyChannel = ChannelAttributeKeyUtils.getNextChannel(channel);
proxyChannel.close();// 真实通道关闭
channel.close(); // 数据传输通道关闭
}
}

View File

@ -0,0 +1,39 @@
package org.framework.lazy.cloud.network.heartbeat.client.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.socks.client.AbstractHandleSocksDistributeClientProxyClientTransferResponseTypeAdvanced;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.proxy.socks.client.AbstractHandleSocksDistributeClientProxyServerTransferResponseTypeAdvanced;
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
import org.wu.framework.core.utils.ObjectUtils;
@Slf4j
public class ClientHandleDistributeSocksClientProxyClientTransferTransferResponseAdvanced extends
AbstractHandleSocksDistributeClientProxyClientTransferResponseTypeAdvanced<NettyProxyMsg> {
/**
* 处理当前数据
*
* @param nettyChannelContext 当前通道
* @param nettyProxyMsg 通道数据
*/
@Override
protected void doHandler(NettyChannelContext nettyChannelContext, NettyProxyMsg nettyProxyMsg) {
// 数据直接下发
Channel channel = nettyChannelContext.channel();
Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(channel);
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("客户端代理服务端socks本地通道已关闭");
}
}
}

View File

@ -0,0 +1,62 @@
package org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.advanced;
import io.netty.channel.Channel;
import io.netty.handler.codec.socksx.v5.Socks5AddressType;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.client.config.NettyClientProperties;
import org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.NettySocksClientProxyClient;
import org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.socket.NettySocksClientProxyClientSocket;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.HandleChannelTypeAdvanced;
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.payload.NettySocketChannelContext;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.proxy.socks.client.AbstractHandleSocketClientProxyClientStartTypeAdvanced;
import org.springframework.stereotype.Component;
import org.wu.framework.spring.utils.SpringContextHolder;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@Component
public class NettySocketProtocolHandleSocketClientProxyClientStartTypeAdvanced
extends AbstractHandleSocketClientProxyClientStartTypeAdvanced<NettyProxyMsg> {
/**
* 处理当前数据
*
* @param nettyChannelContext 当前通道
* @param nettyProxyMsg 通道数据
*/
@Override
protected void doHandler(NettyChannelContext nettyChannelContext, NettyProxyMsg nettyProxyMsg) {
NettySocketChannelContext nettySocketChannelContext = (NettySocketChannelContext) nettyChannelContext;
Channel proxyChannel = nettySocketChannelContext.channel();
String host = nettyProxyMsg.getTargetIpString();
Integer port = Integer.parseInt(nettyProxyMsg.getTargetPortString());
Socks5AddressType socks5AddressType = nettySocketChannelContext.getSocks5AddressType();
List<HandleChannelTypeAdvanced> handleChannelTypeAdvancedList = new ArrayList<>(SpringContextHolder.getApplicationContext().getBeansOfType(HandleChannelTypeAdvanced.class).values());
NettyClientProperties nettyClientProperties = SpringContextHolder.getBean(NettyClientProperties.class);
NettySocksClientProxyClient nettySocksClientProxyClient = new NettySocksClientProxyClient();
nettySocksClientProxyClient.setSsl(false);
nettySocksClientProxyClient.setTargetIp(host);
nettySocksClientProxyClient.setTargetPort(Integer.parseInt(String.valueOf(port)));
nettySocksClientProxyClient.setSocks5AddressType(socks5AddressType);
nettySocksClientProxyClient.setHandleChannelTypeAdvancedList(handleChannelTypeAdvancedList);
nettySocksClientProxyClient.setNettyClientProperties(nettyClientProperties);
// 创建连接
NettySocksClientProxyClientSocket.buildTransferServer(nettySocksClientProxyClient, proxyChannel);
}
}

View File

@ -1,6 +1,5 @@
package org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.advanced;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.handler.codec.socksx.v5.Socks5AddressType;
import lombok.extern.slf4j.Slf4j;
@ -11,7 +10,7 @@ import org.framework.lazy.cloud.network.heartbeat.common.advanced.HandleChannelT
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.payload.NettySocketChannelContext;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.proxy.socks.client.AbstractHandleSocketClientProxyServerTypeAdvanced;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.proxy.socks.client.AbstractHandleSocketClientProxyServerStartTypeAdvanced;
import org.framework.lazy.cloud.network.heartbeat.common.constant.ProxyMessageType;
import org.springframework.stereotype.Component;
import org.wu.framework.spring.utils.SpringContextHolder;
@ -24,8 +23,8 @@ import java.util.List;
*/
@Slf4j
@Component
public class NettySocketProtocolHandleSocketClientProxyServerTypeAdvanced
extends AbstractHandleSocketClientProxyServerTypeAdvanced<NettyProxyMsg> {
public class NettySocketProtocolHandleSocketClientProxyServerStartTypeAdvanced
extends AbstractHandleSocketClientProxyServerStartTypeAdvanced<NettyProxyMsg> {
/**
* 处理当前数据
*

View File

@ -0,0 +1,99 @@
package org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.socket;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.socksx.v5.Socks5AddressType;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.client.config.NettyClientProperties;
import org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.NettySocksClientProxyClient;
import org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.NettySocksClientProxyServer;
import org.framework.lazy.cloud.network.heartbeat.client.netty.proxy.socks.filter.NettySocksClientProxyServerTransferFilter;
import org.framework.lazy.cloud.network.heartbeat.common.adapter.ChannelTypeAdapter;
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.factory.EventLoopGroupFactory;
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
import java.util.concurrent.TimeUnit;
/**
* 客户端代理服务端
*/
@Slf4j
public class NettySocksClientProxyClientSocket {
/**
* 连接服务端通信通道
*/
public static void buildTransferServer(NettySocksClientProxyClient nettySocksClientProxyClient, Channel visitorChannel) {
EventLoopGroup eventLoopGroup = EventLoopGroupFactory.createClientWorkGroup();
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.CONNECT_TIMEOUT_MILLIS, 1000 * 60)//连接超时时间设置为 60 秒
.option(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(1024 * 1024, 1024 * 1024 * 2))
.handler(new NettySocksClientProxyServerTransferFilter(new ChannelTypeAdapter(nettySocksClientProxyClient.getHandleChannelTypeAdvancedList())))
;
NettyClientProperties nettyClientProperties = nettySocksClientProxyClient.getNettyClientProperties();
String inetHost = nettyClientProperties.getInetHost();
int inetPort = nettyClientProperties.getInetPort();
// local client id
String clientId = nettyClientProperties.getClientId();
String targetIp = nettySocksClientProxyClient.getTargetIp();
Integer targetPort = nettySocksClientProxyClient.getTargetPort();
Socks5AddressType socks5AddressType = nettySocksClientProxyClient.getSocks5AddressType();
byte socks5AddressTypeByteValue = socks5AddressType.byteValue();
String visitorId = ChannelAttributeKeyUtils.getVisitorId(visitorChannel);
// 客户端链接服务端
log.info("Client creates a new proxy channel to connect to server IP: {}, connecting to server port: {} with clientId:【{}】 & visitorId:【{}】",
inetHost, inetPort, clientId, visitorId);
ChannelFuture future = bootstrap.connect(inetHost, inetPort);
// 使用的客户端ID:{}
future.addListener((ChannelFutureListener) futureListener -> {
Channel transferChannel = futureListener.channel();
if (futureListener.isSuccess()) {
NettyProxyMsg nettyProxyMsg = new NettyProxyMsg();
nettyProxyMsg.setType(ProxyMessageType.SOCKS_REPORT_CLIENT_PROXY_SERVER_TRANSFER_CONNECTION_);
// other clientId
nettyProxyMsg.setClientTargetIp(targetIp);
nettyProxyMsg.setClientTargetPort(targetPort);
nettyProxyMsg.setVisitorId(visitorId);
nettyProxyMsg.setData(new byte[]{socks5AddressTypeByteValue});
transferChannel.writeAndFlush(nettyProxyMsg);
// 绑定客户端真实通信通道
ChannelAttributeKeyUtils.buildVisitorId(transferChannel, visitorId);
ChannelAttributeKeyUtils.buildClientId(transferChannel, clientId);
// 传输通道
ChannelAttributeKeyUtils.buildNextChannel(visitorChannel, transferChannel);
ChannelAttributeKeyUtils.buildNextChannel(transferChannel, visitorChannel);
} else {
log.info("无法连接到服务端....");
eventLoopGroup.schedule(() -> {
try {
buildTransferServer(nettySocksClientProxyClient, visitorChannel);
} catch (Exception e) {
e.printStackTrace();
}
}, 2, TimeUnit.SECONDS);
}
});
}
}