Skip to content

Commit

Permalink
[node] Enable openssl legacy provider
Browse files Browse the repository at this point in the history
This is to prevent a breaking change in a minor release of Kibana.  The
legacy provider can be disabled by removing `--openssl-legacy-provider`
in `config/node.options`.

[Node.js documentation](https://nodejs.org/docs/latest-v18.x/api/cli.html#--openssl-legacy-provider)
[OpenSSL documentation](https://www.openssl.org/docs/man3.0/man7/OSSL_PROVIDER-legacy.html)
  • Loading branch information
jbudz committed Aug 29, 2023
1 parent 6b20ca9 commit e6de936
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 2 deletions.
3 changes: 3 additions & 0 deletions config/node.options
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@

## restore < Node 16 default DNS lookup behavior
--dns-result-order=ipv4first

## enable OpenSSL 3 legacy provider
--openssl-legacy-provider
9 changes: 9 additions & 0 deletions docs/user/production-considerations/production.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Original file line number Diff line number Diff line change
Expand Up @@ -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
"
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
});
}
Expand Down
18 changes: 18 additions & 0 deletions src/setup_node_env/openssl_legacy_provider/index.js
Original file line number Diff line number Diff line change
@@ -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'
);
}
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -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);
});
});
});
1 change: 1 addition & 0 deletions src/setup_node_env/setup_env.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ require('./harden');
require('symbol-observable');
require('source-map-support').install();
require('./node_version_validator');
require('./openssl_legacy_provider');
1 change: 1 addition & 0 deletions src/setup_node_env/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"include": [
"harden/**/*",
"root/**/*",
"openssl_legacy_provider/**/*",
"*.js",
"*.ts",
],
Expand Down

0 comments on commit e6de936

Please sign in to comment.