Tutorials
Mattermost Analytics with Tirreno
Mattermost does not directly offer user behavior analytics capabilities. To address this, we implement the Tirreno platform on top of Mattermost. This integration allows us to maintain an extended audit trail, monitor login locations, and protect accounts from sharing or takeover. We will perform data capturing by modifying the existing Nginx server configuration without the need to change the Mattermost codebase.
Requirements
Self-hosted Mattermost server.
Installed Tirreno platform.
Attention
Before implementing the provided Nginx configuration in a production environment, testing it in a development or staging environment is crucial. Using these settings without prior testing and validation is not recommended and is at your own risk.
Configuration Nginx with Tirreno
Mirroring of the original request allows the collection of information about user events and transmits them to the Tirreno API.
To perform this, add
location = /mirror {...}
to theserver
section in the config and appendmirror /mirror;
directives to all existinglocation
sections.
location = /mirror {
internal;
set $args "";
set $new_query_string "userName=$cookie_MMUSERID&ipAddress=$remote_addr&userAgent=$http_user_agent&httpReferer=$http_referer&httpMethod=$request_method&url=$request_uri&eventTime=$php_timestamp&browserLanguage=$http_accept_language";
proxy_pass https://tirreno.yourcompany.com; # Replace with your Tirreno URL
proxy_method POST;
rewrite ^ /sensor/ break;
proxy_set_body $new_query_string;
proxy_set_header Content-Type "application/x-www-form-urlencoded";
proxy_set_header Api-Key "XXXXXXXXXXXXXXXXXXXXXXXXX"; # Replace with your Tirreno API key
proxy_pass_request_body off;
}
Set the Tirreno URL in
proxy_pass
(ex. https://tirreno.yourcompany.com)Set
Api-Key
with your current Tirreno API key (copy and paste from API section of Tirreno console).
Restart Nginx & Checking Results
After adjusting the Mattermost Nginx config, check the syntax with
sudo nginx -t
and apply changes by restarting the server with
sudo systemctl restart nginx
. Voilà! Open the Mattermost client
and perform a login, then visit the Tirreno console and check the
event details.
Example of Nginx Configuration File
server {
listen 80;
server_name mattermost.yourcompany.com; # Replace with Mattermost host
return 301 https://$server_name$request_uri;
}
map $time_iso8601 $formatted_datetime {
"~^(?<date>\d{4}-\d{2}-\d{2})T(?<time>\d{2}:\d{2}:\d{2})" "$date $time";
}
map $msec $milliseconds {
'~^\d+\.(?<millis>\d+)$' $millis;
}
map $formatted_datetime $php_timestamp {
"~^(.+)$" "$formatted_datetime.$milliseconds";
}
server {
listen 443 ssl http2;
server_name mattermost.yourcompany.com; # Replace with Mattermost host
ssl_certificate /etc/letsencrypt/live/mattermost.yourcompany.com/fullchain.pem; # Replace with you certificate path
ssl_certificate_key /etc/letsencrypt/live/mattermost.yourcompany.com/privkey.pem; # Replace with you certificate path
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers off;
add_header Strict-Transport-Security "max-age=63072000" always;
location / {
proxy_pass http://backend; # Replace with IP and port if you use container deployment
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Frame-Options SAMEORIGIN;
# Websocket support
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
mirror /mirror;
}
location = /mirror {
internal;
set $args "";
set $new_query_string "userName=$cookie_MMUSERID&ipAddress=$remote_addr&userAgent=$http_user_agent&httpReferer=$http_referer&httpMethod=$request_method&url=$request_uri&eventTime=$php_timestamp&browserLanguage=$http_accept_language";
proxy_pass https://tirreno.yourcompany.com; # Replace with your Tirreno URL
proxy_method POST;
rewrite ^ /sensor/ break;
proxy_set_body $new_query_string;
proxy_set_header Content-Type "application/x-www-form-urlencoded";
proxy_set_header Api-Key "XXXXXXXXXXXXXXXXXXXXXXXXX"; # Replace with your Tirreno API key
proxy_pass_request_body off;
}
}
Troubleshooting
Time format
The Tirreno API requires the Y-m-d H:i:s.u
format for eventTime
.
As Nginx does not directly allow timestamp format manipulation, we use
the map
directive to convert the time to the appropriate format as
per Example. Also, setting the timezone to UTC is recommended if your
server is not already in UTC. Ensure that Nginx or its environment is
configured to use UTC. The env TZ=UTC
directive may be used in the
global Nginx.conf.
User name
By default Mattermost is providing only internal usernames. To find actual
user names check Mattermost admin console at https://mattermost.yourcompany.com/admin_console/user_management/users
and compare MMUSERID
with the user’s name and email.
Your Tirreno Adventure Awaits
This exercise is just one small example of what you can achieve with the Tirreno platform.
Tirreno is the easiest way to get started with security user analytics. We offer an open-source version of Tirreno, available for free on GitHub.