Skip to content

Commit

Permalink
# This is a combination of 2 commits.
Browse files Browse the repository at this point in the history
# This is the 1st commit message:

Add consistent server.ssl settings

Addressing peer review concerns

Refactoring deprecations, and deprecating elasticsearch and console ssl settings

# This is the commit message #2:

Adding a few more tests
  • Loading branch information
kobelb committed Jan 3, 2017
1 parent 1822db0 commit dcf9175
Show file tree
Hide file tree
Showing 57 changed files with 1,336 additions and 302 deletions.
15 changes: 8 additions & 7 deletions config/kibana.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,23 @@
#elasticsearch.username: "user"
#elasticsearch.password: "pass"

# Paths to the PEM-format SSL certificate and SSL key files, respectively. These
# files enable SSL for outgoing requests from the Kibana server to the browser.
#server.ssl.cert: /path/to/your/server.crt
# Enables SSL and paths to the PEM-format SSL certificate and SSL key files, respectively.
# These settings enable SSL for outgoing requests from the Kibana server to the browser.
#server.ssl.enabled: false
#server.ssl.certificate: /path/to/your/server.crt
#server.ssl.key: /path/to/your/server.key

# Optional settings that provide the paths to the PEM-format SSL certificate and key files.
# These files validate that your Elasticsearch backend uses the same key files.
#elasticsearch.ssl.cert: /path/to/your/client.crt
#elasticsearch.ssl.certificate: /path/to/your/client.crt
#elasticsearch.ssl.key: /path/to/your/client.key

# Optional setting that enables you to specify a path to the PEM file for the certificate
# authority for your Elasticsearch instance.
#elasticsearch.ssl.ca: /path/to/your/CA.pem
#elasticsearch.ssl.certificateAuthorities: /path/to/your/CA.pem

# To disregard the validity of SSL certificates, change this setting's value to false.
#elasticsearch.ssl.verify: true
# To disregard the validity of SSL certificates, change this setting's value to 'none'.
#elasticsearch.ssl.verificationMode: full

# Time in milliseconds to wait for Elasticsearch to respond to pings. Defaults to the value of
# the elasticsearch.requestTimeout setting.
Expand Down
16 changes: 9 additions & 7 deletions docs/setup/production.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,15 @@ to work with X-Pack, see {xpack-ref}kibana.html.
Kibana supports SSL encryption for both client requests and the requests the Kibana server
sends to Elasticsearch.

To encrypt communications between the browser and the Kibana server, you configure the `ssl_key_file` and
`ssl_cert_file` properties in `kibana.yml`:
To encrypt communications between the browser and the Kibana server, you configure the `server.ssl.enabled`,
`server.ssl.certificate` and `server.ssl.key` properties in `kibana.yml`:

[source,text]
----
# SSL for outgoing requests from the Kibana Server (PEM formatted)
server.ssl.enabled: true
server.ssl.key: /path/to/your/server.key
server.ssl.cert: /path/to/your/server.crt
server.ssl.certificate: /path/to/your/server.crt
----

If you are using X-Pack Security or a proxy that provides an HTTPS endpoint for Elasticsearch,
Expand All @@ -62,17 +63,18 @@ protocol when you configure the Elasticsearch URL in `kibana.yml`:

[source,text]
----
elasticsearch: "https://<your_elasticsearch_host>.com:9200"
elasticsearch.url: "https://<your_elasticsearch_host>.com:9200"
----

If you are using a self-signed certificate for Elasticsearch, set the `ca` property in
`kibana.yml` to specify the location of the PEM file. Setting the `ca` property lets you leave the `verify_ssl` option enabled.
If you are using a self-signed certificate for Elasticsearch, set the `certificateAuthorities` property in
`kibana.yml` to specify the location of the PEM file. Setting the `certificateAuthorities` property lets you use the
default `verificationMode` option of `full`.

[source,text]
----
# If you need to provide a CA certificate for your Elasticsearch instance, put
# the path of the pem file here.
ca: /path/to/your/ca/cacert.pem
elasticsearch.ssl.certificateAuthorities: /path/to/your/ca/cacert.pem
----

[float]
Expand Down
16 changes: 11 additions & 5 deletions docs/setup/settings.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,20 @@ Specify the position of the subdomain the URL with the token `{s}`.
`elasticsearch.username:` and `elasticsearch.password:`:: If your Elasticsearch is protected with basic authentication,
these settings provide the username and password that the Kibana server uses to perform maintenance on the Kibana index at
startup. Your Kibana users still need to authenticate with Elasticsearch, which is proxied through the Kibana server.
`server.ssl.cert:` and `server.ssl.key:`:: Paths to the PEM-format SSL certificate and SSL key files, respectively. These
files enable SSL for outgoing requests from the Kibana server to the browser.
`server.ssl.enabled`:: *Default: "false"* Enables SSL for outgoing requests from the Kibana server to the browser. When set to `true`, `server.ssl.certificate` and `server.ssl.key` are required
`server.ssl.certificate:` and `server.ssl.key:`:: Paths to the PEM-format SSL certificate and SSL key files, respectively.
`server.ssl.keyPassphrase`:: The passphrase that will be used to decrypt the private key. This value is optional as the key may not be encrypted.
`server.ssl.certificateAuthorities`:: List of paths to PEM encoded certificate files that should be trusted.
`server.ssl.clientAuthentication`:: *Default: none* Controls Kibana's server behavior in regard to requesting a certificate from client connections. Valid values are `required`,
`optional`, and `none`. `required` forces a client to present a certificate, while `optional` requests a client certificate but the client is not required to present one.
`server.ssl.supportedProtocols`:: *Default: TLSv1, TLSv1.1, TLSv1.2* Supported protocols with versions. Valid protocols: `TLSv1`, `TLSv1.1`, `TLSv1.2`
`elasticsearch.ssl.cert:` and `elasticsearch.ssl.key:`:: Optional settings that provide the paths to the PEM-format SSL
certificate and key files. These files validate that your Elasticsearch backend uses the same key files.
`elasticsearch.ssl.ca:`:: Optional setting that enables you to specify a path to the PEM file for the certificate
`elasticsearch.ssl.keyPassphrase`:: The passphrase that will be used to decrypt the private key. This value is optional as the key may not be encrypted.
`elasticsearch.ssl.certificateAuthorities:`:: Optional setting that enables you to specify a list of paths to the PEM file for the certificate
authority for your Elasticsearch instance.
`elasticsearch.ssl.verify:`:: *Default: true* To disregard the validity of SSL certificates, change this setting’s value
to `false`.
`elasticsearch.ssl.verificationMode:`:: *Default: full* Controls the verification of certificates. Valid values are `none`, `certificate`, and `full`.
`full` performs hostname verification, and `certificate` does not.
`elasticsearch.pingTimeout:`:: *Default: the value of the `elasticsearch.requestTimeout` setting* Time in milliseconds to
wait for Elasticsearch to respond to pings.
`elasticsearch.requestTimeout:`:: *Default: 30000* Time in milliseconds to wait for responses from the back end or
Expand Down
28 changes: 15 additions & 13 deletions src/cli/cluster/base_path_proxy.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { Server } from 'hapi';
import { notFound } from 'boom';
import { merge, sample } from 'lodash';
import { map, merge, sample } from 'lodash';
import { format as formatUrl } from 'url';
import { map, fromNode } from 'bluebird';
import { map as promiseMap, fromNode } from 'bluebird';
import { Agent as HttpsAgent } from 'https';
import { readFileSync } from 'fs';

import Config from '../../server/config/config';
import setupConnection from '../../server/http/setup_connection';
import registerHapiPlugins from '../../server/http/register_hapi_plugins';
import setupLogging from '../../server/logging';
import { transformDeprecations } from '../../server/config/transform_deprecations';
import { DEV_SSL_CERT_PATH } from '../dev_ssl';

const alphabet = 'abcdefghijklmnopqrztuvwxyz'.split('');
Expand All @@ -19,20 +20,21 @@ export default class BasePathProxy {
this.clusterManager = clusterManager;
this.server = new Server();

const config = Config.withDefaultSchema(userSettings);
const settings = transformDeprecations(userSettings);
const config = Config.withDefaultSchema(settings);

this.targetPort = config.get('dev.basePathProxyTarget');
this.basePath = config.get('server.basePath');

const { cert } = config.get('server.ssl');
if (cert) {
const httpsAgentConfig = {};
if (cert === DEV_SSL_CERT_PATH && config.get('server.host') !== 'localhost') {
httpsAgentConfig.rejectUnauthorized = false;
} else {
httpsAgentConfig.ca = readFileSync(cert);
}
this.proxyAgent = new HttpsAgent(httpsAgentConfig);
const sslEnabled = config.get('server.ssl.enabled');
if (sslEnabled) {
this.proxyAgent = new HttpsAgent({
key: readFileSync(config.get('server.ssl.key')),
passphrase: config.get('server.ssl.keyPassphrase'),
cert: readFileSync(config.get('server.ssl.certificate')),
ca: map(config.get('server.ssl.certificateAuthorities'), readFileSync),
rejectUnauthorized: false
});
}

if (!this.basePath) {
Expand Down Expand Up @@ -67,7 +69,7 @@ export default class BasePathProxy {
config: {
pre: [
(req, reply) => {
map(clusterManager.workers, worker => {
promiseMap(clusterManager.workers, worker => {
if (worker.type === 'server' && !worker.listening && !worker.crashed) {
return fromNode(cb => {
const done = () => {
Expand Down
48 changes: 0 additions & 48 deletions src/cli/serve/__tests__/deprecated_config.js

This file was deleted.

1 change: 0 additions & 1 deletion src/cli/serve/__tests__/fixtures/deprecated.yml

This file was deleted.

1 change: 0 additions & 1 deletion src/cli/serve/__tests__/fixtures/legacy.yml

This file was deleted.

28 changes: 0 additions & 28 deletions src/cli/serve/__tests__/legacy_config.js

This file was deleted.

42 changes: 0 additions & 42 deletions src/cli/serve/__tests__/read_yaml_config.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,46 +57,4 @@ describe('cli/serve/read_yaml_config', function () {
process.chdir(oldCwd);
});
});

context('stubbed stdout', function () {
let stub;

beforeEach(function () {
stub = sinon.stub(process.stdout, 'write');
});

context('deprecated settings', function () {
it('warns about deprecated settings', function () {
readYamlConfig(fixture('deprecated.yml'));
sinon.assert.calledOnce(stub);
expect(stub.firstCall.args[0]).to.match(/deprecated/);
stub.restore();
});

it('only warns once about deprecated settings', function () {
readYamlConfig(fixture('deprecated.yml'));
readYamlConfig(fixture('deprecated.yml'));
readYamlConfig(fixture('deprecated.yml'));
sinon.assert.notCalled(stub); // already logged in previous test
stub.restore();
});
});

context('legacy settings', function () {
it('warns about deprecated settings', function () {
readYamlConfig(fixture('legacy.yml'));
sinon.assert.calledOnce(stub);
expect(stub.firstCall.args[0]).to.match(/has been replaced/);
stub.restore();
});

it('only warns once about legacy settings', function () {
readYamlConfig(fixture('legacy.yml'));
readYamlConfig(fixture('legacy.yml'));
readYamlConfig(fixture('legacy.yml'));
sinon.assert.notCalled(stub); // already logged in previous test
stub.restore();
});
});
});
});
16 changes: 0 additions & 16 deletions src/cli/serve/deprecated_config.js

This file was deleted.

52 changes: 0 additions & 52 deletions src/cli/serve/legacy_config.js

This file was deleted.

13 changes: 3 additions & 10 deletions src/cli/serve/read_yaml_config.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
import { chain, isArray, isPlainObject, forOwn, memoize, set, transform } from 'lodash';
import { isArray, isPlainObject, forOwn, set, transform } from 'lodash';
import { readFileSync as read } from 'fs';
import { safeLoad } from 'js-yaml';
import { red } from 'ansicolors';

import { fromRoot } from '../../utils';
import { rewriteLegacyConfig } from './legacy_config';
import { checkForDeprecatedConfig } from './deprecated_config';

const log = memoize(function (message) {
console.log(red('WARNING:'), message);
});
import { fromRoot } from '../../utils';

export function merge(sources) {
return transform(sources, (merged, source) => {
Expand All @@ -35,6 +29,5 @@ export function merge(sources) {
export default function (paths) {
const files = [].concat(paths || []);
const yamls = files.map(path => safeLoad(read(path, 'utf8')));
const config = merge(yamls.map(file => rewriteLegacyConfig(file, log)));
return checkForDeprecatedConfig(config, log);
return merge(yamls);
}
9 changes: 7 additions & 2 deletions src/cli/serve/serve.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,13 @@ function readServerSettings(opts, extraCliOptions) {
if (opts.dev) {
set('env', 'development');
set('optimize.lazy', true);
if (opts.ssl && !has('server.ssl.cert') && !has('server.ssl.key')) {
set('server.ssl.cert', DEV_SSL_CERT_PATH);

if (opts.ssl) {
set('server.ssl.enabled', true);
}

if (opts.ssl && !has('server.ssl.certificate') && !has('server.ssl.key')) {
set('server.ssl.certificate', DEV_SSL_CERT_PATH);
set('server.ssl.key', DEV_SSL_KEY_PATH);
}
}
Expand Down
Loading

0 comments on commit dcf9175

Please sign in to comment.