Setup Email Server From Scratch On FreeBSD #2 - 07 RoundCube WebMail
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