Dovecot Replication with SSH
I have a Dovecot server that handles my email and that of some others,
for backup I was using rsync
on the mail spool. This solution works
quite well but I thought it would be cool to replicate the mailstore.
The setup is simple, the below is a cut down version of the information available on the Dovecot wiki.
Check that the following command lists your users:
doveadm user '*'
Enable the replicator plugin:
10-mail.conf
mail_plugins = notify replication
Replicator process should be started with the mail server, all the
configuration steps below are in 90-replicator.conf
which is a new
file.
service replicator {
process_min_avail = 1
unix_listener replicator-doveadm {
mode = 0600
user = dovecot
}
}
dsync_remote_cmd = ssh -l%{login} %{host} doveadm dsync-server -u%u
plugin {
mail_replica = remote:dovecot@othermailserver.com
replication_sync_timeout = 2s
}
service aggregator {
fifo_listener replication-notify-fifo {
user = dovecot
}
unix_listener replication-notify {
user = dovecot
}
}
The line above that may cause you some difficulty is the way this server
connects to the other via ssh. The ssh
command often requires some
extra configuration in order to work well unattended and without a
password. If replication fails it could be that ssh
was checking the
identity of the remote host and could not find it in the approved list.
To disable checking of remote hosts add this to dsync_remote_cmd
:
-o StrictHostKeyChecking=no
Or set a custom known hosts file (with the host fingerprint of course):
-o UserKnownHostsFile=/etc/dovecot/ssh_known_hosts
See later for more on these options.
Allow the dovecot user to login using a public key, in my case I changed
this line of /etc/shadow
:
dovecot:!:18356:0:99999:7:::
to:
dovecot:x:18356:0:99999:7:::
And changed the login shell to /bin/ash
(I am using Alpine Linux) in
the /etc/passwd
file along with a home directory.
In my case I wanted to supply the local private key files and the
remote public key (in the known_hosts
file) and for the dovecot user
on the other server I must provide the authorized_keys
file.
Both hosts must have the following files:
/etc/dovecot/id_ed25519
/etc/dovecot/id_ed25519.pub
/etc/dovecot/ssh_known_hosts
/etc/dovecot/ssh_authorized_keys
id_ed25519
can be generated using ssh-keygen -t ed25519
this step
should be performed twice (once on each server).
Change the /etc/ssh/sshd_config
file so that the dovecot
user has
a different authorized_keys
file:
Match User dovecot
AuthorizedKeysFile /etc/dovecot/ssh_authorized_keys
This file should contain the contents of the /etc/dovecot/id_ed25519.pub
that was generated on the other server. The authorized_keys
file
contains the public portion of the key pair and will allow anyone with
private portion to log in.
Next we have to get the public key from the remote host. The simplest way to do this is to connect to the host and say yes at the authenticity prompt:
The authenticity of host '[dovecot.example.com]:22 ([3.3.3.3:22])' can't be established.
ECDSA key fingerprint is SHA256:VYFEBfta4iaBPKH8zPxJIJCB8HSFjak+vDOnz7+Kz7U.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
Then disconnect and look in ~/.ssh/known_hosts
file for the host you
just connected to, take this line and put it in /etc/dovecot/ssh_known_hosts
.
Then, for the magic, change your configuration file to read:
dsync_remote_cmd = ssh -o UserKnownHostsFile=/etc/dovecot/ssh_known_hosts
-i /etc/dovecot/id_ed25519 -l%{login} %{host} doveadm dsync-server -u%u
All on one line!
If the -o UserKnownHostsFile
is not included the service will seemingly try
to use the known_hosts
file from /root/.ssh/
which is probably not what
you want!
Troubleshooting
For more detail in logs:
conf.d/10-logging.conf
mail_debug = yes
To fire off a replication synchronisation:
doveadm replicator replicate -f ben@example.com
More detail can be found on the dovecot wiki pages!