From 0b1f4fc6329c84eaa7ddc31ea1fef7cf3192f21a Mon Sep 17 00:00:00 2001 From: Tomas Dvorak Date: Thu, 30 Jan 2025 14:25:32 +0100 Subject: [PATCH 1/6] preflight check for password_secret --- .../bindings/PreflightChecksBindings.java | 45 ++++++++++ .../datanode/bootstrap/DatanodeBootstrap.java | 2 +- .../PasswordSecretPreflightCheck.java | 83 +++++++++++++++++++ .../preflight/PreflightEncryptedSecret.java | 22 +++++ .../ServerPreflightChecksModule.java | 1 + .../PasswordSecretPreflightCheckTest.java | 72 ++++++++++++++++ 6 files changed, 224 insertions(+), 1 deletion(-) create mode 100644 graylog2-server/src/main/java/org/graylog2/bootstrap/preflight/PasswordSecretPreflightCheck.java create mode 100644 graylog2-server/src/main/java/org/graylog2/bootstrap/preflight/PreflightEncryptedSecret.java create mode 100644 graylog2-server/src/test/java/org/graylog2/bootstrap/preflight/PasswordSecretPreflightCheckTest.java diff --git a/data-node/src/main/java/org/graylog/datanode/bindings/PreflightChecksBindings.java b/data-node/src/main/java/org/graylog/datanode/bindings/PreflightChecksBindings.java index 0f47e8502069..81f3fde3b464 100644 --- a/data-node/src/main/java/org/graylog/datanode/bindings/PreflightChecksBindings.java +++ b/data-node/src/main/java/org/graylog/datanode/bindings/PreflightChecksBindings.java @@ -16,8 +16,11 @@ */ package org.graylog.datanode.bindings; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.jsontype.NamedType; import com.google.inject.AbstractModule; import com.google.inject.multibindings.MapBinder; +import com.google.inject.multibindings.Multibinder; import org.graylog.datanode.bootstrap.preflight.DatanodeDirectoriesLockfileCheck; import org.graylog.datanode.bootstrap.preflight.DatanodeDnsPreflightCheck; import org.graylog.datanode.bootstrap.preflight.DatanodeKeystoreCheck; @@ -26,16 +29,35 @@ import org.graylog.datanode.bootstrap.preflight.OpensearchDataDirCompatibilityCheck; import org.graylog.datanode.opensearch.CsrRequester; import org.graylog.datanode.opensearch.CsrRequesterImpl; +import org.graylog.grn.GRNRegistry; import org.graylog2.bindings.providers.MongoConnectionProvider; import org.graylog2.bootstrap.preflight.MongoDBPreflightCheck; +import org.graylog2.bootstrap.preflight.PasswordSecretPreflightCheck; import org.graylog2.bootstrap.preflight.PreflightCheck; import org.graylog2.cluster.certificates.CertificateExchange; import org.graylog2.cluster.certificates.CertificateExchangeImpl; import org.graylog2.database.MongoConnection; +import org.graylog2.featureflag.FeatureFlags; +import org.graylog2.jackson.InputConfigurationBeanDeserializerModifier; +import org.graylog2.plugin.inject.JacksonSubTypes; +import org.graylog2.shared.bindings.providers.ObjectMapperProvider; +import org.graylog2.shared.plugins.ChainingClassLoader; +import org.graylog2.shared.plugins.GraylogClassLoader; + +import java.util.Collections; +import java.util.Set; public class PreflightChecksBindings extends AbstractModule { + private final ChainingClassLoader chainingClassLoader; + private final FeatureFlags featureFlags; + + public PreflightChecksBindings(ChainingClassLoader chainingClassLoader, FeatureFlags featureFlags) { + this.chainingClassLoader = chainingClassLoader; + this.featureFlags = featureFlags; + } + @Override protected void configure() { bind(CsrRequester.class).to(CsrRequesterImpl.class).asEagerSingleton(); @@ -47,6 +69,9 @@ protected void configure() { addPreflightCheck(DatanodeDirectoriesLockfileCheck.class); addPreflightCheck(OpenSearchPreconditionsCheck.class); addPreflightCheck(OpensearchDataDirCompatibilityCheck.class); + addPreflightCheck(PasswordSecretPreflightCheck.class); + + bindLimitedObjectMapper(); // Mongodb is needed for legacy datanode storage, where we want to extract the certificate chain from // mongodb and store it in local keystore @@ -54,6 +79,26 @@ protected void configure() { addPreflightCheck(DatanodeKeystoreCheck.class); } + /** + * TODO: + * Is there a way to avoid all of this in the very limited preflight check bindings? + * The whole purpose of this is to create an object mapper that's able to de/serialize EncryptedValues. + */ + private void bindLimitedObjectMapper() { + bind(GRNRegistry.class).toInstance(GRNRegistry.createWithBuiltinTypes()); + jacksonSubTypesBinder(); + bind(Set.class).annotatedWith(JacksonSubTypes.class).toInstance(Collections.emptySet()); + bind(ClassLoader.class).annotatedWith(GraylogClassLoader.class).toInstance(chainingClassLoader); + bind(FeatureFlags.class).toInstance(featureFlags); + bind(InputConfigurationBeanDeserializerModifier.class).toInstance(InputConfigurationBeanDeserializerModifier.withoutConfig()); + bind(ObjectMapper.class).toProvider(ObjectMapperProvider.class).asEagerSingleton(); + } + + protected Multibinder jacksonSubTypesBinder() { + return Multibinder.newSetBinder(binder(), NamedType.class, JacksonSubTypes.class); + } + + protected void addPreflightCheck(Class preflightCheck) { preflightChecksBinder().addBinding(preflightCheck.getCanonicalName()).to(preflightCheck); diff --git a/data-node/src/main/java/org/graylog/datanode/bootstrap/DatanodeBootstrap.java b/data-node/src/main/java/org/graylog/datanode/bootstrap/DatanodeBootstrap.java index 4e112b076704..207e28a124b0 100644 --- a/data-node/src/main/java/org/graylog/datanode/bootstrap/DatanodeBootstrap.java +++ b/data-node/src/main/java/org/graylog/datanode/bootstrap/DatanodeBootstrap.java @@ -84,7 +84,7 @@ private Injector getPreflightInjector(List preflightCheckModules) { new PreflightClusterConfigurationModule(chainingClassLoader), new NamedConfigParametersOverrideModule(jadConfig.getConfigurationBeans()), new ConfigurationModule(configuration), - new PreflightChecksBindings(), + new PreflightChecksBindings(chainingClassLoader, featureFlags), new DatanodeConfigurationBindings(), new Module() { @Override diff --git a/graylog2-server/src/main/java/org/graylog2/bootstrap/preflight/PasswordSecretPreflightCheck.java b/graylog2-server/src/main/java/org/graylog2/bootstrap/preflight/PasswordSecretPreflightCheck.java new file mode 100644 index 000000000000..b5741bb61c94 --- /dev/null +++ b/graylog2-server/src/main/java/org/graylog2/bootstrap/preflight/PasswordSecretPreflightCheck.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2020 Graylog, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * . + */ +package org.graylog2.bootstrap.preflight; + +import jakarta.inject.Inject; +import org.graylog2.plugin.cluster.ClusterConfigService; +import org.graylog2.security.encryption.EncryptedValue; +import org.graylog2.security.encryption.EncryptedValueService; +import org.jetbrains.annotations.NotNull; + +import java.util.Optional; + +/** + * This preflight check exists to validate that every node has the same password_secret value configured. + * The first node in the cluster will persist a known and encoded secret in the cluster_config collection. + * Every other node is then testing if it's possible to read and decode the value. If not, then the password_secret + * is not matching and we'd get problems later during runtime. So it's better to stop the startup and report + * an explicit and readable error. + */ +public class PasswordSecretPreflightCheck implements PreflightCheck { + + + private static final String KNOWN_VALUE = "graylog"; + + private final ClusterConfigService clusterConfigService; + + private final EncryptedValueService encryptionService; + + + @Inject + public PasswordSecretPreflightCheck(ClusterConfigService clusterConfigService, EncryptedValueService encryptionService) { + this.clusterConfigService = clusterConfigService; + this.encryptionService = encryptionService; + } + + @Override + public void runCheck() throws PreflightCheckException { + final PreflightEncryptedSecret encryptedValue = clusterConfigService.get(PreflightEncryptedSecret.class); + Optional.ofNullable(encryptedValue) + .ifPresentOrElse(this::validateSecret, this::persistSecret); + } + + private void persistSecret() { + final EncryptedValue encryptedValue = encryptionService.encrypt(KNOWN_VALUE); + clusterConfigService.write(new PreflightEncryptedSecret(encryptedValue)); + } + + private void validateSecret(@NotNull PreflightEncryptedSecret preflightEncryptedSecret) { + final EncryptedValue encryptedSecret = preflightEncryptedSecret.encryptedSecret(); + + try { + final String decrypted = encryptionService.decrypt(encryptedSecret); + if (!KNOWN_VALUE.equals(decrypted)) { + throwException(); + } + } catch (Exception e) { + throwException(); + } + + } + + private void throwException() { + throw new PreflightCheckException(""" + Invalid password_secret! + Failed to decrypt values from MongoDB. This means that your password_secret has been changed or there + are some nodes in your cluster that are using different password_secret. Secrets have to be configured + to the same value on every node and can't be changed afterwards."""); + } +} diff --git a/graylog2-server/src/main/java/org/graylog2/bootstrap/preflight/PreflightEncryptedSecret.java b/graylog2-server/src/main/java/org/graylog2/bootstrap/preflight/PreflightEncryptedSecret.java new file mode 100644 index 000000000000..2ef5f91f4b3c --- /dev/null +++ b/graylog2-server/src/main/java/org/graylog2/bootstrap/preflight/PreflightEncryptedSecret.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2020 Graylog, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * . + */ +package org.graylog2.bootstrap.preflight; + +import org.graylog2.security.encryption.EncryptedValue; + +public record PreflightEncryptedSecret(EncryptedValue encryptedSecret) { +} diff --git a/graylog2-server/src/main/java/org/graylog2/bootstrap/preflight/ServerPreflightChecksModule.java b/graylog2-server/src/main/java/org/graylog2/bootstrap/preflight/ServerPreflightChecksModule.java index 4acf1ce1c9de..9b4506e664f3 100644 --- a/graylog2-server/src/main/java/org/graylog2/bootstrap/preflight/ServerPreflightChecksModule.java +++ b/graylog2-server/src/main/java/org/graylog2/bootstrap/preflight/ServerPreflightChecksModule.java @@ -53,5 +53,6 @@ protected void configure() { // The MongoDBPreflightCheck is not registered here, because it is called separately from ServerBootstrap addPreflightCheck(SearchDbPreflightCheck.class); addPreflightCheck(DiskJournalPreflightCheck.class); + addPreflightCheck(PasswordSecretPreflightCheck.class); } } diff --git a/graylog2-server/src/test/java/org/graylog2/bootstrap/preflight/PasswordSecretPreflightCheckTest.java b/graylog2-server/src/test/java/org/graylog2/bootstrap/preflight/PasswordSecretPreflightCheckTest.java new file mode 100644 index 000000000000..a7a922819ef9 --- /dev/null +++ b/graylog2-server/src/test/java/org/graylog2/bootstrap/preflight/PasswordSecretPreflightCheckTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2020 Graylog, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * . + */ +package org.graylog2.bootstrap.preflight; + + +import jakarta.annotation.Nonnull; +import org.apache.commons.lang3.RandomStringUtils; +import org.assertj.core.api.Assertions; +import org.graylog.security.certutil.InMemoryClusterConfigService; +import org.graylog2.plugin.cluster.ClusterConfigService; +import org.graylog2.security.encryption.EncryptedValueService; +import org.junit.jupiter.api.Test; + +class PasswordSecretPreflightCheckTest { + + @Test + void testEmptyDB() { + final String passwordSecret = RandomStringUtils.secure().nextAlphanumeric(20); + final InMemoryClusterConfigService clusterConfigService = new InMemoryClusterConfigService(); + final PasswordSecretPreflightCheck preflightCheck = createCheckInstance(passwordSecret, clusterConfigService); + preflightCheck.runCheck(); + } + + @Test + void testSuccessfulValidation() { + final String passwordSecret = RandomStringUtils.secure().nextAlphanumeric(20); + final InMemoryClusterConfigService clusterConfigService = new InMemoryClusterConfigService(); + final PasswordSecretPreflightCheck preflightCheck = createCheckInstance(passwordSecret, clusterConfigService); + + // first check will persist the value in the DB + preflightCheck.runCheck(); + + // second should read it from there and validate + preflightCheck.runCheck(); + } + + @Test + void testFailingValidation() { + final RandomStringUtils randomStringUtils = RandomStringUtils.secure(); + // first check will persist the value in the DB + final InMemoryClusterConfigService clusterConfigService = new InMemoryClusterConfigService(); + createCheckInstance(randomStringUtils.nextAlphanumeric(20), clusterConfigService).runCheck(); + + Assertions.assertThatThrownBy(() -> { + // now repeat the check, but with different password. Should fail + createCheckInstance(randomStringUtils.nextAlphanumeric(20), clusterConfigService).runCheck(); + }) + .isInstanceOf(PreflightCheckException.class) + .hasMessageContaining("Invalid password_secret"); + + } + + @Nonnull + private static PasswordSecretPreflightCheck createCheckInstance(String passwordSecret, ClusterConfigService clusterConfigService) { + final EncryptedValueService encryptionService = new EncryptedValueService(passwordSecret); + return new PasswordSecretPreflightCheck(clusterConfigService, encryptionService); + } +} From 77a7afca51670db0c9e7d35cb5cb0c3f3862c8ce Mon Sep 17 00:00:00 2001 From: Tomas Dvorak Date: Thu, 30 Jan 2025 14:33:26 +0100 Subject: [PATCH 2/6] fixed annotation --- .../bootstrap/preflight/PasswordSecretPreflightCheck.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/graylog2-server/src/main/java/org/graylog2/bootstrap/preflight/PasswordSecretPreflightCheck.java b/graylog2-server/src/main/java/org/graylog2/bootstrap/preflight/PasswordSecretPreflightCheck.java index b5741bb61c94..50a8b6777eca 100644 --- a/graylog2-server/src/main/java/org/graylog2/bootstrap/preflight/PasswordSecretPreflightCheck.java +++ b/graylog2-server/src/main/java/org/graylog2/bootstrap/preflight/PasswordSecretPreflightCheck.java @@ -20,8 +20,8 @@ import org.graylog2.plugin.cluster.ClusterConfigService; import org.graylog2.security.encryption.EncryptedValue; import org.graylog2.security.encryption.EncryptedValueService; -import org.jetbrains.annotations.NotNull; +import javax.annotation.Nonnull; import java.util.Optional; /** @@ -59,7 +59,7 @@ private void persistSecret() { clusterConfigService.write(new PreflightEncryptedSecret(encryptedValue)); } - private void validateSecret(@NotNull PreflightEncryptedSecret preflightEncryptedSecret) { + private void validateSecret(@Nonnull PreflightEncryptedSecret preflightEncryptedSecret) { final EncryptedValue encryptedSecret = preflightEncryptedSecret.encryptedSecret(); try { From e160bbbaaa4c9326d2a87e9e0b65900844773753 Mon Sep 17 00:00:00 2001 From: Tomas Dvorak Date: Fri, 31 Jan 2025 09:40:19 +0100 Subject: [PATCH 3/6] added changelog --- changelog/unreleased/issue-21504.toml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 changelog/unreleased/issue-21504.toml diff --git a/changelog/unreleased/issue-21504.toml b/changelog/unreleased/issue-21504.toml new file mode 100644 index 000000000000..420dbbbb85f5 --- /dev/null +++ b/changelog/unreleased/issue-21504.toml @@ -0,0 +1,5 @@ +type = "a" +message = "Add preflight check for data node and graylog server, veryfing that password_secret is configured to the same value everywhere." + +pulls = ["21491"] +issues = ["21504"] From de6137693f500bafb4e8bb1f3b7534563dd18db5 Mon Sep 17 00:00:00 2001 From: Tomas Dvorak Date: Fri, 31 Jan 2025 12:46:28 +0100 Subject: [PATCH 4/6] preflight object mapper provider --- .../bindings/PreflightChecksBindings.java | 31 ++--------- .../PreflightObjectMapperProvider.java | 53 +++++++++++++++++++ 2 files changed, 56 insertions(+), 28 deletions(-) create mode 100644 data-node/src/main/java/org/graylog/datanode/bindings/PreflightObjectMapperProvider.java diff --git a/data-node/src/main/java/org/graylog/datanode/bindings/PreflightChecksBindings.java b/data-node/src/main/java/org/graylog/datanode/bindings/PreflightChecksBindings.java index 81f3fde3b464..7567052f1c10 100644 --- a/data-node/src/main/java/org/graylog/datanode/bindings/PreflightChecksBindings.java +++ b/data-node/src/main/java/org/graylog/datanode/bindings/PreflightChecksBindings.java @@ -17,10 +17,8 @@ package org.graylog.datanode.bindings; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.jsontype.NamedType; import com.google.inject.AbstractModule; import com.google.inject.multibindings.MapBinder; -import com.google.inject.multibindings.Multibinder; import org.graylog.datanode.bootstrap.preflight.DatanodeDirectoriesLockfileCheck; import org.graylog.datanode.bootstrap.preflight.DatanodeDnsPreflightCheck; import org.graylog.datanode.bootstrap.preflight.DatanodeKeystoreCheck; @@ -29,7 +27,6 @@ import org.graylog.datanode.bootstrap.preflight.OpensearchDataDirCompatibilityCheck; import org.graylog.datanode.opensearch.CsrRequester; import org.graylog.datanode.opensearch.CsrRequesterImpl; -import org.graylog.grn.GRNRegistry; import org.graylog2.bindings.providers.MongoConnectionProvider; import org.graylog2.bootstrap.preflight.MongoDBPreflightCheck; import org.graylog2.bootstrap.preflight.PasswordSecretPreflightCheck; @@ -38,15 +35,9 @@ import org.graylog2.cluster.certificates.CertificateExchangeImpl; import org.graylog2.database.MongoConnection; import org.graylog2.featureflag.FeatureFlags; -import org.graylog2.jackson.InputConfigurationBeanDeserializerModifier; -import org.graylog2.plugin.inject.JacksonSubTypes; -import org.graylog2.shared.bindings.providers.ObjectMapperProvider; import org.graylog2.shared.plugins.ChainingClassLoader; import org.graylog2.shared.plugins.GraylogClassLoader; -import java.util.Collections; -import java.util.Set; - public class PreflightChecksBindings extends AbstractModule { @@ -71,7 +62,7 @@ protected void configure() { addPreflightCheck(OpensearchDataDirCompatibilityCheck.class); addPreflightCheck(PasswordSecretPreflightCheck.class); - bindLimitedObjectMapper(); + bindLimittedObjectMapper(); // Mongodb is needed for legacy datanode storage, where we want to extract the certificate chain from // mongodb and store it in local keystore @@ -79,27 +70,11 @@ protected void configure() { addPreflightCheck(DatanodeKeystoreCheck.class); } - /** - * TODO: - * Is there a way to avoid all of this in the very limited preflight check bindings? - * The whole purpose of this is to create an object mapper that's able to de/serialize EncryptedValues. - */ - private void bindLimitedObjectMapper() { - bind(GRNRegistry.class).toInstance(GRNRegistry.createWithBuiltinTypes()); - jacksonSubTypesBinder(); - bind(Set.class).annotatedWith(JacksonSubTypes.class).toInstance(Collections.emptySet()); + private void bindLimittedObjectMapper() { bind(ClassLoader.class).annotatedWith(GraylogClassLoader.class).toInstance(chainingClassLoader); - bind(FeatureFlags.class).toInstance(featureFlags); - bind(InputConfigurationBeanDeserializerModifier.class).toInstance(InputConfigurationBeanDeserializerModifier.withoutConfig()); - bind(ObjectMapper.class).toProvider(ObjectMapperProvider.class).asEagerSingleton(); - } - - protected Multibinder jacksonSubTypesBinder() { - return Multibinder.newSetBinder(binder(), NamedType.class, JacksonSubTypes.class); + bind(ObjectMapper.class).toProvider(PreflightObjectMapperProvider.class).asEagerSingleton(); } - - protected void addPreflightCheck(Class preflightCheck) { preflightChecksBinder().addBinding(preflightCheck.getCanonicalName()).to(preflightCheck); } diff --git a/data-node/src/main/java/org/graylog/datanode/bindings/PreflightObjectMapperProvider.java b/data-node/src/main/java/org/graylog/datanode/bindings/PreflightObjectMapperProvider.java new file mode 100644 index 000000000000..32a41b61ce36 --- /dev/null +++ b/data-node/src/main/java/org/graylog/datanode/bindings/PreflightObjectMapperProvider.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020 Graylog, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * . + */ +package org.graylog.datanode.bindings; + +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.inject.Inject; +import jakarta.inject.Provider; +import org.graylog.grn.GRNRegistry; +import org.graylog2.jackson.InputConfigurationBeanDeserializerModifier; +import org.graylog2.security.encryption.EncryptedValueService; +import org.graylog2.shared.bindings.providers.ObjectMapperProvider; +import org.graylog2.shared.plugins.GraylogClassLoader; + +import java.util.Collections; + +/** + * This ObjectMapperProvider should be used only for preflight checks and preflight web. It's significantly limited. + * For all other usages, please refer to {@link ObjectMapperProvider}. + */ +public class PreflightObjectMapperProvider implements Provider { + + private final ObjectMapperProvider delegate; + + @Inject + public PreflightObjectMapperProvider(@GraylogClassLoader ClassLoader classLoader, EncryptedValueService encryptedValueService) { + delegate = new ObjectMapperProvider( + classLoader, + Collections.emptySet(), + encryptedValueService, + GRNRegistry.createWithBuiltinTypes(), + InputConfigurationBeanDeserializerModifier.withoutConfig() + ); + } + + @Override + public ObjectMapper get() { + return delegate.get(); + } +} From c25849b1963f034fcf93db7752a4c3671c2aaf6e Mon Sep 17 00:00:00 2001 From: Tomas Dvorak Date: Mon, 10 Feb 2025 12:07:26 +0100 Subject: [PATCH 5/6] code cleanup --- .../datanode/bindings/PreflightChecksBindings.java | 13 +------------ .../datanode/bootstrap/DatanodeBootstrap.java | 2 +- .../PreflightClusterConfigurationModule.java | 10 ++++++++++ 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/data-node/src/main/java/org/graylog/datanode/bindings/PreflightChecksBindings.java b/data-node/src/main/java/org/graylog/datanode/bindings/PreflightChecksBindings.java index 7567052f1c10..0b3ae9730379 100644 --- a/data-node/src/main/java/org/graylog/datanode/bindings/PreflightChecksBindings.java +++ b/data-node/src/main/java/org/graylog/datanode/bindings/PreflightChecksBindings.java @@ -34,7 +34,6 @@ import org.graylog2.cluster.certificates.CertificateExchange; import org.graylog2.cluster.certificates.CertificateExchangeImpl; import org.graylog2.database.MongoConnection; -import org.graylog2.featureflag.FeatureFlags; import org.graylog2.shared.plugins.ChainingClassLoader; import org.graylog2.shared.plugins.GraylogClassLoader; @@ -42,11 +41,9 @@ public class PreflightChecksBindings extends AbstractModule { private final ChainingClassLoader chainingClassLoader; - private final FeatureFlags featureFlags; - public PreflightChecksBindings(ChainingClassLoader chainingClassLoader, FeatureFlags featureFlags) { + public PreflightChecksBindings(ChainingClassLoader chainingClassLoader) { this.chainingClassLoader = chainingClassLoader; - this.featureFlags = featureFlags; } @Override @@ -61,20 +58,12 @@ protected void configure() { addPreflightCheck(OpenSearchPreconditionsCheck.class); addPreflightCheck(OpensearchDataDirCompatibilityCheck.class); addPreflightCheck(PasswordSecretPreflightCheck.class); - - bindLimittedObjectMapper(); - // Mongodb is needed for legacy datanode storage, where we want to extract the certificate chain from // mongodb and store it in local keystore bind(MongoConnection.class).toProvider(MongoConnectionProvider.class); addPreflightCheck(DatanodeKeystoreCheck.class); } - private void bindLimittedObjectMapper() { - bind(ClassLoader.class).annotatedWith(GraylogClassLoader.class).toInstance(chainingClassLoader); - bind(ObjectMapper.class).toProvider(PreflightObjectMapperProvider.class).asEagerSingleton(); - } - protected void addPreflightCheck(Class preflightCheck) { preflightChecksBinder().addBinding(preflightCheck.getCanonicalName()).to(preflightCheck); } diff --git a/data-node/src/main/java/org/graylog/datanode/bootstrap/DatanodeBootstrap.java b/data-node/src/main/java/org/graylog/datanode/bootstrap/DatanodeBootstrap.java index 207e28a124b0..d74e6d0950cf 100644 --- a/data-node/src/main/java/org/graylog/datanode/bootstrap/DatanodeBootstrap.java +++ b/data-node/src/main/java/org/graylog/datanode/bootstrap/DatanodeBootstrap.java @@ -84,7 +84,7 @@ private Injector getPreflightInjector(List preflightCheckModules) { new PreflightClusterConfigurationModule(chainingClassLoader), new NamedConfigParametersOverrideModule(jadConfig.getConfigurationBeans()), new ConfigurationModule(configuration), - new PreflightChecksBindings(chainingClassLoader, featureFlags), + new PreflightChecksBindings(chainingClassLoader), new DatanodeConfigurationBindings(), new Module() { @Override diff --git a/data-node/src/main/java/org/graylog/datanode/bootstrap/preflight/PreflightClusterConfigurationModule.java b/data-node/src/main/java/org/graylog/datanode/bootstrap/preflight/PreflightClusterConfigurationModule.java index c1f55b006f1c..d0c355b67421 100644 --- a/data-node/src/main/java/org/graylog/datanode/bootstrap/preflight/PreflightClusterConfigurationModule.java +++ b/data-node/src/main/java/org/graylog/datanode/bootstrap/preflight/PreflightClusterConfigurationModule.java @@ -16,10 +16,13 @@ */ package org.graylog.datanode.bootstrap.preflight; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.inject.AbstractModule; +import org.graylog.datanode.bindings.PreflightObjectMapperProvider; import org.graylog2.cluster.ClusterConfigServiceImpl; import org.graylog2.plugin.cluster.ClusterConfigService; import org.graylog2.shared.plugins.ChainingClassLoader; +import org.graylog2.shared.plugins.GraylogClassLoader; public class PreflightClusterConfigurationModule extends AbstractModule { private final ChainingClassLoader chainingClassLoader; @@ -32,5 +35,12 @@ public PreflightClusterConfigurationModule(ChainingClassLoader chainingClassLoad protected void configure() { bind(ChainingClassLoader.class).toInstance(chainingClassLoader); bind(ClusterConfigService.class).to(ClusterConfigServiceImpl.class).asEagerSingleton(); + + bindLimitedObjectMapper(); + } + + private void bindLimitedObjectMapper() { + bind(ClassLoader.class).annotatedWith(GraylogClassLoader.class).toInstance(chainingClassLoader); + bind(ObjectMapper.class).toProvider(PreflightObjectMapperProvider.class).asEagerSingleton(); } } From f6e64600e31414e1b6e772cbb1d008aea01d821d Mon Sep 17 00:00:00 2001 From: Tomas Dvorak Date: Mon, 10 Feb 2025 13:53:48 +0100 Subject: [PATCH 6/6] Update graylog2-server/src/main/java/org/graylog2/bootstrap/preflight/PasswordSecretPreflightCheck.java Co-authored-by: Matthias Oesterheld <33032967+moesterheld@users.noreply.github.com> --- .../bootstrap/preflight/PasswordSecretPreflightCheck.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graylog2-server/src/main/java/org/graylog2/bootstrap/preflight/PasswordSecretPreflightCheck.java b/graylog2-server/src/main/java/org/graylog2/bootstrap/preflight/PasswordSecretPreflightCheck.java index 50a8b6777eca..b11268f0af8f 100644 --- a/graylog2-server/src/main/java/org/graylog2/bootstrap/preflight/PasswordSecretPreflightCheck.java +++ b/graylog2-server/src/main/java/org/graylog2/bootstrap/preflight/PasswordSecretPreflightCheck.java @@ -77,7 +77,7 @@ private void throwException() { throw new PreflightCheckException(""" Invalid password_secret! Failed to decrypt values from MongoDB. This means that your password_secret has been changed or there - are some nodes in your cluster that are using different password_secret. Secrets have to be configured + are some nodes in your cluster that are using a different password_secret to the one configured on this node. Secrets have to be configured to the same value on every node and can't be changed afterwards."""); } }