[8.x] Removing experimental for the FIPS mode config (#200734) (#200825)

# Backport

This will backport the following commits from `main` to `8.x`:
- [Removing experimental for the FIPS mode config
(#200734)](https://github.com/elastic/kibana/pull/200734)

<!--- Backport version: 8.9.8 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT
[{"author":{"name":"Kurt","email":"kc13greiner@users.noreply.github.com"},"sourceCommit":{"committedDate":"2024-11-19T20:23:20Z","message":"Removing
experimental for the FIPS mode config (#200734)\n\n##
Summary\r\n\r\nCloses
https://github.com/elastic/kibana/issues/200718\r\n\r\nRemove the
`experimental` from the fipsMode config path\r\n\r\n## Release
note\r\n\r\nKibana's FIPS mode is no longer considered
experimental\r\n\r\n## FIPS Pipeline for this
branch\r\n\r\nhttps://buildkite.com/elastic/kibana-fips/builds/281","sha":"8e7799ae7aed6504b234c1779e6d3654fbcc9a32","branchLabelMapping":{"^v9.0.0$":"main","^v8.17.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["v9.0.0","release_note:feature","backport:version","v8.17.0"],"number":200734,"url":"https://github.com/elastic/kibana/pull/200734","mergeCommit":{"message":"Removing
experimental for the FIPS mode config (#200734)\n\n##
Summary\r\n\r\nCloses
https://github.com/elastic/kibana/issues/200718\r\n\r\nRemove the
`experimental` from the fipsMode config path\r\n\r\n## Release
note\r\n\r\nKibana's FIPS mode is no longer considered
experimental\r\n\r\n## FIPS Pipeline for this
branch\r\n\r\nhttps://buildkite.com/elastic/kibana-fips/builds/281","sha":"8e7799ae7aed6504b234c1779e6d3654fbcc9a32"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","labelRegex":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/200734","number":200734,"mergeCommit":{"message":"Removing
experimental for the FIPS mode config (#200734)\n\n##
Summary\r\n\r\nCloses
https://github.com/elastic/kibana/issues/200718\r\n\r\nRemove the
`experimental` from the fipsMode config path\r\n\r\n## Release
note\r\n\r\nKibana's FIPS mode is no longer considered
experimental\r\n\r\n## FIPS Pipeline for this
branch\r\n\r\nhttps://buildkite.com/elastic/kibana-fips/builds/281","sha":"8e7799ae7aed6504b234c1779e6d3654fbcc9a32"}},{"branch":"8.x","label":"v8.17.0","labelRegex":"^v8.17.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->
This commit is contained in:
Kurt 2024-11-19 19:15:25 -05:00 committed by GitHub
parent 2298269001
commit 5f95241e48
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 79 additions and 73 deletions

View file

@ -146,7 +146,7 @@ if [[ "${KBN_ENABLE_FIPS:-}" == "true" ]] || is_pr_with_label "ci:enable-fips-ag
fi
if [[ -f "$KIBANA_DIR/config/kibana.yml" ]]; then
echo -e '\nxpack.security.experimental.fipsMode.enabled: true' >>"$KIBANA_DIR/config/kibana.yml"
echo -e '\nxpack.security.fipsMode.enabled: true' >>"$KIBANA_DIR/config/kibana.yml"
fi
fi

View file

@ -9,7 +9,7 @@ setup_fips() {
fi
if [ -n "$FIPS" ] && [ "$FIPS" = "1" ]; then
sed -i '/xpack.security.experimental.fipsMode.enabled:/ {s/.*/xpack.security.experimental.fipsMode.enabled: true/; t}; $a\xpack.security.experimental.fipsMode.enabled: true' "$KBN_CONFIG_FILE"
sed -i '/xpack.security.fipsMode.enabled:/ {s/.*/xpack.security.fipsMode.enabled: true/; t}; $a\xpack.security.fipsMode.enabled: true' "$KBN_CONFIG_FILE"
# Patch node_modules so we can start Kibana in dev mode
sed -i 's/hashType = hashType || '\''md5'\'';/hashType = hashType || '\''sha1'\'';/g' "${KBN_DIR}/node_modules/file-loader/node_modules/loader-utils/lib/getHashDigest.js"
@ -21,7 +21,7 @@ setup_fips() {
echo "FIPS mode enabled"
echo "If manually bootstrapping in FIPS mode use: NODE_OPTIONS='' yarn kbn bootstrap"
else
sed -i '/xpack.security.experimental.fipsMode.enabled:/ {s/.*/xpack.security.experimental.fipsMode.enabled: false/; t}; $a\xpack.security.experimental.fipsMode.enabled: false' "$KBN_CONFIG_FILE"
sed -i '/xpack.security.fipsMode.enabled:/ {s/.*/xpack.security.fipsMode.enabled: false/; t}; $a\xpack.security.fipsMode.enabled: false' "$KBN_CONFIG_FILE"
fi
}

View file

@ -29,7 +29,7 @@ For {kib}, adherence to FIPS 140-2 is ensured by:
==== Configuring {kib} for FIPS 140-2
Apart from setting `xpack.security.experimental.fipsMode.enabled` to `true` in your {kib} config, a number of security related
Apart from setting `xpack.security.fipsMode.enabled` to `true` in your {kib} config, a number of security related
settings need to be reviewed and configured in order to run {kib} successfully in a FIPS 140-2 compliant Node.js
environment.
@ -56,8 +56,3 @@ As an example, avoid PKCS#12 specific settings such as:
* `server.ssl.truststore.path`
* `elasticsearch.ssl.keystore.path`
* `elasticsearch.ssl.truststore.path`
===== Limitations
Configuring {kib} to run in FIPS mode is still considered to be experimental. Not all features are guaranteed to
function as expected.

View file

@ -25,26 +25,26 @@ import { loggingSystemMock } from '@kbn/core-logging-server-mocks';
describe('fips', () => {
let securityConfig: SecurityServiceConfigType;
describe('#isFipsEnabled', () => {
it('should return `true` if config.experimental.fipsMode.enabled is `true`', () => {
securityConfig = { experimental: { fipsMode: { enabled: true } } };
it('should return `true` if config.fipsMode.enabled is `true`', () => {
securityConfig = { fipsMode: { enabled: true } };
expect(isFipsEnabled(securityConfig)).toBe(true);
});
it('should return `false` if config.experimental.fipsMode.enabled is `false`', () => {
securityConfig = { experimental: { fipsMode: { enabled: false } } };
it('should return `false` if config.fipsMode.enabled is `false`', () => {
securityConfig = { fipsMode: { enabled: false } };
expect(isFipsEnabled(securityConfig)).toBe(false);
});
it('should return `false` if config.experimental.fipsMode.enabled is `undefined`', () => {
it('should return `false` if config.fipsMode.enabled is `undefined`', () => {
expect(isFipsEnabled(securityConfig)).toBe(false);
});
});
describe('checkFipsConfig', () => {
it('should log an error message if FIPS mode is misconfigured - xpack.security.experimental.fipsMode.enabled true, Nodejs FIPS mode false', async () => {
securityConfig = { experimental: { fipsMode: { enabled: true } } };
it('should log an error message if FIPS mode is misconfigured - xpack.security.fipsMode.enabled true, Nodejs FIPS mode false', async () => {
securityConfig = { fipsMode: { enabled: true } };
const logger = loggingSystemMock.create().get();
let fipsException: undefined | CriticalError;
try {
@ -56,16 +56,16 @@ describe('fips', () => {
expect(fipsException).toBeInstanceOf(CriticalError);
expect(fipsException!.processExitCode).toBe(78);
expect(fipsException!.message).toEqual(
'Configuration mismatch error. xpack.security.experimental.fipsMode.enabled is set to true and the configured Node.js environment has FIPS disabled'
'Configuration mismatch error. xpack.security.fipsMode.enabled is set to true and the configured Node.js environment has FIPS disabled'
);
});
it('should log an error message if FIPS mode is misconfigured - xpack.security.experimental.fipsMode.enabled false, Nodejs FIPS mode true', async () => {
it('should log an error message if FIPS mode is misconfigured - xpack.security.fipsMode.enabled false, Nodejs FIPS mode true', async () => {
mockGetFipsFn.mockImplementationOnce(() => {
return 1;
});
securityConfig = { experimental: { fipsMode: { enabled: false } } };
securityConfig = { fipsMode: { enabled: false } };
const logger = loggingSystemMock.create().get();
let fipsException: undefined | CriticalError;
@ -77,16 +77,16 @@ describe('fips', () => {
expect(fipsException).toBeInstanceOf(CriticalError);
expect(fipsException!.processExitCode).toBe(78);
expect(fipsException!.message).toEqual(
'Configuration mismatch error. xpack.security.experimental.fipsMode.enabled is set to false and the configured Node.js environment has FIPS enabled'
'Configuration mismatch error. xpack.security.fipsMode.enabled is set to false and the configured Node.js environment has FIPS enabled'
);
});
it('should log an info message if FIPS mode is properly configured - xpack.security.experimental.fipsMode.enabled true, Nodejs FIPS mode true', async () => {
it('should log an info message if FIPS mode is properly configured - xpack.security.fipsMode.enabled true, Nodejs FIPS mode true', async () => {
mockGetFipsFn.mockImplementationOnce(() => {
return 1;
});
securityConfig = { experimental: { fipsMode: { enabled: true } } };
securityConfig = { fipsMode: { enabled: true } };
const logger = loggingSystemMock.create().get();
try {
@ -113,7 +113,7 @@ describe('fips', () => {
return 1;
});
securityConfig = { experimental: { fipsMode: { enabled: true } } };
securityConfig = { fipsMode: { enabled: true } };
});
afterEach(function () {

View file

@ -12,7 +12,7 @@ import { getFips } from 'crypto';
import { CriticalError } from '@kbn/core-base-server-internal';
import { PKCS12ConfigType, SecurityServiceConfigType } from '../utils';
export function isFipsEnabled(config: SecurityServiceConfigType): boolean {
return config?.experimental?.fipsMode?.enabled ?? false;
return config?.fipsMode?.enabled ?? false;
}
export function checkFipsConfig(
@ -33,7 +33,7 @@ export function checkFipsConfig(
// FIPS must be enabled on both, or, log/error an exit Kibana
if (isFipsConfigEnabled !== isNodeRunningWithFipsEnabled) {
throw new CriticalError(
`Configuration mismatch error. xpack.security.experimental.fipsMode.enabled is set to ${isFipsConfigEnabled} and the configured Node.js environment has FIPS ${
`Configuration mismatch error. xpack.security.fipsMode.enabled is set to ${isFipsConfigEnabled} and the configured Node.js environment has FIPS ${
isNodeRunningWithFipsEnabled ? 'enabled' : 'disabled'
}`,
'invalidConfig',

View file

@ -32,10 +32,8 @@ describe('SecurityService', function () {
const mockConfig = {
xpack: {
security: {
experimental: {
fipsMode: {
enabled: !!getFips(),
},
fipsMode: {
enabled: !!getFips(),
},
},
},

View file

@ -11,10 +11,8 @@ export { convertSecurityApi } from './convert_security_api';
export { getDefaultSecurityImplementation } from './default_implementation';
export interface SecurityServiceConfigType {
experimental?: {
fipsMode?: {
enabled: boolean;
};
fipsMode?: {
enabled: boolean;
};
}

View file

@ -66,7 +66,7 @@ export function createRootWithSettings(
*/
let oss = true;
if (getFips() === 1) {
set(settings, 'xpack.security.experimental.fipsMode.enabled', true);
set(settings, 'xpack.security.fipsMode.enabled', true);
oss = false;
delete cliArgs.oss;
}

View file

@ -44,7 +44,7 @@ describe('migrator-only node', () => {
'--no-optimizer',
'--no-base-path',
'--no-watch',
isFipsEnabled ? '--xpack.security.experimental.fipsMode.enabled=true' : '--oss',
isFipsEnabled ? '--xpack.security.fipsMode.enabled=true' : '--oss',
],
{ stdio: ['pipe', 'pipe', 'pipe'] }
);

View file

@ -393,7 +393,7 @@ kibana_vars=(
xpack.security.authc.selector.enabled
xpack.security.cookieName
xpack.security.encryptionKey
xpack.security.experimental.fipsMode.enabled
xpack.security.fipsMode.enabled
xpack.security.loginAssistanceMessage
xpack.security.loginHelp
xpack.security.sameSiteCookies

View file

@ -59,7 +59,7 @@ RUN set -e ; \
make install > /dev/null ; \
rm -rf "/usr/share/kibana/openssl-${OPENSSL_VERSION}" ; \
chown -R 1000:0 "${OPENSSL_PATH}";
{{/fips}}
# Ensure that group permissions are the same as user permissions.
# This will help when relying on GID-0 to run Kibana, rather than UID-1000.
@ -156,7 +156,7 @@ RUN /bin/echo -e '\n--enable-fips' >> config/node.options
RUN echo '--openssl-config=/usr/share/kibana/config/nodejs.cnf' >> config/node.options
COPY --chown=1000:0 openssl/nodejs.cnf "/usr/share/kibana/config/nodejs.cnf"
ENV OPENSSL_MODULES=/usr/share/kibana/openssl/lib/ossl-modules
ENV XPACK_SECURITY_EXPERIMENTAL_FIPSMODE_ENABLED=true
ENV XPACK_SECURITY_FIPSMODE_ENABLED=true
{{/fips}}
RUN ln -s /usr/share/kibana /opt/kibana

View file

@ -62,10 +62,8 @@ describe('config schema', () => {
},
"cookieName": "sid",
"encryptionKey": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"experimental": Object {
"fipsMode": Object {
"enabled": false,
},
"fipsMode": Object {
"enabled": false,
},
"loginAssistanceMessage": "",
"public": Object {},
@ -121,10 +119,8 @@ describe('config schema', () => {
},
"cookieName": "sid",
"encryptionKey": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"experimental": Object {
"fipsMode": Object {
"enabled": false,
},
"fipsMode": Object {
"enabled": false,
},
"loginAssistanceMessage": "",
"public": Object {},
@ -179,10 +175,8 @@ describe('config schema', () => {
"selector": Object {},
},
"cookieName": "sid",
"experimental": Object {
"fipsMode": Object {
"enabled": false,
},
"fipsMode": Object {
"enabled": false,
},
"loginAssistanceMessage": "",
"public": Object {},
@ -240,10 +234,8 @@ describe('config schema', () => {
"selector": Object {},
},
"cookieName": "sid",
"experimental": Object {
"fipsMode": Object {
"enabled": false,
},
"fipsMode": Object {
"enabled": false,
},
"loginAssistanceMessage": "",
"public": Object {},

View file

@ -314,10 +314,8 @@ export const ConfigSchema = schema.object({
roleMappingManagementEnabled: schema.boolean({ defaultValue: true }),
}),
}),
experimental: schema.object({
fipsMode: schema.object({
enabled: schema.boolean({ defaultValue: false }),
}),
fipsMode: schema.object({
enabled: schema.boolean({ defaultValue: false }),
}),
});

View file

@ -46,6 +46,28 @@ describe('Config Deprecations', () => {
expect(messages).toHaveLength(0);
});
it('renames `xpack.security.experimental.fipsMode.enabled` to `xpack.security.fipsMode.enabled`', () => {
const config = {
xpack: {
security: {
experimental: {
fipsMode: {
enabled: true,
},
},
},
},
};
const { messages, migrated } = applyConfigDeprecations(cloneDeep(config));
expect(migrated.xpack.security.experimental?.fipsMode?.enabled).not.toBeDefined();
expect(migrated.xpack.security.fipsMode.enabled).toEqual(true);
expect(messages).toMatchInlineSnapshot(`
Array [
"Setting \\"xpack.security.experimental.fipsMode.enabled\\" has been replaced by \\"xpack.security.fipsMode.enabled\\"",
]
`);
});
it('renames sessionTimeout to session.idleTimeout', () => {
const config = {
xpack: {

View file

@ -21,6 +21,9 @@ export const securityConfigDeprecationProvider: ConfigDeprecationProvider = ({
rename('audit.appender.policy.kind', 'audit.appender.policy.type', { level: 'warning' }),
rename('audit.appender.strategy.kind', 'audit.appender.strategy.type', { level: 'warning' }),
rename('audit.appender.path', 'audit.appender.fileName', { level: 'warning' }),
rename('experimental.fipsMode.enabled', 'fipsMode.enabled', {
level: 'critical',
}),
renameFromRoot(
'security.showInsecureClusterWarning',

View file

@ -43,7 +43,7 @@ function buildMockFipsServiceSetupParams(
let mockConfig = {};
if (isFipsConfigured) {
mockConfig = { experimental: { fipsMode: { enabled: true } } };
mockConfig = { fipsMode: { enabled: true } };
}
return {
@ -84,7 +84,7 @@ describe('FipsService', () => {
describe('#validateLicenseForFips', () => {
describe('start-up check', () => {
it('should not throw Error/log.error if license features allowFips and `experimental.fipsMode.enabled` is `false`', () => {
it('should not throw Error/log.error if license features allowFips and `fipsMode.enabled` is `false`', () => {
fipsServiceSetup = fipsService.setup(
buildMockFipsServiceSetupParams('platinum', false, of({ allowFips: true }))
);
@ -93,7 +93,7 @@ describe('FipsService', () => {
expect(logger.error).not.toHaveBeenCalled();
});
it('should not throw Error/log.error if license features allowFips and `experimental.fipsMode.enabled` is `true`', () => {
it('should not throw Error/log.error if license features allowFips and `fipsMode.enabled` is `true`', () => {
fipsServiceSetup = fipsService.setup(
buildMockFipsServiceSetupParams('platinum', true, of({ allowFips: true }))
);
@ -102,7 +102,7 @@ describe('FipsService', () => {
expect(logger.error).not.toHaveBeenCalled();
});
it('should not throw Error/log.error if license features do not allowFips and `experimental.fipsMode.enabled` is `false`', () => {
it('should not throw Error/log.error if license features do not allowFips and `fipsMode.enabled` is `false`', () => {
fipsServiceSetup = fipsService.setup(
buildMockFipsServiceSetupParams('basic', false, of({ allowFips: false }))
);
@ -111,7 +111,7 @@ describe('FipsService', () => {
expect(logger.error).not.toHaveBeenCalled();
});
it('should throw Error/log.error if license features do not allowFips and `experimental.fipsMode.enabled` is `true`', () => {
it('should throw Error/log.error if license features do not allowFips and `fipsMode.enabled` is `true`', () => {
fipsServiceSetup = fipsService.setup(
buildMockFipsServiceSetupParams('basic', true, of({ allowFips: false }))
);
@ -124,7 +124,7 @@ describe('FipsService', () => {
});
describe('monitoring check', () => {
describe('with experimental.fipsMode.enabled', () => {
describe('with fipsMode.enabled', () => {
let mockFeaturesSubject: BehaviorSubject<Partial<SecurityLicenseFeatures>>;
let mockIsAvailableSubject: BehaviorSubject<boolean>;
let mockFeatures$: Observable<Partial<SecurityLicenseFeatures>>;
@ -149,23 +149,23 @@ describe('FipsService', () => {
mockIsAvailableSubject.next(true);
});
it('should not log.error if license changes to unavailable and `experimental.fipsMode.enabled` is `true`', () => {
it('should not log.error if license changes to unavailable and `fipsMode.enabled` is `true`', () => {
mockIsAvailableSubject.next(false);
expect(logger.error).not.toHaveBeenCalled();
});
it('should not log.error if license features continue to allowFips and `experimental.fipsMode.enabled` is `true`', () => {
it('should not log.error if license features continue to allowFips and `fipsMode.enabled` is `true`', () => {
mockFeaturesSubject.next({ allowFips: true });
expect(logger.error).not.toHaveBeenCalled();
});
it('should log.error if license features change to not allowFips and `experimental.fipsMode.enabled` is `true`', () => {
it('should log.error if license features change to not allowFips and `fipsMode.enabled` is `true`', () => {
mockFeaturesSubject.next({ allowFips: false });
expect(logger.error).toHaveBeenCalledTimes(1);
});
});
describe('with not experimental.fipsMode.enabled', () => {
describe('with not fipsMode.enabled', () => {
let mockFeaturesSubject: BehaviorSubject<Partial<SecurityLicenseFeatures>>;
let mockIsAvailableSubject: BehaviorSubject<boolean>;
let mockFeatures$: Observable<Partial<SecurityLicenseFeatures>>;
@ -191,17 +191,17 @@ describe('FipsService', () => {
mockIsAvailableSubject.next(true);
});
it('should not log.error if license changes to unavailable and `experimental.fipsMode.enabled` is `false`', () => {
it('should not log.error if license changes to unavailable and `fipsMode.enabled` is `false`', () => {
mockIsAvailableSubject.next(false);
expect(logger.error).not.toHaveBeenCalled();
});
it('should not log.error if license features continue to allowFips and `experimental.fipsMode.enabled` is `false`', () => {
it('should not log.error if license features continue to allowFips and `fipsMode.enabled` is `false`', () => {
mockFeaturesSubject.next({ allowFips: true });
expect(logger.error).not.toHaveBeenCalled();
});
it('should not log.error if license change to not allowFips and `experimental.fipsMode.enabled` is `false`', () => {
it('should not log.error if license change to not allowFips and `fipsMode.enabled` is `false`', () => {
mockFeaturesSubject.next({ allowFips: false });
expect(logger.error).not.toHaveBeenCalled();
});

View file

@ -40,7 +40,7 @@ export class FipsService {
const errorMessage = `Your current license level is ${license.getLicenseType()} and does not support running in FIPS mode.`;
if (license.isLicenseAvailable() && !this.isInitialLicenseLoaded) {
if (config?.experimental.fipsMode.enabled && !license.getFeatures().allowFips) {
if (config?.fipsMode.enabled && !license.getFeatures().allowFips) {
this.logger.error(errorMessage);
throw new Error(errorMessage);
}
@ -51,7 +51,7 @@ export class FipsService {
if (
this.isInitialLicenseLoaded &&
license.isLicenseAvailable() &&
config?.experimental.fipsMode.enabled &&
config?.fipsMode.enabled &&
!features.allowFips
) {
this.logger.error(