From b08bef691f73a34a45317632d40f43576c91dfff Mon Sep 17 00:00:00 2001 From: suxiang <2585546823@qq.com> Date: Tue, 17 Sep 2024 14:57:57 +0800 Subject: [PATCH] =?UTF-8?q?optimizer:=20=E6=9C=8D=E5=8A=A1=E5=99=A8?= =?UTF-8?q?=E8=AF=81=E4=B9=A6=E7=BB=B4=E6=8A=A4=E6=96=B0=E5=A2=9E=E5=88=A0?= =?UTF-8?q?=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/proxy/enhance/HttpsProxy.java | 39 +-------------- .../proxy/enhance/SslContextManager.java | 50 ++++++++----------- .../server/service/DomainService.java | 7 ++- 3 files changed, 30 insertions(+), 66 deletions(-) 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 1055fe73..d7b7bff7 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,7 +1,6 @@ package org.dromara.neutrinoproxy.server.proxy.enhance; import io.netty.bootstrap.ServerBootstrap; -import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelInitializer; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; @@ -9,9 +8,7 @@ import io.netty.channel.socket.nio.NioServerSocketChannel; 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 lombok.extern.slf4j.Slf4j; -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.security.HttpVisitorSecurityChannelHandler; @@ -21,13 +18,6 @@ import org.noear.solon.annotation.Inject; import org.noear.solon.core.event.AppLoadEndEvent; import org.noear.solon.core.event.EventListener; -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; - /** * HTTPS代理 * @author: aoshiguchen @@ -70,32 +60,6 @@ public class HttpsProxy implements EventListener { } } - private ChannelHandler createSslHandler() { - try { - InputStream jksInputStream = FileUtil.getInputStream(proxyConfig.getServer().getTcp().getJksPath()); - SSLContext serverContext = SSLContext.getInstance("TLS"); - final KeyStore ks = KeyStore.getInstance("JKS"); - - ks.load(jksInputStream, proxyConfig.getServer().getTcp().getKeyStorePassword().toCharArray()); - final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - kmf.init(ks, proxyConfig.getServer().getTcp().getKeyStorePassword().toCharArray()); - TrustManager[] trustManagers = null; - - serverContext.init(kmf.getKeyManagers(), trustManagers, null); - - - SSLEngine sslEngine = serverContext.createSSLEngine(); - sslEngine.setUseClientMode(false); - sslEngine.setNeedClientAuth(false); - - return new SslHandler(sslEngine); - } catch (Exception e) { - log.error("create SSL handler failed", e); - e.printStackTrace(); - } - return null; - } - public SniHandler createSniHandler() { try { return new SniHandler(domainName -> { @@ -103,7 +67,8 @@ public class HttpsProxy implements EventListener { if (sslContext != null) { return sslContext; } else { - throw new IllegalArgumentException("No SSL context available for domain: " + domainName); + log.info("No SSL context available for domain: {}", domainName); + return null; } }); } catch (Exception e) { diff --git a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/proxy/enhance/SslContextManager.java b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/proxy/enhance/SslContextManager.java index 9e6d1ecf..2b0c68c8 100644 --- a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/proxy/enhance/SslContextManager.java +++ b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/proxy/enhance/SslContextManager.java @@ -1,31 +1,20 @@ package org.dromara.neutrinoproxy.server.proxy.enhance; -import ch.qos.logback.core.net.ssl.SSL; import com.baomidou.mybatisplus.core.toolkit.Wrappers; -import io.netty.handler.codec.http.HttpUtil; import io.netty.handler.ssl.ClientAuth; -import io.netty.handler.ssl.SniHandler; import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslContextBuilder; -import io.netty.handler.ssl.util.SelfSignedCertificate; -import io.netty.util.DomainWildcardMappingBuilder; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.solon.annotation.Db; -import org.dromara.neutrinoproxy.core.util.FileUtil; -import org.dromara.neutrinoproxy.server.base.proxy.ProxyConfig; import org.dromara.neutrinoproxy.server.dal.DomainMapper; import org.dromara.neutrinoproxy.server.dal.entity.DomainNameDO; import org.dromara.neutrinoproxy.server.util.ProxyUtil; import org.noear.solon.annotation.Component; -import org.noear.solon.annotation.Http; import org.noear.solon.annotation.Init; -import org.noear.solon.annotation.Inject; import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; import java.io.ByteArrayInputStream; -import java.io.FileInputStream; import java.io.InputStream; import java.security.KeyStore; import java.util.List; @@ -58,23 +47,6 @@ public class SslContextManager { } } - // 使用 JKS 文件加载 SSL 上下文,禁用客户端认证并设置为服务器模式 - private SslContext loadSslContextFromJks(byte[] jks, String keyStorePassword) throws Exception { - InputStream jksInputStream = new ByteArrayInputStream(jks); - // 初始化 KeyStore - KeyStore keyStore = KeyStore.getInstance("JKS"); - keyStore.load(jksInputStream, keyStorePassword.toCharArray()); - - // 初始化 KeyManagerFactory - KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - kmf.init(keyStore, keyStorePassword.toCharArray()); - - // 创建 SslContext 并禁用客户端认证 - return SslContextBuilder.forServer(kmf) - .clientAuth(ClientAuth.NONE) // 禁用客户端认证 - .build(); - } - // 初始化所有域名的 SSL 上下文 private void initializeSslContexts() throws Exception { List domainNameDOS = domainMapper.selectList(Wrappers.lambdaQuery() @@ -99,10 +71,32 @@ public class SslContextManager { domainSslContexts.put(domain, sslContext); } + // 使用 JKS 文件加载 SSL 上下文,禁用客户端认证并设置为服务器模式 + private SslContext loadSslContextFromJks(byte[] jks, String keyStorePassword) throws Exception { + InputStream jksInputStream = new ByteArrayInputStream(jks); + // 初始化 KeyStore + KeyStore keyStore = KeyStore.getInstance("JKS"); + keyStore.load(jksInputStream, keyStorePassword.toCharArray()); + + // 初始化 KeyManagerFactory + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + kmf.init(keyStore, keyStorePassword.toCharArray()); + + // 创建 SslContext 并禁用客户端认证 + return SslContextBuilder.forServer(kmf) + .clientAuth(ClientAuth.NONE) // 禁用客户端认证 + .build(); + } + public SslContext getSslContextByDomain(String domain) { return domainSslContexts.get(domain); } + + public void removeSslContextByDomain(String domain) { + domainSslContexts.remove(domain); + } + public SslContext getSslContextByFullDomain(String fullDomain) { String domain = ProxyUtil.getDomainNameByFullDomain(fullDomain); return domainSslContexts.get(domain); diff --git a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/service/DomainService.java b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/service/DomainService.java index 649f7e02..f5a826ca 100644 --- a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/service/DomainService.java +++ b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/service/DomainService.java @@ -172,8 +172,11 @@ public class DomainService { byte[] byteArray = toByteArray(content); updateWrapper.set(DomainNameDO::getKeyStorePassword, req.getKeyStorePassword()); updateWrapper.set(DomainNameDO::getJks, byteArray); - //添加证书 + //添加证书并删除旧的证书 sslContextManager.addDomainAndCert(req.getDomain(), byteArray, req.getKeyStorePassword()); + if (!req.getDomain().equals(oldDomainNameDO.getDomain())) { + sslContextManager.removeSslContextByDomain(oldDomainNameDO.getDomain()); + } } catch (Exception e) { log.error("证书添加失败", e); e.printStackTrace(); @@ -225,6 +228,8 @@ public class DomainService { ProxyUtil.removeDomainToDomainNameId(domainNameDO.getDomain()); } domainMapper.deleteById(domainNameId); + //删除证书 + sslContextManager.removeSslContextByDomain(domainNameDO.getDomain()); } public DomainUpdateDefaultStatusRes updateDefaultStatus(Integer id, Integer isDefault) {