Setup Email Server From Scratch Debian #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>
# --- or use https://mail.okdeb.com ---
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.
# 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