无需部署客户端待完成

服务端直接转发功能 后续将通过集成nginx来实现服务端转发
This commit is contained in:
xiaojie
2024-06-25 10:12:38 +08:00
parent 26ec45b3f9
commit f0a61a1d30
13 changed files with 48 additions and 57 deletions
+1
View File
@@ -60,3 +60,4 @@ logs
data
**/cert/**
neutrino-proxy-server/src/main/resources/static/**
/neutrino-proxy-server/src/main/resources/static/
+1 -1
View File
@@ -3,7 +3,7 @@
# what is new? 在原版的基础上新增了【域名解析】功能,域名解析【无需】绑定【本地端口】
<p>
<a href="https://gitee.com/zcans" target="_blank">
<img src="assets/run-example/domain.png" width="45%">
<img src="assets/run-example/domain.png" >
</a>
<p align="center">
+1 -1
View File
@@ -1,7 +1,7 @@
module.exports = {
NODE_ENV: '"development"',
ENV_CONFIG: '"dev"',
BASE_API: '"https://server.com"',
BASE_API: '"http://localhost:8888/neutrino-proxy-server"',
USER_NAME: '"visitor"',
USER_PWD: '"123456"'
}
+2 -2
View File
@@ -55,8 +55,8 @@ module.exports = {
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
// you can set by youself according to actual condition
assetsPublicPath: './',
// you can set by youself according to actual condition
assetsPublicPath: '/',
/**
* Source Maps
+1 -1
View File
@@ -1,5 +1,5 @@
module.exports = {
NODE_ENV: '"production"',
ENV_CONFIG: '"prod"',
BASE_API: '"https://api-prod"'
BASE_API: '"http://np.myone.cc"' // 后端访问地址与 server配置一致
}
@@ -63,11 +63,13 @@
</el-table-column>
<el-table-column align="center" :label="$t('table.actions')" width="330" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button v-if="scope.row.id != 1" type="primary" size="mini" @click="handleUpdate(scope.row)">{{$t('table.edit')}}</el-button>
<!-- v-if="scope.row.id != 1" -->
<el-button type="primary" size="mini" @click="handleUpdate(scope.row)">{{$t('table.edit')}}</el-button>
<el-button size="mini" type="primary" @click="handleReset(scope.row)">{{$t('table.resetKey')}}</el-button>
<el-button v-if="scope.row.enable =='1'" size="mini" type="danger" @click="handleModifyStatus(scope.row,2)">{{$t('table.disable')}}</el-button>
<el-button v-if="scope.row.enable =='2'" size="mini" type="success" @click="handleModifyStatus(scope.row,1)">{{$t('table.enable')}}</el-button>
<el-button v-if="scope.row.id != 1" size="mini" type="danger" @click="handleDelete(scope.row)">{{$t('table.delete')}}</el-button>
<!-- v-if="scope.row.id != 1" -->
<el-button size="mini" type="danger" @click="handleDelete(scope.row)">{{$t('table.delete')}}</el-button>
</template>
</el-table-column>
</el-table>
@@ -71,9 +71,10 @@ public interface LicenseMapper extends BaseMapper<LicenseDO> {
);
}
// .ne(LicenseDO::getId, 1)
default void updateOnlineStatus(Integer isOnline, Date updateTime) {
this.update(null, new LambdaUpdateWrapper<LicenseDO>()
.ne(LicenseDO::getId, 1)
.set(LicenseDO::getIsOnline, isOnline)
.set(LicenseDO::getUpdateTime, updateTime)
);
@@ -1,17 +1,16 @@
package org.dromara.neutrinoproxy.server.proxy.enhance;
import cn.hutool.core.util.StrUtil;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.util.concurrent.GenericFutureListener;
import lombok.extern.slf4j.Slf4j;
import org.dromara.neutrinoproxy.server.base.proxy.ProxyConfig;
import org.dromara.neutrinoproxy.server.proxy.core.BytesMetricsHandler;
import org.dromara.neutrinoproxy.server.proxy.core.ProxyTunnelServer;
import org.dromara.neutrinoproxy.server.proxy.security.HttpVisitorSecurityChannelHandler;
import org.dromara.neutrinoproxy.server.proxy.security.VisitorFlowLimiterChannelHandler;
import org.noear.solon.annotation.Component;
@@ -19,9 +18,6 @@ import org.noear.solon.annotation.Inject;
import org.noear.solon.core.event.AppLoadEndEvent;
import org.noear.solon.core.event.EventListener;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
/**
* 应用加载完成事件(即启动完成)- 判断是否配置域名-配置了域名则启动HTTP代理
* 默认端口 80
@@ -60,18 +56,18 @@ public class HttpProxy implements EventListener<AppLoadEndEvent> {
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
if (null != proxyConfig.getServer().getTcp().getTransferLogEnable() &&
proxyConfig.getServer().getTcp().getTransferLogEnable()) {
ch.pipeline().addFirst(new LoggingHandler(HttpProxy.class));
}
ch.pipeline().addFirst(new BytesMetricsHandler())
if (null != proxyConfig.getServer().getTcp().getTransferLogEnable() &&
proxyConfig.getServer().getTcp().getTransferLogEnable()) {
ch.pipeline().addFirst(new LoggingHandler(HttpProxy.class));
}
ch.pipeline().addFirst(new BytesMetricsHandler())
.addLast(new HttpVisitorSecurityChannelHandler())
.addLast("flowLimiter",new VisitorFlowLimiterChannelHandler())
.addLast(new HttpVisitorChannelHandler(ch));
.addLast(new HttpVisitorChannelHandler());
}
});
httpFuture = bootstrap.bind("0.0.0.0", proxyConfig.getServer().getTcp().getHttpProxyPort()).sync();
log.info("Http proxy server start successport:{}", proxyConfig.getServer().getTcp().getHttpProxyPort());
log.info("Http proxy server started successport:{}", proxyConfig.getServer().getTcp().getHttpProxyPort());
//添加关闭重启的监听器,3秒后尝试重启
// httpFuture.channel().closeFuture().addListener(genericFutureListener);
// httpFuture.channel().closeFuture().sync();
@@ -1,24 +1,19 @@
package org.dromara.neutrinoproxy.server.proxy.enhance;
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.proxy.ProxyHandler;
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.apache.commons.lang3.StringUtils;
import org.dromara.neutrinoproxy.core.Constants;
import org.dromara.neutrinoproxy.core.ProxyMessage;
import org.dromara.neutrinoproxy.core.util.HttpUtil;
import org.dromara.neutrinoproxy.server.constant.NetworkProtocolEnum;
import org.dromara.neutrinoproxy.server.proxy.domain.DomainMapping;
import org.dromara.neutrinoproxy.server.proxy.domain.ProxyAttachment;
import org.dromara.neutrinoproxy.server.proxy.domain.ProxyMapping;
import org.dromara.neutrinoproxy.server.proxy.domain.VisitorChannelAttachInfo;
import org.dromara.neutrinoproxy.server.service.FlowReportService;
import org.dromara.neutrinoproxy.server.util.ProxyUtil;
import org.h2.store.DataHandler;
import org.noear.solon.Solon;
import java.net.InetSocketAddress;
@@ -30,11 +25,6 @@ import java.net.InetSocketAddress;
*/
@Slf4j
public class HttpVisitorChannelHandler extends SimpleChannelInboundHandler<ByteBuf> {
private SocketChannel sch;
public HttpVisitorChannelHandler(SocketChannel sch) {
this.sch = sch;
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf byteBuf) throws Exception {
@@ -1,8 +1,10 @@
package org.dromara.neutrinoproxy.server.proxy.enhance;
import cn.hutool.core.util.StrUtil;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
@@ -13,7 +15,6 @@ import org.apache.commons.lang3.StringUtils;
import org.dromara.neutrinoproxy.core.util.FileUtil;
import org.dromara.neutrinoproxy.server.base.proxy.ProxyConfig;
import org.dromara.neutrinoproxy.server.proxy.core.BytesMetricsHandler;
import org.dromara.neutrinoproxy.server.proxy.core.ProxyTunnelServer;
import org.dromara.neutrinoproxy.server.proxy.security.HttpVisitorSecurityChannelHandler;
import org.dromara.neutrinoproxy.server.proxy.security.VisitorFlowLimiterChannelHandler;
import org.noear.solon.annotation.Component;
@@ -21,7 +22,10 @@ import org.noear.solon.annotation.Inject;
import org.noear.solon.core.event.AppLoadEndEvent;
import org.noear.solon.core.event.EventListener;
import javax.net.ssl.*;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.TrustManager;
import java.io.InputStream;
import java.security.KeyStore;
@@ -70,7 +74,7 @@ public class HttpsProxy implements EventListener<AppLoadEndEvent> {
.addFirst(new BytesMetricsHandler())
.addLast(new HttpVisitorSecurityChannelHandler())
.addLast("flowLimiter", new VisitorFlowLimiterChannelHandler())
.addLast(new HttpVisitorChannelHandler(ch));
.addLast(new HttpVisitorChannelHandler());
}
});
httpsFuture = bootstrap.bind("0.0.0.0", proxyConfig.getServer().getTcp().getHttpsProxyPort()).sync();
@@ -1,11 +1,8 @@
package org.dromara.neutrinoproxy.server.proxy.security;
import cn.hutool.core.util.StrUtil;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.proxy.ProxyHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.dromara.neutrinoproxy.core.Constants;
@@ -63,7 +60,7 @@ public class HttpVisitorSecurityChannelHandler extends ChannelInboundHandlerAdap
}
ctx.channel().attr(Constants.REAL_REMOTE_IP).set(ip);
ctx.channel().attr(Constants.SERVER_PORT).set(dm.getId());
// ctx.channel().attr(Constants.LICENSE_ID).set(dm.getLicenseId());
ctx.channel().attr(Constants.LICENSE_ID).set(dm.getLicenseId());
}
// 继续传播
@@ -205,18 +205,18 @@ public class LicenseService implements LifecycleBean {
*/
@Tran
public LicenseUpdateEnableStatusRes updateEnableStatus(LicenseUpdateEnableStatusReq req) {
// 服务端免通道 直接转发,所以无需建立客户端通道。启用即在线,禁用即离线
if (req.getId() == 1) {
licenseMapper.update(null, new LambdaUpdateWrapper<LicenseDO>()
.eq(LicenseDO::getId, req.getId())
.set(LicenseDO::getEnable, req.getEnable())
.set(LicenseDO::getIsOnline, req.getEnable())
.set(LicenseDO::getUpdateTime, new Date()));
} else {
// 服务端免通道 直接转发,所以无需建立客户端通道。启用即在线,禁用即离线 20240311 设计取消
// if (req.getId() == 1) {
// licenseMapper.update(null, new LambdaUpdateWrapper<LicenseDO>()
// .eq(LicenseDO::getId, req.getId())
// .set(LicenseDO::getEnable, req.getEnable())
// .set(LicenseDO::getIsOnline, req.getEnable())
// .set(LicenseDO::getUpdateTime, new Date()));
// } else {
licenseMapper.updateEnableStatus(req.getId(), req.getEnable(), new Date());
// 更新VisitorChannel
visitorChannelService.updateVisitorChannelByLicenseId(req.getId(), req.getEnable());
}
// }
return new LicenseUpdateEnableStatusRes();
}
@@ -1,3 +1,3 @@
#license
INSERT INTO license(`id`, `name`, `key`, `user_id`, `is_online`, `enable`, `create_time`, `update_time`) VALUES
(1, '服务端(不可编辑删除,可禁用)', 'b0a907332b474b25897c4dcb31fc7eb6', 1, 1, 1, now(), now());
(1, '测试客户端', 'b0a907332b474b25897c4dcb31fc7eb6', 1, 1, 1, now(), now());