Skip to content

Webmail using Roundcube

Now that the email has arrived, our valued user surely wants to read it. Most humans nowadays seem to prefer reading their email in the web browser, because it’s the simplest way. (Don’t worry. Power users who prefer mail clients like Thunderbird will also get what they want.) So let’s prepare Roundcube for them.

Click here to learn more about virtual hosts…

A web server like Apache has the job of answering HTTP or HTTPS requests from people’s browsers. Running just a single website per server (or per IP address) would be both inefficient and limiting, so the idea of virtual hosts was introduced. With virtual hosts, one server can host many different websites. The browser helps by sending a Host: mail.example.org header with each request, which tells the server which website it should serve. This works fine for HTTP—though plain HTTP is rarely used anymore.

With HTTPS, things get trickier. Browsers expect the server to present a TLS certificate that matches the domain being requested. If you try to open mail.example.org but the server responds with a certificate for shop.example.org, the browser will block the connection. That means the server needs to know which domain the browser is asking for before the encrypted connection is set up.

The solution is a feature called SNI (Server Name Indication). When establishing an HTTPS connection, the browser includes the domain name it wants in the handshake. This allows the server to pick the correct TLS certificate right from the start.

Fortunately you do not have to worry about it that much because Apache is doing the heavy lifting for you. A virtual host configuration essentially looks like:

<VirtualHost *:443>
ServerName mail.example.org
SSLCertificateFile /etc/letsencrypt/live/mail.example.org/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/mail.example.org/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>

There are two directories dealing with virtual hosts:

  • /etc/apache2/sites-available
  • /etc/apache2/sites-enabled

The actual file containing the configuration lives in sites-available. If that configuration should be active, then a symbolic link (symlink) is added to the sites-enabled directory pointing to the file in the sites-available directory. That way you can switch sites on and off without deleting the actual configuration file. You can enable a site using the a2ensite (apache2 enable config) command or disable it using a2dissite.

Since you ran certbot earlier to create a TLS certificate for your site, the default configuration files for HTTP and HTTPS have been adapted already:

  • 000-default.conf: This is the virtual host configuration for HTTP requests. It uses a RewriteRule to redirect users to the HTTPS site. So if user accidentally forget to type https://, we will add it for them.
  • 000-default-le-ssl.conf: This is the HTTPS virtual host.

So to get Apache to serve the Roundcube application you need to edit the /etc/apache2/sites-available/000-default-le-ssl.conf file.

Set this:

Edit /etc/apache2/sites-available/000-default-le-ssl.conf
ServerName mail.example.org
DocumentRoot /var/lib/roundcube/public_html
Include /etc/roundcube/apache.conf

Meaning:

  • ServerName sets the domain name that a user’s browser will request.
  • DocumentRoot points the entire web site to the directory where Roundcube is installed.
  • Include loads additional security settings that the Roundcube package provides.

And as usual Apache needs to be restarted after the configuration change:

Terminal window
systemctl restart apache2

Check that Apache is running properly:

Terminal window
systemctl status apache2

In case of a problem run apache2ctl configtest to find the cause.

The main configuration file of Roundcube is located at /etc/roundcube/config.inc.php. Feel free to customize the file. Fortunately nowadays the basic settings are already as we need them. However these two settings need to be changed by you.

Edit /etc/roundcube/config.inc.php
$config['imap_host'] = 'tls://mail.example.org:143';
$config['smtp_host'] = 'tls://mail.example.org:587';

So now when your users enter https://webmail.example.org/ in their browser they should get the Roundcube login form:

Roundcube login dialog

Keep in mind that we are using the email address as the account name of the user. So when logging in please enter the email address as the user name. E.g. john@example.org and password summersun.

If the login fails, check /var/log/roundcube/errors.log.

Roundcube comes with various plugins that you can offer your users. I suggest that you enable at least

  • the password plugin so that your users can change their access password
  • the managesieve plugin so that your users can create server-based filtering rules

Again edit the /etc/roundcube/config.inc.php file and look for the plugins configuration. To enable the recommended plugins change it to:

$config['plugins'] = array(
'password',
'managesieve',
);

Plugins are configured through files located in the /etc/roundcube/plugins directory.

Let’s quickly set up the password plugin:

Run this on your server
cat > /etc/roundcube/plugins/password/config.inc.php << 'EOF'
<?php
$config['password_driver'] = 'sql';
$config['password_minimum_length'] = 12;
$config['password_force_save'] = true;
$config['password_algorithm'] = 'blowfish-crypt';
$config['password_algorithm_prefix'] = '{CRYPT}';
$config['password_db_dsn'] = 'mysql://mailadmin:MAILADMIN-PASSWORD-HERE@localhost/mailserver';
$config['password_query'] = "UPDATE virtual_users SET password=%P WHERE email=%u";
?>
EOF
chown root:www-data /etc/roundcube/plugins/password/config.inc.php
chmod u=rw,g=r,o= /etc/roundcube/plugins/password/config.inc.php

What these settings mean:

  • $config['password_driver'] = 'sql';
    Use SQL as a backend.
  • $config['password_minimum_length'] = 12;
    New passwords must be at least 12 characters long.
  • $config['password_force_save'] = true;
    This will overwrite the password in the database even if it hasn’t changed. It helps us improve the strength of the password hash by re-encoding it with a better algorithm even if the user chooses to keep his old password.
  • $config['password_algorithm'] = 'blowfish-crypt';
    The cryptographic algorithm to encode the password. This one is considered very secure and supported by Dovecot.
  • $config['password_algorithm_prefix'] = '{CRYPT}';
    Prepend every password with this string so that Dovecot knows how we encrypted the password.
  • $config['password_db_dsn'] = 'mysql://mailadmin:MAILADMIN-PASSWORD-HERE@localhost/mailserver';
    Connection information for the local database. Use your own password for the mailadmin (!) database user here. We cannot use the restricted mailserver user because we have to write the new password to the database.
  • $config['password_query'] = "UPDATE virtual_users SET password=%P WHERE email=%u";
    The SQL query that is run to write the new password hash into the database. %P is a placeholder for the new password hash. %u is the logged-in user and conveniently matches the email address.

For a complete reference please see /usr/share/roundcube/plugins/password/config.inc.php.dist.

The last two lines make sure that this config file is only accessible to everyone.

Roundcube password dialog

Try it. Log into Roundcube as john@example.org with password ‘summersun’. Go to the Settings. Choose Password. Enter a new password twice. You should get a success message at the bottom right. Now logout and login with the new password. Does it work? Great.

Sieve is a simple programming language to be used for server-side rules. Dovecot executes these rules every time a new email comes in. There are global rules that are executed for every email. And of course every user/mailbox can have its own rules. To manage sieve rules Dovecot offers the managesieve interface that you enabled earlier. So we just need to tell Roundcube how to access it.

The configuration file for Roundcube’s managesieve plugin is found at /etc/roundcube/plugins/managesieve/config.inc.php. But the defaults are fine so you do not need to change it.

Sieve rules are stored in a special syntax on the server. This is an example that moves all incoming emails to the test folder that have “test” in the subject:

require ["fileinto"];
if header :contains "subject" "test"
{
fileinto "INBOX/test";
}

You do not need to learn this syntax though. Roundcube’s sieve rule editor is way more user-friendly.

Try adding a sieve rule for john@example.org in Roundcube. That feature is located in Settings/Filters. You will find the machine-readable sieve code at /var/vmail/example.org/john/sieve/roundcube.sieve.

The rule editor looks like this:

Roundcube's sieve rule editor