mirror of
https://github.com/valitydev/wazuh-kibana-app.git
synced 2024-11-06 09:55:18 +00:00
407 lines
12 KiB
JavaScript
407 lines
12 KiB
JavaScript
/*
|
|
* Wazuh app - Module for app initialization
|
|
* Copyright (C) 2015-2019 Wazuh, Inc.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Find more information about this on the LICENSE file.
|
|
*/
|
|
import colors from 'ansicolors';
|
|
import { log } from './logger';
|
|
import { ElasticWrapper } from './lib/elastic-wrapper';
|
|
import packageJSON from '../package.json';
|
|
import { kibanaTemplate } from './integration-files/kibana-template';
|
|
import { getConfiguration } from './lib/get-configuration';
|
|
import { defaultExt } from './lib/default-ext';
|
|
import { BuildBody } from './lib/replicas-shards-helper';
|
|
import { checkKnownFields } from './lib/refresh-known-fields';
|
|
import { totalmem } from 'os';
|
|
|
|
export function Initialize(server) {
|
|
const blueWazuh = colors.blue('wazuh');
|
|
|
|
// Elastic JS Client
|
|
const wzWrapper = new ElasticWrapper(server);
|
|
log('initialize', `Kibana index: ${wzWrapper.WZ_KIBANA_INDEX}`, 'info');
|
|
log('initialize', `App revision: ${packageJSON.revision}`, 'info');
|
|
|
|
let configurationFile = {};
|
|
let pattern = null;
|
|
// Read config from package.json and config.yml
|
|
try {
|
|
configurationFile = getConfiguration();
|
|
|
|
pattern =
|
|
configurationFile && typeof configurationFile.pattern !== 'undefined'
|
|
? configurationFile.pattern
|
|
: 'wazuh-alerts-3.x-*';
|
|
global.XPACK_RBAC_ENABLED =
|
|
configurationFile &&
|
|
typeof configurationFile['xpack.rbac.enabled'] !== 'undefined'
|
|
? configurationFile['xpack.rbac.enabled']
|
|
: true;
|
|
} catch (e) {
|
|
log('initialize', e.message || e);
|
|
server.log(
|
|
[blueWazuh, 'initialize', 'error'],
|
|
'Something went wrong while reading the configuration.' + e.message
|
|
);
|
|
}
|
|
|
|
try {
|
|
// RAM in MB
|
|
const ram = Math.ceil(totalmem() / 1024 / 1024);
|
|
log('initialize', `Total RAM: ${ram}MB`, 'info');
|
|
} catch (error) {
|
|
log(
|
|
'initialize',
|
|
`Could not check total RAM due to: ${error.message || error}`
|
|
);
|
|
}
|
|
|
|
const defaultIndexPattern = pattern || 'wazuh-alerts-3.x-*';
|
|
|
|
// Save Wazuh App setup
|
|
const saveConfiguration = async () => {
|
|
try {
|
|
const shardConfiguration = BuildBody(configurationFile, 'wazuh-version');
|
|
|
|
await wzWrapper.createWazuhVersionIndex(shardConfiguration);
|
|
|
|
const commonDate = new Date().toISOString();
|
|
|
|
const configuration = {
|
|
name: 'Wazuh App',
|
|
'app-version': packageJSON.version,
|
|
revision: packageJSON.revision,
|
|
installationDate: commonDate,
|
|
lastRestart: commonDate
|
|
};
|
|
|
|
try {
|
|
await wzWrapper.insertWazuhVersionConfiguration(configuration);
|
|
|
|
log(
|
|
'initialize:saveConfiguration',
|
|
'Wazuh configuration inserted',
|
|
'debug'
|
|
);
|
|
} catch (error) {
|
|
log('initialize:saveConfiguration', error.message || error);
|
|
server.log(
|
|
[blueWazuh, 'initialize', 'error'],
|
|
'Could not insert Wazuh configuration'
|
|
);
|
|
}
|
|
|
|
return;
|
|
} catch (error) {
|
|
log('initialize:saveConfiguration', error.message || error);
|
|
server.log(
|
|
[blueWazuh, 'initialize', 'error'],
|
|
'Error creating index .wazuh-version.'
|
|
);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Checks for new extensions added to the config.yml,
|
|
* useful whenever a new extension is added and it's enabled by default.
|
|
* An old app package needs to update its stored API entries, this way we have consistency
|
|
* with the new extensions.
|
|
*/
|
|
const checkAPIEntriesExtensions = async () => {
|
|
try {
|
|
log(
|
|
'initialize:checkAPIEntriesExtensions',
|
|
`Checking extensions consistency for all API entries`,
|
|
'debug'
|
|
);
|
|
|
|
const apiEntries = await wzWrapper.getWazuhAPIEntries();
|
|
const configFile = await getConfiguration();
|
|
|
|
if ((((apiEntries || {}).hits || {}).total || {}).value > 0) {
|
|
const currentExtensions = !configFile ? defaultExt : {};
|
|
|
|
if (configFile) {
|
|
for (const key in defaultExt) {
|
|
currentExtensions[key] =
|
|
typeof configFile['extensions.' + key] !== 'undefined'
|
|
? configFile['extensions.' + key]
|
|
: defaultExt[key];
|
|
}
|
|
}
|
|
|
|
for (const item of apiEntries.hits.hits) {
|
|
for (const key in currentExtensions) {
|
|
if ((((item || {})._source || {}).extensions || {})[key]) {
|
|
continue;
|
|
} else {
|
|
if (((item || {})._source || {}).extensions) {
|
|
item._source.extensions[key] = currentExtensions[key];
|
|
}
|
|
}
|
|
}
|
|
try {
|
|
await wzWrapper.updateWazuhIndexDocument(null, item._id, {
|
|
doc: { extensions: item._source.extensions }
|
|
});
|
|
log(
|
|
'initialize:checkAPIEntriesExtensions',
|
|
`Successfully updated API entry extensions with ID: ${item._id}`,
|
|
'debug'
|
|
);
|
|
} catch (error) {
|
|
log(
|
|
'initialize:checkAPIEntriesExtensions',
|
|
`Error updating API entry extensions with ID: ${
|
|
item._id
|
|
} due to ${error.message || error}`
|
|
);
|
|
server.log(
|
|
[blueWazuh, 'initialize:checkAPIEntriesExtensions', 'error'],
|
|
`Error updating API entry extensions with ID: ${
|
|
item._id
|
|
} due to ${error.message || error}`
|
|
);
|
|
}
|
|
}
|
|
} else {
|
|
log(
|
|
'initialize:checkAPIEntriesExtensions',
|
|
'There are no API entries, skipping extensions check',
|
|
'debug'
|
|
);
|
|
}
|
|
|
|
return;
|
|
} catch (error) {
|
|
return Promise.reject(error);
|
|
}
|
|
};
|
|
|
|
const checkWazuhIndex = async () => {
|
|
try {
|
|
log('initialize:checkWazuhIndex', 'Checking .wazuh index.', 'debug');
|
|
|
|
const result = await wzWrapper.checkIfIndexExists('.wazuh');
|
|
|
|
const shardConfiguration = BuildBody(configurationFile, 'wazuh');
|
|
|
|
if (!result) {
|
|
try {
|
|
await wzWrapper.createWazuhIndex(shardConfiguration);
|
|
|
|
log('initialize:checkWazuhIndex', 'Index .wazuh created.', 'debug');
|
|
} catch (error) {
|
|
throw new Error('Error creating index .wazuh.');
|
|
}
|
|
} else {
|
|
await wzWrapper.updateIndexSettings('.wazuh', shardConfiguration);
|
|
await checkAPIEntriesExtensions();
|
|
}
|
|
} catch (error) {
|
|
return Promise.reject(error);
|
|
}
|
|
};
|
|
|
|
const checkWazuhVersionIndex = async () => {
|
|
try {
|
|
log(
|
|
'initialize[checkWazuhVersionIndex]',
|
|
'Checking .wazuh-version index.',
|
|
'debug'
|
|
);
|
|
|
|
try {
|
|
await wzWrapper.getWazuhVersionIndex();
|
|
const shardConfiguration = BuildBody(
|
|
configurationFile,
|
|
'wazuh-version'
|
|
);
|
|
await wzWrapper.updateIndexSettings(
|
|
'.wazuh-version',
|
|
shardConfiguration
|
|
);
|
|
} catch (error) {
|
|
log(
|
|
'initialize[checkWazuhVersionIndex]',
|
|
'.wazuh-version document does not exist. Initializating configuration...',
|
|
'debug'
|
|
);
|
|
|
|
// Save Setup Info
|
|
await saveConfiguration();
|
|
}
|
|
|
|
await wzWrapper.updateWazuhVersionIndexLastRestart(
|
|
packageJSON.version,
|
|
packageJSON.revision
|
|
);
|
|
} catch (error) {
|
|
return Promise.reject(error);
|
|
}
|
|
};
|
|
|
|
// Init function. Check for "wazuh-version" document existance.
|
|
const init = async () => {
|
|
try {
|
|
await Promise.all([
|
|
checkWazuhIndex(),
|
|
checkWazuhVersionIndex(),
|
|
checkKnownFields(wzWrapper, log, server, defaultIndexPattern)
|
|
]);
|
|
const reindexResult = await wzWrapper.reindexAppIndices();
|
|
Array.isArray(reindexResult) &&
|
|
reindexResult.length === 2 &&
|
|
log(
|
|
'initialize:init',
|
|
`${reindexResult[0].value} (${reindexResult[0].result}) / ${
|
|
reindexResult[1].value
|
|
} (${reindexResult[1].result})`,
|
|
'debug'
|
|
);
|
|
} catch (error) {
|
|
log('initialize:init', error.message || error);
|
|
server.log(
|
|
[blueWazuh, 'initialize:init', 'error'],
|
|
error.message || error
|
|
);
|
|
return Promise.reject(error);
|
|
}
|
|
};
|
|
|
|
const createKibanaTemplate = () => {
|
|
log(
|
|
'initialize:createKibanaTemplate',
|
|
`Creating template for ${wzWrapper.WZ_KIBANA_INDEX}`,
|
|
'debug'
|
|
);
|
|
|
|
try {
|
|
kibanaTemplate.template = wzWrapper.WZ_KIBANA_INDEX + '*';
|
|
} catch (error) {
|
|
log('initialize:createKibanaTemplate', error.message || error);
|
|
server.log(
|
|
[blueWazuh, 'initialize', 'error'],
|
|
'Exception: ' + error.message || error
|
|
);
|
|
}
|
|
|
|
return wzWrapper.putWazuhKibanaTemplate(kibanaTemplate);
|
|
};
|
|
|
|
const createEmptyKibanaIndex = async () => {
|
|
try {
|
|
await wzWrapper.createEmptyKibanaIndex();
|
|
log(
|
|
'initialize:checkKibanaStatus',
|
|
`Successfully created ${wzWrapper.WZ_KIBANA_INDEX} index.`,
|
|
'debug'
|
|
);
|
|
await init();
|
|
return;
|
|
} catch (error) {
|
|
return Promise.reject(
|
|
new Error(
|
|
`Error creating ${
|
|
wzWrapper.WZ_KIBANA_INDEX
|
|
} index due to ${error.message || error}`
|
|
)
|
|
);
|
|
}
|
|
};
|
|
|
|
const fixKibanaTemplate = async () => {
|
|
try {
|
|
await createKibanaTemplate();
|
|
log(
|
|
'initialize:checkKibanaStatus',
|
|
`Successfully created ${wzWrapper.WZ_KIBANA_INDEX} template.`,
|
|
'debug'
|
|
);
|
|
await createEmptyKibanaIndex();
|
|
return;
|
|
} catch (error) {
|
|
return Promise.reject(
|
|
new Error(
|
|
`Error creating template for ${
|
|
wzWrapper.WZ_KIBANA_INDEX
|
|
} due to ${error.message || error}`
|
|
)
|
|
);
|
|
}
|
|
};
|
|
|
|
const getTemplateByName = async () => {
|
|
try {
|
|
await wzWrapper.getTemplateByName('wazuh-kibana');
|
|
log(
|
|
'initialize:checkKibanaStatus',
|
|
`No need to create the ${
|
|
wzWrapper.WZ_KIBANA_INDEX
|
|
} template, already exists.`,
|
|
'debug'
|
|
);
|
|
await createEmptyKibanaIndex();
|
|
return;
|
|
} catch (error) {
|
|
log('initialize:checkKibanaStatus', error.message || error);
|
|
return fixKibanaTemplate();
|
|
}
|
|
};
|
|
|
|
// Does Kibana index exist?
|
|
const checkKibanaStatus = async () => {
|
|
try {
|
|
const data = await wzWrapper.checkIfIndexExists(
|
|
wzWrapper.WZ_KIBANA_INDEX
|
|
);
|
|
if (data) {
|
|
// It exists, initialize!
|
|
await init();
|
|
} else {
|
|
// No Kibana index created...
|
|
log(
|
|
'initialize:checkKibanaStatus',
|
|
"Didn't find " + wzWrapper.WZ_KIBANA_INDEX + ' index...',
|
|
'info'
|
|
);
|
|
server.log(
|
|
[blueWazuh, 'initialize', 'info'],
|
|
"Didn't find " + wzWrapper.WZ_KIBANA_INDEX + ' index...'
|
|
);
|
|
await getTemplateByName();
|
|
}
|
|
} catch (error) {
|
|
log('initialize:checkKibanaStatus', error.message || error);
|
|
server.log(
|
|
[blueWazuh, 'initialize (checkKibanaStatus)', 'error'],
|
|
error.message || error
|
|
);
|
|
}
|
|
};
|
|
|
|
// Wait until Elasticsearch js is ready
|
|
const checkStatus = async () => {
|
|
try {
|
|
await server.plugins.elasticsearch.waitUntilReady();
|
|
return checkKibanaStatus();
|
|
} catch (error) {
|
|
log(
|
|
'initialize:checkStatus',
|
|
'Waiting for elasticsearch plugin to be ready...',
|
|
'debug'
|
|
);
|
|
setTimeout(() => checkStatus(), 3000);
|
|
}
|
|
};
|
|
|
|
// Check Kibana index and if it is prepared, start the initialization of Wazuh App.
|
|
checkStatus();
|
|
}
|