new: Added full audit logging to ZMQ and Syslog, fixes #2635

- syslog now includes all audit log entries and it's separated into proper severity levels
- ZMQ logging and syslog logging are both optional features
pull/2697/head
iglocska 2017-11-24 12:00:50 +01:00
parent 7d5890b2fc
commit 6135468c41
5 changed files with 64 additions and 15 deletions

View File

@ -129,6 +129,11 @@ class PubSubTool {
return $this->__pushToRedis(':data:misp_json_' . $type, json_encode($data, JSON_PRETTY_PRINT));
}
public function publish($data, $type, $action = false) {
if (!empty($action)) $data['action'] = $action;
return $this->__pushToRedis(':data:misp_json_' . $type, json_encode($data, JSON_PRETTY_PRINT));
}
public function killService($settings = false) {
$redis = new Redis();
if ($this->checkIfRunning()) {

View File

@ -3,7 +3,16 @@
App::uses('AppModel', 'Model');
class Log extends AppModel {
public $warningActions = array(
'warning',
'change_pw',
'login_fail',
'version_warning',
'auth_fail'
);
public $errorActions = array(
'error'
);
public $validate = array(
'action' => array(
'rule' => array('inList', array(
@ -94,6 +103,7 @@ class Log extends AppModel {
$this->data['Log'][$tf] = substr($this->data['Log'][$tf], 0, 65532) . '...';
}
}
$this->logData($this->data);
return true;
}
@ -223,4 +233,31 @@ class Log extends AppModel {
return $result;
}
}
function logData($data) {
if (Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_user_notifications_enable')) {
$pubSubTool = $this->getPubSubTool();
$pubSubTool->publish($data, 'audit', 'log');
}
if (Configure::read('Security.syslog')) {
// write to syslogd as well
$syslog = new SysLog();
$action = 'info';
if (isset($data['Log']['action'])) {
if (in_array($data['Log']['action'], $this->errorActions)) {
$action = 'err';
}
if (in_array($data['Log']['action'], $this->warningActions)) {
$action = 'warning';
}
}
$entry = $data['Log']['action'];
if (!empty($data['Log']['description'])) {
$entry .= sprintf(' -- %s', $data['Log']['description']);
}
$syslog->write($action, $entry);
}
return true;
}
}

View File

@ -952,6 +952,15 @@ class Server extends AppModel {
'type' => 'string',
'editable' => false,
),
'syslog' => array(
'level' => 0,
'description' => 'Enable this setting to pass all audit log entries directly to syslog. Keep in mind, this is verbose and will include user, organisation, event data.',
'value' => false,
'errorMessage' => '',
'test' => 'testBool',
'type' => 'boolean',
'null' => true
),
'password_policy_length' => array(
'level' => 2,
'description' => 'Password length requirement. If it is not set or it is set to 0, then the default value is assumed (12).',
@ -1244,6 +1253,14 @@ class Server extends AppModel {
'test' => 'testBool',
'type' => 'boolean'
),
'ZeroMQ_audit_notifications_enable' => array(
'level' => 2,
'description' => 'Enables or disables the publishing of log entries to the ZMQ pubsub feed. Keep in mind, this can get pretty verbose depending on your logging settings.',
'value' => false,
'errorMessage' => '',
'test' => 'testBool',
'type' => 'boolean'
),
'Sightings_enable' => array(
'level' => 1,
'description' => 'Enables or disables the sighting functionality. When enabled, users can use the UI or the appropriate APIs to submit sightings data about indicators.',

View File

@ -249,20 +249,10 @@ class SysLogLogableBehavior extends LogableBehavior {
}
}
$this->Log->create($logData);
$this->Log->save(null, array(
'validate' => false));
// write to syslogd as well
$syslog = new SysLog();
if (isset($logData['Log']['change'])) {
$syslog->write('notice', $logData['Log']['description'].' -- '.$logData['Log']['change']);
} else {
$syslog->write('notice', $logData['Log']['description']);
}
$this->Log->save(null, array('validate' => false));
}
function setup(Model $Model, $config = array()) {
if (!is_array($config)) {
$config = array();
}

View File

@ -74,9 +74,9 @@ def main(args):
command = r.lpop(namespace + ":command")
if command is not None:
handleCommand(command)
topics = ["misp_json", "misp_json_event", "misp_json_attribute", "misp_json_sighting",
topics = ["misp_json", "misp_json_event", "misp_json_attribute", "misp_json_sighting",
"misp_json_organisation", "misp_json_user", "misp_json_conversation",
"misp_json_object", "misp_json_object_reference"]
"misp_json_object", "misp_json_object_reference", "misp_json_audit"]
message_received = False
for topic in topics:
data = r.lpop(namespace + ":data:" + topic)
@ -84,7 +84,7 @@ def main(args):
pubMessage(topic, data, socket)
message_received = True
if (message_received == False):
time.sleep(1)
time.sleep(0.2)
if ((int(time.time()) - start_time) % 10 == 0):
status_entry = int(((int(time.time()) - start_time)/10) % 5)
status_message = {