diff --git a/docs/reference/migration/migrate_8_0/settings.asciidoc b/docs/reference/migration/migrate_8_0/settings.asciidoc index bfb1569eb1f53..e5dadd65084fe 100644 --- a/docs/reference/migration/migrate_8_0/settings.asciidoc +++ b/docs/reference/migration/migrate_8_0/settings.asciidoc @@ -226,16 +226,17 @@ Discontinue use of the removed settings. Specifying these settings in ==== [[system-call-filter-setting]] -.System call filter setting deprecated +.System call filter setting removed [%collapsible] ==== *Details* + Elasticsearch uses system call filters to remove its ability to fork another process. This is useful to mitigate remote code exploits. These system call -filters are enabled by default, and controlled via the setting +filters are enabled by default, and were previously controlled via the setting `bootstrap.system_call_filter`. Starting in Elasticsearch 8.0, system call -filters will be required. As such, the setting `bootstrap.system_call_filter` is -deprecated and will be removed in Elasticsearch 8.0. +filters will be required. As such, the setting `bootstrap.system_call_filter` +was deprecated in Elasticsearch 7.13.0, and is removed as of Elasticsearch +8.0.0. *Impact* + Discontinue use of the removed setting. Specifying this setting in Elasticsearch diff --git a/server/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java b/server/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java index a7a12f880b49a..94e295a440384 100644 --- a/server/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java +++ b/server/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java @@ -89,8 +89,15 @@ public void run() { }); } - /** initialize native resources */ - public static void initializeNatives(Path tmpFile, boolean mlockAll, boolean systemCallFilter, boolean ctrlHandler) { + /** + * Initialize native resources. + * + * @param tmpFile the temp directory + * @param mlockAll whether or not to lock memory + * @param systemCallFilter whether or not to install system call filters + * @param ctrlHandler whether or not to install the ctrl-c handler (applies to Windows only) + */ + static void initializeNatives(final Path tmpFile, final boolean mlockAll, final boolean systemCallFilter, final boolean ctrlHandler) { final Logger logger = LogManager.getLogger(Bootstrap.class); // check if the user is running as root, and bail @@ -98,8 +105,12 @@ public static void initializeNatives(Path tmpFile, boolean mlockAll, boolean sys throw new RuntimeException("can not run elasticsearch as root"); } - // enable system call filter if (systemCallFilter) { + /* + * Try to install system call filters; if they fail to install; a bootstrap check will fail startup in production mode. + * + * TODO: should we fail hard here if system call filters fail to install, or remain lenient in non-production environments? + */ Natives.tryInstallSystemCallFilter(tmpFile); } @@ -165,7 +176,7 @@ private void setup(boolean addShutdownHook, Environment environment) throws Boot initializeNatives( environment.tmpFile(), BootstrapSettings.MEMORY_LOCK_SETTING.get(settings), - BootstrapSettings.SYSTEM_CALL_FILTER_SETTING.get(settings), + true, // always install system call filters, not user-configurable since 8.0.0 BootstrapSettings.CTRLHANDLER_SETTING.get(settings)); // initialize probes before the security manager is installed diff --git a/server/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java b/server/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java index 3fe05be3f315d..63f534ec862e0 100644 --- a/server/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java +++ b/server/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java @@ -523,15 +523,14 @@ String getUseSerialGC() { } /** - * Bootstrap check that if system call filters are enabled, then system call filters must have installed successfully. + * Bootstrap check that system call filters must have installed successfully. */ static class SystemCallFilterCheck implements BootstrapCheck { @Override public BootstrapCheckResult check(BootstrapContext context) { - if (BootstrapSettings.SYSTEM_CALL_FILTER_SETTING.get(context.settings()) && isSystemCallFilterInstalled() == false) { - final String message = "system call filters failed to install; " + - "check the logs and fix your configuration or disable system call filters at your own risk"; + if (isSystemCallFilterInstalled() == false) { + final String message = "system call filters failed to install; check the logs and fix your configuration"; return BootstrapCheckResult.failure(message); } else { return BootstrapCheckResult.success(); @@ -590,10 +589,10 @@ String onError() { String message(BootstrapContext context) { return String.format( Locale.ROOT, - "OnError [%s] requires forking but is prevented by system call filters ([%s=true]);" + + "OnError [%s] requires forking but is prevented by system call filters;" + " upgrade to at least Java 8u92 and use ExitOnOutOfMemoryError", - onError(), - BootstrapSettings.SYSTEM_CALL_FILTER_SETTING.getKey()); + onError() + ); } } @@ -614,10 +613,10 @@ String onOutOfMemoryError() { String message(BootstrapContext context) { return String.format( Locale.ROOT, - "OnOutOfMemoryError [%s] requires forking but is prevented by system call filters ([%s=true]);" + + "OnOutOfMemoryError [%s] requires forking but is prevented by system call filters;" + " upgrade to at least Java 8u92 and use ExitOnOutOfMemoryError", - onOutOfMemoryError(), - BootstrapSettings.SYSTEM_CALL_FILTER_SETTING.getKey()); + onOutOfMemoryError() + ); } } diff --git a/server/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java b/server/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java index 01013cfbe093c..bbbf3a8c2b974 100644 --- a/server/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java +++ b/server/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java @@ -430,7 +430,6 @@ public void apply(Settings value, Settings current, Settings previous) { PluginsService.MANDATORY_SETTING, BootstrapSettings.SECURITY_FILTER_BAD_DEFAULTS_SETTING, BootstrapSettings.MEMORY_LOCK_SETTING, - BootstrapSettings.SYSTEM_CALL_FILTER_SETTING, BootstrapSettings.CTRLHANDLER_SETTING, KeyStoreWrapper.SEED_SETTING, IndexingMemoryController.INDEX_BUFFER_SIZE_SETTING, diff --git a/server/src/test/java/org/elasticsearch/bootstrap/BootstrapChecksTests.java b/server/src/test/java/org/elasticsearch/bootstrap/BootstrapChecksTests.java index 388aa71e0d650..98a6081891ed1 100644 --- a/server/src/test/java/org/elasticsearch/bootstrap/BootstrapChecksTests.java +++ b/server/src/test/java/org/elasticsearch/bootstrap/BootstrapChecksTests.java @@ -417,14 +417,20 @@ String getUseSerialGC() { public void testSystemCallFilterCheck() throws NodeValidationException { final AtomicBoolean isSystemCallFilterInstalled = new AtomicBoolean(); - BootstrapContext context = randomBoolean() ? createTestContext(Settings.builder().put("bootstrap.system_call_filter", true) - .build(), null) : emptyContext; + final BootstrapContext context; + if (randomBoolean()) { + context = createTestContext(Settings.builder().put("bootstrap.system_call_filter", true).build(), null); + } else { + context = emptyContext; + } final BootstrapChecks.SystemCallFilterCheck systemCallFilterEnabledCheck = new BootstrapChecks.SystemCallFilterCheck() { + @Override boolean isSystemCallFilterInstalled() { return isSystemCallFilterInstalled.get(); } + }; final NodeValidationException e = expectThrows( @@ -432,22 +438,10 @@ boolean isSystemCallFilterInstalled() { () -> BootstrapChecks.check(context, true, Collections.singletonList(systemCallFilterEnabledCheck))); assertThat( e.getMessage(), - containsString("system call filters failed to install; " + - "check the logs and fix your configuration or disable system call filters at your own risk")); + containsString("system call filters failed to install; check the logs and fix your configuration")); isSystemCallFilterInstalled.set(true); BootstrapChecks.check(context, true, Collections.singletonList(systemCallFilterEnabledCheck)); - BootstrapContext context_1 = createTestContext(Settings.builder().put("bootstrap.system_call_filter", false).build(), null); - final BootstrapChecks.SystemCallFilterCheck systemCallFilterNotEnabledCheck = new BootstrapChecks.SystemCallFilterCheck() { - @Override - boolean isSystemCallFilterInstalled() { - return isSystemCallFilterInstalled.get(); - } - }; - isSystemCallFilterInstalled.set(false); - BootstrapChecks.check(context_1, true, Collections.singletonList(systemCallFilterNotEnabledCheck)); - isSystemCallFilterInstalled.set(true); - BootstrapChecks.check(context_1, true, Collections.singletonList(systemCallFilterNotEnabledCheck)); } public void testMightForkCheck() throws NodeValidationException { @@ -482,6 +476,7 @@ public void testOnErrorCheck() throws NodeValidationException { final AtomicBoolean isSystemCallFilterInstalled = new AtomicBoolean(); final AtomicReference onError = new AtomicReference<>(); final BootstrapChecks.MightForkCheck check = new BootstrapChecks.OnErrorCheck() { + @Override boolean isSystemCallFilterInstalled() { return isSystemCallFilterInstalled.get(); @@ -491,6 +486,7 @@ boolean isSystemCallFilterInstalled() { String onError() { return onError.get(); } + }; final String command = randomAlphaOfLength(16); @@ -502,14 +498,15 @@ String onError() { e -> assertThat( e.getMessage(), containsString( - "OnError [" + command + "] requires forking but is prevented by system call filters " + - "([bootstrap.system_call_filter=true]); upgrade to at least Java 8u92 and use ExitOnOutOfMemoryError"))); + "OnError [" + command + "] requires forking but is prevented by system call filters;" + + " upgrade to at least Java 8u92 and use ExitOnOutOfMemoryError"))); } public void testOnOutOfMemoryErrorCheck() throws NodeValidationException { final AtomicBoolean isSystemCallFilterInstalled = new AtomicBoolean(); final AtomicReference onOutOfMemoryError = new AtomicReference<>(); final BootstrapChecks.MightForkCheck check = new BootstrapChecks.OnOutOfMemoryErrorCheck() { + @Override boolean isSystemCallFilterInstalled() { return isSystemCallFilterInstalled.get(); @@ -519,6 +516,7 @@ boolean isSystemCallFilterInstalled() { String onOutOfMemoryError() { return onOutOfMemoryError.get(); } + }; final String command = randomAlphaOfLength(16); @@ -531,7 +529,7 @@ String onOutOfMemoryError() { e.getMessage(), containsString( "OnOutOfMemoryError [" + command + "]" - + " requires forking but is prevented by system call filters ([bootstrap.system_call_filter=true]);" + + " requires forking but is prevented by system call filters;" + " upgrade to at least Java 8u92 and use ExitOnOutOfMemoryError"))); } diff --git a/server/src/test/java/org/elasticsearch/bootstrap/BootstrapSettingsTests.java b/server/src/test/java/org/elasticsearch/bootstrap/BootstrapSettingsTests.java index 778f697dab5ce..47fed80575ce9 100644 --- a/server/src/test/java/org/elasticsearch/bootstrap/BootstrapSettingsTests.java +++ b/server/src/test/java/org/elasticsearch/bootstrap/BootstrapSettingsTests.java @@ -16,7 +16,6 @@ public class BootstrapSettingsTests extends ESTestCase { public void testDefaultSettings() { assertTrue(BootstrapSettings.SECURITY_FILTER_BAD_DEFAULTS_SETTING.get(Settings.EMPTY)); assertFalse(BootstrapSettings.MEMORY_LOCK_SETTING.get(Settings.EMPTY)); - assertTrue(BootstrapSettings.SYSTEM_CALL_FILTER_SETTING.get(Settings.EMPTY)); assertTrue(BootstrapSettings.CTRLHANDLER_SETTING.get(Settings.EMPTY)); } diff --git a/test/framework/src/main/java/org/elasticsearch/bootstrap/BootstrapForTesting.java b/test/framework/src/main/java/org/elasticsearch/bootstrap/BootstrapForTesting.java index 8f6ed735a4685..f353e582be3d3 100644 --- a/test/framework/src/main/java/org/elasticsearch/bootstrap/BootstrapForTesting.java +++ b/test/framework/src/main/java/org/elasticsearch/bootstrap/BootstrapForTesting.java @@ -73,6 +73,7 @@ public class BootstrapForTesting { // just like bootstrap, initialize natives, then SM final boolean memoryLock = BootstrapSettings.MEMORY_LOCK_SETTING.get(Settings.EMPTY); // use the default bootstrap.memory_lock setting + // some tests need the ability to disable system call filters (so they can fork other processes as part of test execution) final boolean systemCallFilter = Booleans.parseBoolean(System.getProperty("tests.system_call_filter", "true")); Bootstrap.initializeNatives(javaTmpDir, memoryLock, systemCallFilter, true); diff --git a/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/DeprecationChecks.java b/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/DeprecationChecks.java index cd447c84c27a5..d4bb45bf27bee 100644 --- a/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/DeprecationChecks.java +++ b/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/DeprecationChecks.java @@ -32,8 +32,7 @@ private DeprecationChecks() { static List> CLUSTER_SETTINGS_CHECKS = Collections.emptyList(); - static List> NODE_SETTINGS_CHECKS = - List.of(NodeDeprecationChecks::checkBootstrapSystemCallFilterSetting); + static List> NODE_SETTINGS_CHECKS = List.of(); static List> INDEX_SETTINGS_CHECKS = List.of(IndexDeprecationChecks::oldIndicesCheck, IndexDeprecationChecks::translogRetentionSettingCheck); diff --git a/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/NodeDeprecationChecks.java b/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/NodeDeprecationChecks.java index 06b59718db2ba..935dc55574eb6 100644 --- a/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/NodeDeprecationChecks.java +++ b/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/NodeDeprecationChecks.java @@ -8,7 +8,6 @@ package org.elasticsearch.xpack.deprecation; import org.elasticsearch.action.admin.cluster.node.info.PluginsAndModules; -import org.elasticsearch.bootstrap.BootstrapSettings; import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.xpack.core.deprecation.DeprecationIssue; @@ -18,14 +17,6 @@ public class NodeDeprecationChecks { - static DeprecationIssue checkBootstrapSystemCallFilterSetting(final Settings settings, final PluginsAndModules pluginsAndModules) { - return checkRemovedSetting( - settings, - BootstrapSettings.SYSTEM_CALL_FILTER_SETTING, - "https://www.elastic.co/guide/en/elasticsearch/reference/7.13/breaking-changes-7.13.html#deprecate-system-call-filter-setting" - ); - } - private static DeprecationIssue checkDeprecatedSetting( final Settings settings, final PluginsAndModules pluginsAndModules, diff --git a/x-pack/plugin/deprecation/src/test/java/org/elasticsearch/xpack/deprecation/NodeDeprecationChecksTests.java b/x-pack/plugin/deprecation/src/test/java/org/elasticsearch/xpack/deprecation/NodeDeprecationChecksTests.java index 9cfe12ea4d855..5f01a4fcaa9d2 100644 --- a/x-pack/plugin/deprecation/src/test/java/org/elasticsearch/xpack/deprecation/NodeDeprecationChecksTests.java +++ b/x-pack/plugin/deprecation/src/test/java/org/elasticsearch/xpack/deprecation/NodeDeprecationChecksTests.java @@ -7,38 +7,17 @@ package org.elasticsearch.xpack.deprecation; -import org.elasticsearch.action.admin.cluster.node.info.PluginsAndModules; -import org.elasticsearch.bootstrap.BootstrapSettings; import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.core.deprecation.DeprecationIssue; -import java.util.List; - import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.nullValue; public class NodeDeprecationChecksTests extends ESTestCase { - public void testCheckBootstrapSystemCallFilterSetting() { - final boolean boostrapSystemCallFilter = randomBoolean(); - final Settings settings = - Settings.builder().put(BootstrapSettings.SYSTEM_CALL_FILTER_SETTING.getKey(), boostrapSystemCallFilter).build(); - final PluginsAndModules pluginsAndModules = new PluginsAndModules(List.of(), List.of()); - final List issues = - DeprecationChecks.filterChecks(DeprecationChecks.NODE_SETTINGS_CHECKS, c -> c.apply(settings, pluginsAndModules)); - final DeprecationIssue expected = new DeprecationIssue( - DeprecationIssue.Level.CRITICAL, - "setting [bootstrap.system_call_filter] is deprecated and will be removed in the next major version", - "https://www.elastic.co/guide/en/elasticsearch/reference/7.13/breaking-changes-7.13.html#deprecate-system-call-filter-setting", - "the setting [bootstrap.system_call_filter] is currently set to [" + boostrapSystemCallFilter + "], remove this setting"); - assertThat(issues, hasItem(expected)); - assertSettingDeprecationsAndWarnings(new Setting[]{BootstrapSettings.SYSTEM_CALL_FILTER_SETTING}); - } - public void testRemovedSettingNotSet() { final Settings settings = Settings.EMPTY; final Setting removedSetting = Setting.simpleString("node.removed_setting");