From c5fafa539ebca966180723c003c7531011050477 Mon Sep 17 00:00:00 2001 From: Kai Hudalla Date: Sat, 14 Oct 2023 16:16:16 +0200 Subject: [PATCH] [#3569] Use TLS endpoint when connecting to Sandbox The command line client was still trying to connect to the insecure ports of the Sandbox. This has been changed so that the client now uses the TLS endpoints and requires the user to specify a trust store for validating the server certificate. The Getting Started guide has been adapted accordingly. --- .../eclipse/hono/cli/app/NorthBoundApis.java | 54 +++++++++++-------- .../hono/cli/util/ConnectionOptions.java | 3 +- .../content/getting-started/_index.md | 4 +- 3 files changed, 35 insertions(+), 26 deletions(-) diff --git a/cli/src/main/java/org/eclipse/hono/cli/app/NorthBoundApis.java b/cli/src/main/java/org/eclipse/hono/cli/app/NorthBoundApis.java index 6e7adc73aa..2fe7d0f5d6 100644 --- a/cli/src/main/java/org/eclipse/hono/cli/app/NorthBoundApis.java +++ b/cli/src/main/java/org/eclipse/hono/cli/app/NorthBoundApis.java @@ -99,14 +99,23 @@ public class NorthBoundApis { ApplicationClient client; private void validateConnectionOptions() { - if (!connectionOptions.useSandbox && (connectionOptions.hostname.isEmpty() || connectionOptions.portNumber.isEmpty())) { + if (connectionOptions.useSandbox) { + if (!connectionOptions.trustStorePath.isPresent()) { + throw new ParameterException( + spec.commandLine(), + """ + Missing required option: '--ca-file=' needs to be specified \ + when using '--sandbox'. + """); + } + } else if (connectionOptions.hostname.isEmpty() || connectionOptions.portNumber.isEmpty()) { throw new ParameterException( spec.commandLine(), """ Missing required option: both '--host=' and '--port= need to \ - be specified if not using '--sandbox'. + be specified when not using '--sandbox'. """); - } + } } private String scramJaasConfig(final String username, final String password) { @@ -116,13 +125,25 @@ private String scramJaasConfig(final String username, final String password) { } Future createKafkaClient() { + + validateConnectionOptions(); final var commonProps = new HashMap(); final String bootstrapServers; + connectionOptions.trustStorePath + .ifPresent(path -> { + commonProps.put(SslConfigs.SSL_TRUSTSTORE_LOCATION_CONFIG, path); + connectionOptions.trustStorePassword + .ifPresent(pwd -> commonProps.put(SslConfigs.SSL_TRUSTSTORE_PASSWORD_CONFIG, pwd)); + + Optional.ofNullable(FileFormat.detect(path)) + .ifPresent(fileFormat -> commonProps.put(SslConfigs.SSL_TRUSTSTORE_TYPE_CONFIG, fileFormat.name())); + }); + if (connectionOptions.useSandbox) { - bootstrapServers = "%1$s:9092,%1$s:9094".formatted(ConnectionOptions.SANDBOX_HOST_NAME); + bootstrapServers = "%s:9094".formatted(ConnectionOptions.SANDBOX_HOST_NAME); commonProps.put(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); - commonProps.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, SecurityProtocol.SASL_PLAINTEXT.name); + commonProps.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, SecurityProtocol.SASL_SSL.name); commonProps.put(SaslConfigs.SASL_MECHANISM, ScramMechanism.SCRAM_SHA_512.mechanismName()); Optional.ofNullable(connectionOptions.credentials) .ifPresentOrElse( @@ -133,22 +154,11 @@ Future createKafkaClient() { SaslConfigs.SASL_JAAS_CONFIG, scramJaasConfig(SANDBOX_KAFKA_USER, SANDBOX_KAFKA_PWD))); } else { - validateConnectionOptions(); bootstrapServers = "%s:%d".formatted(connectionOptions.hostname.get(), connectionOptions.portNumber.get()); commonProps.put(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); - - connectionOptions.trustStorePath - .ifPresent(path -> { - commonProps.put(SslConfigs.SSL_TRUSTSTORE_LOCATION_CONFIG, path); - connectionOptions.trustStorePassword - .ifPresent(pwd -> commonProps.put(SslConfigs.SSL_TRUSTSTORE_PASSWORD_CONFIG, pwd)); - - Optional.ofNullable(FileFormat.detect(path)) - .ifPresent(s -> commonProps.put(SslConfigs.SSL_TRUSTSTORE_TYPE_CONFIG, s.name())); - if (connectionOptions.disableHostnameVerification) { - commonProps.put(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, ""); - } - }); + if (connectionOptions.disableHostnameVerification) { + commonProps.put(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, ""); + } if (connectionOptions.credentials == null) { if (connectionOptions.trustStorePath.isPresent()) { @@ -190,6 +200,7 @@ Future createKafkaClient() { Future createAmqpClient() { + validateConnectionOptions(); final var clientConfig = new ClientConfigProperties(); clientConfig.setReconnectAttempts(5); connectionOptions.trustStorePath.ifPresent(path -> { @@ -198,15 +209,12 @@ Future createAmqpClient() { }); if (connectionOptions.useSandbox) { clientConfig.setHost(ConnectionOptions.SANDBOX_HOST_NAME); - clientConfig.setPort(connectionOptions.trustStorePath.map(s -> 15671).orElse(15672)); + clientConfig.setPort(15671); clientConfig.setUsername(SANDBOX_AMQP_USER); clientConfig.setPassword(SANDBOX_AMQP_PWD); } else { - validateConnectionOptions(); connectionOptions.hostname.ifPresent(clientConfig::setHost); connectionOptions.portNumber.ifPresent(clientConfig::setPort); - connectionOptions.trustStorePath.ifPresent(clientConfig::setTrustStorePath); - connectionOptions.trustStorePassword.ifPresent(clientConfig::setTrustStorePassword); clientConfig.setHostnameVerificationRequired(!connectionOptions.disableHostnameVerification); Optional.ofNullable(connectionOptions.credentials) .ifPresent(creds -> { diff --git a/cli/src/main/java/org/eclipse/hono/cli/util/ConnectionOptions.java b/cli/src/main/java/org/eclipse/hono/cli/util/ConnectionOptions.java index 5b7d7fb83b..923ddb2882 100644 --- a/cli/src/main/java/org/eclipse/hono/cli/util/ConnectionOptions.java +++ b/cli/src/main/java/org/eclipse/hono/cli/util/ConnectionOptions.java @@ -59,7 +59,8 @@ public class ConnectionOptions { names = { "--ca-file" }, description = { "Absolute path to a file containing trusted CA certificates to enable encrypted communication.", - "If not set explicitly, the platform's default trust store will be used." + "Needs to be set if connecting to an endpoint using TLS.", + "In particular, this needs to be set when connecting to the Hono Sandbox." }, order = 4) public Optional trustStorePath; diff --git a/site/documentation/content/getting-started/_index.md b/site/documentation/content/getting-started/_index.md index 7328814409..7b8826291c 100644 --- a/site/documentation/content/getting-started/_index.md +++ b/site/documentation/content/getting-started/_index.md @@ -120,7 +120,7 @@ export REGISTRY_IP=hono.eclipseprojects.io export HTTP_ADAPTER_IP=hono.eclipseprojects.io export MQTT_ADAPTER_IP=hono.eclipseprojects.io export KAFKA_IP=hono.eclipseprojects.io -export APP_OPTIONS="-H hono.eclipseprojects.io -P 9094 --ca-file /etc/ssl/certs/ca-certificates.crt -u hono -p hono-secret" +export APP_OPTIONS="--sandbox --ca-file /etc/ssl/certs/ca-certificates.crt" export CURL_OPTIONS= export MOSQUITTO_OPTIONS='--cafile /etc/ssl/certs/ca-certificates.crt' EOS @@ -136,7 +136,7 @@ export REGISTRY_IP=hono.eclipseprojects.io export HTTP_ADAPTER_IP=hono.eclipseprojects.io export MQTT_ADAPTER_IP=hono.eclipseprojects.io export KAFKA_IP=hono.eclipseprojects.io -export APP_OPTIONS="-H hono.eclipseprojects.io -P 9094 --ca-file /etc/ssl/certs/ca-certificates.crt -u hono -p hono-secret" +export APP_OPTIONS="--sandbox --ca-file /etc/ssl/certs/ca-certificates.crt" export CURL_OPTIONS= export MOSQUITTO_OPTIONS='--cafile /etc/ssl/certs/ca-certificates.crt' ~~~