diff --git a/src/etc/inc/plugins.inc.d/core.inc b/src/etc/inc/plugins.inc.d/core.inc index 5016a0203..cc68e8d4f 100644 --- a/src/etc/inc/plugins.inc.d/core.inc +++ b/src/etc/inc/plugins.inc.d/core.inc @@ -244,6 +244,7 @@ function core_syslog() { $logfacilities = array(); + $logfacilities['audit'] = array('facility' => array('audit')); $logfacilities['configd'] = array('facility' => array('configd.py')); $logfacilities['dhcpd'] = array('facility' => array('dhcpd', 'dhcrelay')); $logfacilities['filter'] = array('facility' => array('filterlog')); diff --git a/src/opnsense/mvc/app/library/OPNsense/Auth/AuthenticationFactory.php b/src/opnsense/mvc/app/library/OPNsense/Auth/AuthenticationFactory.php index 34d075641..998cdb2d6 100644 --- a/src/opnsense/mvc/app/library/OPNsense/Auth/AuthenticationFactory.php +++ b/src/opnsense/mvc/app/library/OPNsense/Auth/AuthenticationFactory.php @@ -187,6 +187,7 @@ class AuthenticationFactory */ public function authenticate($service_name, $username, $password) { + openlog("audit", LOG_ODELAY, LOG_AUTH); $service = $this->getService($service_name); if ($service !== null) { $service->setUserName($username); @@ -203,6 +204,7 @@ class AuthenticationFactory get_class($service), get_class($authenticator) )); + closelog(); return true; } else { // since checkConstraints() is defined on the service, who doesn't know about the @@ -214,6 +216,7 @@ class AuthenticationFactory get_class($service), get_class($authenticator) )); + closelog(); return false; } } else { @@ -229,12 +232,13 @@ class AuthenticationFactory } } syslog(LOG_WARNING, sprintf( - "user %s could not authenticate for %s. [using %s + %s]\n", + "user %s could not authenticate for %s. [using %s + %s]", $username, $service_name, !empty($service) ? get_class($service) : '-', !empty($authenticator) ? get_class($authenticator) : '-' )); + closelog(); return false; } diff --git a/src/opnsense/mvc/app/library/OPNsense/Core/Config.php b/src/opnsense/mvc/app/library/OPNsense/Core/Config.php index b2be0139c..7fbfffaf4 100644 --- a/src/opnsense/mvc/app/library/OPNsense/Core/Config.php +++ b/src/opnsense/mvc/app/library/OPNsense/Core/Config.php @@ -463,6 +463,27 @@ class Config extends Singleton } } + /** + * send config change to audit log including the context we currently know of. + */ + private function auditLogChange($backup_filename, $revision=null) + { + openlog("audit", LOG_ODELAY, LOG_AUTH); + $append_message = ""; + if (is_array($revision) && !empty($revision['description'])) { + $append_message = sprintf(" [%s]", $revision['description']); + } + syslog(LOG_NOTICE, sprintf( + "user %s%s changed configuration to %s in %s%s", + !empty($_SESSION["Username"]) ? $_SESSION["Username"] : "(system)", + !empty($_SERVER['REMOTE_ADDR']) ? "@" . $_SERVER['REMOTE_ADDR'] : "", + $backup_filename, + !empty($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : $_SERVER['SCRIPT_NAME'], + $append_message + )); + closelog(); + } + /** * backup current config * @return string target filename @@ -626,6 +647,7 @@ class Config extends Singleton fflush($this->config_file_handle); $backup_filename = $backup ? $this->backup() : null; if ($backup_filename) { + $this->auditLogChange($backup_filename, $revision); // use syslog to trigger a new configd event, which should signal a syshook config (in batch). // Althought we include the backup filename, the event handler is responsible to determine the // last processed event itself. (it's merely added for debug purposes) diff --git a/src/opnsense/mvc/app/models/OPNsense/Core/Menu/Menu.xml b/src/opnsense/mvc/app/models/OPNsense/Core/Menu/Menu.xml index b9faf99d1..50428bb6b 100644 --- a/src/opnsense/mvc/app/models/OPNsense/Core/Menu/Menu.xml +++ b/src/opnsense/mvc/app/models/OPNsense/Core/Menu/Menu.xml @@ -90,6 +90,7 @@ + diff --git a/src/opnsense/service/templates/OPNsense/Syslog/local/audit.conf b/src/opnsense/service/templates/OPNsense/Syslog/local/audit.conf new file mode 100644 index 000000000..ffb6a3f5b --- /dev/null +++ b/src/opnsense/service/templates/OPNsense/Syslog/local/audit.conf @@ -0,0 +1,6 @@ +################################################################### +# Local syslog-ng configuration filter definition [audit]. +################################################################### +filter f_local_audit { + program("audit") or facility(auth); +}; diff --git a/src/www/system_groupmanager.php b/src/www/system_groupmanager.php index 6ad199cd5..132c029ff 100644 --- a/src/www/system_groupmanager.php +++ b/src/www/system_groupmanager.php @@ -155,8 +155,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { } } } - - write_config(); + if (isset($id) && $a_group[$id]) { + $audit_msg = sprintf("group \"%s\" changed", $group['name']); + } else { + $audit_msg = sprintf("group \"%s\" created", $group['name']); + } + write_config($audit_msg); // XXX: signal backend which users have changed. // core_user_changed_groups() would change local group assignments in that case as well. $new_members = !empty($group['member']) ? $group['member'] : array(); diff --git a/src/www/system_usermanager.php b/src/www/system_usermanager.php index c5bcfe63b..200da25f6 100644 --- a/src/www/system_usermanager.php +++ b/src/www/system_usermanager.php @@ -181,7 +181,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { local_user_del($a_user[$id]); $userdeleted = $a_user[$id]['name']; unset($a_user[$id]); - write_config(); + write_config(sprintf('The user "%s" was successfully removed.', $userdeleted)); $savemsg = sprintf(gettext('The user "%s" was successfully removed.'), $userdeleted); header(url_safe('Location: /system_usermanager.php?savemsg=%s', array($savemsg))); exit; @@ -191,7 +191,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { $certdeleted = lookup_cert($a_user[$id]['cert'][$pconfig['certid']]); $certdeleted = $certdeleted['descr']; unset($a_user[$id]['cert'][$pconfig['certid']]); - write_config(); + write_config(sprintf('The certificate association "%s" was successfully removed.', $certdeleted)); $savemsg = sprintf(gettext('The certificate association "%s" was successfully removed.'), $certdeleted); header(url_safe('Location: /system_usermanager.php?savemsg=%s&act=edit&userid=%d', array($savemsg, $id))); exit; @@ -385,7 +385,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { local_user_set_groups($userent, $pconfig['groups']); local_user_set($userent); - write_config(); + if (isset($id)) { + $audit_msg = sprintf("user \"%s\" changed", $userent['name']); + } else { + $audit_msg = sprintf("user \"%s\" created", $userent['name']); + } + write_config($audit_msg); // XXX: signal backend that the user has changed. configdp_run('auth user changed', [$userent['name']]);