# 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