Setup Email Server From Scratch Debian #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>
# --- 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