Last Login Plugin¶
New in version 2.2.14.
This plugin can be used to update user’s last-login timestamp in a configured dictionary.
Last login information is useful for trouble shooting scenarios, which usually starts with end user contacting customer care agent that the mailbox is unreachable or empty. Amongst the first things is to check when the customer last successfully did login to the mailbox and using which protocol as this might indicate that there might be some device with POP3 configured thus emptying the mailbox. Last login feature is designed for this use case, to allow easy way to search per any account the timestamp of last login or last mail delivery to the mailbox.
Settings¶
See last-login plugin.
Example Configuration¶
protocol imap {
mail_plugins = $mail_plugins last_login
}
protocol pop3 {
mail_plugins = $mail_plugins last_login
}
plugin {
last_login_dict = redis:host=127.0.0.1:port=6379
#last_login_key = last-login/%u # default
}
Note
We enable last_login plugin explicitly only for imap & pop3 protocols. If
enabled globally, it’ll also update the timestamp whenever new mails are
delivered via lda/lmtp or when doveadm is run for the user. This can also be
thought of as a feature, so if you want to update a different timestamp for
user when new mails are delivered, you can do that by enabling the last_login
plugin also for lda/lmtp and changing the last_login_key setting to include
%{service}
.
MySQL Example¶
This includes the service and remote IP address as well.
dovecot.conf:
plugin {
last_login_dict = proxy::sql
last_login_key = last-login/%{service}/%{user}/%{remote_ip}
last_login_precision = ms
}
dict {
sql = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext
}
SQL schema:
CREATE TABLE last_login (
userid VARCHAR(255) NOT NULL,
service VARCHAR(10) NOT NULL,
last_access BIGINT NOT NULL,
last_ip VARCHAR(40) NOT NULL,
PRIMARY KEY (userid, service)
);
dovecot-dict-sql.conf.ext:
connect = host=sql.example.com dbname=mails user=dovecot password=pass
map {
pattern = shared/last-login/$service/$user/$remote_ip
table = last_login
value_field = last_access
value_type = uint
fields {
userid = $user
service = $service
last_ip = $remote_ip
}
}
Cassandra Example¶
This includes the service and remote IP address as well.
dovecot.conf:
plugin {
last_login_dict = proxy:dict-async:cassandra
last_login_key = last-login/%{service}/%{user}/%{remote_ip}
last_login_precision = ms
}
dict {
cassandra = cassandra:/etc/dovecot/dovecot-dict-cql.conf.ext
}
Cassandra schema:
CREATE TABLE last_login (
userid TEXT,
service TEXT,
last_access TIMESTAMP,
last_ip TEXT,
PRIMARY KEY ((userid), service)
);
dovecot-dict-cql.conf.ext:
connect = host=sql.example.com dbname=mails user=dovecot password=pass
map {
pattern = shared/last-login/$service/$user/$remote_ip
table = last_login
value_field = last_access
value_type = uint
fields {
userid = $user
service = $service
last_ip = $remote_ip
}
}
Alternative Schema Cassandra Example¶
Instead of using a separate last_login table, add different services as separate fields to the main users table.
dovecot.conf:
plugin {
last_login_dict = proxy:dict-async:cassandra
last_login_key = last-login/%{service}/%{user}/%{remote_ip}
last_login_precision = ms
}
dict {
cassandra = cassandra:/etc/dovecot/dovecot-dict-cql.conf.ext
}
Cassandra schema:
CREATE TABLE users (
userid TEXT,
last_imap_access TIMESTAMP,
last_pop3_access TIMESTAMP,
last_lmtp_access TIMESTAMP,
last_imap_ip TEXT,
last_pop3_ip TEXT,
last_lmtp_ip TEXT,
PRIMARY KEY ((userid))
);
dovecot-dict-cql.conf.ext:
connect = host=sql.example.com dbname=mails user=dovecot password=pass
map {
pattern = shared/last-login/imap/$user/$remote_ip
table = users
value_field = last_imap_access
value_type = uint
fields {
userid = $user
last_imap_ip = $remote_ip
}
}
map {
pattern = shared/last-login/pop3/$user/$remote_ip
table = users
value_field = last_pop3_access
value_type = uint
fields {
userid = $user
last_pop3_ip = $remote_ip
}
}
map {
pattern = shared/last-login/lmtp/$user/$remote_ip
table = users
value_field = last_lmtp_access
value_type = uint
fields {
userid = $user
last_lmtp_ip = $remote_ip
}
}