Unable to resolve DNSname while enabling TLS for GRPC java with ame resolver

22 Views Asked by At

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.

0

There are 0 best solutions below