解析趋势科技服务器深度安全防护系统日志-AWS Lambda'splunk-logger'node.js

时间:2018-09-12 02:07:17

标签: javascript node.js aws-lambda splunk deepsecurity

我正在尝试修改一个名为“ splunk-logger”的Node.js函数。问题在于,当SNS消息进入该功能时,来自防病毒(趋势科技趋势科技服务器深度安全防护系统)控制台的事件会组合在一起。我已经联系了他们的支持人员,他们说这只是事件发送的方式,他们无济于事。

示例:{消息{Event_1} {Event_2} {Event_3}}

现在,JavaScript函数可以正常运行,并且事件将转发到Splunk。但是,由于它们甚至在命中了Lambda函数之前就已经分组在一起,因此Splunk将其视为1个单个事件,而不是3个。

我的想法是采用'event'变量(因为它包含sns'message')并对其进行解析以分隔每个事件(可能使用正则表达式或某些东西)。然后,我可以创建另一个函数来立即发送每个事件,也可以简单地调用“ logger.flushAsync”函数来发送它们。

链接至splunk-dev的功能说明:http://dev.splunk.com/view/event-collector/SP-CAAAE6Y#create

这是index.js中的代码:

const loggerConfig = {
    url: process.env.SPLUNK_HEC_URL,
    token: process.env.SPLUNK_HEC_TOKEN,
};
const SplunkLogger = require('./lib/mysplunklogger');
const logger = new SplunkLogger(loggerConfig);
exports.handler = (event, context, callback) => {
    console.log('Received event:', JSON.stringify(event, null, 2));
// Log JSON objects to Splunk
    logger.log(event);
// Send all the events in a single batch to Splunk
    logger.flushAsync((error, response) => {
        if (error) {
            callback(error);
        } else {
            console.log(`Response from Splunk:\n${response}`);
            callback(null, event.key1); // Echo back the first key value
        }
    });
};

这是mysplunklogger.js文件中的代码。

'use strict';

const url = require('url');

const Logger = function Logger(config) {
    this.url = config.url;
    this.token = config.token;

    this.addMetadata = true;
    this.setSource = true;

    this.parsedUrl = url.parse(this.url);
    // eslint-disable-next-line import/no-dynamic-require
    this.requester = require(this.parsedUrl.protocol.substring(0, this.parsedUrl.protocol.length - 1));
    // Initialize request options which can be overridden & extended by consumer as needed
    this.requestOptions = {
        hostname: this.parsedUrl.hostname,
        path: this.parsedUrl.path,
        port: this.parsedUrl.port,
        method: 'POST',
        headers: {
            Authorization: `Splunk ${this.token}`,
        },
        rejectUnauthorized: false,
    };

    this.payloads = [];
};

// Simple logging API for Lambda functions
Logger.prototype.log = function log(message, context) {
    this.logWithTime(Date.now(), message, context);
};

Logger.prototype.logWithTime = function logWithTime(time, message, context) {
    const payload = {};

    if (Object.prototype.toString.call(message) === '[object Array]') {
        throw new Error('message argument must be a string or a JSON object.');
    }
    payload.event = message;

    // Add Lambda metadata
    if (typeof context !== 'undefined') {
        if (this.addMetadata) {
            // Enrich event only if it is an object
            if (message === Object(message)) {
                payload.event = JSON.parse(JSON.stringify(message)); // deep copy
                payload.event.awsRequestId = context.awsRequestId;
            }
        }
        if (this.setSource) {
            payload.source = `lambda:${context.functionName}`;
        }
    }

    payload.time = new Date(time).getTime() / 1000;

    this.logEvent(payload);
};

Logger.prototype.logEvent = function logEvent(payload) {
    this.payloads.push(JSON.stringify(payload));
};

Logger.prototype.flushAsync = function flushAsync(callback) {
    callback = callback || (() => {}); // eslint-disable-line no-param-reassign

    console.log('Sending event(s)');
    const req = this.requester.request(this.requestOptions, (res) => {
        res.setEncoding('utf8');

        console.log('Response received');
        res.on('data', (data) => {
            let error = null;
            if (res.statusCode !== 200) {
                error = new Error(`error: statusCode=${res.statusCode}\n\n${data}`);
                console.error(error);
            }
            this.payloads.length = 0;
            callback(error, data);
        });
    });

    req.on('error', (error) => {
        callback(error);
    });

    req.end(this.payloads.join(''), 'utf8');
};

module.exports = Logger;

2 个答案:

答案 0 :(得分:0)

数组是趋势科技服务器深度安全防护系统10.0或更高版本将事件发送到Amazon SNS时使用的数据类型。但是Splunk希望每条消息有一个事件。所以不要直接发送数组。

相反,请使用Splunk记录器或Lambda遍历数组,将每一项作为单独的消息发送。您可以为Node.js修改此示例Lambda脚本:

https://github.com/deep-security/amazon-sns/blob/master/lambda-save-ds-event-to-s3.js

它将事件分别发送到S3(这是您需要的)。只需将其更改为发送给Splunk。

披露:我为趋势科技工作。

答案 1 :(得分:0)

import requests
import re
import json
import os

def lambda_handler(event, context):

    data = json.dumps(event)

    EventIds = re.findall(r'{\\\".+?\\\"}', data)
    EventLength = len(EventIds)

    headers = {'Authorization': 'Splunk ' + os.environ['SPLUNK_HEC_TOKEN']}

    i = 0
    while i < EventLength:
        response = requests.post(os.environ['SPLUNK_HEC_URL'], headers=headers, json={"event":EventIds[i]}, verify=True)
    i+=1