Need Help on tls config in java

Our client uses tls connection not the mtls. As we use jwt authorisation for the public front end. So our server config looks like below

frontend:
   server:
    requireClientAuth: true
    certFile: ./certificates/internode/cluster-internode.pem
    keyFile: ./certificates/internode/cluster-internode.key
    clientCaFiles:
     - ./certificates/internode/server-intermediate-ca.pem
   hostOverrides:
    temporal:
     requireClientAuth: false
     certFile: ./certificates/frontend/cluster-internode.pem
     keyFile: ./certificates/frontend/cluster-internode.key
     clientCaFiles:
      - ./certificates/frontend/server-intermediate-ca.pem

public endpoint should route to temporal i,e temporal:7233. It works fine with tctl .

tctl --address temporal:7233 --tls_ca_path ca.pem --headers_provider_plugin /usr/local/bin/tctl-authorization-plugin namespace list

But we cannot make it work with java client as it routes to the default server config. As it doesn’t find the server name . We see the logs in temporal server as below “server-name” is empty and it doesn’t recognise the host override.

{"level":"warn","ts":"2022-01-13T11:41:41.008Z","msg":"cannot find a per-host provider for attempted incoming TLS connection. returning default TLS configuration","server-name":"","address":"127.0.0.1:57946","logging-call-at":"localStoreTlsProvider.go:277"}

sslContext = SslContextBuilder
    .forClient().trustManager(this.getClass().getClassLoader().getResourceAsStream(prefix + "ca.pem"))
    .applicationProtocolConfig(
        new ApplicationProtocolConfig(
            ApplicationProtocolConfig.Protocol.ALPN,
            ApplicationProtocolConfig.SelectorFailureBehavior.CHOOSE_MY_LAST_PROTOCOL,
            ApplicationProtocolConfig.SelectedListenerFailureBehavior
                .CHOOSE_MY_LAST_PROTOCOL, "h2"))
    .clientAuth(ClientAuth.NONE).build();
 WorkflowServiceStubsOptions serviceStubOptions =
        WorkflowServiceStubsOptions.newBuilder()
            .addGrpcMetadataProvider(new AuthorizationGrpcMetadataProvider(tokenSupplier))
            .setTarget(config.getTemporalHostPort())
            .setSslContext(sslContext)
            .build();

We have narrowed it down to the the Netty/GRPC library behaviour where if the endpoint is supplied as temporal SNI is not getting added where if endpoint is temporal.local then SNI works just fine and the client TLS Hello contains the server name. It does look like the dot in the dns name makes a difference.

I think it has something to do with this:

Netty checks if a host name has a dot in it and if it doesn’t - it discards it as a valid SNI.

2 Likes

See

https://gamlor.info/posts-output/2019-09-05-java-client-sni/en/
It looks like you have to work with “temporal.local” and just “temporal” can not be used as a valid SNI name according to the spec.

@spikhalskiy Thanks