wazuh-kibana-app/server/api/wazuh-elastic.js
2017-11-17 03:56:59 -05:00

258 lines
7.6 KiB
JavaScript

module.exports = (server, options) => {
// Elastic JS Client
const elasticRequest = server.plugins.elasticsearch.getCluster('data');
//Handlers
const fetchElastic = (req, payload) => {
return elasticRequest.callWithRequest(req, 'search', {
index: 'wazuh-alerts-*',
type: 'wazuh',
body: payload
});
};
const getConfig = (callback) => {
elasticRequest
.callWithInternalUser('search', {
index: '.wazuh',
type: 'wazuh-configuration',
q: 'active:true'
})
.then((data) => {
if (data.hits.total === 1) {
callback({
'user': data.hits.hits[0]._source.api_user,
'password': Buffer.from(data.hits.hits[0]._source.api_password, 'base64').toString("ascii"),
'url': data.hits.hits[0]._source.url,
'port': data.hits.hits[0]._source.api_port,
'insecure': data.hits.hits[0]._source.insecure,
'cluster_info': data.hits.hits[0]._source.cluster_info,
'extensions': data.hits.hits[0]._source.extensions
});
} else {
callback({
'error': 'no credentials',
'error_code': 1
});
}
})
.catch((error) => {
callback({
'error': 'no elasticsearch',
'error_code': 2
});
});
};
// Returns alerts count for fields/value array between timeGTE and timeLT
const alertsCount = (req, reply) => {
var payload = {
"size": 1,
"query": {
"bool": {
"must": [],
"filter": {
"range": {
"@timestamp": {}
}
}
}
}
};
// Set up time interval, default to Last 15m
const timeGTE = req.payload.timeinterval.gte ? req.payload.timeinterval.gte : 'now-15m';
const timeLT = req.payload.timeinterval.lt ? req.payload.timeinterval.lt : 'now';
payload.query.bool.filter.range['@timestamp']['gte'] = timeGTE;
if (timeLT !== 'now'){
payload.query.bool.filter.range['@timestamp']['lte'] = timeLT;
} else {
payload.query.bool.filter.range['@timestamp']['lt'] = timeLT;
}
// Set up match for default cluster name
payload.query.bool.must.push({
'match': {
'cluster.name': req.payload.cluster
}
});
// Set up match for different pairs field/value
for(let item of req.payload.fields){
let obj = {};
obj[item.field] = item.value;
payload.query.bool.must.push({ 'match': obj });
}
fetchElastic(req, payload)
.then((data) => {
reply({
'statusCode': 200,
'data': data.hits.total
});
})
.catch((error) => {
reply({
'statusCode': 500,
'error': 9,
'message': 'Could not get data from elasticsearch'
}).code(500);
});
};
const getFieldTop = (req, reply) => {
// Top field payload
var payload = {
"size": 1,
"query": {
"bool": {
"must": [],
"filter": {
"range": {
"@timestamp": {}
}
}
}
},
"aggs": {
"2": {
"terms": {
"field": "",
"size": 1,
"order": {
"_count": "desc"
}
}
}
}
};
// Set up time interval, default to Last 24h
const timeGTE = 'now-1d';
const timeLT = 'now';
payload.query.bool.filter.range['@timestamp']['gte'] = timeGTE;
payload.query.bool.filter.range['@timestamp']['lt'] = timeLT;
// Set up match for default cluster name
payload.query.bool.must.push({
"match": {
"cluster.name": req.params.cluster
}
});
payload.aggs['2'].terms.field = req.params.field;
fetchElastic(req, payload)
.then((data) => {
if (data.hits.total === 0 || typeof data.aggregations['2'].buckets[0] === 'undefined'){
reply({
'statusCode': 200,
'data': ''
});
} else {
reply({
'statusCode': 200,
'data': data.aggregations['2'].buckets[0].key
});
}
})
.catch((error) => {
reply({
'statusCode': 500,
'error': 9,
'message': 'Could not get data from elasticsearch'
}).code(500);
});
};
const getSetupInfo = (req, reply) => {
elasticRequest
.callWithInternalUser('search', {
index: '.wazuh-version',
type: 'wazuh-version'
})
.then((data) => {
if (data.hits.total === 0) {
reply({
'statusCode': 200,
'data': ''
});
} else {
reply({
'statusCode': 200,
'data': data.hits.hits[0]._source
});
}
})
.catch((error) => {
reply({
'statusCode': 500,
'error': 9,
'message': 'Could not get data from elasticsearch'
}).code(500);
});
};
module.exports = getConfig;
//Server routes
/*
* GET /api/wazuh-elastic/top/{cluster}/{field}/{time?}
* Returns the agent with most alerts
*
**/
server.route({
method: 'GET',
path: '/api/wazuh-elastic/top/{cluster}/{field}/{time?}',
handler: getFieldTop
});
/*
* GET /api/wazuh-elastic/top/{cluster}/{field}/{fieldFilter}/{fieldValue}/{time?}
* Returns the agent with most alerts
*
**/
server.route({
method: 'GET',
path: '/api/wazuh-elastic/top/{cluster}/{field}/{fieldFilter}/{fieldValue}/{time?}',
handler: getFieldTop
});
/*
* GET /api/wazuh-elastic/top/{cluster}/{field}/{fieldFilter}/{fieldValue}/{fieldFilter}/{fieldValue}/{time?}
* Returns the agent with most alerts
*
**/
server.route({
method: 'GET',
path: '/api/wazuh-elastic/top/{cluster}/{field}/{fieldFilter}/{fieldValue}/{fieldFilter2}/{fieldValue2}/{time?}',
handler: getFieldTop
});
/*
* /api/wazuh-elastic/alerts-count
* Returns alerts count for fields/value array between timeGTE and timeLT
* @params: fields[{field,value}], cluster, timeinterval{gte,lte}
**/
server.route({
method: 'POST',
path: '/api/wazuh-elastic/alerts-count/',
handler: alertsCount
});
/*
* GET /api/wazuh-elastic/setup
* Return Wazuh Appsetup info
*
**/
server.route({
method: 'GET',
path: '/api/wazuh-elastic/setup',
handler: getSetupInfo
});
};