diff --git a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/proxy/enhance/HttpsProxy.java b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/proxy/enhance/HttpsProxy.java index 7ebd5226..1055fe73 100644 --- a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/proxy/enhance/HttpsProxy.java +++ b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/proxy/enhance/HttpsProxy.java @@ -1,8 +1,8 @@ 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.ChannelHandler; +import io.netty.channel.ChannelInitializer; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; @@ -10,13 +10,10 @@ import io.netty.handler.logging.LoggingHandler; import io.netty.handler.ssl.SniHandler; import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslHandler; -import io.netty.util.Mapping; import lombok.extern.slf4j.Slf4j; -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; @@ -24,7 +21,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; @@ -42,12 +42,7 @@ public class HttpsProxy implements EventListener { private SslContextManager sslContextManager; @Override - public void onEvent(AppLoadEndEvent appLoadEndEvent) throws Throwable { - if (null == proxyConfig.getServer().getTcp().getHttpsProxyPort() || - StringUtils.isEmpty(proxyConfig.getServer().getTcp().getJksPath()) || StringUtils.isEmpty(proxyConfig.getServer().getTcp().getKeyStorePassword())) { - log.info("no config domain name,nonsupport https proxy."); - return; - } + public void onEvent(AppLoadEndEvent appLoadEndEvent) { this.start(); } diff --git a/neutrino-proxy-server/src/main/resources/app-copy.yml b/neutrino-proxy-server/src/main/resources/app-copy.yml index e7360e41..44045e4b 100644 --- a/neutrino-proxy-server/src/main/resources/app-copy.yml +++ b/neutrino-proxy-server/src/main/resources/app-copy.yml @@ -1,63 +1,100 @@ server: # 服务端web端口,用于支持HTTP接口,管理后台页面访问 - port: 8888 + port: ${WEB_PORT:8888} + context-path: /neutrino-proxy-server +solon: + app: + name: neutrino-proxy-server + version: 2.0.1 + config: + add: ./app.yml # 日志级别 -solon.logging: - logger: - "root": - level: info - appender: - file: - level: info +solon.logging.appender: + console: + pattern: "%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) %magenta(${PID:-}) --- %-15([%15.15thread]) %-56(%cyan(%-40.40logger{39}%L)) : %msg%n" + file: + enable: true + pattern: "%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level ${PID:-} --- %-15([%15.15thread]) %-56(%-40.40logger{39}%L) : %msg%n" + name: "logs/${solon.app.name}" + rolling: "logs/${solon.app.name}_%d{yyyy-MM-dd}_%i.log" +solon.logging.logger: + "root": + level: info neutrino: proxy: + protocol: + max-frame-length: ${MAX_FRAME_LENGTH:2097152} + length-field-offset: 0 + length-field-length: 4 + initial-bytes-to-strip: 0 + length-adjustment: 0 + read-idle-time: 120 + write-idle-time: 20 + all-idle-time-seconds: 0 # 隧道相关配置-用于维持服务端与客户端的通信 tunnel: # 线程池相关配置,用于技术调优,可忽略 boss-thread-count: 2 work-thread-count: 10 # 隧道非SSL端口 - port: 9000 + port: ${OPEN_PORT:9000} # 隧道SSL端口 - ssl-port: 9002 + ssl-port: ${SSL_PORT:9002} # 隧道SSL证书配置 - key-store-password: 123456 - key-manager-password: 123456 - jks-path: classpath:/test.jks + key-store-password: ${STORE_PASS:123456} + key-manager-password: ${MGR_PASS:123456} + jks-path: ${JKS_PATH:classpath:/test.jks} # 是否开启隧道传输报文日志(日志级别为debug时开启才有效) - transfer-log-enable: false + transfer-log-enable: ${TUNNEL_LOG:false} # 是否开启心跳日志 - heartbeat-log-enable: false + heartbeat-log-enable: ${HEARTBEAT_LOG:false} server: tcp: # 线程池相关配置,用于技术调优,可忽略 boss-thread-count: 5 work-thread-count: 20 # http代理端口,默认80 - http-proxy-port: 80 + http-proxy-port: ${HTTP_PROXY_PORT:80} # https代理端口,默认443 (需要配置域名、证书) - https-proxy-port: 443 - # 如果不配置,则不支持域名映射 - domain-name: - # https证书配置 - key-store-password: - jks-path: + https-proxy-port: ${HTTPS_PROXY_PORT:443} # 是否开启代理服务报文日志(日志级别为debug时开启才有效) - transfer-log-enable: false + transfer-log-enable: ${SERVER_LOG:false} udp: # 线程池相关配置,用于技术调优,可忽略 boss-thread-count: 5 work-thread-count: 20 # 是否开启代理服务报文日志(日志级别为debug时开启才有效) - transfer-log-enable: false + transfer-log-enable: ${SERVER_LOG:false} data: db: # 数据库类型,目前支持h2、mysql、mariadb - type: h2 + type: ${DB_TYPE:h2} # 数据库连接URL - url: jdbc:h2:file:./data/db;MODE=MySQL;AUTO_SERVER=TRUE + url: ${DB_URL:jdbc:h2:file:./data/db;MODE=MySQL;AUTO_SERVER=TRUE} # 数据库用户名 - username: + username: ${DB_USER:} # 数据库密码 - password: + password: ${DB_PASSWORD:} + +#添加MIME印射(如果有需要?) +#是否启用静态文件服务。(可不配,默认为启用) +solon.staticfiles.enable: true +#静态文件的304缓存时长。(可不配,默认为10分钟) +solon.staticfiles.maxAge: 600 +#添加静态目录映射。(按需选择)#v1.11.0 后支持 +solon.staticfiles.mappings: + - path: "/" + repository: "./neutrino-proxy-admin/dist/" #2.添加资源路径(仓库只能是目录) + +mybatis.db: + typeAliases: #支持包名 或 类名(大写开头 或 *)//支持 ** 或 * 占位符 + - "org.dromara.neutrinoproxy.server.dal.entity" + mappers: #支持包名 或 类名(大写开头 或 *)或 xml(.xml结尾)//支持 ** 或 * 占位符 + - "classpath:mapper/*.xml" + - "org.dromara.neutrinoproxy.server.dal" + configuration: #扩展配置(要与 MybatisConfiguration 类的属性一一对应) + cacheEnabled: false + mapUnderscoreToCamelCase: true + globalConfig: #全局配置(要与 GlobalConfig 类的属性一一对应) + banner: true diff --git a/neutrino-proxy-server/src/main/resources/app.yml b/neutrino-proxy-server/src/main/resources/app.yml index cbdfa3a6..8cd614c5 100644 --- a/neutrino-proxy-server/src/main/resources/app.yml +++ b/neutrino-proxy-server/src/main/resources/app.yml @@ -19,7 +19,7 @@ solon.logging.appender: rolling: "logs/${solon.app.name}_%d{yyyy-MM-dd}_%i.log" solon.logging.logger: "root": - level: info + level: debug neutrino: proxy: @@ -58,9 +58,6 @@ neutrino: http-proxy-port: ${HTTP_PROXY_PORT:80} # https代理端口,默认443 (需要配置域名、证书) https-proxy-port: ${HTTPS_PROXY_PORT:443} - # https证书配置 - key-store-password: ${HTTPS_STORE_PASS:} - jks-path: ${HTTPS_JKS_PATH:} # 是否开启代理服务报文日志(日志级别为debug时开启才有效) transfer-log-enable: ${SERVER_LOG:false} udp: diff --git a/neutrino-proxy-server/src/main/resources/sql/mysql/init-structure.sql b/neutrino-proxy-server/src/main/resources/sql/mysql/init-structure.sql index 620c7740..d84d5d13 100644 --- a/neutrino-proxy-server/src/main/resources/sql/mysql/init-structure.sql +++ b/neutrino-proxy-server/src/main/resources/sql/mysql/init-structure.sql @@ -118,7 +118,6 @@ CREATE TABLE IF NOT EXISTS `port_mapping` ( `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID', `license_id` int NOT NULL COMMENT 'licenseID', `protocal` varchar(10) NOT NULL DEFAULT 'TCP' COMMENT '协议', - `subdomain` varchar(50) DEFAULT NULL COMMENT '子域名(仅HTTP时有效)', `server_port` int NOT NULL COMMENT '服务端端口', `client_ip` varchar(20) NOT NULL COMMENT '客户端IP', `client_port` int NOT NULL COMMENT '客户端端口', @@ -135,6 +134,34 @@ CREATE TABLE IF NOT EXISTS `port_mapping` ( PRIMARY KEY (`id`), KEY `I_port_mapping_server_port` (`server_port`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +#域名表 +CREATE TABLE IF NOT EXISTS `domain_name` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `domain` varchar(50) NOT NULL COMMENT '域名', + `user_id` int NOT NULL COMMENT '用户Id', + `jks` BLOB DEFAULT NULL COMMENT 'jks文件', + `key_store_password` varchar(255) DEFAULT NULL COMMENT 'jks密码', + `is_default` int(2) NOT NULL COMMENT '是否开启默认域名(1、开启 2、关闭)', + `force_https` int(2) NOT NULL COMMENT '是否启用强制https(1、开启 2、关闭)', + `enable` int(2) NOT NULL COMMENT '是否启用(1、启用 2、禁用)', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_time` datetime NOT NULL COMMENT '更新时间', + PRIMARY KEY (`id`), + UNIQUE INDEX `I_domain_name_domain` (`domain` ASC) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +#域映射中间表 +CREATE TABLE IF NOT EXISTS `domain_port_mapping` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '创建时间', + `subdomain` varchar(50) NOT NULL COMMENT '子域名', + `domain_name_id` int NOT NULL COMMENT '域名Id', + `port_mapping_id` int NOT NULL COMMENT '端口映射Id', + PRIMARY KEY (`id`), + UNIQUE INDEX `I_unique_domain_port_mapping` (`domain_name_id` ASC, `subdomain` ASC), + INDEX `I_domain_port_mapping_domain_name_id` (`domain_name_id` ASC), + INDEX `I_domain_port_mapping_port_mapping_id` (`port_mapping_id` ASC) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; #############################日志管理相关表############################# #用户登录记录表 CREATE TABLE IF NOT EXISTS `user_login_record` ( diff --git a/neutrino-proxy-server/src/main/resources/sql/mysql/port_mapping.data.sql b/neutrino-proxy-server/src/main/resources/sql/mysql/port_mapping.data.sql index 9063ecea..d1b7ef40 100644 --- a/neutrino-proxy-server/src/main/resources/sql/mysql/port_mapping.data.sql +++ b/neutrino-proxy-server/src/main/resources/sql/mysql/port_mapping.data.sql @@ -1,7 +1,7 @@ #port_mapping -INSERT INTO port_mapping(`id`, `license_id`, `server_port`, `protocal`, `subdomain`, `client_ip`, `client_port`, `is_online`, `enable`, `create_time`, `update_time`) VALUES -(1, 1, 9101, 'HTTP', 'test1', '127.0.0.1', 8080, 2, 1, now(), now()); -INSERT INTO port_mapping(`id`, `license_id`, `server_port`, `protocal`, `subdomain`, `client_ip`, `client_port`, `is_online`, `enable`, `create_time`, `update_time`) VALUES -(2, 1, 9102, 'TCP', '', '127.0.0.1', 3306, 2, 1, now(), now()); -INSERT INTO port_mapping(`id`, `license_id`, `server_port`, `protocal`, `subdomain`, `client_ip`, `client_port`, `is_online`, `enable`, `create_time`, `update_time`) VALUES -(3, 1, 9103, 'HTTP', 'test2', '127.0.0.1', 8081, 2, 1, now(), now()); +INSERT INTO port_mapping(`id`, `license_id`, `server_port`, `protocal`, `client_ip`, `client_port`, `is_online`, `enable`, `create_time`, `update_time`) VALUES +(1, 1, 9101, 'HTTP', '127.0.0.1', 8080, 2, 1, now(), now()); +INSERT INTO port_mapping(`id`, `license_id`, `server_port`, `protocal`, `client_ip`, `client_port`, `is_online`, `enable`, `create_time`, `update_time`) VALUES +(2, 1, 9102, 'TCP', '127.0.0.1', 3306, 2, 1, now(), now()); +INSERT INTO port_mapping(`id`, `license_id`, `server_port`, `protocal`, `client_ip`, `client_port`, `is_online`, `enable`, `create_time`, `update_time`) VALUES +(3, 1, 9103, 'HTTP', '127.0.0.1', 8081, 2, 1, now(), now()); diff --git a/neutrino-proxy-server/src/main/resources/sql/mysql/update/UPDATE-20240808.SQL b/neutrino-proxy-server/src/main/resources/sql/mysql/update/UPDATE-20240808.SQL new file mode 100644 index 00000000..c9673166 --- /dev/null +++ b/neutrino-proxy-server/src/main/resources/sql/mysql/update/UPDATE-20240808.SQL @@ -0,0 +1,30 @@ +#域名表 +CREATE TABLE IF NOT EXISTS `domain_name` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `domain` varchar(50) NOT NULL COMMENT '域名', + `user_id` int NOT NULL COMMENT '用户Id', + `jks` BLOB DEFAULT NULL COMMENT 'jks文件', + `key_store_password` varchar(255) DEFAULT NULL COMMENT 'jks密码', + `is_default` int(2) NOT NULL COMMENT '是否开启默认域名(1、开启 2、关闭)', + `force_https` int(2) NOT NULL COMMENT '是否启用强制https(1、开启 2、关闭)', + `enable` int(2) NOT NULL COMMENT '是否启用(1、启用 2、禁用)', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_time` datetime NOT NULL COMMENT '更新时间', + PRIMARY KEY (`id`), + UNIQUE INDEX `I_domain_name_domain` (`domain` ASC) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +#域映射中间表 +CREATE TABLE IF NOT EXISTS `domain_port_mapping` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '创建时间', + `subdomain` varchar(50) NOT NULL COMMENT '子域名', + `domain_name_id` int NOT NULL COMMENT '域名Id', + `port_mapping_id` int NOT NULL COMMENT '端口映射Id', + PRIMARY KEY (`id`), + UNIQUE INDEX `I_unique_domain_port_mapping` (`domain_name_id` ASC, `subdomain` ASC), + INDEX `I_domain_port_mapping_domain_name_id` (`domain_name_id` ASC), + INDEX `I_domain_port_mapping_port_mapping_id` (`port_mapping_id` ASC) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +# port_mapping表删除字段 +ALTER TABLE `port_mapping` DROP COLUMN `subdomain`; \ No newline at end of file