Roundcube Installation & Configuration

# Roundcube setup

roundcube_version=1.6.9
ROOT_MYSQL_PASSWORD="penguin"
ROUNDCUBE_MYSQL_PASSWORD="penguin"
domain_name="tuxmail.io"
RANDOM_STRING=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1`
POSTFIX_ADMIN_PASSWORD="penguin"

# Download roundcube

wget https://github.com/roundcube/roundcubemail/releases/download/$roundcube_version/roundcubemail-$roundcube_version-complete.tar.gz

# Extract the tar.gz

tar xvf roundcubemail-$roundcube_version-complete.tar.gz

# Move it to the appropriate location

mv roundcubemail-$roundcube_version /var/www/roundcube

# Set the ownership

chown www-data:www-data /var/www/roundcube/temp/ /var/www/roundcube/logs/ -R

# Install the required PHP extensions

apt install -y software-properties-common

# Install php

apt install -y php-net-ldap2 php-net-ldap3 php-imagick php8.1-common php8.1-gd php8.1-imap php8.1-mysql php8.1-curl php8.1-zip php8.1-xml php8.1-mbstring php8.1-bz2 php8.1-intl php8.1-gmp php8.1-redis

# Create database for Roundcube

mysql -u root -p$ROOT_MYSQL_PASSWORD -e "CREATE DATABASE roundcubemail DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;"

# Create a new database user for roundcube

mysql -u root -p$ROOT_MYSQL_PASSWORD -e "CREATE USER roundcube@localhost IDENTIFIED BY '$ROUNDCUBE_MYSQL_PASSWORD';"

# Grant all permission of the new database to the new user
# And flush the privileges table

mysql -u root -p$ROOT_MYSQL_PASSWORD roundcubemail < "/etc/apache2/sites-available/mail.$domain_name.conf"

ServerName mail.$domain_name
DocumentRoot /var/www/roundcube/

ErrorLog ${APACHE_LOG_DIR}/roundcube_error.log
CustomLog ${APACHE_LOG_DIR}/roundcube_access.log combined

Options FollowSymLinks
AllowOverride All

Options FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all

EOF

# Restart apache2

systemctl reload apache2

# Install TLS certificate already obtained for mail

printf "1\n" | certbot --apache --agree-tos --redirect --hsts --staple-ocsp --email user1@$domain_name -d mail.$domain_name

# Replace 127.0.0.1 localhost with 127.0.0.1 localhost mail.$domain_name to reduce lookup time

sed -i "s/127.0.0.1 localhost/127.0.0.1 localhost mail.$domain_name/g" /etc/hosts

# Duplicate the sample configuration file

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

# Replace $config['db_dsnw'] = 'mysql://roundcube:pass@localhost/roundcubemail'; with the actual password ie replace pass

sed -i "s/roundcube:pass/roundcube:$ROUNDCUBE_MYSQL_PASSWORD/g" /var/www/roundcube/config/config.inc.php

# Replace localhost with mail domain name

sed -i "s/localhost:143/tls:\/\/mail.$domain_name:143/g" /var/www/roundcube/config/config.inc.php

sed -i "s/localhost:587/tls:\/\/mail.$domain_name:587/g" /var/www/roundcube/config/config.inc.php

# Replace the default key $config['des_key'] = with some random characters

sed -i "s/rcmail-\!24ByteDESkey\*Str/$RANDOM_STRING/g" /var/www/roundcube/config/config.inc.php

# Delete the active plugins section

sed -i '/active plugins/,/];/d' /var/www/roundcube/config/config.inc.php

# Add back the active plugins section

cat << EOF >> "/var/www/roundcube/config/config.inc.php"
// List of active plugins (in plugins/ directory)
\$config['plugins'] = ['acl', 'additional_message_headers', 'archive', 'attachment_reminder', 'autologon', 'debug_logger', 'emoticons', 'enigma', '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'];
EOF

# Enable the spellchecker

cat << EOF >> "/var/www/roundcube/config/config.inc.php"
\$config['enable_spellcheck'] = true;
EOF

# Set a name for the installation based on the domain name

sed -i "s/'Roundcube Webmail'/'$domain_name Webmail'/g" /var/www/roundcube/config/config.inc.php

# Set the default domain so we don't end up with mail.domain.com

cat << EOF >> "/var/www/roundcube/config/config.inc.php"
\$config['mail_domain'] = '$domain_name';
EOF

# Delete the installer for security reasons

rm /var/www/roundcube/installer/ -r

# Make directory for storing users GPG keys for the enigma plugin

mkdir -p /var/vmail/pgp-keys

# Set the ownership to www-data

chown www-data:www-data /var/vmail/pgp-keys

# Set the home directory for storing GPG keys for the enigma plugin

cat << EOF >> "/var/www/roundcube/config/config.inc.php"
\$config['enigma_pgp_homedir'] = '/var/vmail/pgp-keys';
EOF

# Redirect main domain and www to mail.domain.com

cat << EOF > "/etc/apache2/sites-enabled/$domain_name.conf"

ServerName $domain_name
ServerAlias $domain_name
Redirect permanent / http://mail.$domain_name/

EOF

cat << EOF > "/etc/apache2/sites-enabled/www.$domain_name.conf"

ServerName $domain_name
ServerAlias www.$domain_name
Redirect permanent / http://mail.$domain_name/

EOF

# Restart apache2

systemctl restart apache2

# Install the ManageSieve server, to enable mail filtering

apt install -y dovecot-sieve dovecot-managesieved

# Install the Dovecot LMTP Server
# Required for the sieve plugin to filter inbound messages

apt install -y dovecot-lmtpd

# Add sieve to the supported protocols

sed -i "s/imap pop3 lmtp/imap pop3 lmtp sieve/g" /etc/dovecot/dovecot.conf

# Add the sieve plugin to local delivery agent (LDA)

sed -i "s/#mail_plugins = \$mail_plugins/mail_plugins = \$mail_plugins sieve/g" /etc/dovecot/conf.d/15-lda.conf

# Enable the sieve plugin in 20-lmtp.conf s well

sed -i "s/#mail_plugins = \$mail_plugins/mail_plugins = quota sieve/g" /etc/dovecot/conf.d/20-lmtp.conf

# Restart postfix and dovecot

systemctl restart postfix dovecot

# Tell Postfix to ignore the User-Agent string Roundcube adds

cat << EOF >> "/etc/postfix/smtp_header_checks"
/^User-Agent.*Roundcube Webmail/ IGNORE
EOF

# Add the following line main.cf

cat << EOF >> "/etc/postfix/main.cf"
smtp_header_checks = regexp:/etc/postfix/smtp_header_checks
EOF

# Rebuild hash table

postmap /etc/postfix/smtp_header_checks

# Reload postfix

systemctl reload postfix

# Enable the password plugin

cp /var/www/roundcube/plugins/password/config.inc.php.dist /var/www/roundcube/plugins/password/config.inc.php

# Tell the password plugin where the user passwords are stored

sed -i "s/\$config\['password_db_dsn'\] = ''/\$config\['password_db_dsn'\] = 'mysql:\/\/postfixadmin:$POSTFIX_ADMIN_PASSWORD@127.0.0.1\/postfixadmin'/g" /var/www/roundcube/plugins/password/config.inc.php

Also change:

sed -i "s/\$config\['password_query'\] = 'SELECT update_passwd(%P, %u)'/\$config\['password_query'\] = 'UPDATE mailbox SET password=%P,modified=NOW() WHERE username=%u'/g" /var/www/roundcube/plugins/password/config.inc.php

# Enable a password strength checker to prevent users from setting weak passwords

sed -i "s/\$config\['password_strength_driver'\] = null/\$config\['password_strength_driver'\] = 'zxcvbn'/g" /var/www/roundcube/plugins/password/config.inc.php

# Allow strong passwords only

cat << EOF >> "/var/www/roundcube/plugins/password/config.inc.php"
\$config['password_zxcvbn_min_score'] = 5;
EOF

# Change the password algorithm to dovecot

sed -i "s/\$config\['password_algorithm'\] = 'clear'/\$config\['password_algorithm'\] = 'dovecot'/g" /var/www/roundcube/plugins/password/config.inc.php

# Set the location of the password hash generator

sed -i "s/\$config\['password_dovecotpw'\] = '\/usr\/local\/sbin\/dovecotpw'/\$config\['password_dovecotpw'\] = '\/usr\/bin\/doveadm pw -r 5'/g" /var/www/roundcube/plugins/password/config.inc.php

# Delete description

sed -i "s/\/\/ for dovecot-1.x//g" /var/www/roundcube/plugins/password/config.inc.php

# Change the password scheme used to ARGON2I

sed -i "s/\$config\['password_dovecotpw_method'\] = 'CRAM-MD5'/\$config\['password_dovecotpw_method'\] = 'ARGON2I'/g" /var/www/roundcube/plugins/password/config.inc.php

# This will add a {ARGON2I} prefix to the hashed password, so you will recognize which password scheme is used

sed -i "s/\$config\['password_dovecotpw_with_method'\] = false/\$config\['password_dovecotpw_with_method'\] = true/g" /var/www/roundcube/plugins/password/config.inc.php

# This file contains the database password, we should allow only the www-data user to read and write to this file

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

# Increase the upload size limit in PHP

sed -i "s/upload_max_filesize = 2M/upload_max_filesize = 50M/g" /etc/php/8.1/fpm/php.ini

# Change the maximum size of POST data that PHP will accept too

sed -i "s/post_max_size = 8M/post_max_size = 50M/g" /etc/php/8.1/fpm/php.ini

# Restart php

systemctl restart php8.1-fpm