I am enabling TLS on grpc using grpc java api. I have couple of services A,b,C,D - all exporting differenent services from different servers
And then another set of services X,Y,Z - they opens connects to Grpc servers (A/B/C/D).
We are using Consul as service discover which maintain information about servers where GRPC servers (a/B/c/D) are deployed.
For enabling TLS, I am using below code on client side:
SslContext sslContext = GrpcSslContexts.forClient()
.trustManager(new File("rgroot.crt"))
.keyManager("rg.crt", "test.key")
.build();
ManagedChannel channel = NettyChannelBuilder
.forTarget(target)
.sslContext(sslContext)
.build();
In the above target is passed as
testscheme://servicename
Then testScheme is resolved by using below NameResolver
public class GrpcServicesNameResolver extends NameResolver {
private final URI targetURI;
private final Logger logger;
private final ServiceDiscovery serviceDiscovery;
public CatGrpcServicesNameResolver(final URI targetURI, final LoggerFactory loggerFactory, final Config config,
final ServiceDiscovery serviceDiscovery, final SharedResourceHolder.Resource<Executor> executorResource,
final Args args) {
this.targetURI = targetURI;
this.logger = loggerFactory.create(CatGrpcServicesNameResolver.class);
this.serviceDiscovery = serviceDiscovery;
this.executorResource = executorResource;
this.syncContext = checkNotNull(args.getSynchronizationContext(), "syncContext");
this.executor = args.getOffloadExecutor();
this.usingExecutorResource = executor == null;
listenerRef = new AtomicReference<>();
scheduledExecutorService = Executors.newScheduledThreadPool(1);
}
public String getServiceAuthority() {
return targetURI.getAuthority();
}
public void refresh() {
checkState(listenerRef.get() != null, "not started");
resolve();
}
public void scheduleRefreshCache() {
scheduledExecutorService.schedule(this::refresh, 10, TimeUnit.MINUTES);
}
private final class Resolve implements Runnable {
// The listener is stored in an extra variable to avoid NPEs if the resolver is shutdown while resolving
private final Listener2 savedListener;
/**
* Creates a new Resolve that stores a snapshot of the relevant states of the resolver.
*
* @param listener The listener to send the results to.
*/
Resolve(final Listener2 listener) {
this.savedListener = requireNonNull(listener, "listener");
}
@Override
public void run() {
final AtomicReference<InternalResolutionResult> resultContainer = new AtomicReference<>();
try {
final InternalResolutionResult result = doResolve();
resultContainer.set(result);
} catch (final Exception e) {
resultContainer.set(InternalResolutionResult.builder().error(Status.UNAVAILABLE.withCause(e)
.withDescription("Failed to update server list for " + targetURI.getScheme())).build());
} finally {
final InternalResolutionResult internalResolutionResult = resultContainer.get();
final boolean succeed = internalResolutionResult != null && internalResolutionResult.error == null;
if (succeed) {
this.savedListener.onResult(ResolutionResult.newBuilder().setAddresses(internalResolutionResult.getAddresses()).build());
} else {
this.savedListener.onError(internalResolutionResult.getError());
}
syncContext.execute(() -> {
if (succeed) {
resolved = true;
GrpcServicesNameResolver.this.resolvedResult.set(resultContainer.get());
scheduleRefreshCache();
}
resolving = false;
});
}
}}
I am facing below error:
Caused by: java.security.cert.CertificateException: No subject alternative DNS name matching test found.
at java.base/sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:212)
at java.base/sun.security.util.HostnameChecker.match(HostnameChecker.java:103)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:452)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:426)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:292)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:144)
at io.grpc.netty.shaded.io.netty.handler.ssl.ReferenceCountedOpenSslClientContext$ExtendedTrustManagerVerifyCallback.verify(ReferenceCountedOpenSslClientContext.java:234)
at io.grpc.netty.shaded.io.netty.handler.ssl.ReferenceCountedOpenSslContext$AbstractCertificateVerifier.verify(ReferenceCountedOpenSslContext.java:773)
at io.grpc.netty.shaded.io.netty.internal.tcnative.CertificateVerifierTask.runTask(CertificateVerifierTask.java:36)
at io.grpc.netty.shaded.io.netty.internal.tcnative.SSLTask.run(SSLTask.java:48)
at io.grpc.netty.shaded.io.netty.internal.tcnative.SSLTask.run(SSLTask.java:42)
at io.grpc.netty.shaded.io.netty.handler.ssl.ReferenceCountedOpenSslEngine.runAndResetNeedTask(ReferenceCountedOpenSslEngine.java:1496)
at io.grpc.netty.shaded.io.netty.handler.ssl.ReferenceCountedOpenSslEngine.access$700(ReferenceCountedOpenSslEngine.java:94)
at io.grpc.netty.shaded.io.netty.handler.ssl.ReferenceCountedOpenSslEngine$TaskDecorator.run(ReferenceCountedOpenSslEngine.java:1471)
at io.grpc.netty.shaded.io.netty.handler.ssl.SslHandler$SslTasksRunner.run(SslHandler.java:1787)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
As per hyperlink https://github.com/grpc/grpc-java/pull/2662, Name resolver is behaving correct. As I don't have server information available statically and I can not add service name in certificates, Can someone please suggest any alternatives or any resolution for this.