mirror of
https://github.com/mail-in-a-box/mailinabox.git
synced 2025-01-23 12:37:05 +00:00
93d1055869
using "primary" to describe the domain of the box / mail server is confusing when working with multiple domains. Usually the box domain is different from the domain you want to host your mail for.
225 lines
8.9 KiB
Bash
225 lines
8.9 KiB
Bash
#!/bin/bash
|
|
# Webmail with Roundcube
|
|
# ----------------------
|
|
|
|
source setup/functions.sh # load our functions
|
|
source /etc/mailinabox.conf # load global vars
|
|
|
|
# ### Installing Roundcube
|
|
|
|
# We install Roundcube from sources, rather than from Ubuntu, because:
|
|
#
|
|
# 1. Ubuntu's `roundcube-core` package has dependencies on Apache & MySQL, which we don't want.
|
|
#
|
|
# 2. The Roundcube shipped with Ubuntu is consistently out of date.
|
|
#
|
|
# 3. It's packaged incorrectly --- it seems to be missing a directory of files.
|
|
#
|
|
# So we'll use apt-get to manually install the dependencies of roundcube that we know we need,
|
|
# and then we'll manually install roundcube from source.
|
|
|
|
# These dependencies are from `apt-cache showpkg roundcube-core`.
|
|
echo "Installing Roundcube (webmail)..."
|
|
apt_install \
|
|
dbconfig-common \
|
|
php"${PHP_VER}"-cli php"${PHP_VER}"-sqlite3 php"${PHP_VER}"-intl php"${PHP_VER}"-common php"${PHP_VER}"-curl php"${PHP_VER}"-imap \
|
|
php"${PHP_VER}"-gd php"${PHP_VER}"-pspell php"${PHP_VER}"-mbstring php"${PHP_VER}"-xml libjs-jquery libjs-jquery-mousewheel libmagic1 \
|
|
sqlite3
|
|
|
|
# Install Roundcube from source if it is not already present or if it is out of date.
|
|
# Combine the Roundcube version number with the commit hash of plugins to track
|
|
# whether we have the latest version of everything.
|
|
# For the latest versions, see:
|
|
# https://github.com/roundcube/roundcubemail/releases
|
|
# https://github.com/mfreiholz/persistent_login/commits/master
|
|
# https://github.com/stremlau/html5_notifier/commits/master
|
|
# https://github.com/mstilkerich/rcmcarddav/releases
|
|
# The easiest way to get the package hashes is to run this script and get the hash from
|
|
# the error message.
|
|
VERSION=1.6.9
|
|
HASH=b63f74209cf287402f6f44b85877388899261f3c
|
|
PERSISTENT_LOGIN_VERSION=bde7b6840c7d91de627ea14e81cf4133cbb3c07a # version 5.3
|
|
HTML5_NOTIFIER_VERSION=68d9ca194212e15b3c7225eb6085dbcf02fd13d7 # version 0.6.4+
|
|
CARDDAV_VERSION=4.4.3
|
|
CARDDAV_HASH=74f8ba7aee33e78beb9de07f7f44b81f6071b644
|
|
|
|
UPDATE_KEY=$VERSION:$PERSISTENT_LOGIN_VERSION:$HTML5_NOTIFIER_VERSION:$CARDDAV_VERSION
|
|
|
|
# paths that are often reused.
|
|
RCM_DIR=/usr/local/lib/roundcubemail
|
|
RCM_PLUGIN_DIR=${RCM_DIR}/plugins
|
|
RCM_CONFIG=${RCM_DIR}/config/config.inc.php
|
|
|
|
needs_update=0 #NODOC
|
|
if [ ! -f /usr/local/lib/roundcubemail/version ]; then
|
|
# not installed yet #NODOC
|
|
needs_update=1 #NODOC
|
|
elif [[ "$UPDATE_KEY" != $(cat /usr/local/lib/roundcubemail/version) ]]; then
|
|
# checks if the version is what we want
|
|
needs_update=1 #NODOC
|
|
fi
|
|
if [ $needs_update == 1 ]; then
|
|
# if upgrading from 1.3.x, clear the temp_dir
|
|
if [ -f /usr/local/lib/roundcubemail/version ]; then
|
|
if [ "$(cat /usr/local/lib/roundcubemail/version | cut -c1-3)" == '1.3' ]; then
|
|
find /var/tmp/roundcubemail/ -type f ! -name 'RCMTEMP*' -delete
|
|
fi
|
|
fi
|
|
|
|
# install roundcube
|
|
wget_verify \
|
|
https://github.com/roundcube/roundcubemail/releases/download/$VERSION/roundcubemail-$VERSION-complete.tar.gz \
|
|
$HASH \
|
|
/tmp/roundcube.tgz
|
|
tar -C /usr/local/lib --no-same-owner -zxf /tmp/roundcube.tgz
|
|
rm -rf /usr/local/lib/roundcubemail
|
|
mv /usr/local/lib/roundcubemail-$VERSION/ $RCM_DIR
|
|
rm -f /tmp/roundcube.tgz
|
|
|
|
# install roundcube persistent_login plugin
|
|
git_clone https://github.com/mfreiholz/Roundcube-Persistent-Login-Plugin.git $PERSISTENT_LOGIN_VERSION '' ${RCM_PLUGIN_DIR}/persistent_login
|
|
|
|
# install roundcube html5_notifier plugin
|
|
git_clone https://github.com/kitist/html5_notifier.git $HTML5_NOTIFIER_VERSION '' ${RCM_PLUGIN_DIR}/html5_notifier
|
|
|
|
# download and verify the full release of the carddav plugin
|
|
wget_verify \
|
|
https://github.com/mstilkerich/rcmcarddav/releases/download/v${CARDDAV_VERSION}/carddav-v${CARDDAV_VERSION}.tar.gz \
|
|
$CARDDAV_HASH \
|
|
/tmp/carddav.tar.gz
|
|
|
|
# unzip and cleanup
|
|
tar -C ${RCM_PLUGIN_DIR} -zxf /tmp/carddav.tar.gz
|
|
rm -f /tmp/carddav.tar.gz
|
|
|
|
# record the version we've installed
|
|
echo $UPDATE_KEY > ${RCM_DIR}/version
|
|
fi
|
|
|
|
# ### Configuring Roundcube
|
|
|
|
# Generate a secret key of PHP-string-safe characters appropriate
|
|
# for the cipher algorithm selected below.
|
|
SECRET_KEY=$(dd if=/dev/urandom bs=1 count=32 2>/dev/null | base64 | sed s/=//g)
|
|
|
|
# Create a configuration file.
|
|
#
|
|
# For security, temp and log files are not stored in the default locations
|
|
# which are inside the roundcube sources directory. We put them instead
|
|
# in normal places.
|
|
cat > $RCM_CONFIG <<EOF;
|
|
<?php
|
|
/*
|
|
* Do not edit. Written by Mail-in-a-Box. Regenerated on updates.
|
|
*/
|
|
\$config = array();
|
|
\$config['log_dir'] = '/var/log/roundcubemail/';
|
|
\$config['temp_dir'] = '/var/tmp/roundcubemail/';
|
|
\$config['db_dsnw'] = 'sqlite:///$STORAGE_ROOT/mail/roundcube/roundcube.sqlite?mode=0640';
|
|
\$config['imap_host'] = 'ssl://localhost:993';
|
|
\$config['imap_conn_options'] = array(
|
|
'ssl' => array(
|
|
'verify_peer' => false,
|
|
'verify_peer_name' => false,
|
|
),
|
|
);
|
|
\$config['imap_timeout'] = 15;
|
|
\$config['smtp_host'] = 'tls://127.0.0.1';
|
|
\$config['smtp_conn_options'] = array(
|
|
'ssl' => array(
|
|
'verify_peer' => false,
|
|
'verify_peer_name' => false,
|
|
),
|
|
);
|
|
\$config['support_url'] = 'https://mailinabox.email/';
|
|
\$config['product_name'] = '$BOX_HOSTNAME Webmail';
|
|
\$config['cipher_method'] = 'AES-256-CBC'; # persistent login cookie and potentially other things
|
|
\$config['des_key'] = '$SECRET_KEY'; # 37 characters -> ~256 bits for AES-256, see above
|
|
\$config['plugins'] = array('html5_notifier', 'archive', 'zipdownload', 'password', 'managesieve', 'jqueryui', 'persistent_login', 'carddav');
|
|
\$config['skin'] = 'elastic';
|
|
\$config['login_autocomplete'] = 2;
|
|
\$config['login_username_filter'] = 'email';
|
|
\$config['password_charset'] = 'UTF-8';
|
|
\$config['junk_mbox'] = 'Spam';
|
|
/* ensure roudcube session id's aren't leaked to other parts of the server */
|
|
\$config['session_path'] = '/mail/';
|
|
/* prevent CSRF, requires php 7.3+ */
|
|
\$config['session_samesite'] = 'Strict';
|
|
?>
|
|
EOF
|
|
|
|
# Configure CardDav
|
|
cat > ${RCM_PLUGIN_DIR}/carddav/config.inc.php <<EOF;
|
|
<?php
|
|
/* Do not edit. Written by Mail-in-a-Box. Regenerated on updates. */
|
|
\$prefs['_GLOBAL']['hide_preferences'] = true;
|
|
\$prefs['_GLOBAL']['suppress_version_warning'] = true;
|
|
\$prefs['ownCloud'] = array(
|
|
'name' => 'ownCloud',
|
|
'username' => '%u', // login username
|
|
'password' => '%p', // login password
|
|
'url' => 'https://${BOX_HOSTNAME}/cloud/remote.php/dav/addressbooks/users/%u/contacts/',
|
|
'active' => true,
|
|
'readonly' => false,
|
|
'refresh_time' => '02:00:00',
|
|
'fixed' => array('username','password'),
|
|
'preemptive_auth' => '1',
|
|
'hide' => false,
|
|
);
|
|
?>
|
|
EOF
|
|
|
|
# Create writable directories.
|
|
mkdir -p /var/log/roundcubemail /var/tmp/roundcubemail "$STORAGE_ROOT/mail/roundcube"
|
|
chown -R www-data:www-data /var/log/roundcubemail /var/tmp/roundcubemail "$STORAGE_ROOT/mail/roundcube"
|
|
|
|
# Ensure the log file monitored by fail2ban exists, or else fail2ban can't start.
|
|
sudo -u www-data touch /var/log/roundcubemail/errors.log
|
|
|
|
# Password changing plugin settings
|
|
# The config comes empty by default, so we need the settings
|
|
# we're not planning to change in config.inc.dist...
|
|
cp ${RCM_PLUGIN_DIR}/password/config.inc.php.dist \
|
|
${RCM_PLUGIN_DIR}/password/config.inc.php
|
|
|
|
tools/editconf.py ${RCM_PLUGIN_DIR}/password/config.inc.php \
|
|
"\$config['password_minimum_length']=8;" \
|
|
"\$config['password_db_dsn']='sqlite:///$STORAGE_ROOT/mail/users.sqlite';" \
|
|
"\$config['password_query']='UPDATE users SET password=%P WHERE email=%u';" \
|
|
"\$config['password_algorithm']='sha512-crypt';" \
|
|
"\$config['password_algorithm_prefix']='{SHA512-CRYPT}';"
|
|
|
|
# so PHP can use doveadm, for the password changing plugin
|
|
usermod -a -G dovecot www-data
|
|
|
|
# set permissions so that PHP can use users.sqlite
|
|
# could use dovecot instead of www-data, but not sure it matters
|
|
chown root:www-data "$STORAGE_ROOT/mail"
|
|
chmod 775 "$STORAGE_ROOT/mail"
|
|
chown root:www-data "$STORAGE_ROOT/mail/users.sqlite"
|
|
chmod 664 "$STORAGE_ROOT/mail/users.sqlite"
|
|
|
|
# Fix Carddav permissions:
|
|
chown -f -R root:www-data ${RCM_PLUGIN_DIR}/carddav
|
|
# root:www-data need all permissions, others only read
|
|
chmod -R 774 ${RCM_PLUGIN_DIR}/carddav
|
|
|
|
# Run Roundcube database migration script (database is created if it does not exist)
|
|
php"$PHP_VER" ${RCM_DIR}/bin/updatedb.sh --dir ${RCM_DIR}/SQL --package roundcube
|
|
chown www-data:www-data "$STORAGE_ROOT/mail/roundcube/roundcube.sqlite"
|
|
chmod 664 "$STORAGE_ROOT/mail/roundcube/roundcube.sqlite"
|
|
|
|
# Patch the Roundcube code to eliminate an issue that causes postfix to reject our sqlite
|
|
# user database (see https://github.com/mail-in-a-box/mailinabox/issues/2185)
|
|
sed -i.miabold 's/^[^#]\+.\+PRAGMA journal_mode = WAL.\+$/#&/' \
|
|
/usr/local/lib/roundcubemail/program/lib/Roundcube/db/sqlite.php
|
|
|
|
# Because Roundcube wants to set the PRAGMA we just deleted from the source, we apply it here
|
|
# to the roundcube database (see https://github.com/roundcube/roundcubemail/issues/8035)
|
|
# Database should exist, created by migration script
|
|
hide_output sqlite3 "$STORAGE_ROOT/mail/roundcube/roundcube.sqlite" 'PRAGMA journal_mode=WAL;'
|
|
|
|
# Enable PHP modules.
|
|
phpenmod -v "$PHP_VER" imap
|
|
restart_service php"$PHP_VER"-fpm
|