Mosquitto
An audit trail (also called an audit log) is a security-relevant chronological record, set of records, and/or destination and source of records that provide documentary evidence of the sequence of activities that have affected at any time a specific operation, procedure, event, or device.
In Pro Mosquitto, the audit trail feature has two components - the in-broker functionality which provides a mechanism for the broker and plugins to send audit events and which can be configured to filter which events are accepted. The second part is a reporting plugin which sends the filtered events on to their final destination. At present, the syslog reporting plugin is available.
Audit trail syslog plugin configuration
To configure the syslog plugin, add the following to your mosquitto.conf file:
global_plugin /path/to/cedalo_audit_trail_syslog.so
The plugin has some options which can be configured.
Docker usage
If you are using Pro Mosquitto via docker, please add the following mount to your docker-compose file to be able to get the logs directly wired to your host system. Otherwise, the logs stay within the docker container.
volumes:
- /dev/log:/dev/log
Log ident
By default, the log ident will be the program name, i.e. mosquitto. This can
be changed with the plugin_opt_log_ident option:
plugin_opt_log_ident audittrail
Log facility
By default, logging will use the daemon facility. This can be changed to one
of local0 to local7 if required.
plugin_opt_log_facility local2
Log timestamp
By default the event timestamp in the payload is a Unix timestamp with
millisecond resolution. Alternatively, the plugin_opt_iso8601_timestamp
option may be used to have an ISO-8601 format timestamp.
plugin_opt_iso8601_timestamp true
Exclude IP address
By default the IP address of the client which originated the request will be
included in the audit event. If this is not wanted, the
plugin_opt_exclude_ip_address option can be set to true.
plugin_opt_exclude_ip_address true
Audit trail configuration
The Audit Trail feature in Mosquitto can be configured to allow control over which events are reported. There are two mechanisms to achieve this. The first is through the use of a log threshold, which only reports events which are greater than or equal to an importance threshold set by the administrator. The second is through the use of fine grained filters.
All configuration is done through a configuration file audit-trail.json,
which must be located in the persistence_location directory.
If the audit-trail.json file is not found, no audit events will be reported.
An example of the file is given below:
{
"filters": [
{
"filterType": "include",
"source": "dynamic-security"
},
{
"filterType": "include",
"source": "ha",
"operation": "createCluster"
},
{
"filterType": "exclude",
"operationType": "read"
}
],
"logThreshold": "debug"
}
Log threshold
The logThreshold option can be set to one of debug, info, notice,
warning, and error, which relate to the corresponding syslog log levels.
Any audit events which have a lower importance than the log threshold will not
be logged. For example, setting the log threshold to warning, means that only
events with importance of warning and error will be logged.
The default threshold is info.
Filters
All audit events have an associated source, operationType, and operation
property. The filters functionality allows events to be filtered using all of
those properties.
The filters part of the configuration file is a list of individual filters
that are to be applied to each event to determine whether it is to be reported.
The filters are evaluated in order and the final result applies. This means it
is straightforward to arrange very specific filters to pick out or exclude
certain events.
Each filter has a filterType property which is the only required property,
and must be set to either include, or exclude. If the final result of
evaluating the filter list is include, then the event will be reported. If
the final result is exclude then the event will not be reported.
It is recommended to order the filters from most general to most specific.
The default behaviour is exclude reporting of events, so at least one include
filter must be provided.
The source, operationType, and operation properties are used to match
events. All of these properties are optional. If the property is not present
then any property of that type will match. If the property is present, then an
event must match that property for the filter to be applied to the event.
The source property is used to match against the provider of the event. This
will be core for events coming from the core Mosquitto broker, or the name of
a plugin, e.g. dynamic-security, ha.
The operationType property is used to match against the CRUD type of the
operation. If present, this property must be one of create, read, update,
delete, or other. The other type includes operation types that are not
well covered by the first four types, such as client connection/disconnection.
The operation property is used to match against a specific operation by a
source. The list of available properties for each source is provided below. If
this property is available, the event operation must match exactly.
Filter example - exclude all
This is the default behaviour if audit-trail.json is missing or empty, or if
no include filters are defined.
Filter example - include all
Because only the filterType property is used, this matches against every
event.
{
"filters": [
{
"filterType": "include"
}
]
}
Filter example - dynamic security source only
This matches against the dynamic security plugin events and reports all of them.
{
"filters": [
{
"filterType": "include",
"source": "dynamic-security"
}
]
}
Filter example - dynamic security excluding some operations
This matches against the dynamic security plugin events and reports all of
them apart from the disableClient operation.
{
"filters": [
{
"filterType": "include",
"source": "dynamic-security"
},
{
"filterType": "exclude",
"source": "dynamic-security",
"operation": "disableClient"
}
]
}
Filter example - core broker excluding other operation types
This matches against the core broker events and reports all of
them apart from the other operation type.
{
"filters": [
{
"filterType": "include",
"source": "core"
},
{
"filterType": "exclude",
"operationType": "other"
}
]
}
Filter example - multiple types
This is a more realistic setup that addresses multiple sources.
All core events match and are reported.
All dynamic-security events match, apart from those that are read operation.
All ha events match, except the specific getRaftStatus and isLeader operations.
For the getRaftStatus and isLeader operations, the source isn't
specifically set to ha, however in this case those operations are only
available on that source.
{
"filters": [
{
"filterType": "include",
"source": "core"
},
{
"filterType": "include",
"source": "dynamic-security"
},
{
"filterType": "include",
"source": "ha"
},
{
"filterType": "exclude",
"source": "dynamic-security"
"operationType": "read"
},
{
"filterType": "exclude",
"operation": "getRaftStatus"
},
{
"filterType": "exclude",
"operation": "isLeader"
}
]
}
List of audit events
| source | operation | operationType | log level |
|---|---|---|---|
| core | brokerStart | other | notice |
| core | brokerStop | other | notice |
| core | brokerReload | other | notice |
| core | clientConnect | other | notice |
| core | clientDisconnect | other | notice |
| dynamic-security | createClient | create | notice |
| dynamic-security | deleteClient | delete | notice |
| dynamic-security | enableClient | update | notice |
| dynamic-security | disableClient | update | notice |
| dynamic-security | setClientId | update | info |
| dynamic-security | setClientPassword | update | info |
| dynamic-security | getClient | read | debug |
| dynamic-security | listClients | read | debug |
| dynamic-security | addClientRole | update | info |
| dynamic-security | removeClientRole | update | info |
| dynamic-security | modifyClient | update | info |
| dynamic-security | createGroup | create | notice |
| dynamic-security | getGroup | read | debug |
| dynamic-security | listGroups | read | debug |
| dynamic-security | addGroupClient | update | info |
| dynamic-security | removeGroupClient | update | info |
| dynamic-security | addGroupRole | update | info |
| dynamic-security | removeGroupRole | update | info |
| dynamic-security | modifyGroup | update | info |
| dynamic-security | setAnonymousGroup | update | info |
| dynamic-security | getAnonymousGroup | update | info |
| dynamic-security | createRole | create | notice |
| dynamic-security | deleteRole | delete | notice |
| dynamic-security | getRole | read | debug |
| dynamic-security | listRoles | read | debug |
| dynamic-security | addRoleAcl | update | info |
| dynamic-security | removeRoleAcl | update | info |
| dynamic-security | modifyRole | update | info |
| dynamic-security | getDefaultAcl | read | debug |
| dynamic-security | setDefaultAcl | update | notice |
| ha | createCluster | create | notice |
| ha | joinCluster | create | notice |
| ha | leaveCluster | update | notice |
| ha | deleteCluster | delete | notice |
| ha | addNode | update | notice |
| ha | removeNode | update | notice |
| ha | isLeader | read | debug |
| ha | setLeader | update | notice |
| ha | getNode | read | debug |
| ha | getCluster | read | debug |
| ha | getRaftStatus | read | debug |
| ha | nodeRole | update | info |
| ha | clusterStatus | update | info |