diff --git a/config/node.options b/config/node.options index d5799f2c2068a..abcb40a5c19d4 100644 --- a/config/node.options +++ b/config/node.options @@ -10,3 +10,6 @@ ## restore < Node 16 default DNS lookup behavior --dns-result-order=ipv4first + +## enable OpenSSL 3 legacy provider +--openssl-legacy-provider diff --git a/docs/user/production-considerations/production.asciidoc b/docs/user/production-considerations/production.asciidoc index 92cb77cc401f7..aa4421125aed9 100644 --- a/docs/user/production-considerations/production.asciidoc +++ b/docs/user/production-considerations/production.asciidoc @@ -118,3 +118,12 @@ The option accepts a limit in MB: -------- --max-old-space-size=2048 -------- + +[float] +[[openssl-legacy-provider]] +=== OpenSSL Legacy Provider + +Starting in 8.10.0, Kibana has upgraded its runtime environment, Node.js, from version 16 to version 18 and with it the underlying version of OpenSSL to 3. +Algorithms deemed legacy by OpenSSL 3 have been re-enabled to avoid potential breaking changes in a minor version release of Kibana. +If SSL certificates configured for Kibana are not using any of the legacy algorithms mentioned in the https://www.openssl.org/docs/man3.0/man7/OSSL_PROVIDER-legacy.html[OpenSSL legacy provider documentation], +we recommend disabling this setting by removing `--openssl-legacy-provider` in the `node.options` config file. diff --git a/packages/kbn-plugin-helpers/src/integration_tests/build.test.ts b/packages/kbn-plugin-helpers/src/integration_tests/build.test.ts index e3d1ca81e2c26..7a3cf7f85ddf2 100644 --- a/packages/kbn-plugin-helpers/src/integration_tests/build.test.ts +++ b/packages/kbn-plugin-helpers/src/integration_tests/build.test.ts @@ -54,7 +54,8 @@ it('builds a generated plugin into a viable archive', async () => { }; expect(filterLogs(generateProc.all)).toMatchInlineSnapshot(` - " succ 🎉 + "Kibana is currently running with legacy OpenSSL providers enabled! For details and instructions on how to disable see https://www.elastic.co/guide/en/kibana/current/production.html#openssl-legacy-provider + succ 🎉 Your plugin has been created in plugins/foo_test_plugin " @@ -73,7 +74,8 @@ it('builds a generated plugin into a viable archive', async () => { ); expect(filterLogs(buildProc.all)).toMatchInlineSnapshot(` - " info deleting the build and target directories + "Kibana is currently running with legacy OpenSSL providers enabled! For details and instructions on how to disable see https://www.elastic.co/guide/en/kibana/current/production.html#openssl-legacy-provider + info deleting the build and target directories info run bazel and build required artifacts for the optimizer succ bazel run successfully and artifacts were created info running @kbn/optimizer diff --git a/src/dev/build/tasks/os_packages/docker_generator/templates/base/Dockerfile b/src/dev/build/tasks/os_packages/docker_generator/templates/base/Dockerfile index a44fae27c4265..8bf470f489cb7 100644 --- a/src/dev/build/tasks/os_packages/docker_generator/templates/base/Dockerfile +++ b/src/dev/build/tasks/os_packages/docker_generator/templates/base/Dockerfile @@ -127,6 +127,9 @@ COPY --chown=1000:0 config/serverless.es.yml /usr/share/kibana/config/serverless COPY --chown=1000:0 config/serverless.oblt.yml /usr/share/kibana/config/serverless.oblt.yml COPY --chown=1000:0 config/serverless.security.yml /usr/share/kibana/config/serverless.security.yml {{/serverless}} +{{^opensslLegacyProvider}} +RUN sed 's/\(--openssl-legacy-provider\)/#\1/' -i config/node.options +{{/opensslLegacyProvider}} # Add the launcher/wrapper script. It knows how to interpret environment # variables and translate them to Kibana CLI options. diff --git a/src/dev/build/tasks/os_packages/docker_generator/templates/dockerfile.template.ts b/src/dev/build/tasks/os_packages/docker_generator/templates/dockerfile.template.ts index ca597e5c38941..456a09ccc3db3 100755 --- a/src/dev/build/tasks/os_packages/docker_generator/templates/dockerfile.template.ts +++ b/src/dev/build/tasks/os_packages/docker_generator/templates/dockerfile.template.ts @@ -19,6 +19,7 @@ function generator(options: TemplateContext) { packageManager: options.baseImage.includes('ubi') ? 'microdnf' : 'apt-get', ubi: options.baseImage.includes('ubi'), ubuntu: options.baseImage === 'ubuntu', + opensslLegacyProvider: !(options.cloud || options.serverless), ...options, }); } diff --git a/src/setup_node_env/openssl_legacy_provider/index.js b/src/setup_node_env/openssl_legacy_provider/index.js new file mode 100644 index 0000000000000..159c2a5e62e9a --- /dev/null +++ b/src/setup_node_env/openssl_legacy_provider/index.js @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +var branch = require('../../../package.json').branch; +var docsBranch = branch.match(/^\d\.\d\d?$/) || 'current'; +var openSSLLegacyProviderEnabled = require('./openssl_legacy_provider_enabled')(); + +if (openSSLLegacyProviderEnabled) { + console.log( + 'Kibana is currently running with legacy OpenSSL providers enabled! For details and instructions on how to disable see https://www.elastic.co/guide/en/kibana/' + + docsBranch + + '/production.html#openssl-legacy-provider' + ); +} diff --git a/src/setup_node_env/openssl_legacy_provider/openssl_legacy_provider_enabled.js b/src/setup_node_env/openssl_legacy_provider/openssl_legacy_provider_enabled.js new file mode 100644 index 0000000000000..bf2f68a1cee76 --- /dev/null +++ b/src/setup_node_env/openssl_legacy_provider/openssl_legacy_provider_enabled.js @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +module.exports = function () { + var nodeOptions = process.env.NODE_OPTIONS + ? process.env.NODE_OPTIONS.split(' ').filter(Boolean) + : []; + var execOptions = process.execArgv; + + var cliOpenSSLLegacyProvider = checkOpenSSLLegacyProvider(execOptions); + var envOpenSSLLegacyProvider = checkOpenSSLLegacyProvider(nodeOptions); + + if (typeof cliOpenSSLLegacyProvider === 'boolean') return cliOpenSSLLegacyProvider; + return Boolean(envOpenSSLLegacyProvider); +}; + +function checkOpenSSLLegacyProvider(options) { + var openSSLLegacyProvider = null; + options.forEach(function (option) { + if (option === '--openssl-legacy-provider') { + openSSLLegacyProvider = true; + } + if (option === '--no-openssl-legacy-provider') { + openSSLLegacyProvider = false; + } + }); + return openSSLLegacyProvider; +} diff --git a/src/setup_node_env/openssl_legacy_provider/openssl_legacy_provider_enabled.test.js b/src/setup_node_env/openssl_legacy_provider/openssl_legacy_provider_enabled.test.js new file mode 100644 index 0000000000000..1ae3b6d273579 --- /dev/null +++ b/src/setup_node_env/openssl_legacy_provider/openssl_legacy_provider_enabled.test.js @@ -0,0 +1,77 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +describe('openSSLLegacyProviderEnabled', function () { + var env = process.env; + var execArgv = process.execArgv; + + beforeEach(function () { + jest.resetModules(); + process.env.NODE_OPTIONS = ''; + process.execArgv = []; + }); + + afterAll(function () { + process.env = env; + process.execArgv = execArgv; + }); + + describe('using NODE_OPTIONS', function () { + it('should be enabled when --openssl-legacy-provider is set', function () { + process.env.NODE_OPTIONS = '--openssl-legacy-provider'; + expect(require('./openssl_legacy_provider_enabled')()).toBe(true); + }); + + it('should be enabled when --openssl-legacy-provider is set after --no-openssl-legacy-provider', function () { + process.env.NODE_OPTIONS = '--no-openssl-legacy-provider --openssl-legacy-provider'; + expect(require('./openssl_legacy_provider_enabled')()).toBe(true); + }); + + it('should be disabled by default', function () { + process.env.NODE_OPTIONS = ''; + expect(require('./openssl_legacy_provider_enabled')()).toBe(false); + }); + + it('should be disabled when --no-openssl-legacy-provider is set', function () { + process.env.NODE_OPTIONS = '--no-openssl-legacy-provider'; + expect(require('./openssl_legacy_provider_enabled')()).toBe(false); + }); + + it('should be disabled when --no-openssl-legacy-provider is set after --openssl-legacy-provider', function () { + process.env.NODE_OPTIONS = '--openssl-legacy-provider --no-openssl-legacy-provider'; + expect(require('./openssl_legacy_provider_enabled')()).toBe(false); + }); + }); + + describe('using exec arguments', function () { + it('should be enabled when --openssl-legacy-provider is set', function () { + process.execArgv = ['--openssl-legacy-provider']; + expect(require('./openssl_legacy_provider_enabled')()).toBe(true); + }); + + it('should be enabled when --openssl-legacy-provider is set after --no-openssl-legacy-provider', function () { + process.execArgv = ['--no-openssl-legacy-provider', '--openssl-legacy-provider']; + expect(require('./openssl_legacy_provider_enabled')()).toBe(true); + }); + + it('should be disabled by default', function () { + process.execArgv = []; + expect(require('./openssl_legacy_provider_enabled')()).toBe(false); + }); + + it('should be disabled when --no-openssl-legacy-provider is set', function () { + process.execArgv = ['--no-openssl-legacy-provider']; + expect(require('./openssl_legacy_provider_enabled')()).toBe(false); + }); + + it('should be disabled when --no-openssl-legacy-provider is set after --openssl-legacy-provider', function () { + process.execArgv = ['--openssl-legacy-provider', '--no-openssl-legacy-provider']; + expect(require('./openssl_legacy_provider_enabled')()).toBe(false); + }); + }); +}); diff --git a/src/setup_node_env/setup_env.js b/src/setup_node_env/setup_env.js index 08897eb5a78c5..7b37d98011cfb 100644 --- a/src/setup_node_env/setup_env.js +++ b/src/setup_node_env/setup_env.js @@ -14,3 +14,4 @@ require('./harden'); require('symbol-observable'); require('source-map-support').install(); require('./node_version_validator'); +require('./openssl_legacy_provider'); diff --git a/src/setup_node_env/tsconfig.json b/src/setup_node_env/tsconfig.json index ed753806b9f4f..931afbdfaf0a3 100644 --- a/src/setup_node_env/tsconfig.json +++ b/src/setup_node_env/tsconfig.json @@ -6,6 +6,7 @@ "include": [ "harden/**/*", "root/**/*", + "openssl_legacy_provider/**/*", "*.js", "*.ts", ],