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

07 RoundCube WebMail <- Intro -> 09 Virtual Domains

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!


If you used the first Roundcube installation from git skip this. I got this working
first but wasn't able to install calendar. If you will never want or need calendar
this works well.

##################################################################
# Setup Roundcube Webmail On Debian Using Packages - No Calendar #
##################################################################

Getting Roundcube setup and installing the modules could be a tutorial by itself.
There are many ways to get and install Roundcube so if you're up for experimentation
try a few different options and see which works best.

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

apt install -y roundcube roundcube-plugins roundcube-plugins-extra roundcube-mysql
Configure roundcube with dbconfig-common: Yes
Database: mysql
<password>
<password>

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 "/usr/share/roundcube" Alias /roundcube "/usr/share/roundcube" <Directory /usr/share/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 ---
DocumentRoot /usr/share/roundcube/ Alias /webmail "/usr/share/roundcube" Alias /roundcube "/usr/share/roundcube" <Directory /usr/share/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.

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 = 200M 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 = 200M

Configure Roundcube imap, smtp, and spell checking.

Install spelling modules
apt install aspell php-enchant php-pspell

nano /etc/roundcube/config.inc.php
$config['imap_host'] = 'tls://mx.okdeb.com:143'; $config['smtp_host'] = 'tls://mx.okdeb.com:587'; $config['enable_spellcheck'] = true; $config['spellcheck_engine'] = 'enchant'; $config['max_message_size'] = '134M'; $config['create_default_folders'] = true;

Check these are enabled and restart apache

a2enmod proxy_fcgi setenvif
a2enconf php8.2-fpm
apachectl restart

Go to https://mx.okdeb.com/webmail

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.

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

Check what roundcube packages are available and installed.

apt search roundcube

All Roundcube packages are installed except those for unused databases and the RTF
converter which might be nice to have.

apt install php-roundcube-rtf-html-php

Enable some plugins

nano /etc/roundcube/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'];

apt remove gnupg
apt install gnupg

Configure Enigma Plugin - fix identity and signature problems

Install gnupg and crypt
apt install gnupg
pear install Crypt_GPG

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

Configure Enigma
cd /usr/share/roundcube/plugins/enigma
cp /usr/share/roundcube/plugins/enigma/config.inc.php.dist /etc/roundcube/plugins/enigma/config.inc.php
cd /etc/roundcube/plugins/enigma

nano /etc/roundcube/plugins/enigma/config.inc.php
$config['enigma_pgp_homedir'] = "/usr/share/roundcube/plugins/enigma/home";

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, this does not backup
the database. If something break what is working so far, the old files serve as a
reference or can be use to restore the system to the last known working configuration.

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_roundcube.tgz roundcube
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_roundcube.tgz roundcube
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 /etc/roundcube/config.inc.php
--- make sure password plugin is included ---
... $config['des_key'] = '123456789012345678901234'; // List of active plugins (in plugins/ directory) // Debian: install roundcube-plugins first to have any //$config['plugins'] = [ // 'archive', // 'zipdownload', //]; $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['max_pagesize'] = 1000; // Disable spellchecking // Debian: spellchecking needs additional packages to be installed, or calling external APIs // see defaults.inc.php for additional informations // $config['enable_spellcheck'] = false; $config['enable_spellcheck'] = true; $config['spellcheck_engine'] = 'enchant';

Enable the plugin in roundcube

cd /usr/share/roundcube/plugins/password/
cp config.inc.php config.inc.php_default
cp config.inc.php.dist config.inc.php

Usually 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:supersecret@127.0.0.1/postfixadmin'; $config['password_query'] = 'UPDATE mailbox SET password=%P,modified=NOW() WHERE username=%u';

Check permissions
ls -l /etc/roundcube/debian-db.php
-rw-r----- 1 root www-data 523 Jul 22 15:38 /etc/roundcube/debian-db.php

Fix password plugin permissions

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

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

Roundcube has an extensive set of plugins which are beyond the scope of
this setup tutorial. It would be interesting to set this up properly with caldav cardav

Next - Multiple "Virtual" Mail Domains

07 RoundCube WebMail <- Intro -> 09 Virtual Domains