From 525c7685b229fb165887c762ffdc7d715b641896 Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Thu, 17 Aug 2017 15:32:23 +0200 Subject: [PATCH] Persist created keystore on startup unless keystore is present (#26253) We already added the functionality to create a new keystore on startup in #26126 but apparently missed to persist the keystore. This change adds peristence and adds a test for the boostrap loading. --- .../elasticsearch/bootstrap/Bootstrap.java | 7 +- .../bootstrap/BootstrapTests.java | 76 +++++++++++++++++++ .../settings/KeyStoreCommandTestCase.java | 2 +- 3 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 core/src/test/java/org/elasticsearch/bootstrap/BootstrapTests.java diff --git a/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java b/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java index 1b18e2a4160a0..f61b964daadf0 100644 --- a/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java +++ b/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java @@ -35,7 +35,6 @@ import org.elasticsearch.common.PidFile; import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.common.inject.CreationException; -import org.elasticsearch.common.logging.DeprecationLogger; import org.elasticsearch.common.logging.ESLoggerFactory; import org.elasticsearch.common.logging.LogConfigurator; import org.elasticsearch.common.logging.Loggers; @@ -220,7 +219,7 @@ protected void validateNodeBeforeAcceptingRequests( }; } - private static SecureSettings loadSecureSettings(Environment initialEnv) throws BootstrapException { + static SecureSettings loadSecureSettings(Environment initialEnv) throws BootstrapException { final KeyStoreWrapper keystore; try { keystore = KeyStoreWrapper.load(initialEnv.configFile()); @@ -231,7 +230,9 @@ private static SecureSettings loadSecureSettings(Environment initialEnv) throws try { if (keystore == null) { // create it, we always want one! we use an empty passphrase, but a user can change this later if they want. - KeyStoreWrapper.create(new char[0]); + KeyStoreWrapper keyStoreWrapper = KeyStoreWrapper.create(new char[0]); + keyStoreWrapper.save(initialEnv.configFile()); + return keyStoreWrapper; } else { keystore.decrypt(new char[0] /* TODO: read password from stdin */); } diff --git a/core/src/test/java/org/elasticsearch/bootstrap/BootstrapTests.java b/core/src/test/java/org/elasticsearch/bootstrap/BootstrapTests.java new file mode 100644 index 0000000000000..42d2d902c3f0e --- /dev/null +++ b/core/src/test/java/org/elasticsearch/bootstrap/BootstrapTests.java @@ -0,0 +1,76 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.elasticsearch.bootstrap; + +import org.apache.lucene.util.IOUtils; +import org.elasticsearch.common.settings.KeyStoreCommandTestCase; +import org.elasticsearch.common.settings.KeyStoreWrapper; +import org.elasticsearch.common.settings.SecureSettings; +import org.elasticsearch.common.settings.SecureString; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.env.Environment; +import org.elasticsearch.test.ESTestCase; +import org.junit.After; +import org.junit.Before; + +import java.io.IOException; +import java.nio.file.FileSystem; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +public class BootstrapTests extends ESTestCase { + Environment env; + List fileSystems = new ArrayList<>(); + + @After + public void closeMockFileSystems() throws IOException { + IOUtils.close(fileSystems); + } + + @Before + public void setupEnv() throws IOException { + env = KeyStoreCommandTestCase.setupEnv(true, fileSystems); + } + + public void testLoadSecureSettingsCreatesKeystore() throws BootstrapException { + final Path configPath = env.configFile(); + assertFalse(Files.exists(configPath.resolve("elasticsearch.keystore"))); + Bootstrap.loadSecureSettings(env); + assertTrue(Files.exists(configPath.resolve("elasticsearch.keystore"))); + } + + public void testLoadSecureSettings() throws Exception { + final Path configPath = env.configFile(); + final SecureString seed; + try (KeyStoreWrapper keyStoreWrapper = KeyStoreWrapper.create(new char[0])) { + seed = KeyStoreWrapper.SEED_SETTING.get(Settings.builder().setSecureSettings(keyStoreWrapper).build()); + assertNotNull(seed); + assertTrue(seed.length() > 0); + keyStoreWrapper.save(configPath); + } + assertTrue(Files.exists(configPath.resolve("elasticsearch.keystore"))); + try (SecureSettings secureSettings = Bootstrap.loadSecureSettings(env)) { + SecureString seedAfterLoad = KeyStoreWrapper.SEED_SETTING.get(Settings.builder().setSecureSettings(secureSettings).build()); + assertEquals(seedAfterLoad.toString(), seed.toString()); + assertTrue(Files.exists(configPath.resolve("elasticsearch.keystore"))); + } + } +} diff --git a/core/src/test/java/org/elasticsearch/common/settings/KeyStoreCommandTestCase.java b/core/src/test/java/org/elasticsearch/common/settings/KeyStoreCommandTestCase.java index 500b7b627b840..3d853404664b1 100644 --- a/core/src/test/java/org/elasticsearch/common/settings/KeyStoreCommandTestCase.java +++ b/core/src/test/java/org/elasticsearch/common/settings/KeyStoreCommandTestCase.java @@ -58,7 +58,7 @@ public void setupEnv() throws IOException { env = setupEnv(true, fileSystems); // default to posix, but tests may call setupEnv(false) to overwrite } - static Environment setupEnv(boolean posix, List fileSystems) throws IOException { + public static Environment setupEnv(boolean posix, List fileSystems) throws IOException { final Configuration configuration; if (posix) { configuration = Configuration.unix().toBuilder().setAttributeViews("basic", "owner", "posix", "unix").build();