Skip to content

Commit

Permalink
Configurable custom response headers for server (#13045)
Browse files Browse the repository at this point in the history
* Configurable custom response headers for server

The server.customResponseHeaders configuration allows users to configure
custom headers to send on all responses to the client from anywhere in
the Kibana server.

This can be useful for setting headers like x-frame-options when you
don't want people embedding even Kibana dashboards in an iframe.

* Consistent header overriding and explicit unknown
  • Loading branch information
epixa committed Jul 21, 2017
1 parent fbcbb4f commit cba3e93
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 14 deletions.
21 changes: 11 additions & 10 deletions docs/setup/settings.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ you'll need to update your `kibana.yml` file. You can also enable SSL and set a
`server.maxPayloadBytes:`:: *Default: 1048576* The maximum payload size in bytes for incoming server requests.
`server.name:`:: *Default: "your-hostname"* A human-readable display name that identifies this Kibana instance.
`server.defaultRoute:`:: *Default: "/app/kibana"* This setting specifies the default route when opening Kibana. You can use this setting to modify the landing page when opening Kibana.
`server.customResponseHeaders:`:: *Default: `{}`* Header names and values to send on all responses to the client from the Kibana server.
`elasticsearch.url:`:: *Default: "http://localhost:9200"* The URL of the Elasticsearch instance to use for all your
queries.
`elasticsearch.preserveHost:`:: *Default: true* When this setting’s value is true Kibana uses the hostname specified in
Expand All @@ -23,34 +24,34 @@ to this Kibana instance.
dashboards. Kibana creates a new index if the index doesn’t already exist.
`kibana.defaultAppId:`:: *Default: "discover"* The default application to load.
[[tilemap-settings]]`tilemap.url:`:: The URL to the tile
service that Kibana uses to display map tiles in tilemap visualizations. By default, Kibana reads this url from an external metadata service, but users can still override this parameter to use their own Tile Map Service. For example: `"https://tiles.elastic.co/v2/default/{z}/{x}/{y}.png?elastic_tile_service_tos=agree&my_app_name=kibana"`
service that Kibana uses to display map tiles in tilemap visualizations. By default, Kibana reads this url from an external metadata service, but users can still override this parameter to use their own Tile Map Service. For example: `"https://tiles.elastic.co/v2/default/{z}/{x}/{y}.png?elastic_tile_service_tos=agree&my_app_name=kibana"`
`tilemap.options.minZoom:`:: *Default: 1* The minimum zoom level.
`tilemap.options.maxZoom:`:: *Default: 10* The maximum zoom level.
`tilemap.options.attribution:`:: *Default: `"© [Elastic Maps Service](https://www.elastic.co/elastic-maps-service)"`* The map attribution string.
`tilemap.options.subdomains:`:: An array of subdomains used by the tile service.
Specify the position of the subdomain the URL with the token `{s}`.

[[regionmap-settings]] `regionmap`:: Specifies additional vector layers for use in <<regionmap, Region Map>> visualizations.
Each layer object points to an external vector file that contains a geojson FeatureCollection.
The file must use the WGS84 coordinate reference system and only include polygons.
If the file is hosted on a separate domain from Kibana, the server needs to be CORS-enabled so Kibana can download the file.
The url field also serves as a unique identifier for the file.
Each layer can contain multiple fields to indicate what properties from the geojson features you want to expose.
[[regionmap-settings]] `regionmap`:: Specifies additional vector layers for use in <<regionmap, Region Map>> visualizations.
Each layer object points to an external vector file that contains a geojson FeatureCollection.
The file must use the WGS84 coordinate reference system and only include polygons.
If the file is hosted on a separate domain from Kibana, the server needs to be CORS-enabled so Kibana can download the file.
The url field also serves as a unique identifier for the file.
Each layer can contain multiple fields to indicate what properties from the geojson features you want to expose.
The field.description is the human readable text that is shown in the Region Map visualization's field menu.
An optional attribution value can be added as well.
The following example shows a valid regionmap configuration.

regionmap:
layers:
layers:
- name: "Departments of France"
url: "http://my.cors.enabled.server.org/france_departements.geojson"
attribution: "INRAP"
fields:
- name: "department"
description: "Full department name"
- name: "INSEE"
description: "INSEE numeric identifier"
description: "INSEE numeric identifier"

`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.
Expand Down
1 change: 1 addition & 0 deletions src/server/config/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ module.exports = () => Joi.object({
autoListen: Joi.boolean().default(true),
defaultRoute: Joi.string().default('/app/kibana').regex(/^\//, `start with a slash`),
basePath: Joi.string().default('').allow('').regex(/(^$|^\/.*[^\/]$)/, `start with a slash, don't end with one`),
customResponseHeaders: Joi.object().unknown(true).default({}),
ssl: Joi.object({
enabled: Joi.boolean().default(false),
certificate: Joi.string().when('enabled', {
Expand Down
17 changes: 13 additions & 4 deletions src/server/http/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,21 @@ module.exports = async function (kbnServer, server, config) {
server.ext('onPreResponse', function (req, reply) {
const response = req.response;

const customHeaders = {
...config.get('server.customResponseHeaders'),
'kbn-name': kbnServer.name,
'kbn-version': kbnServer.version,
};

if (response.isBoom) {
response.output.headers['kbn-name'] = kbnServer.name;
response.output.headers['kbn-version'] = kbnServer.version;
response.output.headers = {
...response.output.headers,
...customHeaders
};
} else {
response.header('kbn-name', kbnServer.name);
response.header('kbn-version', kbnServer.version);
Object.keys(customHeaders).forEach(name => {
response.header(name, customHeaders[name]);
});
}

return reply.continue();
Expand Down

0 comments on commit cba3e93

Please sign in to comment.