Refactor grpc tls (#10759)
* Move Tls negotiator to GrpcSdkServer. * use protocol negotiator builder replace directly create. * use SPI load negotiator and set tls as default negotiator. * Remove tlsconfig in BaseRpcServer. * Add some ut. * For checkstyle.
This commit is contained in:
parent
a83e2cc542
commit
9069730a04
@ -54,7 +54,7 @@ public class ServiceInfoUpdateServiceTest {
|
||||
notifyer);
|
||||
|
||||
serviceInfoUpdateService.scheduleUpdateIfAbsent("aa", "bb", "cc");
|
||||
TimeUnit.SECONDS.sleep(2);
|
||||
TimeUnit.MILLISECONDS.sleep(1500);
|
||||
Mockito.verify(proxy).queryInstancesOfService(serviceName, group, clusters, 0, false);
|
||||
}
|
||||
|
||||
|
@ -18,10 +18,9 @@ package com.alibaba.nacos.core.remote;
|
||||
|
||||
import com.alibaba.nacos.common.remote.ConnectionType;
|
||||
import com.alibaba.nacos.common.remote.PayloadRegistry;
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.core.remote.tls.RpcServerSslContextRefresherHolder;
|
||||
import com.alibaba.nacos.core.utils.Loggers;
|
||||
import com.alibaba.nacos.sys.env.EnvUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
@ -38,18 +37,13 @@ public abstract class BaseRpcServer {
|
||||
PayloadRegistry.init();
|
||||
}
|
||||
|
||||
@Autowired
|
||||
protected RpcServerTlsConfig rpcServerTlsConfig;
|
||||
|
||||
/**
|
||||
* Start sever.
|
||||
*/
|
||||
@PostConstruct
|
||||
public void start() throws Exception {
|
||||
String serverName = getClass().getSimpleName();
|
||||
String tlsConfig = JacksonUtils.toJson(rpcServerTlsConfig);
|
||||
Loggers.REMOTE.info("Nacos {} Rpc server starting at port {} and tls config:{}", serverName, getServicePort(),
|
||||
tlsConfig);
|
||||
Loggers.REMOTE.info("Nacos {} Rpc server starting at port {}", serverName, getServicePort());
|
||||
|
||||
startServer();
|
||||
|
||||
@ -57,8 +51,7 @@ public abstract class BaseRpcServer {
|
||||
RpcServerSslContextRefresherHolder.getInstance().refresh(this);
|
||||
}
|
||||
|
||||
Loggers.REMOTE.info("Nacos {} Rpc server started at port {} and tls config:{}", serverName, getServicePort(),
|
||||
tlsConfig);
|
||||
Loggers.REMOTE.info("Nacos {} Rpc server started at port {}", serverName, getServicePort());
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||
Loggers.REMOTE.info("Nacos {} Rpc server stopping", serverName);
|
||||
try {
|
||||
@ -78,18 +71,15 @@ public abstract class BaseRpcServer {
|
||||
*/
|
||||
public abstract ConnectionType getConnectionType();
|
||||
|
||||
public RpcServerTlsConfig getRpcServerTlsConfig() {
|
||||
return rpcServerTlsConfig;
|
||||
}
|
||||
|
||||
public void setRpcServerTlsConfig(RpcServerTlsConfig rpcServerTlsConfig) {
|
||||
this.rpcServerTlsConfig = rpcServerTlsConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* reload ssl context.
|
||||
* Reload protocol context if necessary.
|
||||
*
|
||||
* <p>
|
||||
* protocol like:
|
||||
* <li>Tls</li>
|
||||
* </p>
|
||||
*/
|
||||
public abstract void reloadSslContext();
|
||||
public abstract void reloadProtocolContext();
|
||||
|
||||
/**
|
||||
* Start sever.
|
||||
|
@ -17,14 +17,7 @@
|
||||
package com.alibaba.nacos.core.remote.grpc;
|
||||
|
||||
import com.alibaba.nacos.api.grpc.auto.Payload;
|
||||
import com.alibaba.nacos.common.packagescan.resource.DefaultResourceLoader;
|
||||
import com.alibaba.nacos.common.packagescan.resource.Resource;
|
||||
import com.alibaba.nacos.common.packagescan.resource.ResourceLoader;
|
||||
import com.alibaba.nacos.common.remote.ConnectionType;
|
||||
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.common.utils.TlsTypeResolve;
|
||||
import com.alibaba.nacos.core.remote.BaseRpcServer;
|
||||
import com.alibaba.nacos.core.remote.ConnectionManager;
|
||||
import com.alibaba.nacos.core.utils.Loggers;
|
||||
@ -37,22 +30,14 @@ import io.grpc.ServerCallHandler;
|
||||
import io.grpc.ServerInterceptor;
|
||||
import io.grpc.ServerInterceptors;
|
||||
import io.grpc.ServerServiceDefinition;
|
||||
import io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts;
|
||||
import io.grpc.netty.shaded.io.grpc.netty.InternalProtocolNegotiator;
|
||||
import io.grpc.netty.shaded.io.grpc.netty.NettyServerBuilder;
|
||||
import io.grpc.netty.shaded.io.netty.handler.ssl.ClientAuth;
|
||||
import io.grpc.netty.shaded.io.netty.handler.ssl.SslContext;
|
||||
|
||||
import io.grpc.netty.shaded.io.netty.handler.ssl.SslContextBuilder;
|
||||
import io.grpc.netty.shaded.io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
import io.grpc.protobuf.ProtoUtils;
|
||||
import io.grpc.stub.ServerCalls;
|
||||
import io.grpc.util.MutableHandlerRegistry;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.net.ssl.SSLException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@ -66,8 +51,6 @@ public abstract class BaseGrpcServer extends BaseRpcServer {
|
||||
|
||||
private Server server;
|
||||
|
||||
private final ResourceLoader resourceLoader = new DefaultResourceLoader();
|
||||
|
||||
@Autowired
|
||||
private GrpcRequestAcceptor grpcCommonRequestAcceptor;
|
||||
|
||||
@ -77,8 +60,6 @@ public abstract class BaseGrpcServer extends BaseRpcServer {
|
||||
@Autowired
|
||||
private ConnectionManager connectionManager;
|
||||
|
||||
private OptionalTlsProtocolNegotiator optionalTlsProtocolNegotiator;
|
||||
|
||||
@Override
|
||||
public ConnectionType getConnectionType() {
|
||||
return ConnectionType.GRPC;
|
||||
@ -90,10 +71,11 @@ public abstract class BaseGrpcServer extends BaseRpcServer {
|
||||
addServices(handlerRegistry, new GrpcConnectionInterceptor(), new GrpcServerParamCheckInterceptor());
|
||||
NettyServerBuilder builder = NettyServerBuilder.forPort(getServicePort()).executor(getRpcExecutor());
|
||||
|
||||
if (rpcServerTlsConfig.getEnableTls()) {
|
||||
builder.protocolNegotiator(
|
||||
new OptionalTlsProtocolNegotiator(getSslContextBuilder(), rpcServerTlsConfig.getCompatibility()));
|
||||
|
||||
Optional<InternalProtocolNegotiator.ProtocolNegotiator> negotiator = newProtocolNegotiator();
|
||||
if (negotiator.isPresent()) {
|
||||
InternalProtocolNegotiator.ProtocolNegotiator actual = negotiator.get();
|
||||
Loggers.REMOTE.info("Add protocol negotiator {}", actual.getClass().getCanonicalName());
|
||||
builder.protocolNegotiator(actual);
|
||||
}
|
||||
|
||||
server = builder.maxInboundMessageSize(getMaxInboundMessageSize()).fallbackHandlerRegistry(handlerRegistry)
|
||||
@ -107,20 +89,26 @@ public abstract class BaseGrpcServer extends BaseRpcServer {
|
||||
server.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadProtocolContext() {
|
||||
reloadProtocolNegotiator();
|
||||
}
|
||||
|
||||
/**
|
||||
* reload ssl context.
|
||||
* Build new one protocol negotiator.
|
||||
*
|
||||
* <p>Such as support tls, proxy protocol and so on</p>
|
||||
*
|
||||
* @return ProtocolNegotiator
|
||||
*/
|
||||
public void reloadSslContext() {
|
||||
if (optionalTlsProtocolNegotiator != null) {
|
||||
try {
|
||||
optionalTlsProtocolNegotiator.setSslContext(getSslContextBuilder());
|
||||
} catch (Throwable throwable) {
|
||||
Loggers.REMOTE.info("Nacos {} Rpc server reload ssl context fail at port {} and tls config:{}",
|
||||
this.getClass().getSimpleName(), getServicePort(),
|
||||
JacksonUtils.toJson(super.rpcServerTlsConfig));
|
||||
throw throwable;
|
||||
}
|
||||
}
|
||||
protected Optional<InternalProtocolNegotiator.ProtocolNegotiator> newProtocolNegotiator() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* reload protocol negotiator If necessary.
|
||||
*/
|
||||
public void reloadProtocolNegotiator() {
|
||||
}
|
||||
|
||||
protected long getPermitKeepAliveTime() {
|
||||
@ -136,8 +124,8 @@ public abstract class BaseGrpcServer extends BaseRpcServer {
|
||||
}
|
||||
|
||||
protected int getMaxInboundMessageSize() {
|
||||
Integer property = EnvUtil.getProperty(GrpcServerConstants.GrpcConfig.MAX_INBOUND_MSG_SIZE_PROPERTY,
|
||||
Integer.class);
|
||||
Integer property = EnvUtil
|
||||
.getProperty(GrpcServerConstants.GrpcConfig.MAX_INBOUND_MSG_SIZE_PROPERTY, Integer.class);
|
||||
if (property != null) {
|
||||
return property;
|
||||
}
|
||||
@ -148,8 +136,8 @@ public abstract class BaseGrpcServer extends BaseRpcServer {
|
||||
|
||||
// unary common call register.
|
||||
final MethodDescriptor<Payload, Payload> unaryPayloadMethod = MethodDescriptor.<Payload, Payload>newBuilder()
|
||||
.setType(MethodDescriptor.MethodType.UNARY).setFullMethodName(
|
||||
MethodDescriptor.generateFullMethodName(GrpcServerConstants.REQUEST_SERVICE_NAME,
|
||||
.setType(MethodDescriptor.MethodType.UNARY).setFullMethodName(MethodDescriptor
|
||||
.generateFullMethodName(GrpcServerConstants.REQUEST_SERVICE_NAME,
|
||||
GrpcServerConstants.REQUEST_METHOD_NAME))
|
||||
.setRequestMarshaller(ProtoUtils.marshaller(Payload.getDefaultInstance()))
|
||||
.setResponseMarshaller(ProtoUtils.marshaller(Payload.getDefaultInstance())).build();
|
||||
@ -157,8 +145,9 @@ public abstract class BaseGrpcServer extends BaseRpcServer {
|
||||
final ServerCallHandler<Payload, Payload> payloadHandler = ServerCalls.asyncUnaryCall(
|
||||
(request, responseObserver) -> grpcCommonRequestAcceptor.request(request, responseObserver));
|
||||
|
||||
final ServerServiceDefinition serviceDefOfUnaryPayload = ServerServiceDefinition.builder(
|
||||
GrpcServerConstants.REQUEST_SERVICE_NAME).addMethod(unaryPayloadMethod, payloadHandler).build();
|
||||
final ServerServiceDefinition serviceDefOfUnaryPayload = ServerServiceDefinition
|
||||
.builder(GrpcServerConstants.REQUEST_SERVICE_NAME).addMethod(unaryPayloadMethod, payloadHandler)
|
||||
.build();
|
||||
handlerRegistry.addService(ServerInterceptors.intercept(serviceDefOfUnaryPayload, serverInterceptor));
|
||||
|
||||
// bi stream register.
|
||||
@ -166,14 +155,15 @@ public abstract class BaseGrpcServer extends BaseRpcServer {
|
||||
(responseObserver) -> grpcBiStreamRequestAcceptor.requestBiStream(responseObserver));
|
||||
|
||||
final MethodDescriptor<Payload, Payload> biStreamMethod = MethodDescriptor.<Payload, Payload>newBuilder()
|
||||
.setType(MethodDescriptor.MethodType.BIDI_STREAMING).setFullMethodName(
|
||||
MethodDescriptor.generateFullMethodName(GrpcServerConstants.REQUEST_BI_STREAM_SERVICE_NAME,
|
||||
.setType(MethodDescriptor.MethodType.BIDI_STREAMING).setFullMethodName(MethodDescriptor
|
||||
.generateFullMethodName(GrpcServerConstants.REQUEST_BI_STREAM_SERVICE_NAME,
|
||||
GrpcServerConstants.REQUEST_BI_STREAM_METHOD_NAME))
|
||||
.setRequestMarshaller(ProtoUtils.marshaller(Payload.newBuilder().build()))
|
||||
.setResponseMarshaller(ProtoUtils.marshaller(Payload.getDefaultInstance())).build();
|
||||
|
||||
final ServerServiceDefinition serviceDefOfBiStream = ServerServiceDefinition.builder(
|
||||
GrpcServerConstants.REQUEST_BI_STREAM_SERVICE_NAME).addMethod(biStreamMethod, biStreamHandler).build();
|
||||
final ServerServiceDefinition serviceDefOfBiStream = ServerServiceDefinition
|
||||
.builder(GrpcServerConstants.REQUEST_BI_STREAM_SERVICE_NAME).addMethod(biStreamMethod, biStreamHandler)
|
||||
.build();
|
||||
handlerRegistry.addService(ServerInterceptors.intercept(serviceDefOfBiStream, serverInterceptor));
|
||||
|
||||
}
|
||||
@ -185,57 +175,6 @@ public abstract class BaseGrpcServer extends BaseRpcServer {
|
||||
}
|
||||
}
|
||||
|
||||
private SslContext getSslContextBuilder() {
|
||||
try {
|
||||
if (StringUtils.isBlank(rpcServerTlsConfig.getCertChainFile()) || StringUtils.isBlank(
|
||||
rpcServerTlsConfig.getCertPrivateKey())) {
|
||||
throw new IllegalArgumentException("Server certChainFile or certPrivateKey must be not null");
|
||||
}
|
||||
InputStream certificateChainFile = getInputStream(rpcServerTlsConfig.getCertChainFile(), "certChainFile");
|
||||
InputStream privateKeyFile = getInputStream(rpcServerTlsConfig.getCertPrivateKey(), "certPrivateKey");
|
||||
SslContextBuilder sslClientContextBuilder = SslContextBuilder.forServer(certificateChainFile,
|
||||
privateKeyFile, rpcServerTlsConfig.getCertPrivateKeyPassword());
|
||||
|
||||
if (StringUtils.isNotBlank(rpcServerTlsConfig.getProtocols())) {
|
||||
sslClientContextBuilder.protocols(rpcServerTlsConfig.getProtocols().split(","));
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(rpcServerTlsConfig.getCiphers())) {
|
||||
sslClientContextBuilder.ciphers(Arrays.asList(rpcServerTlsConfig.getCiphers().split(",")));
|
||||
}
|
||||
if (rpcServerTlsConfig.getMutualAuthEnable()) {
|
||||
// trust all certificate
|
||||
if (rpcServerTlsConfig.getTrustAll()) {
|
||||
sslClientContextBuilder.trustManager(InsecureTrustManagerFactory.INSTANCE);
|
||||
} else {
|
||||
if (StringUtils.isBlank(rpcServerTlsConfig.getTrustCollectionCertFile())) {
|
||||
throw new IllegalArgumentException(
|
||||
"enable mutual auth,trustCollectionCertFile must be not null");
|
||||
}
|
||||
|
||||
InputStream clientCert = getInputStream(rpcServerTlsConfig.getTrustCollectionCertFile(),
|
||||
"trustCollectionCertFile");
|
||||
sslClientContextBuilder.trustManager(clientCert);
|
||||
}
|
||||
sslClientContextBuilder.clientAuth(ClientAuth.REQUIRE);
|
||||
}
|
||||
SslContextBuilder configure = GrpcSslContexts.configure(sslClientContextBuilder,
|
||||
TlsTypeResolve.getSslProvider(rpcServerTlsConfig.getSslProvider()));
|
||||
return configure.build();
|
||||
} catch (SSLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private InputStream getInputStream(String path, String config) {
|
||||
try {
|
||||
Resource resource = resourceLoader.getResource(path);
|
||||
return resource.getInputStream();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(config + " load fail", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get rpc executor.
|
||||
*
|
||||
|
@ -48,8 +48,8 @@ public class GrpcClusterServer extends BaseGrpcServer {
|
||||
|
||||
@Override
|
||||
protected long getKeepAliveTime() {
|
||||
Long property = EnvUtil.getProperty(GrpcServerConstants.GrpcConfig.CLUSTER_KEEP_ALIVE_TIME_PROPERTY,
|
||||
Long.class);
|
||||
Long property = EnvUtil
|
||||
.getProperty(GrpcServerConstants.GrpcConfig.CLUSTER_KEEP_ALIVE_TIME_PROPERTY, Long.class);
|
||||
if (property != null) {
|
||||
return property;
|
||||
}
|
||||
@ -58,8 +58,8 @@ public class GrpcClusterServer extends BaseGrpcServer {
|
||||
|
||||
@Override
|
||||
protected long getKeepAliveTimeout() {
|
||||
Long property = EnvUtil.getProperty(GrpcServerConstants.GrpcConfig.CLUSTER_KEEP_ALIVE_TIMEOUT_PROPERTY,
|
||||
Long.class);
|
||||
Long property = EnvUtil
|
||||
.getProperty(GrpcServerConstants.GrpcConfig.CLUSTER_KEEP_ALIVE_TIMEOUT_PROPERTY, Long.class);
|
||||
if (property != null) {
|
||||
return property;
|
||||
}
|
||||
@ -68,8 +68,7 @@ public class GrpcClusterServer extends BaseGrpcServer {
|
||||
|
||||
@Override
|
||||
protected long getPermitKeepAliveTime() {
|
||||
Long property = EnvUtil.getProperty(GrpcServerConstants.GrpcConfig.CLUSTER_PERMIT_KEEP_ALIVE_TIME,
|
||||
Long.class);
|
||||
Long property = EnvUtil.getProperty(GrpcServerConstants.GrpcConfig.CLUSTER_PERMIT_KEEP_ALIVE_TIME, Long.class);
|
||||
if (property != null) {
|
||||
return property;
|
||||
}
|
||||
@ -78,8 +77,8 @@ public class GrpcClusterServer extends BaseGrpcServer {
|
||||
|
||||
@Override
|
||||
protected int getMaxInboundMessageSize() {
|
||||
Integer property = EnvUtil.getProperty(GrpcServerConstants.GrpcConfig.CLUSTER_MAX_INBOUND_MSG_SIZE_PROPERTY,
|
||||
Integer.class);
|
||||
Integer property = EnvUtil
|
||||
.getProperty(GrpcServerConstants.GrpcConfig.CLUSTER_MAX_INBOUND_MSG_SIZE_PROPERTY, Integer.class);
|
||||
if (property != null) {
|
||||
return property;
|
||||
}
|
||||
@ -92,5 +91,4 @@ public class GrpcClusterServer extends BaseGrpcServer {
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,11 +17,15 @@
|
||||
package com.alibaba.nacos.core.remote.grpc;
|
||||
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
import com.alibaba.nacos.core.remote.grpc.negotiator.NacosGrpcProtocolNegotiator;
|
||||
import com.alibaba.nacos.core.remote.grpc.negotiator.ProtocolNegotiatorBuilderSingleton;
|
||||
import com.alibaba.nacos.core.utils.GlobalExecutor;
|
||||
import com.alibaba.nacos.core.utils.Loggers;
|
||||
import com.alibaba.nacos.sys.env.EnvUtil;
|
||||
import io.grpc.netty.shaded.io.grpc.netty.InternalProtocolNegotiator;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
/**
|
||||
@ -33,6 +37,8 @@ import java.util.concurrent.ThreadPoolExecutor;
|
||||
@Service
|
||||
public class GrpcSdkServer extends BaseGrpcServer {
|
||||
|
||||
private NacosGrpcProtocolNegotiator protocolNegotiator;
|
||||
|
||||
@Override
|
||||
public int rpcPortOffset() {
|
||||
return Constants.SDK_GRPC_PORT_DEFAULT_OFFSET;
|
||||
@ -64,8 +70,8 @@ public class GrpcSdkServer extends BaseGrpcServer {
|
||||
|
||||
@Override
|
||||
protected int getMaxInboundMessageSize() {
|
||||
Integer property = EnvUtil.getProperty(GrpcServerConstants.GrpcConfig.SDK_MAX_INBOUND_MSG_SIZE_PROPERTY,
|
||||
Integer.class);
|
||||
Integer property = EnvUtil
|
||||
.getProperty(GrpcServerConstants.GrpcConfig.SDK_MAX_INBOUND_MSG_SIZE_PROPERTY, Integer.class);
|
||||
if (property != null) {
|
||||
return property;
|
||||
}
|
||||
@ -89,4 +95,26 @@ public class GrpcSdkServer extends BaseGrpcServer {
|
||||
}
|
||||
return super.getPermitKeepAliveTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<InternalProtocolNegotiator.ProtocolNegotiator> newProtocolNegotiator() {
|
||||
protocolNegotiator = ProtocolNegotiatorBuilderSingleton.getSingleton().build();
|
||||
return Optional.ofNullable(protocolNegotiator);
|
||||
}
|
||||
|
||||
/**
|
||||
* reload ssl context.
|
||||
*/
|
||||
public void reloadProtocolNegotiator() {
|
||||
if (protocolNegotiator != null) {
|
||||
try {
|
||||
protocolNegotiator.reloadNegotiator();
|
||||
} catch (Throwable throwable) {
|
||||
Loggers.REMOTE
|
||||
.info("Nacos {} Rpc server reload negotiator fail at port {}.", this.getClass().getSimpleName(),
|
||||
getServicePort());
|
||||
throw throwable;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.remote.grpc.negotiator;
|
||||
|
||||
import io.grpc.netty.shaded.io.grpc.netty.InternalProtocolNegotiator;
|
||||
|
||||
/**
|
||||
* Nacos Grpc protocol negotiator.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public interface NacosGrpcProtocolNegotiator extends InternalProtocolNegotiator.ProtocolNegotiator {
|
||||
|
||||
/**
|
||||
* Reload this negotiator, such as config, tls context and so on if necessary.
|
||||
*/
|
||||
void reloadNegotiator();
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.remote.grpc.negotiator;
|
||||
|
||||
/**
|
||||
* Protocol negotiator builder.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public interface ProtocolNegotiatorBuilder {
|
||||
|
||||
/**
|
||||
* Build new ProtocolNegotiator.
|
||||
*
|
||||
* @return ProtocolNegotiator, Nullable.
|
||||
*/
|
||||
NacosGrpcProtocolNegotiator build();
|
||||
|
||||
/**
|
||||
* Builder type of ProtocolNegotiator.
|
||||
*
|
||||
* @return type
|
||||
*/
|
||||
String type();
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.remote.grpc.negotiator;
|
||||
|
||||
import com.alibaba.nacos.common.spi.NacosServiceLoader;
|
||||
import com.alibaba.nacos.core.remote.grpc.negotiator.tls.DefaultTlsProtocolNegotiatorBuilder;
|
||||
import com.alibaba.nacos.core.utils.Loggers;
|
||||
import com.alibaba.nacos.sys.env.EnvUtil;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static com.alibaba.nacos.core.remote.grpc.negotiator.tls.DefaultTlsProtocolNegotiatorBuilder.TYPE_DEFAULT_TLS;
|
||||
|
||||
/**
|
||||
* Protocol Negotiator Builder Singleton.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public class ProtocolNegotiatorBuilderSingleton implements ProtocolNegotiatorBuilder {
|
||||
|
||||
private static final String TYPE_PROPERTY_KEY = "nacos.remote.server.rpc.protocol.negotiator.type";
|
||||
|
||||
private static final ProtocolNegotiatorBuilderSingleton SINGLETON = new ProtocolNegotiatorBuilderSingleton();
|
||||
|
||||
private final Map<String, ProtocolNegotiatorBuilder> builderMap;
|
||||
|
||||
private String actualType;
|
||||
|
||||
private ProtocolNegotiatorBuilderSingleton() {
|
||||
actualType = EnvUtil.getProperty(TYPE_PROPERTY_KEY, TYPE_DEFAULT_TLS);
|
||||
builderMap = new ConcurrentHashMap<>();
|
||||
loadAllBuilders();
|
||||
}
|
||||
|
||||
private void loadAllBuilders() {
|
||||
try {
|
||||
for (ProtocolNegotiatorBuilder each : NacosServiceLoader.load(ProtocolNegotiatorBuilder.class)) {
|
||||
builderMap.put(each.type(), each);
|
||||
Loggers.REMOTE.info("Load ProtocolNegotiatorBuilder {} for type {}", each.getClass().getCanonicalName(),
|
||||
each.type());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Loggers.REMOTE.warn("Load ProtocolNegotiatorBuilder failed, use default ProtocolNegotiatorBuilder", e);
|
||||
builderMap.put(TYPE_DEFAULT_TLS, new DefaultTlsProtocolNegotiatorBuilder());
|
||||
actualType = TYPE_DEFAULT_TLS;
|
||||
}
|
||||
}
|
||||
|
||||
public static ProtocolNegotiatorBuilderSingleton getSingleton() {
|
||||
return SINGLETON;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NacosGrpcProtocolNegotiator build() {
|
||||
ProtocolNegotiatorBuilder actualBuilder = builderMap.get(actualType);
|
||||
if (null == actualBuilder) {
|
||||
Loggers.REMOTE.warn("Not found ProtocolNegotiatorBuilder for type {}, will use default", actualType);
|
||||
return builderMap.get(TYPE_DEFAULT_TLS).build();
|
||||
}
|
||||
return actualBuilder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String type() {
|
||||
return actualType;
|
||||
}
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.remote.grpc.negotiator.tls;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.exception.runtime.NacosRuntimeException;
|
||||
import com.alibaba.nacos.common.packagescan.resource.DefaultResourceLoader;
|
||||
import com.alibaba.nacos.common.packagescan.resource.Resource;
|
||||
import com.alibaba.nacos.common.packagescan.resource.ResourceLoader;
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.common.utils.TlsTypeResolve;
|
||||
import com.alibaba.nacos.core.remote.tls.RpcServerTlsConfig;
|
||||
import com.alibaba.nacos.core.utils.Loggers;
|
||||
import io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts;
|
||||
import io.grpc.netty.shaded.io.netty.handler.ssl.ClientAuth;
|
||||
import io.grpc.netty.shaded.io.netty.handler.ssl.SslContext;
|
||||
import io.grpc.netty.shaded.io.netty.handler.ssl.SslContextBuilder;
|
||||
import io.grpc.netty.shaded.io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
|
||||
import javax.net.ssl.SSLException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Ssl context builder.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public class DefaultTlsContextBuilder {
|
||||
|
||||
private static final ResourceLoader RESOURCE_LOADER = new DefaultResourceLoader();
|
||||
|
||||
static SslContext getSslContext(RpcServerTlsConfig rpcServerTlsConfig) {
|
||||
try {
|
||||
if (StringUtils.isBlank(rpcServerTlsConfig.getCertChainFile()) || StringUtils
|
||||
.isBlank(rpcServerTlsConfig.getCertPrivateKey())) {
|
||||
throw new IllegalArgumentException("Server certChainFile or certPrivateKey must be not null");
|
||||
}
|
||||
InputStream certificateChainFile = getInputStream(rpcServerTlsConfig.getCertChainFile(), "certChainFile");
|
||||
InputStream privateKeyFile = getInputStream(rpcServerTlsConfig.getCertPrivateKey(), "certPrivateKey");
|
||||
SslContextBuilder sslClientContextBuilder = SslContextBuilder
|
||||
.forServer(certificateChainFile, privateKeyFile, rpcServerTlsConfig.getCertPrivateKeyPassword());
|
||||
|
||||
if (StringUtils.isNotBlank(rpcServerTlsConfig.getProtocols())) {
|
||||
sslClientContextBuilder.protocols(rpcServerTlsConfig.getProtocols().split(","));
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(rpcServerTlsConfig.getCiphers())) {
|
||||
sslClientContextBuilder.ciphers(Arrays.asList(rpcServerTlsConfig.getCiphers().split(",")));
|
||||
}
|
||||
if (rpcServerTlsConfig.getMutualAuthEnable()) {
|
||||
// trust all certificate
|
||||
if (rpcServerTlsConfig.getTrustAll()) {
|
||||
sslClientContextBuilder.trustManager(InsecureTrustManagerFactory.INSTANCE);
|
||||
} else {
|
||||
if (StringUtils.isBlank(rpcServerTlsConfig.getTrustCollectionCertFile())) {
|
||||
throw new IllegalArgumentException(
|
||||
"enable mutual auth,trustCollectionCertFile must be not null");
|
||||
}
|
||||
|
||||
InputStream clientCert = getInputStream(rpcServerTlsConfig.getTrustCollectionCertFile(),
|
||||
"trustCollectionCertFile");
|
||||
sslClientContextBuilder.trustManager(clientCert);
|
||||
}
|
||||
sslClientContextBuilder.clientAuth(ClientAuth.REQUIRE);
|
||||
}
|
||||
SslContextBuilder configure = GrpcSslContexts.configure(sslClientContextBuilder,
|
||||
TlsTypeResolve.getSslProvider(rpcServerTlsConfig.getSslProvider()));
|
||||
return configure.build();
|
||||
} catch (SSLException e) {
|
||||
Loggers.REMOTE.info("Nacos Rpc server reload ssl context fail tls config:{}",
|
||||
JacksonUtils.toJson(rpcServerTlsConfig));
|
||||
throw new NacosRuntimeException(NacosException.SERVER_ERROR, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static InputStream getInputStream(String path, String config) {
|
||||
try {
|
||||
Resource resource = RESOURCE_LOADER.getResource(path);
|
||||
return resource.getInputStream();
|
||||
} catch (IOException e) {
|
||||
throw new NacosRuntimeException(NacosException.SERVER_ERROR, config + " load fail", e);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.remote.grpc.negotiator.tls;
|
||||
|
||||
import com.alibaba.nacos.core.remote.grpc.negotiator.NacosGrpcProtocolNegotiator;
|
||||
import com.alibaba.nacos.core.remote.grpc.negotiator.ProtocolNegotiatorBuilder;
|
||||
import com.alibaba.nacos.core.remote.tls.RpcServerTlsConfig;
|
||||
import io.grpc.netty.shaded.io.netty.handler.ssl.SslContext;
|
||||
|
||||
/**
|
||||
* Default optional tls protocol negotiator builder.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public class DefaultTlsProtocolNegotiatorBuilder implements ProtocolNegotiatorBuilder {
|
||||
|
||||
public static final String TYPE_DEFAULT_TLS = "DEFAULT_TLS";
|
||||
|
||||
@Override
|
||||
public NacosGrpcProtocolNegotiator build() {
|
||||
RpcServerTlsConfig rpcServerTlsConfig = RpcServerTlsConfig.getInstance();
|
||||
if (rpcServerTlsConfig.getEnableTls()) {
|
||||
SslContext sslContext = DefaultTlsContextBuilder.getSslContext(rpcServerTlsConfig);
|
||||
return new OptionalTlsProtocolNegotiator(sslContext, rpcServerTlsConfig.getCompatibility());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String type() {
|
||||
return TYPE_DEFAULT_TLS;
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1999-2022 Alibaba Group Holding Ltd.
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -14,10 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.remote.grpc;
|
||||
package com.alibaba.nacos.core.remote.grpc.negotiator.tls;
|
||||
|
||||
import com.alibaba.nacos.core.remote.grpc.negotiator.NacosGrpcProtocolNegotiator;
|
||||
import com.alibaba.nacos.core.remote.tls.RpcServerTlsConfig;
|
||||
import io.grpc.netty.shaded.io.grpc.netty.GrpcHttp2ConnectionHandler;
|
||||
import io.grpc.netty.shaded.io.grpc.netty.InternalProtocolNegotiator;
|
||||
import io.grpc.netty.shaded.io.grpc.netty.InternalProtocolNegotiators;
|
||||
import io.grpc.netty.shaded.io.grpc.netty.ProtocolNegotiationEvent;
|
||||
import io.grpc.netty.shaded.io.netty.buffer.ByteBuf;
|
||||
@ -36,11 +37,11 @@ import java.util.List;
|
||||
*
|
||||
* @author githubcheng2978.
|
||||
*/
|
||||
public class OptionalTlsProtocolNegotiator implements InternalProtocolNegotiator.ProtocolNegotiator {
|
||||
public class OptionalTlsProtocolNegotiator implements NacosGrpcProtocolNegotiator {
|
||||
|
||||
private static final int MAGIC_VALUE = 5;
|
||||
|
||||
private boolean supportPlainText;
|
||||
private final boolean supportPlainText;
|
||||
|
||||
private SslContext sslContext;
|
||||
|
||||
@ -71,6 +72,14 @@ public class OptionalTlsProtocolNegotiator implements InternalProtocolNegotiator
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadNegotiator() {
|
||||
RpcServerTlsConfig rpcServerTlsConfig = RpcServerTlsConfig.getInstance();
|
||||
if (rpcServerTlsConfig.getEnableTls()) {
|
||||
sslContext = DefaultTlsContextBuilder.getSslContext(rpcServerTlsConfig);
|
||||
}
|
||||
}
|
||||
|
||||
private ProtocolNegotiationEvent getDefPne() {
|
||||
ProtocolNegotiationEvent protocolNegotiationEvent = null;
|
||||
try {
|
@ -1,13 +1,5 @@
|
||||
package com.alibaba.nacos.core.remote;
|
||||
|
||||
/**
|
||||
* ssl context refresher spi holder.
|
||||
*
|
||||
* @author liuzunfei
|
||||
* @version $Id: RequestFilters.java, v 0.1 2023年03月17日 12:00 PM liuzunfei Exp $
|
||||
*/
|
||||
/*
|
||||
* Copyright 1999-2020 Alibaba Group Holding Ltd.
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -22,6 +14,16 @@ package com.alibaba.nacos.core.remote;
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.remote.tls;
|
||||
|
||||
import com.alibaba.nacos.core.remote.BaseRpcServer;
|
||||
|
||||
/**
|
||||
* ssl context refresher spi holder.
|
||||
*
|
||||
* @author liuzunfei
|
||||
* @version $Id: RequestFilters.java, v 0.1 2023年03月17日 12:00 PM liuzunfei Exp $
|
||||
*/
|
||||
public interface RpcServerSslContextRefresher {
|
||||
|
||||
/**
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1999-2020 Alibaba Group Holding Ltd.
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -14,12 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.remote;
|
||||
package com.alibaba.nacos.core.remote.tls;
|
||||
|
||||
import com.alibaba.nacos.common.spi.NacosServiceLoader;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.core.utils.Loggers;
|
||||
import com.alibaba.nacos.sys.utils.ApplicationUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
@ -43,11 +42,11 @@ public class RpcServerSslContextRefresherHolder {
|
||||
if (init) {
|
||||
return instance;
|
||||
}
|
||||
RpcServerTlsConfig rpcServerTlsConfig = ApplicationUtils.getBean(RpcServerTlsConfig.class);
|
||||
RpcServerTlsConfig rpcServerTlsConfig = RpcServerTlsConfig.getInstance();
|
||||
String sslContextRefresher = rpcServerTlsConfig.getSslContextRefresher();
|
||||
if (StringUtils.isNotBlank(sslContextRefresher)) {
|
||||
Collection<RpcServerSslContextRefresher> load = NacosServiceLoader.load(
|
||||
RpcServerSslContextRefresher.class);
|
||||
Collection<RpcServerSslContextRefresher> load = NacosServiceLoader
|
||||
.load(RpcServerSslContextRefresher.class);
|
||||
for (RpcServerSslContextRefresher contextRefresher : load) {
|
||||
if (sslContextRefresher.equals(contextRefresher.getName())) {
|
||||
instance = contextRefresher;
|
||||
@ -61,8 +60,8 @@ public class RpcServerSslContextRefresherHolder {
|
||||
}
|
||||
|
||||
} else {
|
||||
Loggers.REMOTE.info(
|
||||
"No RpcServerSslContextRefresher specified,Ssl Context auto refresh not supported.");
|
||||
Loggers.REMOTE
|
||||
.info("No RpcServerSslContextRefresher specified,Ssl Context auto refresh not supported.");
|
||||
}
|
||||
|
||||
Loggers.REMOTE.info("RpcServerSslContextRefresher init end");
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1999-2022 Alibaba Group Holding Ltd.
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -14,32 +14,49 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.remote;
|
||||
package com.alibaba.nacos.core.remote.tls;
|
||||
|
||||
import com.alibaba.nacos.common.remote.TlsConfig;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.core.utils.Loggers;
|
||||
import com.alibaba.nacos.sys.env.EnvUtil;
|
||||
import com.alibaba.nacos.sys.utils.PropertiesUtil;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
/**
|
||||
* Grpc config.
|
||||
*
|
||||
* @author githubcheng2978.
|
||||
*/
|
||||
|
||||
@ConfigurationProperties(prefix = RpcServerTlsConfig.PREFIX)
|
||||
@Component
|
||||
public class RpcServerTlsConfig extends TlsConfig {
|
||||
|
||||
public static final String PREFIX = "nacos.remote.server.rpc.tls";
|
||||
|
||||
public static final String PREFIX = "nacos.remote.server.rpc.tls";
|
||||
|
||||
private static RpcServerTlsConfig instance;
|
||||
|
||||
private String sslContextRefresher = "";
|
||||
|
||||
private Boolean compatibility = true;
|
||||
|
||||
|
||||
public static synchronized RpcServerTlsConfig getInstance() {
|
||||
if (null == instance) {
|
||||
try {
|
||||
instance = PropertiesUtil
|
||||
.handleSpringBinder(EnvUtil.getEnvironment(), PREFIX, RpcServerTlsConfig.class);
|
||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | ClassNotFoundException e) {
|
||||
Loggers.REMOTE.warn("TLS config bind failed, use default value", e);
|
||||
instance = new RpcServerTlsConfig();
|
||||
}
|
||||
}
|
||||
Loggers.REMOTE.info("Nacos Rpc server tls config:{}", JacksonUtils.toJson(instance));
|
||||
return instance;
|
||||
}
|
||||
|
||||
public Boolean getCompatibility() {
|
||||
return compatibility;
|
||||
}
|
||||
|
||||
|
||||
public void setCompatibility(Boolean compatibility) {
|
||||
this.compatibility = compatibility;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1999-2020 Alibaba Group Holding Ltd.
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -14,7 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.remote;
|
||||
package com.alibaba.nacos.core.remote.tls;
|
||||
|
||||
import com.alibaba.nacos.core.remote.BaseRpcServer;
|
||||
|
||||
/**
|
||||
* ssl context refresher spi holder.
|
@ -0,0 +1,17 @@
|
||||
#
|
||||
# Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
com.alibaba.nacos.core.remote.grpc.negotiator.tls.DefaultTlsProtocolNegotiatorBuilder
|
@ -18,9 +18,9 @@
|
||||
package com.alibaba.nacos.core.remote.grpc;
|
||||
|
||||
import com.alibaba.nacos.common.remote.ConnectionType;
|
||||
import com.alibaba.nacos.core.remote.RpcServerTlsConfig;
|
||||
import com.alibaba.nacos.sys.env.EnvUtil;
|
||||
import com.alibaba.nacos.sys.utils.ApplicationUtils;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
@ -31,11 +31,6 @@ import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* {@link GrpcSdkServer} and {@link GrpcClusterServer} unit test.
|
||||
*
|
||||
@ -45,12 +40,12 @@ import static org.mockito.Mockito.when;
|
||||
@RunWith(MockitoJUnitRunner.Silent.class)
|
||||
public class GrpcServerTest {
|
||||
|
||||
private final RpcServerTlsConfig grpcServerConfig = mock(RpcServerTlsConfig.class);
|
||||
|
||||
static MockedStatic<ApplicationUtils> applicationUtilsMockedStatic = null;
|
||||
|
||||
private BaseGrpcServer grpcSdkServer;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() {
|
||||
public static void setUpBeforeClass() {
|
||||
EnvUtil.setEnvironment(new MockEnvironment());
|
||||
applicationUtilsMockedStatic = Mockito.mockStatic(ApplicationUtils.class);
|
||||
}
|
||||
@ -60,107 +55,27 @@ public class GrpcServerTest {
|
||||
applicationUtilsMockedStatic.close();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
if (null != grpcSdkServer) {
|
||||
grpcSdkServer.stopServer();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrpcSdkServer() throws Exception {
|
||||
BaseGrpcServer grpcSdkServer = new GrpcSdkServer();
|
||||
grpcSdkServer.setRpcServerTlsConfig(grpcServerConfig);
|
||||
when(grpcServerConfig.getEnableTls()).thenReturn(false);
|
||||
when(ApplicationUtils.getBean(RpcServerTlsConfig.class)).thenReturn(grpcServerConfig);
|
||||
grpcSdkServer = new GrpcSdkServer();
|
||||
grpcSdkServer.start();
|
||||
Assert.assertEquals(grpcSdkServer.getConnectionType(), ConnectionType.GRPC);
|
||||
Assert.assertEquals(grpcSdkServer.rpcPortOffset(), 1000);
|
||||
grpcSdkServer.stopServer();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrpcClusterServer() throws Exception {
|
||||
BaseGrpcServer grpcSdkServer = new GrpcClusterServer();
|
||||
grpcSdkServer.setRpcServerTlsConfig(grpcServerConfig);
|
||||
when(grpcServerConfig.getEnableTls()).thenReturn(false);
|
||||
when(ApplicationUtils.getBean(RpcServerTlsConfig.class)).thenReturn(grpcServerConfig);
|
||||
grpcSdkServer = new GrpcClusterServer();
|
||||
grpcSdkServer.start();
|
||||
Assert.assertEquals(grpcSdkServer.getConnectionType(), ConnectionType.GRPC);
|
||||
Assert.assertEquals(grpcSdkServer.rpcPortOffset(), 1001);
|
||||
grpcSdkServer.stopServer();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrpcEnableTls() throws Exception {
|
||||
final BaseGrpcServer grpcSdkServer = new BaseGrpcServer() {
|
||||
@Override
|
||||
public ThreadPoolExecutor getRpcExecutor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int rpcPortOffset() {
|
||||
return 100;
|
||||
}
|
||||
};
|
||||
when(grpcServerConfig.getEnableTls()).thenReturn(true);
|
||||
when(grpcServerConfig.getCiphers()).thenReturn("ECDHE-RSA-AES128-GCM-SHA256,ECDHE-RSA-AES256-GCM-SHA384");
|
||||
when(grpcServerConfig.getProtocols()).thenReturn("TLSv1.2,TLSv1.3");
|
||||
|
||||
when(grpcServerConfig.getCertPrivateKey()).thenReturn("test-server-key.pem");
|
||||
when(grpcServerConfig.getCertChainFile()).thenReturn("test-server-cert.pem");
|
||||
when(ApplicationUtils.getBean(RpcServerTlsConfig.class)).thenReturn(grpcServerConfig);
|
||||
grpcSdkServer.setRpcServerTlsConfig(grpcServerConfig);
|
||||
grpcSdkServer.start();
|
||||
grpcSdkServer.shutdownServer();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrpcEnableMutualAuthAndTrustAll() throws Exception {
|
||||
|
||||
final BaseGrpcServer grpcSdkServer = new BaseGrpcServer() {
|
||||
@Override
|
||||
public ThreadPoolExecutor getRpcExecutor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int rpcPortOffset() {
|
||||
return 100;
|
||||
}
|
||||
};
|
||||
|
||||
when(grpcServerConfig.getEnableTls()).thenReturn(true);
|
||||
when(grpcServerConfig.getTrustAll()).thenReturn(true);
|
||||
when(grpcServerConfig.getCiphers()).thenReturn("ECDHE-RSA-AES128-GCM-SHA256,ECDHE-RSA-AES256-GCM-SHA384");
|
||||
when(grpcServerConfig.getProtocols()).thenReturn("TLSv1.2,TLSv1.3");
|
||||
when(grpcServerConfig.getCertPrivateKey()).thenReturn("test-server-key.pem");
|
||||
when(grpcServerConfig.getCertChainFile()).thenReturn("test-server-cert.pem");
|
||||
grpcSdkServer.setRpcServerTlsConfig(grpcServerConfig);
|
||||
grpcSdkServer.start();
|
||||
grpcSdkServer.shutdownServer();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrpcEnableMutualAuthAndPart() throws Exception {
|
||||
final BaseGrpcServer grpcSdkServer = new BaseGrpcServer() {
|
||||
@Override
|
||||
public ThreadPoolExecutor getRpcExecutor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int rpcPortOffset() {
|
||||
return 100;
|
||||
}
|
||||
};
|
||||
when(grpcServerConfig.getEnableTls()).thenReturn(true);
|
||||
when(grpcServerConfig.getMutualAuthEnable()).thenReturn(true);
|
||||
when(grpcServerConfig.getEnableTls()).thenReturn(true);
|
||||
when(grpcServerConfig.getCiphers()).thenReturn("ECDHE-RSA-AES128-GCM-SHA256,ECDHE-RSA-AES256-GCM-SHA384");
|
||||
when(grpcServerConfig.getProtocols()).thenReturn("TLSv1.2,TLSv1.3");
|
||||
|
||||
when(grpcServerConfig.getCertPrivateKey()).thenReturn("test-server-key.pem");
|
||||
when(grpcServerConfig.getCertChainFile()).thenReturn("test-server-cert.pem");
|
||||
when(grpcServerConfig.getTrustCollectionCertFile()).thenReturn("test-ca-cert.pem");
|
||||
|
||||
grpcSdkServer.setRpcServerTlsConfig(grpcServerConfig);
|
||||
|
||||
grpcSdkServer.start();
|
||||
grpcSdkServer.shutdownServer();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.remote.grpc.negotiator.tls;
|
||||
|
||||
import com.alibaba.nacos.api.exception.runtime.NacosRuntimeException;
|
||||
import com.alibaba.nacos.core.remote.tls.RpcServerTlsConfig;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class DefaultTlsContextBuilderTest {
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
RpcServerTlsConfig.getInstance().setEnableTls(true);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
RpcServerTlsConfig.getInstance().setEnableTls(false);
|
||||
RpcServerTlsConfig.getInstance().setTrustAll(false);
|
||||
RpcServerTlsConfig.getInstance().setMutualAuthEnable(false);
|
||||
RpcServerTlsConfig.getInstance().setCertChainFile(null);
|
||||
RpcServerTlsConfig.getInstance().setCertPrivateKey(null);
|
||||
RpcServerTlsConfig.getInstance().setCiphers(null);
|
||||
RpcServerTlsConfig.getInstance().setProtocols(null);
|
||||
RpcServerTlsConfig.getInstance().setTrustCollectionCertFile(null);
|
||||
RpcServerTlsConfig.getInstance().setSslProvider("");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testGetSslContextIllegal() {
|
||||
DefaultTlsContextBuilder.getSslContext(RpcServerTlsConfig.getInstance());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSslContextWithoutMutual() {
|
||||
RpcServerTlsConfig grpcServerConfig = RpcServerTlsConfig.getInstance();
|
||||
grpcServerConfig.setCiphers("ECDHE-RSA-AES128-GCM-SHA256,ECDHE-RSA-AES256-GCM-SHA384");
|
||||
grpcServerConfig.setProtocols("TLSv1.2,TLSv1.3");
|
||||
grpcServerConfig.setCertPrivateKey("test-server-key.pem");
|
||||
grpcServerConfig.setCertChainFile("test-server-cert.pem");
|
||||
DefaultTlsContextBuilder.getSslContext(RpcServerTlsConfig.getInstance());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSslContextWithMutual() {
|
||||
RpcServerTlsConfig grpcServerConfig = RpcServerTlsConfig.getInstance();
|
||||
grpcServerConfig.setTrustAll(true);
|
||||
grpcServerConfig.setMutualAuthEnable(true);
|
||||
grpcServerConfig.setCiphers("ECDHE-RSA-AES128-GCM-SHA256,ECDHE-RSA-AES256-GCM-SHA384");
|
||||
grpcServerConfig.setProtocols("TLSv1.2,TLSv1.3");
|
||||
grpcServerConfig.setCertPrivateKey("test-server-key.pem");
|
||||
grpcServerConfig.setCertChainFile("test-server-cert.pem");
|
||||
DefaultTlsContextBuilder.getSslContext(RpcServerTlsConfig.getInstance());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSslContextWithMutualAndPart() {
|
||||
RpcServerTlsConfig grpcServerConfig = RpcServerTlsConfig.getInstance();
|
||||
grpcServerConfig.setMutualAuthEnable(true);
|
||||
grpcServerConfig.setCiphers("ECDHE-RSA-AES128-GCM-SHA256,ECDHE-RSA-AES256-GCM-SHA384");
|
||||
grpcServerConfig.setProtocols("TLSv1.2,TLSv1.3");
|
||||
grpcServerConfig.setCertPrivateKey("test-server-key.pem");
|
||||
grpcServerConfig.setCertChainFile("test-server-cert.pem");
|
||||
grpcServerConfig.setTrustCollectionCertFile("test-ca-cert.pem");
|
||||
DefaultTlsContextBuilder.getSslContext(RpcServerTlsConfig.getInstance());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testGetSslContextWithMutualAndPartIllegal() {
|
||||
RpcServerTlsConfig grpcServerConfig = RpcServerTlsConfig.getInstance();
|
||||
grpcServerConfig.setMutualAuthEnable(true);
|
||||
grpcServerConfig.setCiphers("ECDHE-RSA-AES128-GCM-SHA256,ECDHE-RSA-AES256-GCM-SHA384");
|
||||
grpcServerConfig.setProtocols("TLSv1.2,TLSv1.3");
|
||||
grpcServerConfig.setCertPrivateKey("test-server-key.pem");
|
||||
grpcServerConfig.setCertChainFile("test-server-cert.pem");
|
||||
DefaultTlsContextBuilder.getSslContext(RpcServerTlsConfig.getInstance());
|
||||
}
|
||||
|
||||
@Test(expected = NacosRuntimeException.class)
|
||||
public void testGetSslContextForNonExistFile() {
|
||||
RpcServerTlsConfig grpcServerConfig = RpcServerTlsConfig.getInstance();
|
||||
grpcServerConfig.setCiphers("ECDHE-RSA-AES128-GCM-SHA256,ECDHE-RSA-AES256-GCM-SHA384");
|
||||
grpcServerConfig.setProtocols("TLSv1.2,TLSv1.3");
|
||||
grpcServerConfig.setCertPrivateKey("non-exist-server-key.pem");
|
||||
grpcServerConfig.setCertChainFile("non-exist-cert.pem");
|
||||
DefaultTlsContextBuilder.getSslContext(RpcServerTlsConfig.getInstance());
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 1999-2023 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.core.remote.grpc.negotiator.tls;
|
||||
|
||||
import com.alibaba.nacos.core.remote.tls.RpcServerTlsConfig;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
public class DefaultTlsProtocolNegotiatorBuilderTest {
|
||||
|
||||
private DefaultTlsProtocolNegotiatorBuilder builder;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
builder = new DefaultTlsProtocolNegotiatorBuilder();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
RpcServerTlsConfig.getInstance().setEnableTls(false);
|
||||
RpcServerTlsConfig.getInstance().setCertChainFile(null);
|
||||
RpcServerTlsConfig.getInstance().setCertPrivateKey(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildDisabled() {
|
||||
assertNull(builder.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildEnabled() {
|
||||
RpcServerTlsConfig.getInstance().setEnableTls(true);
|
||||
RpcServerTlsConfig.getInstance().setCertPrivateKey("test-server-key.pem");
|
||||
RpcServerTlsConfig.getInstance().setCertChainFile("test-server-cert.pem");
|
||||
assertNotNull(builder.build());
|
||||
}
|
||||
}
|
@ -23,7 +23,7 @@ import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.client.config.NacosConfigService;
|
||||
import com.alibaba.nacos.client.config.listener.impl.AbstractConfigChangeListener;
|
||||
import com.alibaba.nacos.common.remote.client.RpcConstants;
|
||||
import com.alibaba.nacos.core.remote.RpcServerTlsConfig;
|
||||
import com.alibaba.nacos.core.remote.tls.RpcServerTlsConfig;
|
||||
import com.alibaba.nacos.test.base.ConfigCleanUtils;
|
||||
import org.junit.*;
|
||||
import org.junit.runner.RunWith;
|
||||
|
@ -23,7 +23,7 @@ import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.client.config.NacosConfigService;
|
||||
import com.alibaba.nacos.client.config.listener.impl.AbstractConfigChangeListener;
|
||||
import com.alibaba.nacos.common.remote.client.RpcConstants;
|
||||
import com.alibaba.nacos.core.remote.RpcServerTlsConfig;
|
||||
import com.alibaba.nacos.core.remote.tls.RpcServerTlsConfig;
|
||||
import com.alibaba.nacos.test.base.ConfigCleanUtils;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
|
@ -24,7 +24,7 @@ import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.client.config.NacosConfigService;
|
||||
import com.alibaba.nacos.client.config.listener.impl.AbstractConfigChangeListener;
|
||||
import com.alibaba.nacos.common.remote.client.RpcConstants;
|
||||
import com.alibaba.nacos.core.remote.RpcServerTlsConfig;
|
||||
import com.alibaba.nacos.core.remote.tls.RpcServerTlsConfig;
|
||||
import com.alibaba.nacos.test.base.ConfigCleanUtils;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
|
@ -25,7 +25,7 @@ import com.alibaba.nacos.common.remote.client.Connection;
|
||||
import com.alibaba.nacos.common.remote.client.RpcClient;
|
||||
import com.alibaba.nacos.common.remote.client.RpcClientFactory;
|
||||
import com.alibaba.nacos.common.remote.client.RpcClientTlsConfig;
|
||||
import com.alibaba.nacos.core.remote.RpcServerTlsConfig;
|
||||
import com.alibaba.nacos.core.remote.tls.RpcServerTlsConfig;
|
||||
import com.alibaba.nacos.test.ConfigCleanUtils;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
|
@ -25,7 +25,7 @@ import com.alibaba.nacos.common.remote.client.Connection;
|
||||
import com.alibaba.nacos.common.remote.client.RpcClient;
|
||||
import com.alibaba.nacos.common.remote.client.RpcClientFactory;
|
||||
import com.alibaba.nacos.common.remote.client.RpcClientTlsConfig;
|
||||
import com.alibaba.nacos.core.remote.RpcServerTlsConfig;
|
||||
import com.alibaba.nacos.core.remote.tls.RpcServerTlsConfig;
|
||||
import com.alibaba.nacos.test.ConfigCleanUtils;
|
||||
import org.junit.*;
|
||||
import org.junit.runner.RunWith;
|
||||
|
@ -25,7 +25,7 @@ import com.alibaba.nacos.common.remote.client.Connection;
|
||||
import com.alibaba.nacos.common.remote.client.RpcClient;
|
||||
import com.alibaba.nacos.common.remote.client.RpcClientFactory;
|
||||
import com.alibaba.nacos.common.remote.client.RpcClientTlsConfig;
|
||||
import com.alibaba.nacos.core.remote.RpcServerTlsConfig;
|
||||
import com.alibaba.nacos.core.remote.tls.RpcServerTlsConfig;
|
||||
import com.alibaba.nacos.sys.env.EnvUtil;
|
||||
import com.alibaba.nacos.test.ConfigCleanUtils;
|
||||
import org.junit.*;
|
||||
|
@ -27,7 +27,7 @@ import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
import com.alibaba.nacos.api.naming.pojo.Service;
|
||||
import com.alibaba.nacos.api.selector.ExpressionSelector;
|
||||
import com.alibaba.nacos.api.selector.NoneSelector;
|
||||
import com.alibaba.nacos.core.remote.RpcServerTlsConfig;
|
||||
import com.alibaba.nacos.core.remote.tls.RpcServerTlsConfig;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
|
@ -23,7 +23,7 @@ import com.alibaba.nacos.api.naming.NamingFactory;
|
||||
import com.alibaba.nacos.api.naming.NamingService;
|
||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
import com.alibaba.nacos.common.remote.client.RpcConstants;
|
||||
import com.alibaba.nacos.core.remote.RpcServerTlsConfig;
|
||||
import com.alibaba.nacos.core.remote.tls.RpcServerTlsConfig;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.FixMethodOrder;
|
||||
|
@ -23,7 +23,7 @@ import com.alibaba.nacos.api.naming.NamingFactory;
|
||||
import com.alibaba.nacos.api.naming.NamingService;
|
||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
import com.alibaba.nacos.common.remote.client.RpcConstants;
|
||||
import com.alibaba.nacos.core.remote.RpcServerTlsConfig;
|
||||
import com.alibaba.nacos.core.remote.tls.RpcServerTlsConfig;
|
||||
import org.junit.Assert;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Ignore;
|
||||
|
Loading…
Reference in New Issue
Block a user