[Reporting] Allow Chromium to work by default in Docker (#149080)

## Summary

Closes https://github.com/elastic/kibana/issues/129148


### Checklist

Delete any items that are not applicable to this PR.

- [x]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

## Release Note
Fixed a bug where Kibana Reporting would not work in Elastic Docker
without adding a special setting in kibana.yml.
This commit is contained in:
Tim Sullivan 2023-07-11 08:16:03 -07:00 committed by GitHub
parent a92432869f
commit 787491e2bb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 48 additions and 9 deletions

View file

@ -28,14 +28,15 @@ For an additional layer of security, use the sandbox. The Chromium sandbox uses
[[reporting-linux-sandbox]]
==== Linux sandbox
The Linux sandbox depends on user namespaces, which were introduced with the 3.8 Linux kernel. However, many
distributions don't have user namespaces enabled by default, or they require the CAP_SYS_ADMIN capability. The {report-features}
automatically disable the sandbox when it is running on Debian because additional steps are required to enable
unprivileged usernamespaces. In these situations, you'll see the following message in your {kib} startup logs:
distributions don't support or allow non-privileged processes to create user namespaces, or they require the CAP_SYS_ADMIN capability. The {report-features}
automatically disable the sandbox when it detects it is running on systems where it is not enabled.
Without explicitly setting `xpack.screenshotting.browser.chromium.disableSandbox: false` in `kibana.yml`,
the {report-features} may detect that it can't be enabled. In the event it is automatically disabled, you'll see the following message in your {kib} startup logs:
`Chromium sandbox provides an additional layer of protection, but is not supported for your OS.
Automatically setting 'xpack.screenshotting.browser.chromium.disableSandbox: true'.`
Reporting automatically enables the Chromium sandbox at startup when a supported OS is detected. However, if your kernel is 3.8 or newer, it's
recommended to set `xpack.screenshotting.browser.chromium.disableSandbox: false` in your `kibana.yml` to explicitly enable usernamespaces.
recommended to set `xpack.screenshotting.browser.chromium.disableSandbox: false` in your `kibana.yml` to explicitly enable the sandbox.
[float]
[[reporting-docker-sandbox]]

View file

@ -115,6 +115,7 @@ WORKDIR /usr/share/kibana
RUN ln -s /usr/share/kibana /opt/kibana
{{! Please notify @elastic/kibana-security if you want to remove or change this environment variable. }}
{{! Kibana applications may depend on the ELASTIC_CONTAINER value. Screenshotting uses this to conditionally disable the Chromium sandbox when launching Puppeteer. }}
ENV ELASTIC_CONTAINER true
ENV PATH=/usr/share/kibana/bin:$PATH

View file

@ -52,6 +52,7 @@ WORKDIR /usr/share/kibana
RUN ln -s /usr/share/kibana /opt/kibana
{{! Please notify @elastic/kibana-security if you want to remove or change this environment variable. }}
{{! Kibana applications may depend on the ELASTIC_CONTAINER value. Screenshotting uses this to conditionally disable the Chromium sandbox when launching Puppeteer. }}
ENV ELASTIC_CONTAINER true
ENV PATH=/usr/share/kibana/bin:$PATH

View file

@ -33,3 +33,32 @@ describe('getDefaultChromiumSandboxDisabled', () => {
);
});
});
describe('Docker', () => {
const mockOs = { os: 'linux', dist: 'Ubuntu Linux', release: '20.01' };
it('Non-Docker', async () => {
(getos as jest.Mock).mockImplementation((cb) => cb(null, mockOs));
await expect(getDefaultChromiumSandboxDisabled()).resolves.toHaveProperty(
'disableSandbox',
false
);
});
it('Elastic Docker container', async () => {
// setup: mock environment variables
const env = { ...process.env };
process.env.ELASTIC_CONTAINER = 'true';
(getos as jest.Mock).mockImplementation((cb) => cb(null, mockOs));
await expect(getDefaultChromiumSandboxDisabled()).resolves.toHaveProperty(
'disableSandbox',
true
);
// cleanup: restore the environment variables
process.env = env;
});
});

View file

@ -11,7 +11,7 @@ import { promisify } from 'util';
const getOs = promisify(getOsSync);
const distroSupportsUnprivilegedUsernamespaces = (distro: string) => {
// Debian 7 and 8 don't support usernamespaces by default
// Debian 7 and 8 don't support user namespaces by default
// this should be reevaluated when Debian 9 is available
if (distro.toLowerCase() === 'debian') {
return false;
@ -40,8 +40,15 @@ interface OsSummary {
export async function getDefaultChromiumSandboxDisabled(): Promise<OsSummary> {
const os = await getOs();
return {
os,
disableSandbox: os.os === 'linux' && !distroSupportsUnprivilegedUsernamespaces(os.dist),
};
let enableSandbox: boolean;
if (process.env.ELASTIC_CONTAINER) {
// In the Elastic Docker image, user namespaces is not supported. This is relatively safe since Docker
// provides a level of isolation. In addition, Chromium is only used to open Kibana URLs within the
// deployment, which makes it relatively locked down from being able to exploit Chromium.
enableSandbox = false;
} else {
enableSandbox = os.os !== 'linux' || distroSupportsUnprivilegedUsernamespaces(os.dist);
}
return { os, disableSandbox: !enableSandbox };
}