Search in sources :

Example 1 with SecureSettings

use of org.opensearch.common.settings.SecureSettings in project OpenSearch by opensearch-project.

the class BootstrapTests method testLoadSecureSettings.

public void testLoadSecureSettings() throws Exception {
    final Path configPath = env.configFile();
    final SecureString seed;
    try (KeyStoreWrapper keyStoreWrapper = KeyStoreWrapper.create()) {
        seed = KeyStoreWrapper.SEED_SETTING.get(Settings.builder().setSecureSettings(keyStoreWrapper).build());
        assertNotNull(seed);
        assertTrue(seed.length() > 0);
        keyStoreWrapper.save(configPath, new char[0]);
    }
    assertTrue(Files.exists(configPath.resolve("opensearch.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("opensearch.keystore")));
    }
}
Also used : Path(java.nio.file.Path) SecureSettings(org.opensearch.common.settings.SecureSettings) KeyStoreWrapper(org.opensearch.common.settings.KeyStoreWrapper) SecureString(org.opensearch.common.settings.SecureString)

Example 2 with SecureSettings

use of org.opensearch.common.settings.SecureSettings in project OpenSearch by opensearch-project.

the class Bootstrap method init.

/**
 * This method is invoked by {@link OpenSearch#main(String[])} to startup opensearch.
 */
static void init(final boolean foreground, final Path pidFile, final boolean quiet, final Environment initialEnv) throws BootstrapException, NodeValidationException, UserException {
    // force the class initializer for BootstrapInfo to run before
    // the security manager is installed
    BootstrapInfo.init();
    INSTANCE = new Bootstrap();
    final SecureSettings keystore = loadSecureSettings(initialEnv);
    final Environment environment = createEnvironment(pidFile, keystore, initialEnv.settings(), initialEnv.configFile());
    LogConfigurator.setNodeName(Node.NODE_NAME_SETTING.get(environment.settings()));
    try {
        LogConfigurator.configure(environment);
    } catch (IOException e) {
        throw new BootstrapException(e);
    }
    if (JavaVersion.current().compareTo(JavaVersion.parse("11")) < 0) {
        final String message = String.format(Locale.ROOT, "future versions of OpenSearch will require Java 11; " + "your Java version from [%s] does not meet this requirement", System.getProperty("java.home"));
        DeprecationLogger.getLogger(Bootstrap.class).deprecate("java_version_11_required", message);
    }
    if (environment.pidFile() != null) {
        try {
            PidFile.create(environment.pidFile(), true);
        } catch (IOException e) {
            throw new BootstrapException(e);
        }
    }
    final boolean closeStandardStreams = (foreground == false) || quiet;
    try {
        if (closeStandardStreams) {
            final Logger rootLogger = LogManager.getRootLogger();
            final Appender maybeConsoleAppender = Loggers.findAppender(rootLogger, ConsoleAppender.class);
            if (maybeConsoleAppender != null) {
                Loggers.removeAppender(rootLogger, maybeConsoleAppender);
            }
            closeSystOut();
        }
        // fail if somebody replaced the lucene jars
        checkLucene();
        // install the default uncaught exception handler; must be done before security is
        // initialized as we do not want to grant the runtime permission
        // setDefaultUncaughtExceptionHandler
        Thread.setDefaultUncaughtExceptionHandler(new OpenSearchUncaughtExceptionHandler());
        INSTANCE.setup(true, environment);
        try {
            // any secure settings must be read during node construction
            IOUtils.close(keystore);
        } catch (IOException e) {
            throw new BootstrapException(e);
        }
        INSTANCE.start();
        // startup errors via journalctl.
        if (foreground == false) {
            closeSysError();
        }
    } catch (NodeValidationException | RuntimeException e) {
        // disable console logging, so user does not see the exception twice (jvm will show it already)
        final Logger rootLogger = LogManager.getRootLogger();
        final Appender maybeConsoleAppender = Loggers.findAppender(rootLogger, ConsoleAppender.class);
        if (foreground && maybeConsoleAppender != null) {
            Loggers.removeAppender(rootLogger, maybeConsoleAppender);
        }
        Logger logger = LogManager.getLogger(Bootstrap.class);
        // HACK, it sucks to do this, but we will run users out of disk space otherwise
        if (e instanceof CreationException) {
            // guice: log the shortened exc to the log file
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            PrintStream ps = null;
            try {
                ps = new PrintStream(os, false, "UTF-8");
            } catch (UnsupportedEncodingException uee) {
                assert false;
                e.addSuppressed(uee);
            }
            new StartupException(e).printStackTrace(ps);
            ps.flush();
            try {
                logger.error("Guice Exception: {}", os.toString("UTF-8"));
            } catch (UnsupportedEncodingException uee) {
                assert false;
                e.addSuppressed(uee);
            }
        } else if (e instanceof NodeValidationException) {
            logger.error("node validation exception\n{}", e.getMessage());
        } else {
            // full exception
            logger.error("Exception", e);
        }
        // re-enable it if appropriate, so they can see any logging during the shutdown process
        if (foreground && maybeConsoleAppender != null) {
            Loggers.addAppender(rootLogger, maybeConsoleAppender);
        }
        throw e;
    }
}
Also used : Appender(org.apache.logging.log4j.core.Appender) ConsoleAppender(org.apache.logging.log4j.core.appender.ConsoleAppender) ConsoleAppender(org.apache.logging.log4j.core.appender.ConsoleAppender) PrintStream(java.io.PrintStream) UnsupportedEncodingException(java.io.UnsupportedEncodingException) CreationException(org.opensearch.common.inject.CreationException) IOException(java.io.IOException) SecureString(org.opensearch.common.settings.SecureString) ByteArrayOutputStream(java.io.ByteArrayOutputStream) DeprecationLogger(org.opensearch.common.logging.DeprecationLogger) Logger(org.apache.logging.log4j.Logger) NodeValidationException(org.opensearch.node.NodeValidationException) SecureSettings(org.opensearch.common.settings.SecureSettings) Environment(org.opensearch.env.Environment)

Example 3 with SecureSettings

use of org.opensearch.common.settings.SecureSettings in project OpenSearch by opensearch-project.

the class ReloadSecureSettingsIT method testReloadWhileKeystoreChanged.

public void testReloadWhileKeystoreChanged() throws Exception {
    final PluginsService pluginsService = internalCluster().getInstance(PluginsService.class);
    final MockReloadablePlugin mockReloadablePlugin = pluginsService.filterPlugins(MockReloadablePlugin.class).stream().findFirst().get();
    final Environment environment = internalCluster().getInstance(Environment.class);
    final int initialReloadCount = mockReloadablePlugin.getReloadCount();
    for (int i = 0; i < randomIntBetween(4, 8); i++) {
        // write keystore
        final SecureSettings secureSettings = writeEmptyKeystore(environment, new char[0]);
        // read seed setting value from the test case (not from the node)
        final String seedValue = KeyStoreWrapper.SEED_SETTING.get(Settings.builder().put(environment.settings()).setSecureSettings(secureSettings).build()).toString();
        // reload call
        successfulReloadCall();
        assertThat(mockReloadablePlugin.getSeedValue(), equalTo(seedValue));
        assertThat(mockReloadablePlugin.getReloadCount() - initialReloadCount, equalTo(i + 1));
    }
}
Also used : PluginsService(org.opensearch.plugins.PluginsService) Environment(org.opensearch.env.Environment) SecureSettings(org.opensearch.common.settings.SecureSettings) SecureString(org.opensearch.common.settings.SecureString) Matchers.containsString(org.hamcrest.Matchers.containsString)

Example 4 with SecureSettings

use of org.opensearch.common.settings.SecureSettings in project OpenSearch by opensearch-project.

the class ReloadSecureSettingsIT method testMisbehavingPlugin.

public void testMisbehavingPlugin() throws Exception {
    final Environment environment = internalCluster().getInstance(Environment.class);
    final PluginsService pluginsService = internalCluster().getInstance(PluginsService.class);
    final MockReloadablePlugin mockReloadablePlugin = pluginsService.filterPlugins(MockReloadablePlugin.class).stream().findFirst().get();
    // make plugins throw on reload
    for (final String nodeName : internalCluster().getNodeNames()) {
        internalCluster().getInstance(PluginsService.class, nodeName).filterPlugins(MisbehavingReloadablePlugin.class).stream().findFirst().get().setShouldThrow(true);
    }
    final AtomicReference<AssertionError> reloadSettingsError = new AtomicReference<>();
    final int initialReloadCount = mockReloadablePlugin.getReloadCount();
    // "some" keystore should be present
    final SecureSettings secureSettings = writeEmptyKeystore(environment, new char[0]);
    // read seed setting value from the test case (not from the node)
    final String seedValue = KeyStoreWrapper.SEED_SETTING.get(Settings.builder().put(environment.settings()).setSecureSettings(secureSettings).build()).toString();
    final CountDownLatch latch = new CountDownLatch(1);
    final SecureString emptyPassword = randomBoolean() ? new SecureString(new char[0]) : null;
    client().admin().cluster().prepareReloadSecureSettings().setSecureStorePassword(emptyPassword).setNodesIds(Strings.EMPTY_ARRAY).execute(new ActionListener<NodesReloadSecureSettingsResponse>() {

        @Override
        public void onResponse(NodesReloadSecureSettingsResponse nodesReloadResponse) {
            try {
                assertThat(nodesReloadResponse, notNullValue());
                final Map<String, NodesReloadSecureSettingsResponse.NodeResponse> nodesMap = nodesReloadResponse.getNodesMap();
                assertThat(nodesMap.size(), equalTo(cluster().size()));
                for (final NodesReloadSecureSettingsResponse.NodeResponse nodeResponse : nodesReloadResponse.getNodes()) {
                    assertThat(nodeResponse.reloadException(), notNullValue());
                    assertThat(nodeResponse.reloadException().getMessage(), containsString("If shouldThrow I throw"));
                }
            } catch (final AssertionError e) {
                reloadSettingsError.set(e);
            } finally {
                latch.countDown();
            }
        }

        @Override
        public void onFailure(Exception e) {
            reloadSettingsError.set(new AssertionError("Nodes request failed", e));
            latch.countDown();
        }
    });
    latch.await();
    if (reloadSettingsError.get() != null) {
        throw reloadSettingsError.get();
    }
    // even if one plugin fails to reload (throws Exception), others should be
    // unperturbed
    assertThat(mockReloadablePlugin.getReloadCount() - initialReloadCount, equalTo(1));
    // mock plugin should have been reloaded successfully
    assertThat(mockReloadablePlugin.getSeedValue(), equalTo(seedValue));
}
Also used : PluginsService(org.opensearch.plugins.PluginsService) AtomicReference(java.util.concurrent.atomic.AtomicReference) SecureString(org.opensearch.common.settings.SecureString) Matchers.containsString(org.hamcrest.Matchers.containsString) CountDownLatch(java.util.concurrent.CountDownLatch) OpenSearchException(org.opensearch.OpenSearchException) RemoteTransportException(org.opensearch.transport.RemoteTransportException) AccessControlException(java.security.AccessControlException) Environment(org.opensearch.env.Environment) SecureSettings(org.opensearch.common.settings.SecureSettings) Map(java.util.Map) SecureString(org.opensearch.common.settings.SecureString) NodesReloadSecureSettingsResponse(org.opensearch.action.admin.cluster.node.reload.NodesReloadSecureSettingsResponse)

Example 5 with SecureSettings

use of org.opensearch.common.settings.SecureSettings in project OpenSearch by opensearch-project.

the class InternalTestCluster method buildNode.

/**
 * builds a new node
 *
 * @param nodeId                    node ordinal
 * @param settings                  the settings to use
 * @param reuseExisting             if a node with the same name is already part of {@link #nodes}, no new node will be built and
 *                                  the method will return the existing one
 * @param onTransportServiceStarted callback to run when transport service is started
 */
private synchronized NodeAndClient buildNode(int nodeId, Settings settings, boolean reuseExisting, Runnable onTransportServiceStarted) {
    assert Thread.holdsLock(this);
    ensureOpen();
    Collection<Class<? extends Plugin>> plugins = getPlugins();
    String name = settings.get("node.name");
    final NodeAndClient nodeAndClient = nodes.get(name);
    if (reuseExisting && nodeAndClient != null) {
        // reusing an existing node implies its transport service already started
        onTransportServiceStarted.run();
        return nodeAndClient;
    }
    assert reuseExisting || nodeAndClient == null : "node name [" + name + "] already exists but not allowed to use it";
    SecureSettings secureSettings = Settings.builder().put(settings).getSecureSettings();
    if (secureSettings instanceof MockSecureSettings) {
        // we clone this here since in the case of a node restart we might need it again
        secureSettings = ((MockSecureSettings) secureSettings).clone();
    }
    MockNode node = new MockNode(settings, plugins, nodeConfigurationSource.nodeConfigPath(nodeId), forbidPrivateIndexSettings);
    node.injector().getInstance(TransportService.class).addLifecycleListener(new LifecycleListener() {

        @Override
        public void afterStart() {
            onTransportServiceStarted.run();
        }
    });
    try {
        IOUtils.close(secureSettings);
    } catch (IOException e) {
        throw new UncheckedIOException(e);
    }
    return new NodeAndClient(name, node, settings, nodeId);
}
Also used : MockNode(org.opensearch.node.MockNode) UncheckedIOException(java.io.UncheckedIOException) LifecycleListener(org.opensearch.common.component.LifecycleListener) UncheckedIOException(java.io.UncheckedIOException) IOException(java.io.IOException) MockSecureSettings(org.opensearch.common.settings.MockSecureSettings) TransportService(org.opensearch.transport.TransportService) MockTransportService(org.opensearch.test.transport.MockTransportService) MockSecureSettings(org.opensearch.common.settings.MockSecureSettings) SecureSettings(org.opensearch.common.settings.SecureSettings) Plugin(org.opensearch.plugins.Plugin)

Aggregations

SecureSettings (org.opensearch.common.settings.SecureSettings)5 SecureString (org.opensearch.common.settings.SecureString)4 Environment (org.opensearch.env.Environment)3 IOException (java.io.IOException)2 Matchers.containsString (org.hamcrest.Matchers.containsString)2 PluginsService (org.opensearch.plugins.PluginsService)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 PrintStream (java.io.PrintStream)1 UncheckedIOException (java.io.UncheckedIOException)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 Path (java.nio.file.Path)1 AccessControlException (java.security.AccessControlException)1 Map (java.util.Map)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 Logger (org.apache.logging.log4j.Logger)1 Appender (org.apache.logging.log4j.core.Appender)1 ConsoleAppender (org.apache.logging.log4j.core.appender.ConsoleAppender)1 OpenSearchException (org.opensearch.OpenSearchException)1 NodesReloadSecureSettingsResponse (org.opensearch.action.admin.cluster.node.reload.NodesReloadSecureSettingsResponse)1