new: [logging] Log user IPs on login

- feature is optional and needs to be enabled in the server settings
- on successful login logs the associated user ID for a given IP (30 day retention)
- also logs the IP for the associated user ID (indefinite retention)
- added two command line tools to query
  - Get IPs For User ID: MISP/app/Console/cake Admin UserIP [user_id]
  - Get User ID For User IP: MISP/app/Console/cake Admin IPUser [ip]
pull/5662/head
iglocska 2020-02-20 16:07:10 +01:00
parent c35f5c34dc
commit 363d0cd69a
No known key found for this signature in database
GPG Key ID: BEA224F1FEF113AC
3 changed files with 70 additions and 1 deletions

View File

@ -589,4 +589,54 @@ class AdminShell extends AppShell
echo __("Something went wrong. Could not find the existing db version or fetch the current database schema.") . PHP_EOL;
}
}
public function UserIP()
{
$this->ConfigLoad->execute();
if (empty($this->args[0])) {
die('Usage: ' . $this->Server->command_line_functions['console_admin_tasks']['data']['Get IPs for user ID'] . PHP_EOL);
die();
}
$user_id = trim($this->args[0]);
$redis = $this->Server->setupRedis();
$user = $this->User->find('first', array(
'recursive' => -1,
'conditions' => array('User.id' => $user_id)
));
if (empty($user)) {
echo PHP_EOL . 'Invalid user ID.';
die();
}
$ips = $redis->smembers('misp:user_ip:' . $user_id);
$ips = implode(PHP_EOL, $ips);
echo sprintf(
'%s==============================%sUser #%s: %s%s==============================%s%s%s==============================%s',
PHP_EOL, PHP_EOL, $user['User']['id'], $user['User']['email'], PHP_EOL, PHP_EOL, $ips, PHP_EOL, PHP_EOL
);
}
public function IPUser()
{
$this->ConfigLoad->execute();
if (empty($this->args[0])) {
die('Usage: ' . $this->Server->command_line_functions['console_admin_tasks']['data']['Get user ID for user IP'] . PHP_EOL);
die();
}
$ip = trim($this->args[0]);
$redis = $this->Server->setupRedis();
$user_id = $redis->get('misp:ip_user:' . $ip);
if (empty($user_id)) {
echo PHP_EOL . 'No hits.' . PHP_EOL;
die();
}
$user = $this->User->find('first', array(
'recursive' => -1,
'conditions' => array('User.id' => $user_id)
));
echo sprintf(
'%s==============================%sIP: %s%s==============================%sUser #%s: %s%s==============================%s',
PHP_EOL, PHP_EOL, $ip, PHP_EOL, PHP_EOL, $user['User']['id'], $user['User']['email'], PHP_EOL, PHP_EOL
);
}
}

View File

@ -297,6 +297,14 @@ class AppController extends Controller
}
if ($this->Auth->user()) {
if (Configure::read('MISP.log_user_ips')) {
$redis = $this->{$this->modelClass}->setupRedis();
if ($redis) {
$redis->set('misp:ip_user:' . trim($_SERVER['REMOTE_ADDR']), $this->Auth->user('id'));
$redis->expire('misp:ip_user:' . trim($_SERVER['REMOTE_ADDR']), 60*60*24*30);
$redis->sadd('misp:user_ip:' . $this->Auth->user('id'), trim($_SERVER['REMOTE_ADDR']));
}
}
// update script
if ($this->Auth->user('Role')['perm_site_admin'] || (Configure::read('MISP.live') && !$this->_isRest())) {
$this->{$this->modelClass}->runUpdates();

View File

@ -133,7 +133,9 @@ class Server extends AppModel
'Update object templates' => 'MISP/app/Console/cake Admin updateObjectTemplates',
'Update Warninglists' => 'MISP/app/Console/cake Admin updateWarningLists',
'Update Noticelists' => 'MISP/app/Console/cake Admin updateNoticeLists',
'Set default role' => 'MISP/app/Console/cake Admin setDefaultRole [role_id]'
'Set default role' => 'MISP/app/Console/cake Admin setDefaultRole [role_id]',
'Get IPs for user ID' => 'MISP/app/Console/cake Admin UserIP [user_id]',
'Get user ID for user IP' => 'MISP/app/Console/cake Admin IPUser [ip]',
),
'description' => __('Certain administrative tasks are exposed to the API, these help with maintaining and configuring MISP in an automated way / via external tools.'),
'header' => __('Administering MISP via the CLI')
@ -812,6 +814,15 @@ class Server extends AppModel
'type' => 'boolean',
'null' => true
),
'log_user_ips' => array(
'level' => 0,
'description' => __('Log user IPs on each request. 30 day retention for lookups by IP to get the last authenticated user ID for the given IP, whilst on the reverse, indefinitely stores all associated IPs for a user ID.'),
'value' => false,
'errorMessage' => '',
'test' => 'testBool',
'type' => 'boolean',
'null' => true
),
'delegation' => array(
'level' => 1,
'description' => __('This feature allows users to create org only events and ask another organisation to take ownership of the event. This allows organisations to remain anonymous by asking a partner to publish an event for them.'),