Setup Email Server From Scratch On FreeBSD #2 - 07 RoundCube WebMail

06 SPF DKIM DMARC <- Intro -> 08 RoundCube WebMail PKG

We believe in data independence, and support others who want data independence.
Debian Email From Scratch version 2 finished 2025-07-30.

We are still adding to it but it all works!


################################################################
# Setup Roundcube Webmail On Debian From Scratch With Calendar #
################################################################

Getting Roundcube setup and installing the modules could be a tutorial by itself.

I first installed roundcube using the Debian packages and got everything working including password
and identities/signatures with enigma, but it was missing bin/initdb.sh and I wasn't able to install
kolab calendar. The package installation puts roundcube in /usr/share/roundcube with configuration
files in /etc/roundcube. I removed everything and started over using instructions from linuxbabe and
roundcube.net and a very short helpful how to for calendar. I prefer this method over using packages
as I do like having calendar available. Here we install from roundcube directly to /var/www/roundcube.

You should already have similar entries to these in /etc/hosts

nano /etc/hosts
15.204.113.148 okdeb.com mx.okdeb.com mail.okdeb.com 2604:2dc0:202:300::3645 okdeb.com mx.okdeb.com mail.okdeb.com

Install Roundcube

Without making any other changes Roundcube works including spellcheck, and
identities with signature and addresses. There is no filters option, password, or
calendar plugins.

Credits to linuxbabe!

This tutorial relies heavily on the work by linuxbabe.com ... but has been updated
to work on Debian 12 where applicable, and modified to use standard system packages.

Go to https://roundcube.net/download/ and get the complete version
Stable version - 1.6.11 complete

scp roundcubemail-1.6.11-complete.tar.gz okdeb:/var/www
cd /var/www
tar xfzv roundcubemail-1.6.11-complete.tar.gz
mv roundcubemail-1.6.11 roundcube
chown -R root:root /var/www/roundcube
chown -R www-data:www-data /var/www/roundcube/temp
chown -R www-data:www-data /var/www/roundcube/logs

Install plugin dependencies

apt install php-net-ldap2 php-net-ldap3 php-imagick php-fpm php-common php-gd php-imap
apt install php-curl php-zip php-xml php-mbstring php-bz2 php-intl php-gmp php-redis php-zip
apt install php-sabre-* php-curl aspell php-enchant php-pspell python3-lesscpy

Install gnupg and crypt
apt install php-pear gnupg python3-lesscpy composer wget
pear install Crypt_GPG

Create Roundcube Database

mysql
> CREATE DATABASE roundcubemail CHARACTER SET utf8 COLLATE utf8_general_ci;
> GRANT ALL PRIVILEGES ON roundcubemail.* TO roundcube@localhost IDENTIFIED BY 'secretpasswd';
> flush privileges;
> exit;

Import Database Tables

mysql roundcubemail < /var/www/roundcube/SQL/mysql.initial.sql

Make Adjustments to php configuation

nano /etc/php/8.2/apache2/php.ini
max_execution_time = 600 max_input_time = 300 max_input_vars = 3000 memory_limit = 256M post_max_size = 200M upload_max_filesize = 100M date.timezone = US/Pacific

nano /etc/php/8.2/cli/php.ini
max_execution_time = 600 max_input_time = 300 max_input_vars = 3000 memory_limit = -1 post_max_size = 200M upload_max_filesize = 100M

nano /etc/php/8.2/fpm/php.ini
max_execution_time = 600 max_input_time = 300 max_input_vars = 3000 memory_limit = -1 post_max_size = 200M upload_max_filesize = 100M

systemctl restart php8.2-fpm.service
apachectl restart

Configure Apache roundcube directory, change trusted ip's to your own list or
just use Require all granted

nano /etc/apache2/site-enabled/ssl-mx.okdeb.conf
--- Use https://mx.okdeb.com/webmail ---
Alias /webmail "/var/www/roundcube" Alias /roundcube "/var/www/roundcube" <Directory /var/www/roundcube/> # Options FollowSymLinks MultiViews Options FollowSymLinks AllowOverride All # Require all granted Require all denied Require ip 10.0.0.0/8 192.168.0.0/16 127.0.0.1 trusted_ip3 trusted_ipv6 </Directory>

nano /etc/apache2/site-enabled/ssl-mx.okdeb.conf
--- or use https://mail.okdeb.com for webmail ---
DocumentRoot /var/www/roundcube/ Alias /webmail "/var/www/roundcube" Alias /roundcube "/var/www/roundcube" <Directory /var/www/roundcube/> # Options FollowSymLinks MultiViews Options FollowSymLinks AllowOverride All # Require all granted Require all denied Require ip 10.0.0.0/8 192.168.0.0/16 127.0.0.1 trusted_ip3 trusted_ipv6 </Directory>

Don't use Alias /mail "/usr/share/roundcube" because /mail is used for autoconfig.
MultiViews doesn't seem to be required. It is better to configure Roundcube with
ssl/https only to force https password encryption. It could work if putting the
autocofig Autodiscover files in the roundcube directory, but this doesn't seem ideal.

Check these are enabled and restart apache

a2enmod proxy_fcgi setenvif
a2enconf php8.2-fpm
apachectl restart

Configure Roundcube imap, smtp, and spell checking.

cd /var/www/roundcube/config
cp /var/www/roundcube/config/config.inc.php.sample /var/www/roundcube/config/config.inc.php

nano /var/www/roundcube/config/config.inc.php
$config['db_dsnw'] = 'mysql://roundcube:secretpasswd@localhost/roundcubemail'; $config['imap_host'] = 'tls://mx.okdeb.com:143'; $config['smtp_host'] = 'tls://mx.okdeb.com:587'; // Replace the default key with 24 random characters. $config['des_key'] = '123456789012345678901234'; // Enable more plugins $config['plugins'] = ['acl', 'additional_message_headers', 'archive', 'attachment_reminder', 'autologon', 'debug_logger', 'emoticons', 'enigma', 'filesystem_attachments', 'help', 'hide_blockquote', 'http_authentication', 'identicon', 'identity_select', 'jqueryui', 'krb_authentication', 'managesieve', 'markasjunk', 'new_user_dialog', 'new_user_identity', 'newmail_notifier', 'password', 'reconnect', 'redundant_attachments', 'show_additional_headers', 'squirrelmail_usercopy', 'subscriptions_option', 'userinfo', 'vcard_attachments', 'virtuser_file', 'virtuser_query', 'zipdownload']; // skin name: folder from skins/ $config['skin'] = 'elastic'; $config['enable_spellcheck'] = true; $config['spellcheck_engine'] = 'enchant'; // this will make max upload 75% so 100M => 75M $config['max_message_size'] = '134M'; $config['create_default_folders'] = true;

Fix directories and permissions

mkdir -p /var/www/roundcube/logs
chown www-data:www-data /var/www/roundcube/temp
chown www-data:www-data /var/www/roundcube/logs
chmod 755 /var/www/roundcube/temp
chmod 755 /var/www/roundcube/logs

chown root:www-data /var/www/roundcube/config/config.inc.php
chmod 640 /var/www/roundcube/config/config.inc.php

Go to https://mail.okdeb.com and login.

If you have problems with Identity and user Signature in Roundcube you need to configure Enigma.

Configure Enigma Plugin - pgp error

Install gnupg and crypt
apt install gnupg
pear install Crypt_GPG

Create enigma home
mkdir -p /var/www/roundcube/plugins/enigma/home
chown www-data:www-data /var/www/roundcube/plugins/enigma/home
chmod 750 /var/www/roundcube/plugins/enigma/home

Configure Enigma
cd /var/www/roundcube/plugins/enigma
cp /var/www/roundcube/plugins/enigma/config.inc.php.dist /var/www/roundcube/plugins/enigma/config.inc.php

nano /var/www/roundcube/plugins/enigma/config.inc.php
$config['enigma_pgp_homedir'] = "/var/www/roundcube/plugins/enigma/home";

This doesn't seem to be the best place to put enigma home since if roundcube gets replaced
with an update the user data in engima/home could be deleted. It works, and it's part of
roundcube.

* If it ain't broke don't fix it! *

Check Settings -> Identities -> Click On User -> If fixed it shows Signature and Manage PGP Keys

Configure the Sieve filter

apt install dovecot-sieve dovecot-managesieved dovecot-lmtpd

nano /etc/dovecot/dovecot.conf
protocols = imap lmtp sieve

nano /etc/dovecot/conf.d/10-master.conf
service lmtp { unix_listener /var/spool/postfix/private/dovecot-lmtp { mode = 0600 user = postfix group = postfix } }

nano /etc/postfix/main.cf
--- should be already added if not add to end of file ---
mailbox_transport = lmtp:unix:private/dovecot-lmtp smtputf8_enable = no

nano /etc/dovecot/conf.d/15-lda.conf
protocol lda { # Space separated list of plugins to load (default is global mail_plugins). mail_plugins = $mail_plugins seive }

nano /etc/dovecot/conf.d/20-lmtp.conf
protocol lmtp { # Space separated list of plugins to load (default is global mail_plugins). mail_plugins = $mail_plugins quota sieve }

nano /etc/dovecot/conf.d/10-mail.conf
--- should already be edited, but check it ---
mail_home = /var/vmail/%d/%n

systemctl restart postfix dovecot

Go to Roundcube and check filters, make a new mailbox and set a filter for a your
other address to send the mail to the new mailbox folder. You may have to go into
filters, select the filter, disable and reenable it to get it working.

Once everything is working it is a good idea to make backups.

cd /var
tar cfzv var_www.tgz www
tar cfzv var_vmail.tgz vmail

cd /etc
tar cfzv etc_apache2.tgz apache2
tar cfzv etc_dovecot.tgz dovecot
tar cfzv etc_postfix.tgz postfix
tar cfzv etc_mysql.tgz mysql
tar cfzv etc_postfixadmin.tgz postfixadmin
tar cfzv etc_opendkim.tgz opendkim.conf opendkim dkimkeys
tar cfzv etc_opendmarc.tgz opendmarc.conf opendmarc
tar cfzv etc_default.tgz default
tar cfzv etc_postfix-policyd-spf-python.tgz postfix-policyd-spf-python

cd /usr/share
tar cfzv usr_share_postfixadmin.tgz postfixadmin

I didn't include /etc/letsencrypt or /etc/php

Remove sensitive information from outgoing email headers.

nano /etc/postfix/smtp_header_checks
/^User-Agent.*Roundcube Webmail/ IGNORE

nano /etc/postfix/main.cf
--- add to end of file ---
smtp_header_checks = regexp:/etc/postfix/smtp_header_checks

postmap /etc/postfix/smtp_header_checks
systemctl reload postfix

Configure the password plugin
The des_key should be randomly generated and must be exactly 24 characters, The Debian
Roundcube setup does this for us so no change is needed.

nano /var/www/roundcube/config/config.inc.php
--- make sure password plugin is included ---
$config['plugins'] = ['acl', 'additional_message_headers', 'archive', 'attachment_reminder', 'autologon', 'debug_logger', 'emoticons', 'enigma', 'filesystem_attachments', 'help', 'hide_blockquote', 'http_authentication', 'identicon', 'identity_select', 'jqueryui', 'krb_authentication', 'managesieve', 'markasjunk', 'new_user_dialog', 'new_user_identity', 'newmail_notifier', 'password', 'reconnect', 'redundant_attachments', 'show_additional_headers', 'squirrelmail_usercopy', 'subscriptions_option', 'userinfo', 'vcard_attachments', 'virtuser_file', 'virtuser_query', 'zipdownload', 'password'];

Enable the plugin in roundcube

cd /var/www/roundcube/plugins/password/
cp /var/www/roundcube/plugins/password/config.inc.php_default /var/www/roundcube/plugins/password/config.inc.php

With packages Debian Roundcube will set up the password_db_dsn correctly. You can setup a
password strength driver and minimum length but I leave it at null and 8, though 12
might be better. If there are going to be many third parties using the service,
enabling a password strength driver and increasing the minimum length is advised.

nano /usr/share/roundcube/plugins/password/config.inc.php
--- change these lines and set the supersecret password ---
$config['password_strength_driver'] = null; $config['password_minimum_length'] = 8; $config['password_algorithm'] = 'dovecot'; $config['password_dovecotpw'] = '/usr/bin/doveadm pw -r 5'; $config['password_dovecotpw_method'] = 'ARGON2I'; $config['password_dovecotpw_with_method'] = true; # the password is in /etc/postfix/sql/mysql_virtual_domains_maps.cf $config['password_db_dsn'] = 'mysql://postfixadmin:secretpasswd@127.0.0.1/postfixadmin'; $config['password_query'] = 'UPDATE mailbox SET password=%P,modified=NOW() WHERE username=%u';

Fix password plugin permissions, anything that has the mysql password should be readble by www-data
and root and not world readable.

chown root:www-data /var/www/roundcube/config/config.inc.php
chmod 640 /var/www/roundcube/config/config.inc.php
chown root:www-data /var/www/roundcube/plugins/password/config.inc.php
chmod 640 /var/www/roundcube/plugins/password/config.inc.php

Test it to make sure you can change passwords in Roundcube.

This is the end of basic Roundcube setup, but we can add more plugins.

apt install php-sabre-* php-curl composer wget git

Credits to https://synay.net/en/support/kb/roundcube-calendar-plugin

cd /tmp
git clone https://git.kolab.org/diffusion/RPK/roundcubemail-plugins-kolab.git

cd /var/www/roundcube/plugins
cp -r /tmp/roundcubemail-plugins-kolab/plugins/calendar .
cp -r /tmp/roundcubemail-plugins-kolab/plugins/libcalendaring .
cp -r /tmp/roundcubemail-plugins-kolab/plugins/libkolab .
cd /var/www/roundcube/plugins/calendar
cp /var/www/roundcube/plugins/calendar/config.inc.php.dist /var/www/roundcube/plugins/calendar/config.inc.php

Enable calendar in main roundcube config

nano /var/www/roundcube/config/config.inc.php
$config['plugins'] = ['acl', 'additional_message_headers', 'archive', 'attachment_reminder', 'autologon', 'debug_logger', 'emoticons', 'enigma', 'filesystem_attachments', 'help', 'hide_blockquote', 'http_authentication', 'identicon', 'identity_select', 'jqueryui', 'krb_authentication', 'managesieve', 'markasjunk', 'new_user_dialog', 'new_user_identity', 'newmail_notifier', 'password', 'reconnect', 'redundant_attachments', 'show_additional_headers', 'squirrelmail_usercopy', 'subscriptions_option', 'userinfo', 'vcard_attachments', 'virtuser_file', 'virtuser_query', 'zipdownload', 'password', 'calendar'];

Initilize calendar database

cd /var/www/roundcube
bin/initdb.sh --dir=plugins/calendar/drivers/database/SQL

root@okdeb.com:/var/www/roundcube# grep sabre composer.json
"sabre/dav": "^4.7"

apt install node-less

lessc -x /var/www/roundcube/plugins/libkolab/skins/elastic/libkolab.less > /var/www/roundcube/plugins/libkolab/skins/elastic/libkolab.min.css

Test that everything works as expected

cd /tmp
git clone https://github.com/sblaisot/automatic_addressbook.git
mv /tmp/automatic_addressbook /var/www/roundcube/plugins
cd /var/www/roundcube/plugins/automatic_addressbook/SQL
mysql -u roundcube -psecretpasswd roundcubemail < mysql.initial.sql
cd /var/www/www/roundcube/plugins/automatic_addressbook/config
cp /var/www/www/roundcube/plugins/automatic_addressbook/config/config.inc.php.dist /var/www/www/roundcube/plugins/automatic_addressbook/config/config.inc.php

nano /var/www/roundcube/config/config.inc.php
$config['plugins'] = ['acl', 'additional_message_headers', 'archive', 'attachment_reminder', 'autologon', 'debug_logger', 'emoticons', 'enigma', 'filesystem_attachments', 'help', 'hide_blockquote', 'http_authentication', 'identicon', 'identity_select', 'jqueryui', 'krb_authentication', 'managesieve', 'markasjunk', 'new_user_dialog', 'new_user_identity', 'newmail_notifier', 'password', 'reconnect', 'show_additional_headers', 'squirrelmail_usercopy', 'subscriptions_option', 'userinfo', 'vcard_attachments', 'virtuser_file', 'virtuser_query', 'zipdownload', 'password', 'calendar', 'automatic_addressbook']; // 'redundant_attachments',

cd /tmp
git clone https://github.com/roundcube/larry.git
cp -r larry /var/www/roundcube/skins/
cd /var/www/roundcube/config

There are many more roundcube skins but these are the two paid versions. There
are also some colorful larry skins https://github.com/roundcube/larry.git

cd /tmp
git clone https://github.com/texxasrulez/roundcube_skins.git
cd /tmp/roundcube_skins/skins
mv * /var/www/roundcube/skins

You can now go to settings and select which skin you'd like.

Settings -> Preferences - > User Interface

I didn't see any notifications when I used html5_notifier.

cd /tmp
git clone https://github.com/stremlau/html5_notifier.git
mv /tmp/html5_notifier /var/www/roundcube/plugins/
cd /var/www/roundcube/plugins/html5_notifier/config

cp /var/www/roundcube/plugins/html5_notifier/config/config.inc.php.dist \
/var/www/roundcube/plugins/html5_notifier/config/config.inc.php

nano /var/www/roundcube/config/config.inc.php
--- append to the end of modules list ---
'virtuser_query', 'zipdownload', 'password', 'calendar', 'automatic_addressbook', 'html5_notifier'];

html5_notifier doesn't seem to work under Debian with Firefox...


Roundcube has an extensive set of plugins which are beyond the scope of
this setup tutorial, explore setting up caldav and cardav.

twofactor_gauthenticator

Next - Multiple "Virtual" Mail Domains

06 SPF DKIM DMARC <- Intro -> 08 RoundCube WebMail PKG