#!/usr/bin/env bash ## =================================================================== ## - Install/Update Dovecot Server ## =================================================================== ## ----------------------------------------------------------------- ## ---------------------------------------------------------------- ## --- ## --- For configurations see file conf/install_update_dovecot.conf ## --- ## --- Dont make changes here! ## --- ## ----------------------------------------------------------------- ## ----------------------------------------------------------------- # ------------- # - Settings # ------------- _src_base_dir="$(realpath $(dirname $0))" conf_file="${_src_base_dir}/conf/install_update_dovecot.conf" curdir=`pwd` log_file="$(mktemp)" backup_date="$(date +%Y-%m-%d-%H%M)" _backup_crontab_file="/tmp/crontab_root.${backup_date}" rc_done="\033[71G[ \033[32mdone\033[m ]" rc_failed="\033[71G[ \033[31m\033[1mfailed\033[m ]" rc_skipped="\033[71G[ \033[33m\033[1mskipped\033[m ]" rc_wait="\033[71G[ \033[5m\033[1m..\033[m ]" # ------------- # - Functions an Variable # ------------- clean_up() { if [[ -f "$_backup_crontab_file" ]]; then echononl "(Re)Install previously saved crontab from '$_backup_crontab_file'.." crontab $_backup_crontab_file >> $log_file 2>&1 if [[ $? -eq 0 ]]; then echo -e "$rc_done" else echo -e "$rc_failed" error "$(cat $log_file)" fi fi # Perform program exit housekeeping rm -f $log_file blank_line exit $1 } echononl(){ echo X\\c > /tmp/shprompt$$ if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then echo -e "$*\\c" 1>&2 else echo -en "$*" 1>&2 fi rm /tmp/shprompt$$ } fatal(){ echo "" echo -e "\t[ \033[31m\033[1mFatal\033[m ]: \033[37m\033[1m$*\033[m" echo "" echo -e "\t\033[31m\033[1m Skript wird abgebrochen\033[m\033[m\n" rm -f $log_file clean_up 1 } error(){ echo "" echo -e "\t[ \033[31m\033[1mError\033[m ]: $*" echo "" } warn(){ echo "" echo -e "\t[ \033[33m\033[1mWarning\033[m ]: $*" echo "" } info(){ echo "" echo -e "\t[ \033[32m\033[1mInfo\033[m ]: $*" echo "" } blank_line() { echo "" } # - Support systemd ? # - if [[ "X$(which systemd)" = "X" ]]; then SYSTEMD_EXISTS=false else SYSTEMD_EXISTS=true fi echo echononl "\tInclude Configuration file.." if [[ ! -f $conf_file ]]; then echo -e "$rc_failed" fatal "Missing configuration file '$conf_file'" else source $conf_file echo -e "$rc_done" fi if [[ -z "$systemd_support" ]] ; then if $SYSTEMD_EXISTS ; then systemd_support=true else systemd_support=false fi fi ## - Required parameters ## - [[ -n "$_update" ]] || fatal "Parameter "_update" not set." [[ -n "$postmaster_address" ]] || fatal "Parameter "postmaster_address" not set." [[ -n "$hostname" ]] || fatal "Missing value for parameter 'hostname'." [[ -n "$ipv4" ]] || fatal "Missing value for parameter 'ipv4'." [[ -n "$ipv6" ]] || warn "Missing value for parameter 'ipv6'." [[ -n "$database" ]] || fatal "Parameter "database" not set." if [[ "$database" != "postgres" ]] && [[ "$database" != "mysql" ]] ; then fatal "Wrong value for parameter 'database' ({$database}). Only 'mysql' or 'postgres' is allowed." fi [[ -n "$dbpassword" ]] || fatal "Parameter "dbpassword" not set." [[ -n "$from_address" ]] || fatal ""Parameter "from_address" not set."" [[ -n "$reply_to" ]] || fatal ""Parameter "reply_to" not set."" [[ -n "$webmailer" ]] || fatal ""Parameter "webmailer" not set."" [[ -n "$salutation" ]] || fatal ""Parameter "salutation" not set."" ## - Some defaults if missing ## - if [[ -n "$ipv6" ]] ; then [[ -n "$imap_listener_adresses" ]] || imap_listener_adresses="127.0.0.1 $ipv4 $ipv6" [[ -n "$imaps_listener_adresses" ]] || imaps_listener_adresses="$ipv4 $ipv6" [[ -n "$pop_listener_adresses" ]] || pop_listener_adresses="$ipv4 $ipv6" [[ -n "$pops_listener_adresses" ]] || pops_listener_adresses="$ipv4 $ipv6" else [[ -n "$imap_listener_adresses" ]] || imap_listener_adresses="127.0.0.1 $ipv4" [[ -n "$imaps_listener_adresses" ]] || imaps_listener_adresses="$ipv4" [[ -n "$pop_listener_adresses" ]] || pop_listener_adresses="$ipv4" [[ -n "$pops_listener_adresses" ]] || pops_listener_adresses="$ipv4" fi [[ -n "$xmpp_listener" ]] || xmpp_listener=false if $xmpp_listener ; then # Be compartible with older installations [[ -n "$xmpp_listener_address" ]] && xmpp_listener_addresses="$xmpp_listener_address" [[ -n "$xmpp_listener_addresses" ]] || xmpp_listener_addresses="127.0.0.1 $ipv4" [[ -n "$xmpp_listener_port" ]] || xmpp_listener_port="44444" fi [[ -n "$http_user" ]] || http_user="www-data" [[ -n "$dbname" ]] || dbname="postfix" [[ -n "$dbuser" ]] || dbuser="postfix" if [[ -z "$dbhost" ]] ; then [[ "$dbhost" = "mysql" ]] && dbhost="127.0.0.1" [[ "$dbhost" = "postgres" ]] && dbhost="/var/run/postgresql" fi [[ -n "$cert_base_dir" ]] || cert_base_dir="/etc/dovecot/ssl" [[ -n "$server_cert" ]] || server_cert="${cert_base_dir}/mailserver.crt" [[ -n "$server_key" ]] || server_key="${cert_base_dir}/mailserver.key" [[ -n "$dh_pem_file" ]] || dh_pem_file="${cert_base_dir}/dh_4096.pem" [[ -n "$imap_cert" ]] || imap_cert="${cert_base_dir}/mailserver.crt" [[ -n "$imap_key" ]] || imap_key="${cert_base_dir}/mailserver.key" [[ -n "$pop_cert" ]] || pop_cert="${cert_base_dir}/mailserver.crt" [[ -n "$pop_key" ]] || pop_key="${cert_base_dir}/mailserver.key" [[ -n "$default_pass_scheme" ]] || default_pass_scheme="PLAIN" [[ -n "$spam_folder" ]] || spam_folder="Spam" [[ -n "$max_userip_connections" ]] || max_userip_connections=24 [[ -n "$auth_mechanisms" ]] || auth_mechanisms="plain login" declare -i dovecot_major_version=0 declare -i dovecot_minor_version=0 declare -i dovecot_patch_level=0 echo -e "\033[32m--\033[m" echo "" echo "Version Number of Dovecot to install" echo "" echo "" _version= while [ "X$_version" = "X" ] do echononl "Dovecot Version: " read _version if [ "X$_version" = "X" ]; then echo -e "\n\t\033[33m\033[1mA version number is required!\033[m\n" fi done dovecot_main_version="$(echo $_version | cut -d '.' -f1,2)" dovecot_major_version="$(echo $_version | cut -d '.' -f1)" dovecot_minor_version="$(echo $_version | cut -d '.' -f2)" dovecot_patch_level="$(echo $_version | cut -d '.' -f3)" #echo "" #echo "_version: $_version" #echo "dovecot_main_version $dovecot_main_version" #echo "dovecot_major_version $dovecot_major_version" #echo "dovecot_minor_version $dovecot_minor_version" #echo "dovecot_patch_level $dovecot_patch_level" #echo "" # 'expire plugin'was rRemoved in version 2.3.14: This plugin is not needed. # Use mailbox { autoexpunge } Mailbox settings instead. # if [[ $dovecot_major_version -gt 2 ]] \ || ( [[ $dovecot_major_version -eq 2 ]] \ && [[ $dovecot_minor_version -gt 3 ]] \ ) \ || ( [[ $dovecot_major_version -eq 2 ]] \ && [[ $dovecot_minor_version -eq 3 ]] \ && [[ $dovecot_patch_level -gt 13 ]] \ ) ; then plugin_expire=false else plugin_expire=true fi #if $plugin_expire ; then # info "Install plugin 'expire'.." #else # warn "Plugin 'expire' is no longer supported.." #fi #exit 0 _log_dir=${_src_base_dir}/log-dovecot-$_version echo "" echo -e "\033[32m--\033[m" echo "" echo "Version Number of Pigeonhole to install" echo "" echo "" _pigeonhole= while [ "X$_pigeonhole" = "X" ] do echononl "Pigeonhole Version: " read _pigeonhole if [ "X$_pigeonhole" = "X" ]; then echo -e "\n\t\033[33m\033[1mA version number is required!\033[m\n" fi done echo "" echo -e "\033[32m--\033[m" echo "" echo "Is this a fresh new installation or an update?" echo "" echo "" if [[ -n "$_update" ]]; then if $_update || [[ "${_update,,}" = 'yes' ]] ; then echo -e "\033[37m\033[1m[1] Update\033[m" echo "[2] New Installation" else echo -e "[1] Update" echo -e "\033[37m\033[1m[2] New Installation\033[m" fi echo "" echononl "Choose a number or press for highlighted value: " else echo -e "[1] Update" echo "[2] New Installation" echo "" echononl "Choose a Number: " fi update="" while [[ "$update" != "true" && "$update" != "false" ]] ; do read OPTION case $OPTION in 1) update=true ;; 2) update=false ;; '') if [[ -n "$_update" ]] ; then if $_update || [[ "${_update,,}" = 'yes' ]] ; then update=true else update=false fi else echo "" echo -e "\tWrong entry! [ 1 = Update ; 2 = New Installation ]" echo "" echononl "Reentry: " fi ;; *) update="" echo "" if [[ -n "$_IS_RELAY_HOST" ]]; then echo -e "\tWrong entry! [ 1 = Update ; 2 = New Installation ] or type " else echo -e "\tWrong entry! [ 1 = Update ; 2 = New Installation ]" fi echo "" echononl "Reentry: " ;; esac done # ------------- # - List Script Configurations # ------------- clear; echo "" if $update ;then echo -e "\tUpdate Dovecot................: $update" else echo -e "\tInstall Dovecot first time....: Yes" fi echo "" echo -e "\tDovecot (new) version.........: $_version" echo -e "\t(Sieve) pigeonhole version....: $_pigeonhole" echo "" echo -e "\tSystemd support...............: $systemd_support" echo "" echo -e "\tSFolder containing sources....: $_src_base_dir" echo "" echo -e "\tPostmaser adress..............: $postmaster_address" echo -e "\tHostname......................: $hostname" echo "" echo -e "\tIPv4 address..................: $ipv4" echo -e "\tIPv6 address..................: $ipv6" echo "" echo -e "\tIMAP listener addresses.......: $imap_listener_adresses" echo -e "\tIMAPS listener addresses......: $imaps_listener_adresses" echo "" echo -e "\tPOP3 listener addresses.......: $pop_listener_adresses" echo -e "\tPOP3S listener addresses......: $pops_listener_adresses" echo "" echo -e "\tDatenbank.....................: $database" echo "" echo -e "\tPostfix database host.........: $dbhost" echo -e "\tPostfix database name.........: $dbname" echo -e "\tPostfix database user.........: $dbuser" echo -e "\tPostfix database password.....: $dbpassword" echo "" echo -e "\tDefault password scheme.......: $default_pass_scheme" echo "" echo -e "\tCertificat base directory.....: $cert_base_dir" echo -e "\tServer certificate............: $server_cert" echo -e "\tServer key....................: $server_key" if [[ $dovecot_major_version -ge 3 ]] \ || ( [[ $dovecot_major_version -eq 2 ]] && [[ $dovecot_minor_version -ge 3 ]] ); then echo -e "\tDH Parameters file............: $dh_pem_file" fi echo "" echo -e "\tImap certificate..............: $imap_cert" echo -e "\tImap key......................: $imap_key" echo "" echo -e "\tPop certificate...............: $pop_cert" echo -e "\tPop key.......................: $pop_key" echo "" echo -e "\tSpan folder...................: $spam_folder" echo -e "\tMax user connections per ip...: $max_userip_connections" echo "" echo -e "\tAuth Listener (Jabber)........: $xmpp_listener" if $xmpp_listener ; then echo -e "\t Auth Listener Addresses....: $xmpp_listener_addresses" echo -e "\t AUTH Listener PORT.........: $xmpp_listener_port" fi echo "" echo -e "\tInstall Plugin 'expire'.......: $plugin_expire" echo "" if ! $update ;then if [[ "$database" = "psql" ]] || [[ "$database" = "postgres" ]]; then warn "Take care, your PostgreSQL configuration (pg_hba.conf) contains the following line:\n\n\t pg_hba.conf:\n\t \033[1mlocal all postfix trust\033[m" fi fi echononl "Sind die Angaben richtig [ja/nein]: " read OK while [ "X$OK" != "Xyes" -a "X$OK" != "XYes" -a "X$OK" != "Xja" -a "X$OK" != "XJa" \ -a "X$OK" != "XNo" -a "X$OK" != "Xno" -a "X$OK" != "Xn" -a "X$OK" != "Xnein" -a "X$OK" != "XNein" ] do echononl "falsche Angabe! [ja/nein] :" read OK done [ $OK = "Yes" -o $OK = "yes" -o "$OK" = "ja" -o "$OK" = "Ja" ] || fatal "Edit '$(basename $conf_file)' and correct variables" ## - Let make use multiple cores (-j) ## - export MAKEFLAGS=-j$(expr `grep "^processor" /proc/cpuinfo | sort -u | wc -l` - 1) # ------------- # - Begin Install/Update # ------------- echo "" if $update ;then _new=false; else _new=true; fi if [ "$database" = "mysql" ]; then db_driver=mysql else db_driver=pgsql fi if $_new ; then if [ "$database" = "mysql" ]; then echo "" echo "--" echo "" echo "Gib den Benutzernamen des/eines MySQL root user an.." echo "" _MYSQL_ROOT_USER=root MYSQL_ROOT_USER= while [ "X$MYSQL_ROOT_USER" = "X" ] do echononl "MySQL-User [${_MYSQL_ROOT_USER}]: " read MYSQL_ROOT_USER if [ "X$MYSQL_ROOT_USER" = "X" ]; then MYSQL_ROOT_USER=$_MYSQL_ROOT_USER fi done echo "" echo "--" echo "" echo "Gib ein Passwort für den root user an.." echo "" _MYSQL_ROOT_PW_1="X" _MYSQL_ROOT_PW_2="Y" while [ "$_MYSQL_ROOT_PW_1" != "$_MYSQL_ROOT_PW_2" ] do echononl "Passworteingabe: " read -s _MYSQL_ROOT_PW_1 echo if [ "X$_MYSQL_ROOT_PW_1" = "X" ]; then echo -e "\n\t\033[33m\033[1mPassworteingabe erforderlich!\033[m\n" continue fi echononl "Passwortwiederholung: " read -s _MYSQL_ROOT_PW_2 echo if [ "X$_MYSQL_ROOT_PW_2" = "X" ]; then echo -e "\n\t\033[33m\033[1mPasswortwiederholung erforderlich!\033[m\n" continue fi if [ "$_MYSQL_ROOT_PW_1" != "$_MYSQL_ROOT_PW_2" ];then echo -e "\n\t\033[33m\033[1mPassworteingaben sind nicht identisch!\033[m\n" else MYSQL_ROOT_PW=$_MYSQL_ROOT_PW_1 fi done fi fi export PGPASSWORD=$dbpassword echo "Doing some backups.." echononl "\tBackup existing installation log directory.." if [[ -d "${_log_dir}" ]]; then mv "${_log_dir}" "${_log_dir}.${backup_date}" if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "Cannot Backup (move) directory '${_log_dir}'" fi else echo -e "$rc_skipped" fi echononl "\tBackup existing installation directory.." if [[ -d "/usr/local/dovecot-${_version}" ]]; then mv "/usr/local/dovecot-${_version}" "/usr/local/dovecot-${_version}.${backup_date}" if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "Cannot Backup (move) directory '${_log_dir}'" echononl "Proceed instllation [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/nno]: " read OK done [[ $OK = "yes" ]] || fatal "Abbruch durch User" fi else echo -e "$rc_skipped" fi echononl "\tBackup existing source directory.." if [[ -d "${_src_base_dir}/dovecot-${_version}" ]]; then mv "${_src_base_dir}/dovecot-${_version}" "${_src_base_dir}/dovecot-${_version}.${backup_date}" if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "Cannot Backup (move) directory '${_src_base_dir}/dovecot-${_version}'" echononl "Proceed instllation [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/nno]: " read OK done [[ $OK = "yes" ]] || fatal "Abbruch durch User" fi else echo -e "$rc_skipped" fi mkdir -p $_log_dir ## ----------------- ## --- Download cd ${_src_base_dir} echo "" echo -e "\033[1mDownload sources\033[m.." ## - Downloud Dovecot 2.2.x ## - echononl "\tDownload dovecot-${_version}.tar.gz" if [ ! -f "${_src_base_dir}/dovecot-${_version}.tar.gz" ]; then wget --no-check-certificate https://dovecot.org/releases/${dovecot_main_version}/dovecot-${_version}.tar.gz > /dev/null 2>&1 if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "Direct download of 'dovecot-${_version}.tar.gz' failed Download \033[1mdovecot-${_version}.tar.gz\033[m manually and proceed instllation." echononl "Proceed instllation [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/nno]: " read OK done [[ $OK = "yes" ]] || fatal "Abbruch durch User" fi else echo -e "$rc_skipped" fi ## - Download Pigeonhole for Dovecot v2.2 ## - echononl "\tDownload dovecot-${dovecot_main_version}-pigeonhole-${_pigeonhole}.tar.gz.." if [ ! -f "${_src_base_dir}/dovecot-${dovecot_main_version}-pigeonhole-${_pigeonhole}.tar.gz" ]; then wget --no-check-certificate https://pigeonhole.dovecot.org/releases/${dovecot_main_version}/dovecot-${dovecot_main_version}-pigeonhole-${_pigeonhole}.tar.gz > /dev/null 2>&1 if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "Direct download of 'dovecot-${dovecot_main_version}-pigeonhole-${_pigeonhole}.tar.gz' failed Download \033[1mdovecot-${dovecot_main_version}-pigeonhole-${_pigeonhole}.tar.gz\033[m manually and proceed instllation." echononl "\tProceed instllation [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/nno]: " read OK done [[ $OK = "yes" ]] || fatal "Abbruch durch User" fi else echo -e "$rc_skipped" fi if $_new ; then ## - Install reqired debian packages ## - echo "" echo "Installing required debian packages.." echononl "\tInstalling libpq5 libpq-dev .." if ! dpkg -l libpq-dev | grep -e "^ii" | grep libpq-dev > /dev/null ; then apt-get install libpq5 libpq-dev > ${_log_dir}/debian-install.log 2&>1 if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "installing debian package(s) failed" fi else echo -e "$rc_skipped" fi echononl "\tInstalling libkrb5-dev .." if ! dpkg -l libkrb5-dev | grep -e "^ii" | grep libkrb5-dev > /dev/null ; then apt-get install libkrb5-dev >> ${_log_dir}/debian-install.log 2&>1 if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "installing debian package(s) failed" fi else echo -e "$rc_skipped" fi fi ## ----------------- ## - Create Users/groups needed for dovecot echo "" echo -e "\033[1mCreate required users/groups\033[m.." echononl "\tCreate group dovecot.." if ! grep dovecot /etc/group > /dev/null ; then addgroup --system --gid 91 dovecot > ${_log_dir}/system.log 2>&1 if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal Create group failed fi else echo -e "$rc_skipped" fi echononl "\tCreate user dovecot.." if ! grep dovecot /etc/passwd > /dev/null ; then adduser --system --home /var/empty --no-create-home --shell /usr/sbin/nologin \ --ingroup dovecot --uid 91 dovecot > ${_log_dir}/system.log 2>&1 if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal Create user failed fi else echo -e "$rc_skipped" fi echononl "\tAdd Apache User (${http_user}) to group 'dovecot'.." if getent group dovecot 2> /dev/null | grep -q "\b${http_user}\b" > /dev/null 2>&1 ; then echo -e "$rc_skipped" else usermod -a -G dovecot $http_user > ${_log_dir}/system.log 2>&1 if [[ $? -eq 0 ]] ; then echo -e "$rc_done" else echo -e "$rc_failed" error "Failed to add Apache User (${http_user}) to group 'dovecot'!" fi fi echononl "\tCreate group dovenull.." if ! grep dovenull /etc/group > /dev/null ; then addgroup --system --gid 65533 dovenull > ${_log_dir}/system.log 2>&1 if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal Create group failed fi else echo -e "$rc_skipped" fi echononl "\tCreate user dovenull.." if ! grep dovenull /etc/passwd > /dev/null ; then adduser --system --home /var/empty --no-create-home --shell /usr/sbin/nologin \ --ingroup dovenull --uid 65533 dovenull > ${_log_dir}/system.log 2>&1 if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal Create user failed fi else echo -e "$rc_skipped" fi if $update ; then # - Deaktiviere Cronjobs # - echo "" echononl "\tBackup Crontab (user toot) to '$_backup_crontab_file'" crontab -l > $_backup_crontab_file 2> $log_file if [[ $? -eq 0 ]]; then echo -e "$rc_done" else echo -e "$rc_failed" error "Backup Crontab to '$_backup_crontab_file' failed" # If no crontab was present, the backup file contains # th string "no crontab fo root". Better to delete the # backup crontab file.. # rm -f $_backup_crontab_file fi echononl "\tRemove crontab for user root.." crontab -r > $log_file 2>&1 if [[ $? -eq 0 ]]; then echo -e "$rc_done" else echo -e "$rc_failed" error "" fi fi ## ----------------- ## --- Install Base System echo "" echo -e "\033[1mInstalling Base System\033[m.." ## - Unpack dovecot sources ## - cd ${_src_base_dir} echononl "\tUnpack dovecot-${_version}.tar.gz.." tar -xzf dovecot-${_version}.tar.gz > /dev/null if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal Extracting dovecot failed fi cd dovecot-${_version} ## - Configure dovecot ## - config_params=" --prefix=/usr/local/dovecot-${_version} \ --with-${db_driver} \ --with-gssapi=yes --with-rundir=/var/run/dovecot" if $systemd_support ; then config_params="$config_params \ --with-systemdsystemunitdir=/etc/systemd/system/" fi echononl "\tConfigure Dovecot.." #./configure \ # --prefix=/usr/local/dovecot-${_version} \ # --with-${db_driver} \ # --with-gssapi=yes > ${_log_dir}/dovecot-${_version}-configure.log 2>&1 #--with-systemdsystemunitdir=/etc/systemd/system \ LDFLAGS="-s" \ ./configure $config_params > ${_log_dir}/dovecot-${_version}-configure.log 2>&1 if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal Configuring dovecot failed fi ## - Compile dovecot ## - echononl "\tCompile Dovecot Sources.." make > ${_log_dir}/dovecot-${_version}-make.log 2>&1 || clean_up 1 if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal Compiling dovecot failed fi ## ----------------- ## --- Stop dovecot if running echononl "\tStop dovecot service.." if ps ax 2> /dev/null | grep -q -E "/usr/local/dovecot[0-9.-]*/sbin/dovecot" > /dev/null 2>&1 ; then if $systemd_support ; then systemctl stop dovecot > /dev/null 2>&1 else /etc/init.d/dovecot stop > /dev/null 2>&1 fi if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "Stopping dovecot service failed" fi else echo -e "$rc_skipped" fi ## - Install dovecot ## - echononl "\tInstall Dovecot into Folder /usr/local/dovecot-${_version}" make install > ${_log_dir}/dovecot-${_version}-install.log 2>&1 || clean_up 1 if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal Installing dovecot failed fi ## - Add /usr/local/dovecot/bin to PATH variable ## - ## - Edit /etc/profile and add bevor "export PATH" directive: ## - ## - checkdir="/usr/local/dovecot/bin" ## - if [ -d $checkdir ]; then ## - PATH=$PATH:$checkdir ## - fi ## - echononl "\tAdd /usr/local/dovecot/bin to PATH variable.." if ! grep "checkdir=\"/usr/local/dovecot/bin\"" /etc/profile > /dev/null ; then perl -i -n -p -e "s#^(\s*)(export\ +PATH)#checkdir=\"/usr/local/dovecot/bin\"\nif [ -d \\\$checkdir ]; then\n PATH=\\\$PATH:\\\$checkdir\nfi\n\n\1\2#" /etc/profile if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal Adjusting /etc/profile failed fi else echo -e "$rc_skipped" fi echononl "\tCopy Manpages if not exists.." ## - Manpages ## - if ! grep /usr/local/dovecot/share/man /etc/manpath.config > /dev/null 2<&1 ; then echo >> /etc/manpath.config echo "MANDATORY_MANPATH /usr/local/dovecot/share/man /var/cache/man" >> /etc/manpath.config echo "MANPATH_MAP /usr/local/dovecot/bin /usr/local/dovecot/share/man" >> /etc/manpath.config echo "MANDB_MAP /usr/local/dovecot/share/man /var/cache/man" >> /etc/manpath.config echo -e "$rc_done" else echo -e "$rc_skipped" fi ## ----------------- ## --- Install Pigeonhole ManageSieve cd ${_src_base_dir} echo "" echononl "\tExtracting dovecot-${dovecot_main_version}-pigeonhole-${_pigeonhole}.tar.gz.." gunzip < dovecot-${dovecot_main_version}-pigeonhole-${_pigeonhole}.tar.gz | tar -xf - if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal Extracting dovecot-${dovecot_main_version}-pigeonhole-${_pigeonhole}.tar.gz failed fi cd dovecot-${dovecot_main_version}-pigeonhole-${_pigeonhole} echononl "\tConfigure Pigeonhole ManageSieve.." ./configure \ --prefix=/usr/local/dovecot-${_version} \ --with-dovecot=/usr/local/dovecot-${_version}/lib/dovecot > ${_log_dir}/dovecot-${dovecot_main_version}-pigeonhole-${_pigeonhole}-configure.log 2<&1 if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal Configuring Pigeonhole ManageSieve failed fi echononl "\tCompile Pigeonhole ManageSieve.." make > ${_log_dir}/dovecot-${dovecot_main_version}-pigeonhole-${_pigeonhole}-make.log 2<&1 if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal Compiling Pigeonhole ManageSieve failed fi echononl "\tInstall Pigeonhole ManageSieve.." make install > ${_log_dir}/dovecot-${dovecot_main_version}-pigeonhole-${_pigeonhole}-install.log 2<&1 if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal Installing Pigeonhole ManageSieve failed fi ## ----------------- ## --- Configure dovecot services _failed=false echo "" echo -e "\033[1mConfigure Dovecot\033[m.." ## - Copy example config files to the config directory ## - cp -r /usr/local/dovecot-${_version}/share/doc/dovecot/example-config/* \ /usr/local/dovecot-${_version}/etc/dovecot/ ## - edit /usr/local/dovecot/etc/dovecot/dovecot.conf ## - ## - protocols = imap pop3 sieve ## - listen = $ipv4 $ipv6 ## - base_dir = /var/run/dovecot/ ## - state_dir = /var/run/dovecot ## - shutdown_clients = no ## - ## - dict { ## - expire = $db_driver:/usr/local/dovecot/etc/dovecot/sql-dict.conf.ext ## - } ## - echononl "\tAdjust file dovecot.conf.." if [[ -n "$ipv6" ]]; then perl -i.ORIG -n -p -e "s#^([ ]*)\#?\ ?(listen\ ?=.*)#\1\#\# \2\n\1listen = $ipv4 $ipv6#g" \ /usr/local/dovecot-${_version}/etc/dovecot/dovecot.conf || _failed=true else perl -i.ORIG -n -p -e "s#^([ ]*)\#?\ ?(listen\ ?=.*)#\1\#\# \2\n\1listen = $ipv4#g" \ /usr/local/dovecot-${_version}/etc/dovecot/dovecot.conf || _failed=true fi perl -i -n -p -e "s#^([ ]*)\#?\ ?(protocols\ ?=.*)#\1\#\# \2\n\1protocols = imap pop3 sieve#g" \ /usr/local/dovecot-${_version}/etc/dovecot/dovecot.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(base_dir\ ?=.*)#\1\#\# \2\n\1base_dir = /var/run/dovecot/\n\nstate_dir = /var/run/dovecot#g" \ /usr/local/dovecot-${_version}/etc/dovecot/dovecot.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(shutdown_clients\ ?=.*)#\1\#\# \2\n\1shutdown_clients = no#g" \ /usr/local/dovecot-${_version}/etc/dovecot/dovecot.conf || _failed=true if $plugin_expire ; then perl -i -n -p \ -e "s#^([ ]*)(dict\ +{.*)#\1\2\n\1 expire = $db_driver:/usr/local/dovecot/etc/dovecot/sql-dict.conf.ext#g" \ /usr/local/dovecot-${_version}/etc/dovecot/dovecot.conf || _failed=true fi if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/dovecot.conf failed" fi if $_new ; then if [ "$db_driver" = "pgsql" ]; then echononl "\tCheck if database '$dbname' already exists.." count=`su - postgres -c "psql -q -A -t -l" 2> ${_log_dir}/error.log | grep -c -e "^$dbname"` if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "Checking existence of database '$dbname' failed!" echononl "\tcontinue anyway [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/nno]: " read OK done [[ $OK = "yes" ]] || fatal "Abbruch durch User" fi if [ $count -eq 0 ];then echononl "\tCreate database user ${dbuser}.." echo "CREATE ROLE $dbuser WITH LOGIN NOCREATEDB NOCREATEROLE NOSUPERUSER ENCRYPTED PASSWORD '$dbpassword'" \ | su - postgres -c "psql" > /dev/null 2>&1 if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal Creating database user $dbuser failed fi echononl "\tCreate database ${dbname}.." su - postgres -c "createdb -E utf8 -O ${dbuser} $dbname" if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal Creating database $dbname failed fi fi ## - Create table expires in database ${dbname} ## - echononl "\tCreate table expires in database ${dbname}.." if $plugin_expire ; then cat << EOF | psql -U$dbuser $dbname > ${_log_dir}/error.log 2>&1 CREATE TABLE IF NOT EXISTS expires ( username varchar(100) not null, mailbox varchar(255) not null, expire_stamp integer not null, primary key (username, mailbox) ); EOF if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "$(cat ${_log_dir}/error.log)" echononl "\tcontinue anyway [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/nno]: " read OK done [[ $OK = "yes" ]] || fatal "Abbruch durch User" fi else echo -e "$rc_skipped" fi echononl "\tCreate function merge_expires() / trigger mergeexpires.." if $plugin_expire ; then cat << EOF | psql -U$dbuser $dbname > /dev/null 2>&1 CREATE LANGUAGE plpgsql; create or replace function merge_expires() returns trigger as \$\$ begin update expires set expire_stamp = new.expire_stamp where username = new.username and mailbox = new.mailbox; if found then return null; else return new; end if; end; \$\$ language plpgsql; create trigger mergeexpires before insert on expires for each row execute procedure merge_expires(); EOF if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "$(cat ${_log_dir}/error.log)" echononl "\tcontinue anyway [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/nno]: " read OK done [[ $OK = "yes" ]] || fatal "Abbruch durch User" fi else echo -e "$rc_skipped" fi elif [ "$db_driver" = "mysql" ]; then if ! mysql -u$MYSQL_ROOT_USER -p$MYSQL_ROOT_PW -N -s -e \ "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '$dbname'" 2>/dev/null \ | grep $_db_name > /dev/null 2>&1 ; then echononl "\tCreate database ${dbname}.." mysql -u$MYSQL_ROOT_USER -p$MYSQL_ROOT_PW -N -s -e \ "CREATE DATABASE IF NOT EXISTS $dbname CHARACTER SET utf8 COLLATE utf8_general_ci" > ${_log_dir}/error.log 2>&1 if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "$(cat ${_log_dir}/error.log)" echononl "\tcontinue anyway [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/nno]: " read OK done [[ $OK = "yes" ]] || fatal "Abbruch durch User" fi echononl "\tCreate database user ${dbuser}.." mysql -u$MYSQL_ROOT_USER -p$MYSQL_ROOT_PW -N -s -e \ "GRANT ALL ON ${dbname}.* TO '${dbuser}'@'localhost' IDENTIFIED BY '$dbpassword'" > ${_log_dir}/error.log 2>&1 if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "$(cat ${_log_dir}/error.log)" echononl "\tcontinue anyway [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/nno]: " read OK done [[ $OK = "yes" ]] || fatal "Abbruch durch User" fi echononl "\tFlushing database privileges.." mysql -u$MYSQL_ROOT_USER -p$MYSQL_ROOT_PW -N -s -e "FLUSH PRIVILEGES" > ${_log_dir}/error.log 2>&1 if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "$(cat ${_log_dir}/error.log)" echononl "\tcontinue anyway [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/nno]: " read OK done [[ $OK = "yes" ]] || fatal "Abbruch durch User" fi fi ## - Create table expires in database ${dbname} ## - echononl "\tCreate table expires in database ${dbname}.." if $plugin_expire ; then cat << EOF | mysql -u$dbuser -p$dbpassword $dbname > /dev/null 2>&1 CREATE TABLE IF NOT EXISTS expires ( username varchar(100) not null, mailbox varchar(255) not null, expire_stamp integer not null, primary key (username, mailbox) ); EOF if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "Creating table expires failed" fi else echo -e "$rc_skipped" fi fi fi ## - create sql-dict.conf.ext file ## - echononl "\tCreate file sql-dict.conf.ext with plugin 'expire'.." if $plugin_expire ; then if [ "$db_driver" = "pgsql" ]; then cat </usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext connect = host=$dbhost user=$dbuser password=$dbpassword dbname=$dbname # CREATE TABLE expires ( # username varchar(100) not null, # mailbox varchar(255) not null, # expire_stamp integer not null, # primary key (username, mailbox) # ); ## - if using postgres, you need also to create a trigger as follows: ## - ## - first create language plpgsql if not yet created: ## - # CREATE LANGUAGE plpgsql; # # CREATE OR REPLACE FUNCTION merge_expires() RETURNS TRIGGER AS \$\$ # BEGIN # UPDATE expires SET expire_stamp = NEW.expire_stamp # WHERE username = NEW.username AND mailbox = NEW.mailbox; # IF FOUND THEN # RETURN NULL; # ELSE # RETURN NEW; # END IF; # END; # \$\$ LANGUAGE plpgsql; # # CREATE TRIGGER mergeexpires BEFORE INSERT ON expires # FOR EACH ROW EXECUTE PROCEDURE merge_expires(); map { pattern = shared/expire/\$user/\$mailbox table = expires value_field = expire_stamp fields { username = \$user mailbox = \$mailbox } } EOF if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Creating file sql-dict.conf.ext failed" fi elif [ "$db_driver" = "mysql" ]; then ## - create sql-dict.conf.ext file ## - echononl "\tCreate file sql-dict.conf.ext" cat </usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext # CREATE TABLE expires ( # username varchar(100) not null, # mailbox varchar(255) not null, # expire_stamp integer not null, # primary key (username, mailbox) # ); map { pattern = shared/expire/\$user/\$mailbox table = expires value_field = expire_stamp fields { username = \$user mailbox = \$mailbox } } EOF if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Creating file sql-dict.conf.ext failed" fi fi else echo -e "$rc_skipped" fi ## - edit /usr/local/dovecot/etc/dovecot/conf.d/10-master.conf ## - ## - default_process_limit = 1024 ## - default_client_limit = 10240 ## - ## - default_vsz_limit = 512M ## - ## - !! Bemerkung !! ## - ## - Das Hochsetzen des default_client_limit Parameters auf einen Wert größer ## - als 1024 geht nur dann wenn auch die Anzahl der zulässigen "open files" ## - (default = 1024) geändert wird. ## - ## - ## - Systemd System: ## - =============== ## - ## - In der service datei (z.Bsp. /etc/systemd/system/multi-user.target.wants/dovecot.service) ## - den Wert 'LimitNOFILE' hochsetzen: ## - ## - LimitNOFILE=32768 (must be greater or equal of 'default_client_limit') ## - ## - systemctl daemon-reload ## - systemctl restart dovecot.service ## - ## - Im Falle von LX containern muss zusätzlich auf dem hostsystem ## - in der datei '/etc/systemd/system.conf' der Wert für 'DefaultLimitNOFILE' ## - hochgesetzt werden. ## - ## - System V systems: ## - ================= ## - Das Hochsetzen des default_client_limit Parameters auf einen Wert größer ## - als 1024 geht nur dann wenn auch die Anzahl der zulässigen "open files" ## - (default = 1024) geändert wird. Z.Bsp. in der Datei /etc/init.d/dovecot ## - durch Einfügen der zeile: ## - ulimit -n 32768 ## - ## - Linux VServer: ## - put the following lines into /etc/security/limits.conf ## - ## - @staff hard nofile 32768 ## - root hard nofile 32768 ## - ## - !! Mybe you have also create file /etc/vservers/*/ulimits/nofiles.hard ## - with the same contents: ## - ## - @staff hard nofile 32768 ## - @adm hard nofile 32768 ## - root hard nofile 32768 ## - ## - see also http://linux-vserver.org/Ulimit_Nofiles ## - ## - ## - ## - service auth { ## - ## - # Auth Listener (XMPP - Jabber) ## - inet_listener { ## - address = $xmpp_listener_addresses ## - port = $xmpp_listener_port ## - } ## - .. ## - unix_listener auth-userdb { ## - mode = 0666 ## - user = dovecot ## - group = dovecot ## - } ## - .. ## - unix_listener /var/spool/postfix/private/dovecot-auth { ## - mode = 0666 ## - user = postfix ## - group = postfix ## - } ## - .. ## - } ## - ## - service imap-login { ## - inet_listener imap { ## - address = $imap_listener_adresses ## - .. ## - } ## - inet_listener imaps { ## - address = $imaps_listener_adresses ## - .. ## - } ## - ## - process_min_avail = 16 ## - } ## - ## - service pop3-login { ## - inet_listener pop3 { ## - address = $pop_listener_adresses ## - .. ## - } ## - inet_listener pop3s { ## - address = $pops_listener_adresses ## - .. ## - } ## - } ## - _failed=false echononl "\tAdjusting file 10-master.conf.." perl -i.ORIG -n -p -e "s#^([ ]*)(unix_listener\ +auth-userdb.*)#\1\2\n\1 mode = 0666\n\1 user = dovecot\n\1 group = dovecot#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf || _failed=true perl -i -n -p -e "s#^([ ]*)(\#.*Postfix.*smtp-auth.*)#\1\2\n\1unix_listener /var/spool/postfix/private/dovecot-auth {\n\1 mode = 0666\n\1 user = postfix\n\1 group = postfix\n\1}#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf || _failed=true perl -i -n -p -e "s#^([ ]*)(inet_listener\ +imap\ .*)#\1\2\n\1 address = $imap_listener_adresses#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf || _failed=true perl -i -n -p -e "s#^([ ]*)(inet_listener\ +imaps.*)#\1\2\n\1 address = $imaps_listener_adresses#g#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf || _failed=true perl -i -n -p -e "s#^([ ]*)(\#?process_min_avail\ ?=.*)#\1\#\# \2\n\1process_min_avail = 16#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf || _failed=true perl -i -n -p -e "s#^([ ]*)(inet_listener\ +pop3\ .*)#\1\2\n\1 address = $pop_listener_adresses#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf || _failed=true perl -i -n -p -e "s#^([ ]*)(inet_listener\ +pop3s.*)#\1\2\n\1 address = $pops_listener_adresses#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf || _failed=true if $xmpp_listener ; then perl -i -n -p -e "s#^([ ]*)(service auth\s+\{.*)#\1\2\n\n \# Auth Listener (XMPP - Jabber)\n inet_listener {\n address = $xmpp_listener_addresses\n port = $xmpp_listener_port\n }\n#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf || _failed=true fi ## - setting default prozcess/client limit ## - perl -i -n -p -e "s#^([ ]*\#?[ ]*)(default_process_limit.*)#\1\2\ndefault_process_limit = 1024#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf || _failed=true perl -i -n -p -e "s#^([ ]*\#?[ ]*)(default_client_limit.*)#\1\2\ndefault_client_limit = 10240#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf || _failed=true perl -i -n -p -e "s#^([ ]*\#?[ ]*)(default_vsz_limit.*)#\1\2\ndefault_vsz_limit = 512M#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf || _failed=true if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf failed" fi blank_line echononl "\tCreate Cert/Key Directory '$cert_base_dir'.." if [[ ! -d "$cert_base_dir" ]] ; then mkdir -p "$cert_base_dir" > $log_file 2>&1 if [[ $? -eq 0 ]] ; then echo -e "$rc_done" echononl "\tChange Permissions for Cert/Key Directory '$cert_base_dir'.." chmod 755 "$cert_base_dir" > $log_file 2>&1 if [[ $? -eq 0 ]] ; then echo -e "$rc_done" else echo -e "$rc_failed" error "$(cat "$log_file")" fi else echo -e "$rc_failed" error "$(cat "$log_file")" fi else echo -e "$rc_skipped" fi ## - Since dovecot version 2.3.x SSL DH parameters will be stored ## - permanently on filesystem. So we have to create such a file ## - ## - openssl dhparam -out /etc/postfix/ssl/dh_4096.pem` ## - if [[ $dovecot_major_version -ge 3 ]] \ || ( [[ $dovecot_major_version -eq 2 ]] && [[ $dovecot_minor_version -ge 3 ]] ); then if [[ ! -f "$dh_pem_file" ]] ; then echononl "\tCreate SSL DH parameters '$dh_pem_file'.." echo -en "$rc_wait" openssl dhparam -dsaparam -out "$dh_pem_file" 4096 > /dev/null 2>&1 if [[ $? -eq 0 ]]; then echo -e "$rc_done" else echo -e "$rc_failed" error "Creating DH parameter file '$dh_pem_file' failed." fi fi fi ## - edit /usr/local/dovecot/etc/dovecot/conf.d/10-ssl.conf ## - ## - ssl = required ## - ## - ssl_cert = <$server_cert ## - ssl_key = <$server_key ## - ## - # - 'ssl_dh_parameters_length' is obsolete and no longer needed ## - #ssl_dh_parameters_length = 2048 ## - ## - # - 'ssl_protocols has been' replaced by ssl_min_protocol ## - #ssl_protocols = !SSLv3 ## - ssl_min_protocol = TLSv1.2 ## - ## - ssl_cipher_list = ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA ## - ## - ssl_prefer_server_ciphers = yes ## - ## - ## - there are another possibilities to handle certs, but this did'nt work ## - as i expected.. ## - #local_name imap.warenform.de { ## - # ssl_cert = <$imap_cert ## - # ssl_key = <$imap_key ## - #} ## - #local_name pop.warenform.de { ## - # ssl_cert = <$pop_cert ## - # ssl_key = <$pop_key ## - #} ## - _failed=false echononl "\tAdjusting file 10-ssl.conf.." perl -i.ORIG -n -p -e "s#^(\s*\#*\s*)(ssl\ ?=.*)#\#\1\2\nssl = required#" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-ssl.conf || _failed=true perl -i -n -p -e "s#^([ ]*)(ssl_cert\ ?=.*)#\1\#\# \2\n\1ssl_cert = <$server_cert#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-ssl.conf || _failed=true perl -i -n -p -e "s#^([ ]*)(ssl_key\ ?=.*)#\1\#\# \2\n\1ssl_key = <$server_key#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-ssl.conf || _failed=true if [[ $dovecot_major_version -ge 3 ]] \ || ( [[ $dovecot_major_version -eq 2 ]] && [[ $dovecot_minor_version -ge 3 ]] ); then if [[ ! -f "$dh_pem_file" ]]; then if [[ -f "/etc/postfix/ssl/dh_2048.pem" ]]; then dh_pem_file="/etc/postfix/ssl/dh_2048.pem" fi fi if [[ -f "$dh_pem_file" ]]; then perl -i -n -p -e "s#^(\s*\#*)(ssl_dh\s*=.*)#\#\1\2\nssl_dh = <$dh_pem_file#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-ssl.conf || _failed=true else _failed=true fi else perl -i -n -p -e "s#^([ ]*)\#?(ssl_dh_parameters_length\ ?=.*)#\1\#\# \2\nssl_dh_parameters_length = 2048#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-ssl.conf || _failed=true fi perl -i -n -p -e "s#^([ ]*)\#?(ssl_min_protocol\ ?=.*)#\1\#\# \2\nssl_min_protocol = TLSv1.2#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-ssl.conf || _failed=true # - Replace only the first occurence of the match # - # - Example: # - # Replace first occurence of 'width: .*' in file 'filename.css' # - # - perl -pi -e '$a=1 if(!$a && s/(width:).*;/$1 100%;/);' filename.css # - perl -i -n -p -e '$a=1 if(!$a && s#^([ ]*)\#?(ssl_cipher_list\ ?=.*)#\1\#\# \2\nssl_cipher_list = ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA#);' \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-ssl.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?(ssl_prefer_server_ciphers\ ?=.*)#\1\#\# \2\nssl_prefer_server_ciphers = yes#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-ssl.conf || _failed=true if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting file 10-ssl.conf failed" fi ## - edit /usr/local/dovecot/etc/dovecot/conf.d/10-mail.conf ## - ## - mail_location = maildir:/var/vmail/%d/%n/Maildir ## - ## - mail_uid = vmail ## - mail_gid = vmail ## - ## - first_valid_uid = 5000 ## - last_valid_uid = 5000 ## - ## - mail_temp_dir = /var/vmail/tmp ## - ## - first_valid_gid = 5000 ## - last_valid_gid = 5000 ## - ## - auth_socket_path = /var/run/dovecot/auth-userdb ## - mail_plugins = quota | mail_plugins = quota expire ## - ## - mailbox_list_index = yes ## - _failed=false echononl "\tAdjusting file 10-mail.conf" perl -i.ORIG -n -p -e "s#^([ ]*)\#?\ ?(mail_location\ +=.*)#\1\#\# \2\n\1mail_location = maildir:/var/vmail/%d/%n/Maildir#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(mail_uid.*)#\1\#\# \2\n\1mail_uid = vmail#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(mail_gid.*)#\1\#\# \2\n\1mail_gid = vmail#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(mail_temp_dir.*)#\1\#\# \2\n\1mail_temp_dir = /var/vmail/tmp#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(first_valid_uid.*)#\1\#\# \2\n\1first_valid_uid = 5000#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(last_valid_uid.*)#\1\#\# \2\n\1last_valid_uid = 5000#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(first_valid_gid.*)#\1\#\# \2\n\1first_valid_gid = 5000#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(last_valid_gid.*)#\1\#\# \2\n\1last_valid_gid = 5000#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(auth_socket_path\ +=.*)#\1\#\# \2\n\1auth_socket_path = /var/run/dovecot/auth-userdb#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true if $plugin_expire ; then perl -i -n -p -e "s#^([ ]*)\#?\ ?(mail_plugins\ +=.*)#\1\#\# \2\n\1mail_plugins = quota expire#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true else perl -i -n -p -e "s#^([ ]*)\#?\ ?(mail_plugins\ +=.*)#\1\#\# \2\n\1mail_plugins = quota#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true fi perl -i -n -p -e "s#^([ ]*)\#?\ ?(mailbox_list_index\s*=.*)#\1\#\# \2\n\1mailbox_list_index = yes#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting file '10-mail.conf' failed" fi echononl "\tCreate TEMP directory '/var/vmail/tmp' .." if [[ ! -d /var/vmail/tmp ]] ; then mkdir /var/vmail/tmp > /dev/null 2>&1 if [[ $? -eq 0 ]]; then echo -e "$rc_done" else echo -e "$rc_failed" error "Creating TEMP directory '/var/vmail/tmp' failed." fi else echo -e "$rc_skipped" fi echononl "\tChange ownerchip of directory '/var/vmail/tmp' .." chown vmail:vmail /var/vmail/tmp > /dev/null 2>&1 if [[ $? -eq 0 ]]; then echo -e "$rc_done" else echo -e "$rc_failed" error "Changing ownerchip of directory '/var/vmail/tmp' failed." fi ## - edit /usr/local/dovecot/etc/dovecot/conf.d/10-mail.conf ## - ## - comment out namespace section "namespace inbox". we will create namespaces later. ## - in detail, tha means comment out 3 lines: ## - namespace inbox { ## - .. ## - inbox = yes ## - .. ## - } ## - _failed=false _found=false _tmp_file="$(mktemp)" > $_tmp_file while IFS='' read -r _line || [[ -n $_line ]] ; do if echo "$_line" | grep -i -E "^\s*namespace\s+inbox\s+" > /dev/null 2>&1 ; then echo "## $_line" >> $_tmp_file _found=true continue fi if $_found && echo "$_line" | grep -i -E "^\s*}" > /dev/null 2>&1 ; then echo "## $_line" >> $_tmp_file _found=false continue fi if $_found ; then echo "## $_line" >> $_tmp_file else echo "$_line" >> $_tmp_file fi done < "/usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf" if [[ "$?" != "0" ]] ; then _failed=true fi mv /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf.TMP if [[ "$?" != "0" ]] ; then _failed=true fi mv $_tmp_file /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf if [[ "$?" != "0" ]] ; then _failed=true fi chmod 644 /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf if [[ "$?" != "0" ]] ; then _failed=true fi #perl -i -n -p -e "s#^([ ]*)(namespace\ +inbox\ +{\ *)#\1\#\#\ \2#g" \ # /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true #perl -i -n -p -e "s#^([ ]*)(inbox\ +=\ +yes\ *)#\1\#\#\ \2#g" \ # /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true #perl -i -n -p -e "s#^([ ]*)(}\ *)#\1\#\#\ \2#g" \ # /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf failed" fi ## - edit /usr/local/dovecot/etc/dovecot/conf.d/10-mail.conf ## - ## - Add namespaces type private ## - ## - Add: ## - namespace inbox { ## - type = private ## - separator = / ## - prefix = ## - inbox = yes ## - } ## - echononl "\tAdd namespaces type private to file 10-mail.conf" cat <> /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf ## - Namespaces ## - namespace inbox { # Namespace type: private, shared or public type = private # Hierarchy separator to use. You should use the same separator for all # namespaces or some clients get confused. '/' is usually a good one. # The default however depends on the underlying mail storage format. #separator = separator = / # Prefix required to access this namespace. This needs to be different for # all namespaces. For example "Public/". #prefix = prefix = # Physical location of the mailbox. This is in same format as # mail_location, which is also the default for it. #location = # There can be only one INBOX, and this setting defines which namespace # has it. #inbox = no inbox = yes # If namespace is hidden, it's not advertised to clients via NAMESPACE # extension. You'll most likely also want to set list=no. This is mostly # useful when converting from another server with different namespaces which # you want to deprecate but still keep working. For example you can create # hidden namespaces with prefixes "~/mail/", "~%u/mail/" and "mail/". #hidden = no # Show the mailboxes under this namespace with LIST command. This makes the # namespace visible for clients that don't support NAMESPACE extension. # "children" value lists child mailboxes, but hides the namespace prefix. #list = yes # Namespace handles its own subscriptions. If set to "no", the parent # namespace handles them (empty prefix should always have this as "yes") #subscriptions = yes } EOF if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf failed" fi ## - edit /usr/local/dovecot/etc/dovecot/conf.d/15-mailboxes.conf ## - ## - Add definitions for mailbox Spam: ## - ## - mailbox Drafts { ## - auto = subscribe ## - special_use = \Drafts ## - } ## - ## - mailbox Trash { ## - auto = subscribe ## - special_use = \Trash ## - } ## - ## - mailbox Sent { ## - auto = subscribe ## - special_use = \Sent ## - } ## - ## - mailbox $spam_folder { ## - auto = subscribe ## - special_use = \Junk ## - } ## - _failed=false echononl "\tAdjusting file 15-mailboxes.conf" perl -i.ORIG -n -p -e "s#^([ ]*)(mailbox\ +Drafts\ +{.*)#\1\2\n\1 auto = subscribe#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-mailboxes.conf || _failed=true if [ "$spam_folder" != "Junk" ]; then if $plugin_expire ; then perl -i -n -p -e "s#^([ ]*)(mailbox\ +Junk\ +{.*)#\1mailbox $spam_folder {\n\1 auto = subscribe\n\1 special_use = \\\Junk\n\1}\n\1\2#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-mailboxes.conf || _failed=true perl -i -n -p -e "s#^([ ]*)(mailbox\ +Junk\ +{.*)#\1\2\n\1 auto = no#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-mailboxes.conf || _failed=true else perl -i -n -p -e "s#^([ ]*)(mailbox\ +Junk\ +{.*)#\1mailbox $spam_folder {\n\1 auto = subscribe\n\1 autoexpunge = 30d\n\1 special_use = \\\Junk\n\1}\n\1\2#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-mailboxes.conf || _failed=true perl -i -n -p -e "s#^([ ]*)(mailbox\ +Junk\ +{.*)#\1\2\n\1 auto = no\n\1 autoexpunge = 30d#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-mailboxes.conf || _failed=true fi else if $plugin_expire ; then perl -i -n -p -e "s#^([ ]*)(mailbox\ +$spam_folder\ +{.*)#\1\2\n\1 auto = subscribe#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-mailboxes.conf || _failed=true else perl -i -n -p -e "s#^([ ]*)(mailbox\ +$spam_folder\ +{.*)#\1\2\n\1 auto = subscribe\n\1 autoexpunge = 30d#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-mailboxes.conf || _failed=true fi fi if $plugin_expire ; then perl -i -n -p -e "s#^([ ]*)(mailbox\ +Trash\ +{.*)#\1\2\n\1 auto = subscribe#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-mailboxes.conf || _failed=true else perl -i -n -p -e "s#^([ ]*)(mailbox\ +Trash\ +{.*)#\1\2\n\1 auto = subscribe\n\1 autoexpunge = 3d#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-mailboxes.conf || _failed=true fi perl -i -n -p -e "s#^([ ]*)(mailbox\ +Sent\ +{.*)#\1\2\n\1 auto = subscribe#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-mailboxes.conf || _failed=true perl -i -n -p -e "s#^([ ]*)(mailbox\ +\"Sent Messages\"\ +{.*)#\1\2\n\1 auto = no#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-mailboxes.conf || _failed=true if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-mailboxes.conf failed" fi ## - edit /usr/local/dovecot/etc/dovecot/conf.d/10-auth.conf ## - ## - disable_plaintext_auth = no ## - auth_mechanisms = $auth_mechanisms ## - !include auth-sql.conf.ext # comment all other includes ## - auth_username_translation = "%@" ## - _failed=false echononl "\tAdjusting file 10-auth.conf" perl -i.ORIG -n -p -e "s#^([ ]*)\#?\ ?(disable_plaintext_auth\ +=.*)#\1\#\# \2\n\1disable_plaintext_auth = yes#" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-auth.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(auth_mechanisms\ +=.*)#\1\#\# \2\n\1auth_mechanisms = $auth_mechanisms#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-auth.conf || _failed=true perl -i -n -p -e "s#^(\!include\ auth-.*)#\#\1#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-auth.conf || _failed=true perl -i -n -p -e "s#^\#(\!include\ auth-sql.*)#\1#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-auth.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(auth_username_translation\ +=.*)#\1\#\# \2\n\1auth_username_translation = \"%@\"#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-auth.conf || _failed=true if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-auth.conf failed" fi ## - edit /usr/local/dovecot/etc/dovecot/conf.d/auth-sql.conf.ext ## - ## - passdb { ## - driver = sql ## - ## - ## - # path for sql configuration file, see example-config/dovecot-sql.conf.ext ## - args = /usr/local/dovecot/etc/dovecot/sql-connect.conf.ext ## - } ## - ## - .. ## - ## - userdb { ## - driver = sql ## - args = /usr/local/dovecot/etc/dovecot/sql-connect.conf.ext ## - } ## - echononl "\tAdjusting file auth-sql.conf.ext" perl -i.ORIG -n -p -e "s#^([ ]*)(args\ ?=.*)#\1\#\# \2\n\1args = /usr/local/dovecot/etc/dovecot/sql-connect.conf.ext#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/auth-sql.conf.ext if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting /usr/local/dovecot-${_version}/etc/dovecot/conf.d/auth-sql.conf.ext failed" fi ## - create sql configuration file ## - echononl "\tCreate sql configuration file sql-connect.conf.ext" if [ "$db_driver" = "pgsql" ]; then cat < /usr/local/dovecot-${_version}/etc/dovecot/sql-connect.conf.ext driver = $db_driver ## - if using unix-socket (host=/var/run/postgresql) ensure that ## - coresponding entries in pg_hba.cof fits ## - for example ## - local all all md5 ## - connect = host=$dbhost user=$dbuser password=$dbpassword dbname=$dbname default_pass_scheme = $default_pass_scheme password_query = SELECT username AS user, password \\ FROM mailbox \\ WHERE username = '%u' AND active = true user_query = SELECT '/var/vmail/' || maildir AS home, \\ '5000' AS uid, '5000' AS gid \\ FROM mailbox \\ WHERE username = '%u' AND active = true #WHERE username = substring ('%u' from '#"[^-]+#"_*@%%' for '#') || '@%d' and active = true ## - Query to get a list of all usernames. ## - iterate_query = SELECT username AS user FROM mailbox EOF if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/sql-connect.conf.ext failed" fi elif [ "$db_driver" = "mysql" ]; then cat < /usr/local/dovecot-${_version}/etc/dovecot/sql-connect.conf.ext driver = $db_driver connect = host=$dbhost user=$dbuser password=$dbpassword dbname=$dbname default_pass_scheme = $default_pass_scheme password_query = SELECT username AS user, password \\ FROM mailbox \\ WHERE username = '%u' AND active = true user_query = SELECT CONCAT('/var/vmail/',maildir) AS home, \\ '5000' AS uid, '5000' AS gid \\ FROM mailbox \\ WHERE username = '%u' AND active = true ## - Query to get a list of all usernames. ## - iterate_query = SELECT username AS user FROM mailbox EOF if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/sql-connect.conf.ext failed" fi fi ## - edit /usr/local/dovecot/etc/dovecot/conf.d/10-logging.conf ## - ## - ## - if running inetd-script: ## - ## - log_path = /var/log/dovecot/dovecot.log ## - ## - or for example ## - ## - log_path = syslog ## - syslog_facility = local1 ## - auth_verbose = yes ## - auth_verbose_passwords = plain ## - ## - in conjunction with the the following entries in /etc/rsyslog.conf ## - ## - local1.* -/var/log/dovecot.log ## - local1.info -/var/log/dovecot.info ## - local1.warn -/var/log/dovecot.warn ## - local1.err -/var/log/dovecot.err ## - :msg,contains,"stored mail into mailbox"\ ## - -/var/log/dovecot.lmtp ## - _failed=false echononl "\tAdjusting file 10-logging.conf" perl -i.ORIG -n -p -e "s#^([ ]*)\#?\ ?(log_path\ ?=.*)#\1\#\# \2\n\1log_path = syslog#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-logging.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(syslog_facility\ ?=.*)#\1\#\# \2\n\1syslog_facility = local1#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-logging.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(auth_verbose\ ?=.*)#\1\#\# \2\n\1auth_verbose = yes#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-logging.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(auth_verbose_passwords\ ?=.*)#\1\#\# \2\n\1auth_verbose_passwords = plain#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-logging.conf || _failed=true if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-logging.conf failed" fi if $_new ; then mkdir -p /var/log/dovecot echo echononl "\tCreate file /etc/rsyslog.d/dovecot.conf" cat < /etc/rsyslog.d/dovecot.conf ## - dovecot ## - local1.info -/var/log/dovecot/dovecot.info local1.warn -/var/log/dovecot/dovecot.warn local1.err -/var/log/dovecot/dovecot.err :msg,contains,"stored mail into mailbox" \\ -/var/log/dovecot/dovecot.lmtp local1.* -/var/log/dovecot/dovecot.log & ~ EOF if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Creating file /etc/rsyslog.d/dovecot.conf failed" fi /etc/init.d/rsyslog restart > /dev/null 2>&1 if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "Restarting rsyslog failed" fi ## - logrotate for dovecot log-files ## - echononl "\tCreate file /etc/logrotate.d/dovecot" cat < /etc/logrotate.d/dovecot /var/log/dovecot/dovecot.log /var/log/dovecot/dovecot.info /var/log/dovecot/dovecot.warn /var/log/dovecot/dovecot.err /var/log/dovecot/dovecot.lmtp { daily start 0 rotate 7 missingok notifempty compress delaycompress create 640 root adm copytruncate #sharedscripts #postrotate #/etc/init.d/dovecot reload > /dev/null #/bin/kill -usr1 'cat /var/run/dovecot/master.pid 2>/dev/null' 2>/dev/null || true #endscript } EOF if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Creating file /etc/logrotate.d/dovecot failed" fi echo fi ## - edit /usr/local/dovecot/etc/dovecot/conf.d/15-lda.conf ## - ## - postmaster_address = $postmaster_address ## - hostname = $hostname ## - sendmail_path = /usr/sbin/sendmail ## - lda_mailbox_autocreate = no ## - mail_plugins = $mail_plugins sieve ## - _failed=false echononl "\tAdjusting file 15-lda.conf" perl -i.ORIG -n -p -e "s#^([ ]*)\#?\ ?(postmaster_address\ +=.*)#\1\#\# \2\n\1postmaster_address = $postmaster_address#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-lda.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(hostname\ +=.*)#\1\#\# \2\n\1hostname = $hostname#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-lda.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(sendmail_path\ +=.*)#\1\#\# \2\n\1sendmail_path = /usr/sbin/sendmail#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-lda.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(lda_mailbox_autocreate\ +=.*)#\1\#\# \2\n\1lda_mailbox_autocreate = no#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-lda.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(mail_plugins\ +=.*)#\1\#\# \2\n\1mail_plugins = \\\$mail_plugins sieve#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-lda.conf || _failed=true if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting /usr/local/dovecot-${_version}/etc/dovecot/conf.d/15-lda.conf failed" fi ## - edit /usr/local/dovecot/etc/dovecot/conf.d/20-lmtp ## - ## - lmtp_save_to_detail_mailbox = no ## - mail_plugins = $mail_plugins sieve ## - _failed=false echononl "\tAdjusting file 20-lmtp.conf" perl -i.ORIG -n -p -e "s#^([ ]*)\#?\ ?(lmtp_save_to_detail_mailbox\ +=.*)#\1\#\# \2\n\1lmtp_save_to_detail_mailbox = no#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-lmtp.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(mail_plugins\ +=.*)#\1\#\# \2\n\1mail_plugins = \\\$mail_plugins sieve#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-lmtp.conf || _failed=true if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-lmtp.conf failed" fi ## - edit /usr/local/dovecot/etc/dovecot/conf.d/20-imap.conf ## - ## - ssl_cert = <$imap_cert ## - ssl_key = <$imap_key ## - mail_max_userip_connections = $max_userip_connections ## - mail_plugins = $mail_plugins imap_quota ## - imap_client_workarounds = delay-newmail ## - _failed=false echononl "\tAdjusting file 20-imap.conf" perl -i.ORIG -n -p -e "s#^([ ]*)\#?\ ?(protocol imap \{)#\1\2\n\n\1 ssl_cert = <$imap_cert\n\1 ssl_key = <$imap_key\n#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-imap.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(mail_max_userip_connections\ +=.*)#\1\#\# \2\n\1mail_max_userip_connections = $max_userip_connections#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-imap.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(mail_plugins\ +=.*)#\1\#\# \2\n\1mail_plugins = \\\$mail_plugins imap_quota#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-imap.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(imap_client_workarounds\ +=.*)#\1\#\# \2\n\1imap_client_workarounds = delay-newmail#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-imap.conf || _failed=true if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-imap.conf failed" fi ## - edit /usr/local/dovecot/etc/dovecot/conf.d/20-pop3.conf ## - ## - ssl_cert = <$pop_cert ## - ssl_key = <$pop_key ## - mail_max_userip_connections = 24 ## - pop3_client_workarounds = outlook-no-nuls oe-ns-eoh ## - _failed=false echononl "\tAdjusting file 20-pop3.conf" perl -i.ORIG -n -p -e "s#^([ ]*)\#?\ ?(protocol pop3 \{)#\1\2\n\n\1 ssl_cert = <$pop_cert\n\1 ssl_key = <$pop_key\n#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-pop3.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(mail_max_userip_connections\ +=.*)#\1\#\# \2\n\1mail_max_userip_connections = 24#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-pop3.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(pop3_client_workarounds\ +=.*)#\1\#\# \2\n\1pop3_client_workarounds = outlook-no-nuls oe-ns-eoh#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-pop3.conf || _failed=true if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-pop3.conf failed" fi ## - edit /usr/local/dovecot/etc/dovecot/conf.d/90-plugin.conf ## - ## - Note: ## - Setting "autocreate", "autosubscribe" here is depricated. Use mailbox { auto } setting instead. ## - ## - expire = Trash ## - expire2 = Trash/* ## - expire3 = Spam ## - ## - expire_dict = proxy::expire ## - ## - # Enable caching of dict value in dovecot.index file. This significantly reduces ## - # the number of dict lookups. It makes initial testing more confusing though, so ## - # it's better to enable it only after you've verified that the expire plugin is ## - # working as wanted. (v2.2.16+) ## - expire_cache = yes ## - _failed=false echononl "\tAdjusting file 90-plugin.conf" if $plugin_expire ; then perl -i.ORIG -n -p -e "s#^([ ]*)(\#?\ ?setting_name\ +=.*)#\1\2\n\n\1expire = Trash\n\1expire2 = Trash/*\n\1expire3 = $spam_folder\n\n\1expire_dict = proxy::expire\n\n\1\# Enable caching of dict value in dovecot.index file. This significantly reduces\n\1\# the number of dict lookups. It makes initial testing more confusing though, so\n\1\# it's better to enable it only after you've verified that the expire plugin is\n\1\# working as wanted. (v2.2.16+)\n\1expire_cache = yes#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-plugin.conf || _failed=true if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-plugin.conf failed" fi else echo -e "$rc_skipped" fi ## - edit /usr/local/dovecot/etc/dovecot/conf.d/90-sieve.conf ## - ## - sieve = ~/.dovecot.sieve ## - #sieve_global_path = /usr/local/dovecot/etc/dovecot/sieve/default.sieve ## - sieve_before = /usr/local/dovecot/etc/dovecot/sieve/move-spam.sieve ## - sieve_dir = ~/sieve ## - sieve_global = /usr/local/dovecot/etc/dovecot/sieve/global/ ## - recipient_delimiter = ## - _failed=false echononl "\tAdjusting file 90-sieve.conf" perl -i.ORIG -n -p -e "s#^([ ]*)\#?\ ?(sieve\ ?=.*)#\1\#\# \2\n\1sieve = ~/.dovecot.sieve#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-sieve.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(sieve_before\ ?=.*)#\1\#\# \2\n\1sieve_before =/usr/local/dovecot/etc/dovecot/sieve/move-spam.sieve#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-sieve.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(sieve_dir\ ?=.*)#\1\#\# \2\n\1sieve_dir = ~/sieve#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-sieve.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(sieve_global\ ?=.*)#\1\#\# \2\n\1sieve_global = /usr/local/dovecot/etc/dovecot/sieve/global/#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-sieve.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(recipient_delimiter\ ?=.*)#\1\#\# \2\n\1recipient_delimiter =#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-sieve.conf || _failed=true if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-sieve.conf" fi mkdir -p /usr/local/dovecot-${_version}/etc/dovecot/sieve/global/ ## - ceate global sieve script ## - echononl "\tCeate global sieve script" cat < /usr/local/dovecot-${_version}/etc/dovecot/sieve/move-spam.sieve require ["fileinto"]; # rule:[Move Spam] # Move spam to spam folder if header :contains "X-Spam-Flag" ["YES"] { fileinto "$spam_folder"; #discard; stop; } EOF if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "Creating global sieve script failed" echononl "\tcontinue anyway [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/nno]: " read OK done [[ $OK = "yes" ]] || fatal "Abbruch durch User" fi ## - NOTICE: if you pre-compile your (global) scripts, you will increase ## - performance ## - echononl "\tPrecompile global sieve script" cd /usr/local/dovecot-${_version}/etc/dovecot/sieve/ /usr/local/dovecot-${_version}/bin/sievec \ /usr/local/dovecot-${_version}/etc/dovecot/sieve/move-spam.sieve > $log_file 2>&1 if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "$(cat $log_file)" echononl "\tcontinue anyway [yes/no]: " read OK OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do echononl "Wrong entry! - repeat [yes/nno]: " read OK done [[ $OK = "yes" ]] || fatal "Abbruch durch User" fi ## - you can also give dovecot's delivery service (lda / lmtp) the permissions to write ## - into the sieve directory. then dovecots delivery service will compile the script ## - by first using.. ## - chown -R vmail:vmail /usr/local/dovecot-${_version}/etc/dovecot/sieve if $_new ; then if ! $systemd_support; then _create_init="" echo echo -n "Create init script /etc/init.d/dovecot ? [y/n]: " read _create_init if [ "y" = "$_create_init" -o "Y" = "$_create_init" -o "Yes" = "$_create_init" -o "yes" = "$_create_init" ];then echononl "\tCreate init script for dovecot .." ## - running dovecot service via init-script ## - cat < /etc/init.d/dovecot #! /bin/sh ### BEGIN INIT INFO # Provides: dovecot # Required-Start: \$syslog \$postgresql # Required-Stop: \$syslog \$postgresql # Should-Start: \$local_fs \$time ntp # Should-Stop: \$local_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Dovecot init script # Description: Init script for dovecot services ### END INIT INFO # Author: Miquel van Smoorenburg . # Modified for Debian GNU/Linux # by Ian Murdock . # # Do NOT "set -e" ulimit -n 32768 # PATH should only include /usr/* if it runs after the mountnfs.sh script PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/dovecot/sbin/dovecot:/usr/local/dovecot/bin DESC="IMAP/POP3 mail server" NAME=dovecot DAEMON=/usr/local/dovecot/sbin/dovecot DAEMON_ARGS="" SCRIPTNAME=/etc/init.d/\$NAME CONF=/usr/local/dovecot/etc/dovecot/\${NAME}.conf # Read configuration variable file if it is present [ -r /etc/default/\$NAME ] && . /etc/default/\$NAME # Exit if the package is not installed [ -x "\$DAEMON" ] || exit 0 # Exit if the configuration file doesn't exist [ -f "\$CONF" ] || exit 0 # Load the VERBOSE setting and other rcS variables . /lib/init/vars.sh # Define LSB log_* functions. # Depend on lsb-base (>= 3.0-6) to ensure that this file is present. . /lib/lsb/init-functions # cong file readable? if [ ! -r \${CONF} ]; then [ "\$VERBOSE" != no ] && log_daemon_msg "\${CONF}: not readable" "\$NAME" \\ && log_end_msg 1; exit 1; fi # The init script should do nothing if dovecot or another imap/pop3 server # is being run from inetd, and dovecot is configured to run as an imap or # pop3 service if [ -r /etc/inetd.conf ]; then for p in \`sed -r "s/^ *(([^:]+|\[[^]]+]|\*):)?(pop3s?|imaps?)[ \t].*/\3/;t;d" \\ /etc/inetd.conf\` do for q in \`sed -r "s/^[ \t]*protocols[ \t]*=[ \t]*(([^\"]*)|\"(.*)\")/\2\3/;t;d" \\ \${CONF}\` do if [ \$p = \$q ]; then exit 0 fi done done fi # determine the location of the PID file # overide by setting base_dir in conf file or PIDBASE in /etc/defaults/\$NAME PIDBASE=\${PIDBASE:-\`sed -r "s/^[ \t]*base_dir[ \t]*=[ \t]*([^ \t]*)/\1/;t;d" \${CONF}\`} PIDFILE=\${PIDBASE:-/var/run/dovecot/}master.pid # # Function that starts the daemon/service # do_start() { # Return # 0 if daemon has been started # 1 if daemon was already running # 2 if daemon could not be started start-stop-daemon --start --quiet --pidfile \$PIDFILE --exec \$DAEMON --test > /dev/null \\ || return 1 start-stop-daemon --start --quiet --pidfile \$PIDFILE --exec \$DAEMON -- \\ \$DAEMON_ARGS \\ || return 2 } # # Function that stops the daemon/service # do_stop() { # Return # 0 if daemon has been stopped # 1 if daemon was already stopped # 2 if daemon could not be stopped # other if a failure occurred start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile \$PIDFILE --name \${DAEMON##*/} RETVAL="\$?" [ "\$RETVAL" = 2 ] && return 2 # Wait for children to finish too if this is a daemon that forks # and if the daemon is only ever run from this initscript. # If the above conditions are not satisfied then add some other code # that waits for the process to drop all resources that could be # needed by services started subsequently. A last resort is to # sleep for some time. start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --pidfile \$PIDFILE --name \${DAEMON##*/} [ "\$?" = 2 ] && return 2 # Many daemons don't delete their pidfiles when they exit. rm -f \$PIDFILE return "\$RETVAL" } # # Function that sends a SIGHUP to the daemon/service # do_reload() { # # If the daemon can reload its configuration without # restarting (for example, when it is sent a SIGHUP), # then implement that here. # start-stop-daemon --stop --signal USR1 --quiet --pidfile \$PIDFILE --name \$NAME return 0 } case "\$1" in start) [ "\$VERBOSE" != no ] && log_daemon_msg "Starting \$DESC" "\$NAME" do_start case "\$?" in 0|1) [ "\$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "\$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; stop) [ "\$VERBOSE" != no ] && log_daemon_msg "Stopping \$DESC" "\$NAME" do_stop case "\$?" in 0|1) [ "\$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "\$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; reload|force-reload) log_daemon_msg "Reloading \$DESC" "\$NAME" do_reload log_end_msg \$? ;; restart) # # If the "reload" option is implemented then remove the # 'force-reload' alias # log_daemon_msg "Restarting \$DESC" "\$NAME" do_stop case "\$?" in 0|1) do_start case "\$?" in 0) log_end_msg 0 ;; 1) log_end_msg 1 ;; # Old process is still running *) log_end_msg 1 ;; # Failed to start esac ;; *) # Failed to stop log_end_msg 1 ;; esac ;; *) #echo "Usage: \$SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2 echo "Usage: \$SCRIPTNAME {start|stop|restart|force-reload}" >&2 exit 3 ;; esac exit 0 EOF if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Creating init script for dovecot failed" fi chmod 755 /etc/init.d/dovecot else echononl "\tCreate init script for dovecot .." echo -e "$rc_skipped" fi else ## - # - At time, we don't use private tmp directory for divecot. ## - # - ## - echononl "\tAdjust Systemd service file, set PrivateTmp=false.." ## - if [[ -f "/etc/systemd/system/dovecot.service" ]] ; then ## - ## - if $(grep -o -E "PrivateTmp\s*=\s*[^[:blank:]]+" /etc/systemd/system/dovecot.service | grep -q true 2> /dev/null ) ; then ## - perl -i -n -p -e "s/(PrivateTmp\s*=\s*)true/\1false/" /etc/systemd/system/dovecot.service ## - if [[ $? -eq 0 ]]; then ## - echo -e "$rc_done" ## - else ## - echo -e "$rc_failed" ## - fi ## - else ## - echo -e "$rc_skipped" ## - fi ## - else ## - echo -e "$rc_skipped" ## - fi ## - Increase LimitNOFILE to fit dovecots setting for 'default_client_limit'. ## - ## - here: ## - LimitNOFILE=32768 ## - echononl "\tAdjust 'LimitNOFILE' at file 'dovecot.service'.." if [[ -f "/etc/systemd/system/dovecot.service" ]] ; then if $(grep -q -o -E "LimitNOFILE\s*=\s*[^[:blank:]]+" /etc/systemd/system/dovecot.service 2> /dev/null ) ; then perl -i -n -p -e "s/(LimitNOFILE\s*=\s*.*)/LimitNOFILE=32768/" /etc/systemd/system/dovecot.service if [[ $? -eq 0 ]]; then echo -e "$rc_done" else echo -e "$rc_failed" fi else echo -e "$rc_skipped" fi else echo -e "$rc_skipped" fi echononl "Adjust 'PIDFile' at file 'dovecot.service'.." if [[ -f "/etc/systemd/system/dovecot.service" ]] ; then if $(grep -q -o -E "^\s*PIDFile\s*=\s*/var/run/" /etc/systemd/system/dovecot.service 2> /dev/null ) ; then perl -i -n -p -e "s/^(PIDFile\s*=\/var(\/run\/.+))/#\1\nPIDFile=\2/" /etc/systemd/system/dovecot.service if [[ $? -eq 0 ]]; then echo -e "$rc_done" else echo -e "$rc_failed" fi else echo -e "$rc_skipped" fi else echo -e "$rc_skipped" fi fi ## - Add a cronjob to restart dovecot after booting the system. ## - ## - Notice: ## - On normal start, dovecot started its service even if ipv6 is not ## - yet present and dovecot cannot bind to ipv6 listeners. ## - ## - Doimg a restart (after ipv6 adresses are present) fixes this. ## - echononl "\tCreate cronjob to restart dovecot service after reboot.." _crontab_tmp_file=/tmp/crontab_root.$$ crontab -l > $_crontab_tmp_file 2> /dev/null if [[ ! -s $_crontab_tmp_file ]]; then echo "PATH=/usr/local/dovecot/bin:$PATH" > $_crontab_tmp_file fi if ! grep -q -E "\s*@reboot.*systemctl\s+restart\s+dovecot.service" $_crontab_tmp_file ; then echo "" >> $_crontab_tmp_file echo "# - Restart dovecot after reboot" >> $_crontab_tmp_file echo "# -" >> $_crontab_tmp_file echo "@reboot sleep 15 ; /bin/systemctl restart dovecot.service" >> $_crontab_tmp_file crontab $_crontab_tmp_file echo -e "$rc_done" else echo -e "$rc_skipped" fi rm -f $_crontab_tmp_file ## - Make dovecot start at boot time ## - if $systemd_support ; then echononl "\tReload systemd .." systemctl daemon-reload > /dev/null 2>&1 if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fi fi echononl "\tMake dovecot start at boottime.." if $systemd_support ; then systemctl enable dovecot > /dev/null 2>&1 else update-rc.d dovecot defaults > /dev/null 2>&1 fi if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Make dovecot start at boottime failed" fi ## - update postfix configuration to play with dovecot lda ## - ## - /etc/postfix/master.cf ## - ## - add line ## - dovecot unix - n n - - pipe ## - flags=drhu user=vmail:vmail argv=/usr/local/dovecot/libexec/dovecot/dovecot-lda -f ${sender} -d ${user}@${nexthop} if ! grep -e dovecot-lda /etc/postfix/master.cf > /dev/null ; then cp -a "/etc/postfix/master.cf" "/etc/postfix/master.cf.$backup_date" echononl "\tConfigure /etc/postfix/master.cf to play with dovecot lda" echo -e "\ndovecot unix - n n - - pipe\n flags=drhu user=vmail:vmail argv=/usr/local/dovecot/libexec/dovecot/dovecot-lda -f \${sender} -d \${user}@\${nexthop}" >> /etc/postfix/master.cf if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Configuring /etc/postfix/master.cf failed" fi fi ## - /etc/postfix/main.cf ## - ## - add/uncomment: ## - ## - smtpd_tls_auth_only ## - ## - smtpd_sasl_type = dovecot ## - smtpd_sasl_path = private/dovecot-auth ## - ## - virtual_transport = dovecot ## - dovecot_destination_recipient_limit = 1 ## - ## - in section restrictions, parameter smtpd_recipient_restrictions ## - uncomment add ## - ## - permit_sasl_authenticated, ## - _failed=false echononl "\tAdjust /etc/postfix/main.cf" perl -i.$backup_date -n -p -e "s#^(\s*)(smtpd_tls_auth_only\ *=.*)#smtpd_tls_auth_only = yes#" \ /etc/postfix/main.cf || _failed=true perl -i -n -p -e "s#^(\s*)(smtpd_sasl_auth_enable\ *=.*)#smtpd_sasl_auth_enable = no#" \ /etc/postfix/main.cf || _failed=true perl -i -n -p -e "s#^(\s*)(smtpd_sasl_type\ *=.*)#smtpd_sasl_type = dovecot#" \ /etc/postfix/main.cf || _failed=true perl -i -n -p -e "s#^(\s*)(smtpd_sasl_path\ *=.*)#smtpd_sasl_path = private/dovecot-auth#" \ /etc/postfix/main.cf || _failed=true perl -i -n -p -e "s#^(\s*)(virtual_transport\ *=.*)#virtual_transport = dovecot\ndovecot_destination_recipient_limit = 1#" \ /etc/postfix/main.cf || _failed=true perl -i-n -p -e "s#^(\s*)\#?(permit_sasl_authenticated)#\1\2#" /etc/postfix/main.cf || _failed=true if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting /etc/postfix/main.cf failed" fi ## - add a cronjob to run expunge scripts, to delete old mails ## - from users'mailbox. only cleanup spam and trash directories ## - echononl "\tCreate cronjob to run expunge scripts" _crontab_tmp_file=/tmp/crontab_root.$$ crontab -l > $_crontab_tmp_file 2> /dev/null if [[ ! -s $_crontab_tmp_file ]]; then echo "PATH=/usr/local/dovecot/bin:$PATH" > $_crontab_tmp_file fi if ! grep -e "/usr/local/dovecot/bin/doveadm\ *expunge" $_crontab_tmp_file > /dev/null ; then echo "" >> $_crontab_tmp_file echo "# - cleanup spam and trash directories of users'mailboxes" >> $_crontab_tmp_file echo "# -" >> $_crontab_tmp_file echo "13 3 * * * /usr/local/dovecot/bin/doveadm expunge -A mailbox Trash* savedbefore 3d; /usr/local/dovecot/bin/doveadm expunge -A mailbox ${spam_folder}* savedbefore 30d" >> $_crontab_tmp_file crontab $_crontab_tmp_file echo -e "$rc_done" else echo -e "$rc_skipped" fi rm -f $_crontab_tmp_file else # - Reload systemd # - echononl "\tReload systemd.." if $systemd_support ; then systemctl daemon-reload if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "Reloading systemd failed" fi else echo -e "$rc_skipped" fi fi # if $_new echo echo -e "\033[1mChange (from lda) to lmtp-service\033[m" ## ----------------- ## --- Change (from lda) to lmtp-service ## - edit /usr/local/dovecot/etc/dovecot/dovecot.conf ## - ## - add "lmtp" to protocols ## - _failed=false echononl "\tAdd lmtp to protocols (dovecot.conf)" perl -i -n -p -e "s#^([ ]*)(protocols\ +=\ +.*)#\1\2 lmtp#" \ /usr/local/dovecot-${_version}/etc/dovecot/dovecot.conf || _failed=true if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adding lmtp to protocols in file /usr/local/dovecot-${_version}/etc/dovecot/dovecot.conf failed" fi ## - edit /usr/local/dovecot/etc/dovecot/conf.d/10-master.conf ## - ## - unix_listener /var/spool/postfix/private/dovecot-lmtp { ## - mode = 0600 ## - user = postfix ## - group = postfix ## - } ## - echononl "\tAdding dovecot-lmtp listener to 10-master.conf" perl -i -n -p -e "s#^([ ]*)(unix_listener\ +lmtp\ .*)#\1unix_listener /var/spool/postfix/private/dovecot-lmtp {\n user = postfix\n mode = 0660\n group = postfix#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf failed" fi # - /etc/postfix/main.cf # - # - comment in: # - #virtual_transport = dovecot # - #dovecot_destination_recipient_limit = .. # - # - change: # - smtpd_sasl_auth_enable = yes # - smtpd_sasl_type = dovecot # - smtpd_sasl_path = private/dovecot-auth # - virtual_transport = lmtp:unix:private/dovecot-lmtp var="smtpd_sasl_auth_enable" val="yes" echononl "\t${postfix_main_cf}: adjust '${var}'.." if ! $(grep -E -q "^\s*${var}\s*=\s*${val}" ${postfix_main_cf} 2> /dev/null) ; then perl -i -n -p -e "s#^(\s*)(${var}\ *=.*)#${var} = ${val}#" \ /etc/postfix/main.cf > $log_file 2>&1 if [[ $? -eq 0 ]]; then echo_ok changed=true else echo_failed error "$(cat "$log_file")" fi else echo_skipped fi var="smtpd_sasl_type" val="dovecot" echononl "\t${postfix_main_cf}: adjust '${var}'.." if ! $(grep -E -q "^\s*${var}\s*=\s*${val}" ${postfix_main_cf} 2> /dev/null) ; then perl -i -n -p -e "s#^(\s*)(${var}\ *=.*)#${var} = ${val}#" \ /etc/postfix/main.cf > $log_file 2>&1 if [[ $? -eq 0 ]]; then echo_ok changed=true else echo_failed error "$(cat "$log_file")" fi else echo_skipped fi var="smtpd_sasl_path" val="private/dovecot-auth" echononl "\t${postfix_main_cf}: adjust '${var}'.." if ! $(grep -E -q "^\s*${var}\s*=\s*${val}" ${postfix_main_cf} 2> /dev/null) ; then perl -i -n -p -e "s#^(\s*)(${var}\ *=.*)#${var} = ${val}#" \ /etc/postfix/main.cf > $log_file 2>&1 if [[ $? -eq 0 ]]; then echo_ok changed=true else echo_failed error "$(cat "$log_file")" fi else echo_skipped fi var="virtual_transport" val="lmtp:unix:private/dovecot-lmtp" echononl "\t${postfix_main_cf}: adjust '${var}'.." if ! $(grep -E -q "^\s*${var}\s*=\s*${val}" ${postfix_main_cf} 2> /dev/null) ; then perl -i -n -p -e "s#^(\s*)(${var}\ *=.*)#${var} = ${val}#" \ /etc/postfix/main.cf > $log_file 2>&1 if [[ $? -eq 0 ]]; then echo_ok else echo_failed changed=true error "$(cat "$log_file")" fi else echo_skipped fi echononl "\tComment variable 'dovecot_destination_recipient_limit'.." if $(grep -E -q "^\s*dovecot_destination_recipient_limit" ${postfix_main_cf} 2> /dev/null) ; then perl -i-n -p -e "s/^(\s*)(dovecot_destination_recipient_limit.*)/\1\#\2/" /etc/postfix/main.cf > $log_file 2>&1 if [[ $? -eq 0 ]]; then echo_ok changed=true else echo_failed error "$(cat "$log_file")" fi else echo_skipped fi ## ----------------- ## --- Configure quota support for dovecot echo echo -e "\033[1mConfigure quota support for dovecot\033[m" ## - take care quota plugins (quota,imap-quota) will ## - be loaded: ## - ## - there are two quota related plugins: ## - ## - * quota: implements the actual quota handling and includes also all the quota backends. ## - * imap_quota: for reporting quota information via imap. ## - ## - enable them in configuration files, e.g.: ## - ## - conf.d/10-mail.conf: ## - ## - # space separated list of plugins to load for all services. plugins specific to ## - # imap, lda, etc. are added to this list in their own .conf files. ## - mail_plugins = $mail_plugins quota ## - ## - conf.d/20-imap.conf: ## - ## - protocol imap { ## - # space separated list of plugins to load (default is global mail_plugins). ## - mail_plugins = $mail_plugins imap_quota ## - } ## - ## - we have done it befor, at the basic configuration ## - ## - configure dict service ## - ## - edit /usr/local/dovecot/etc/dovecot/conf.d/10-master.conf ## - ## - add: ## - ## - service dict { ## - unix_listener dict { ## - mode = 0600 ## - user = vmail ## - } ## - } ## - _failed=false echononl "\tConfigure dict service (10-master.conf)" perl -i -n -p -e "s#^([ ]*)(unix_listener\ +dict.*)#\1\2\n\1 mode = 0600\n\1 user = vmail#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf || _failed=true if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf failed" fi ## - edit /usr/local/dovecot/etc/dovecot/dovecot.conf ## - ## - add: ## - ## - dict { ## - quota = $db_driver:/usr/local/dovecot/etc/dovecot/sql-dict.conf.ext ## - } _failed=false echononl "\tAdjust file dovecot.conf for (dict) quota service" perl -i -n -p -e "s#^([ ]*)(dict\ +{.*)#\1\2\n\1 quota = $db_driver:/usr/local/dovecot/etc/dovecot/sql-dict.conf.ext#g" \ /usr/local/dovecot-${_version}/etc/dovecot/dovecot.conf || _failed=true if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/dovecot.conf failed" fi if $_new ; then if [ "$db_driver" = "pgsql" ]; then echononl "\tCreate table quota2 in database \"$dbname\".." cat << EOF | psql -U$dbuser $dbname > /dev/null 2>&1 CREATE TABLE IF NOT EXISTS quota2 ( username varchar(100) not null, bytes bigint not null default 0, messages integer not null default 0, primary key (username) ); EOF if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "Creating table quota2 in database \"$dbname\" failed" fi echononl "\tCreate Trigger mergequota2.." cat << EOF | psql -U$dbuser $dbname > /dev/null 2>&1 CREATE PROCEDURAL LANGUAGE plpgsql; CREATE FUNCTION merge_quota2() RETURNS trigger LANGUAGE plpgsql AS \$\$ BEGIN IF NEW.messages < 0 OR NEW.messages IS NULL THEN -- ugly kludge: we came here from this function, really do try to insert IF NEW.messages IS NULL THEN NEW.messages = 0; ELSE NEW.messages = -NEW.messages; END IF; return NEW; END IF; LOOP UPDATE quota2 SET bytes = bytes + NEW.bytes, messages = messages + NEW.messages WHERE username = NEW.username; IF found THEN RETURN NULL; END IF; BEGIN IF NEW.messages = 0 THEN INSERT INTO quota2 (bytes, messages, username) VALUES (NEW.bytes, NULL, NEW.username); ELSE INSERT INTO quota2 (bytes, messages, username) VALUES (NEW.bytes, -NEW.messages, NEW.username); END IF; return NULL; EXCEPTION WHEN unique_violation THEN -- someone just inserted the record, update it END; END LOOP; END; \$\$; CREATE TRIGGER mergequota2 BEFORE INSERT ON quota2 FOR EACH ROW EXECUTE PROCEDURE merge_quota2(); EOF if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Creating function merge_quota2() / trigger merge_quota2 failed" fi elif [ "$db_driver" = "mysql" ]; then echononl "\tCreate table quota2 in database \"$dbname\".." cat << EOF | mysql -u$dbuser -p$dbpassword $dbname > /dev/null 2>&1 CREATE TABLE IF NOT EXISTS quota2 ( username varchar(100) not null, bytes bigint not null default 0, messages integer not null default 0, primary key (username) ); EOF if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "Creating table quota2 in database \"$dbname\" failed" fi fi fi _failed=false echononl "\tRenew file sql-dict.conf.ext" if [ "$db_driver" = "pgsql" ]; then cat </usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext ## - if using unix-socket (host=/var/run/postgresql) ensure that ## - coresponding entries in pg_hba.cof fits ## - for example ## - local all all md5 ## - connect = host=$dbhost user=$dbuser password=$dbpassword dbname=$dbname # CREATE TABLE quota2 ( # username varchar(100) not null, # bytes bigint not null default 0, # messages integer not null default 0, # primary key (username) # ); # ## - if using postgres, you need also to create a trigger as follows: ## - ## - first create language plpgsql if not yet created: ## - # CREATE PROCEDURAL LANGUAGE plpgsql; # # CREATE FUNCTION merge_quota2() RETURNS trigger # LANGUAGE plpgsql # AS \$\$ # BEGIN # IF NEW.messages < 0 OR NEW.messages IS NULL THEN # -- ugly kludge: we came here from this function, really do try to insert # IF NEW.messages IS NULL THEN # NEW.messages = 0; # ELSE # NEW.messages = -NEW.messages; # END IF; # return NEW; # END IF; # # LOOP # UPDATE quota2 SET bytes = bytes + NEW.bytes, # messages = messages + NEW.messages # WHERE username = NEW.username; # IF found THEN # RETURN NULL; # END IF; # # BEGIN # IF NEW.messages = 0 THEN # INSERT INTO quota2 (bytes, messages, username) VALUES (NEW.bytes, NULL, NEW.username); # ELSE # INSERT INTO quota2 (bytes, messages, username) VALUES (NEW.bytes, -NEW.messages, NEW.username); # END IF; # return NULL; # EXCEPTION WHEN unique_violation THEN # -- someone just inserted the record, update it # END; # END LOOP; # END; # \$\$; # # # ALTER FUNCTION public.merge_quota2() OWNER TO postfix; # # CREATE TRIGGER mergequota2 # BEFORE INSERT ON quota2 # FOR EACH ROW # EXECUTE PROCEDURE merge_quota2(); map { pattern = priv/quota/storage table = quota2 username_field = username value_field = bytes } map { pattern = priv/quota/messages table = quota2 username_field = username value_field = messages } EOF if [[ "$?" -gt 0 ]]; then _failed=true fi if $plugin_expire ; then cat <> /usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext # CREATE TABLE expires ( # username varchar(100) not null, # mailbox varchar(255) not null, # expire_stamp integer not null, # primary key (username, mailbox) # ); ## - if using postgres, you need also to create a trigger as follows: ## - ## - first create language plpgsql if not yet created: ## - # CREATE LANGUAGE plpgsql; # # CREATE OR REPLACE FUNCTION merge_expires() RETURNS TRIGGER AS \$\$ # BEGIN # UPDATE expires SET expire_stamp = NEW.expire_stamp # WHERE username = NEW.username AND mailbox = NEW.mailbox; # IF FOUND THEN # RETURN NULL; # ELSE # RETURN NEW; # END IF; # END; # \$\$ LANGUAGE plpgsql; # # CREATE TRIGGER mergeexpires BEFORE INSERT ON expires # FOR EACH ROW EXECUTE PROCEDURE merge_expires(); map { pattern = shared/expire/\$user/\$mailbox table = expires value_field = expire_stamp fields { username = \$user mailbox = \$mailbox } } EOF if [[ "$?" -gt 0 ]]; then _failed=true fi fi if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Recreating file /usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext failed" fi ## - you also have to update the userdb's query in file ## - "/usr/local/dovecot/etc/dovecot/sql-connect.conf.ext" to ## - support extra variable "quota_rule" ## - echononl "\tRenew file sql-connect.conf.ext" cat < /usr/local/dovecot-${_version}/etc/dovecot/sql-connect.conf.ext driver = $db_driver ## - if using unix-socket (host=/var/run/postgresql) ensure that ## - coresponding entries in pg_hba.cof fits ## - for example ## - local all all md5 ## - connect = host=$dbhost user=$dbuser password=$dbpassword dbname=$dbname default_pass_scheme = $default_pass_scheme password_query = SELECT username AS user, password \\ FROM mailbox \\ WHERE username = '%u' AND active = true user_query = SELECT '/var/vmail/' || maildir AS home, \\ '5000' AS uid, '5000' AS gid, \\ '*:bytes=' || quota AS quota_rule \\ FROM mailbox \\ WHERE username = '%u' AND active = true ## - Query to get a list of all usernames. ## - iterate_query = SELECT username AS user FROM mailbox EOF if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Recreating file /usr/local/dovecot-${_version}/etc/dovecot/sql-connect.conf.ext failed" fi elif [ "$db_driver" = "mysql" ]; then cat </usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext connect = host=$dbhost user=$dbuser password=$dbpassword dbname=$dbname # CREATE TABLE quota2 ( # username varchar(100) not null, # bytes bigint not null default 0, # messages integer not null default 0, # primary key (username) # ); map { pattern = priv/quota/storage table = quota2 username_field = username value_field = bytes } map { pattern = priv/quota/messages table = quota2 username_field = username value_field = messages } EOF if [[ "$?" -gt 0 ]]; then _failed=true fi if $plugin_expire ; then cat <> /usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext # CREATE TABLE expires ( # username varchar(100) not null, # mailbox varchar(255) not null, # expire_stamp integer not null, # primary key (username, mailbox) # ); map { pattern = shared/expire/\$user/\$mailbox table = expires value_field = expire_stamp fields { username = \$user mailbox = \$mailbox } } EOF if [[ "$?" -gt 0 ]]; then _failed=true fi fi if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Recreating file /usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext failed" fi ## - you also have to update the userdb's query in file ## - "/usr/local/dovecot/etc/dovecot/sql-connect.conf.ext" to ## - support extra variable "quota_rule" ## - echononl "\tRenew file sql-connect.conf.ext" cat < /usr/local/dovecot-${_version}/etc/dovecot/sql-connect.conf.ext driver = $db_driver connect = host=$dbhost user=$dbuser password=$dbpassword dbname=$dbname default_pass_scheme = $default_pass_scheme password_query = SELECT username AS user, password \\ FROM mailbox \\ WHERE username = '%u' AND active = true user_query = SELECT CONCAT('/var/vmail/',maildir) AS home, \\ '5000' AS uid, '5000' AS gid, \\ CONCAT('*:bytes=',quota) AS quota_rule \\ FROM mailbox \\ WHERE username = '%u' AND active = true ## - Query to get a list of all usernames. ## - iterate_query = SELECT username AS user FROM mailbox EOF if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Recreating file /usr/local/dovecot-${_version}/etc/dovecot/sql-connect.conf.ext failed" fi fi ## - configure stats service (10-master.conf) ## - echononl "\tConfigure stats service (10-master.conf)" cat <> /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf service stats { fifo_listener stats-mail { user = vmail group = dovecot mode = 0660 } unix_listener stats-reader { user = vmail group = dovecot mode = 0660 } unix_listener stats-writer { user = vmail group = dovecot mode = 0660 } } EOF if [[ $? -gt 0 ]] ; then echo -e "$rc_failed" error "Configure stats service (10-master.conf) failed!" else echo -e "$rc_done" fi ## - configure post-login service (10-master.conf) ## - ## - see also: https://wiki.dovecot.org/PostLoginScripting ## - echononl "\tAdd script '/usr/local/dovecot-${_version}/bin/post-login.sh'.." cat < /usr/local/dovecot-${_version}/bin/post-login.sh #!/usr/bin/env bash touch ~/.last_login exec "\$@" EOF if [[ $? -gt 0 ]] ; then echo -e "$rc_failed" error "Adding script '/usr/local/dovecot-${_version}/bin/post-login.sh' failed!" else echo -e "$rc_done" fi echononl "\tSet Permissions of 'post-login.sh' .." chmod 755 "/usr/local/dovecot-${_version}/bin/post-login.sh" > /dev/null 2>&1 if [[ $? -gt 0 ]] ; then echo -e "$rc_failed" error "Setting permissions to '/usr/local/dovecot-${_version}/bin/post-login.sh' failed!" else echo -e "$rc_done" fi _failed=false echononl "\tConfigure post-login service (10-master.conf)" perl -i -n -p -e "s#^(\s*)(service\s+imap\s+{.*)#\1\2\n\1 \# tell imap to do post-login lookup using a socket called \"imap-postlogin\"\n\1 executable = imap post-login\n#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf || _failed=true perl -i -n -p -e "s#^(\s*)(service\s+pop3\s+{.*)#\1\2\n\1 \# tell imap to do post-login lookup using a socket called \"imap-postlogin\"\n\1 executable = pop3 post-login\n#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf || _failed=true cat <> /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-master.conf service post-login { # all post-login scripts are executed via script-login binary executable = script-login /usr/local/dovecot/bin/post-login.sh # the script process runs as the user specified here: user = vmail # this UNIX socket listener must use the same name as given to imap executable unix_listener post-login { } } EOF if [[ $? -gt 0 ]] ; then _failed=true fi if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Configuring 'post-login' service failed!" fi ## - edit /usr/local/dovecot/etc/dovecot/conf.d/90-quota.conf ## - ## - add to the end of file or in seperate plugin-blocks ## - as designed in that file: ## - plugin { ## - # sql backend: ## - quota = dict:user quota::proxy::quota ## - ## - quota_rule = *:storage=1g ## - quota_rule2 = trash:storage=+100m ## - ## - quota_warning = storage=95%% quota-warning 95 %u ## - quota_warning2 = storage=80%% quota-warning 80 %u ## - } ## - ## - service quota-warning { ## - executable = script /usr/local/bin/quota-warning.sh ## - user = vmail ## - unix_listener quota-warning { ## - user = vmail ## - mode = 0666 ## - } ## - } ## - echononl "\tAdjust file 90-quota.conf" cp -a /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-quota.conf \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-quota.conf.ORIG cat <>/usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-quota.conf ## - plugin { # SQL backend: quota = dict:User quota::proxy::quota quota_rule = *:storage=1G quota_rule2 = Trash:storage=+200M quota_warning = storage=95%% quota-warning 95 %u quota_warning2 = storage=80%% quota-warning 80 %u } service quota-warning { executable = script /usr/local/bin/quota-warning.sh user = vmail unix_listener quota-warning { user = vmail mode = 0666 } } EOF if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-quota.conf failed" fi if $_new ; then echononl "\tCreate quota warning script.." ## - create the user-warning script ## - cat </usr/local/bin/quota-warning.sh #!/usr/bin/env bash # author: zhang huangbin # purpose: send mail to notify user when his mailbox quota exceeds a # specified limit. # project: iredmail (http://www.iredmail.org/) LANG=en_US.UTF-8 percent=\$1 user=\$2 cat << EOF | /usr/local/dovecot/libexec/dovecot/deliver -d \${user} -c /usr/local/dovecot/etc/dovecot/dovecot.conf -o "plugin/quota=dict:User quota::noenforcing:proxy::quota" date: \`date +"%a, %e %b %Y %H:%M:%S %z"\` from: $from_address reply-to: $reply_to to:\${user} subject: mailbox quota warning: \${percent}% belegt. content-type: text/plain; charset=utf-8 Hallo! Deine Mailbox für das Postfach \${user} ist nun zu über \${percent}% voll. Damit Du weiterhin E-Mails empfangen kannst, lösche bitte vorhandene E-Mails vom Server. Dies geht zum Beispiel via Webmailer: $webmailer Viele Grüße $salutation ${_EOF:-EOF} EOF if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Create quota warning script /usr/local/bin/quota-warning.sh failed" fi chmod 755 /usr/local/bin/quota-warning.sh fi ## ----------------- ## --- Configure ACL support for dovecot ## - What to do: ## - ## - 1.) Add shared namespace ## - 2.) Add plugins to the several plugin lists ## - - "acl" to variable mail_plugins in 10-mail.conf ## - - "acl-imap" to variable mail_plugins in 20-imap.conf ## - ## - 3.a) Add acl to the plugin part in 90-acl.conf ## - ## - 3.b) To make shared mailboxes visible a database (dict) is needed. ## - This can also be a dict file. ## - Add acl_shared_dict to the plugin part of 90-acl.conf ## - ## - 4.) If using SQL backend, also a rule "acl =" in "dict" section ## - of file dovecont.conf needed ## - ## - edit /usr/local/dovecot/etc/dovecot/conf.d/10-mail.conf ## - ## - Add namespaces type shared to 10-mail.conf ## - Take care to enable ACL plugin also, otherwise all users can access all the shared ## - mailboxes, assuming they have permissions on filesystem level to do so. ## - we will do that later.. ## - namespace { ## - type = shared ## - separator = / ## - prefix = shared/%%u/ ## - location = maildir:/var/vmail/%%d/%%n/Maildir:INDEX=~/Maildir/shared/%%u ## - subscriptions = no ## - list = children ## - } ## - echononl "\tAdd namespaces type shared to 10-mail.conf" cat <> /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf namespace { #type = shared #separator = / type = shared separator = / # Mailboxes are visible under "shared/user@domain/" # %%n, %%d and %%u are expanded to the destination user. #prefix = shared/%%u/ prefix = shared/%%u/ # Mail location for other users' mailboxes. Note that %variables and ~/ # expands to the logged in user's data. %%n, %%d, %%u and %%h expand to the # destination user's data. #location = maildir:%%h/Maildir:INDEX=~/Maildir/shared/%%u location = maildir:/var/vmail/%%d/%%n/Maildir:INDEX=~/Maildir/shared/%%u # Use the default namespace for saving subscriptions. subscriptions = no # List the shared/ namespace only if there are visible shared mailboxes. list = children } EOF if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adding namespaces to /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf failed" fi ## - edit /usr/local/dovecot/etc/dovecot/conf.d/20-imap.conf ## - ## - mail_plugins = $mail_plugins imap_quota imap_acl ## - _failed=false echononl "\tAdd mail_plugin imap_acl to 20-imap.conf" perl -i -n -p -e "s#^([ ]*)\#?\ ?(mail_plugins\ +=.*)#\1\#\# \2\n\1mail_plugins = \\\$mail_plugins imap_quota imap_acl#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-imap.conf || _failed=true if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-imap.conf failed" fi ## - edit /usr/local/dovecot/etc/dovecot/conf.d/10-mail.conf ## - ## - mail_plugins = quota expire acl ## - _failed=false echononl "\tAdd mail_plugin acl to 10-mail.conf" if $plugin_expire ; then perl -i -n -p -e "s#^([ ]*)\#?\ ?(mail_plugins\ +=.*)#\1\#\# \2\n\1mail_plugins = quota expire acl#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true else perl -i -n -p -e "s#^([ ]*)\#?\ ?(mail_plugins\ +=.*)#\1\#\# \2\n\1mail_plugins = quota acl#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf || _failed=true fi if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-mail.conf failed" fi ## - !! Notice !! ## - There a two possibilities, configuring acl backend: ## - - flat file ## - - SQL dictionary ## - ## - On rage.so36.net we actually uses SQL dictionary not a flat file ## ----------------- ## - Using a flat file as dictionary backend ## - ## - edit /usr/local/dovecot/etc/dovecot/conf.d/90-acl.conf ## - ## - plugin { ## - # Without global ACLs: ## - acl = vfile ## - ## - # With global ACLs in /etc/dovecot/acls/ directory: ## - #acl = vfile:/etc/dovecot/acls ## - #acl = vfile:/etc/dovecot/acls:cache_secs=300 ## - } ## - ## - plugin { ## - #acl_shared_dict = file:/var/run/dovecot/shared-mailboxes.db ## - acl_shared_dict = file:/var/vmail/shared-mailboxes.db ## - } ## - #perl -i.ORIG -n -p -e "s#^([ ]*)\#?\ ?(acl\ +=.*)#\1\#\# \2\n\n\1\# Without global ACLs:\n\1acl = vfile\n\n\1\# With global ACLs in /etc/dovecot/acls/ directory:\n\1\#acl = vfile:/etc/dovecot/acls\n\1\#acl = vfile:/etc/dovecot/acls:cache_secs=300#g" \ # /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-acl.conf #perl -i -n -p -e "s#^([ ]*)\#?\ ?(acl_shared_dict\ +=.*)#\1\#\# \2\n\1acl_shared_dict = file:/var/vmail/shared-mailboxes.db#g" \ # /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-acl.conf ## - ## - End: Using a flat file as dictionary backend ## ------------------------------------------------------------------------ ## ------------------------------------------------------------------------ ## - Using SQL dictionary ## - ## - edit /usr/local/dovecot/etc/dovecot/conf.d/90-acl.conf ## - ## - plugin { ## - ## acl = vfile:/etc/dovecot/global-acls:cache_secs=300 ## - ## - # Without global ACLs: ## - acl = vfile ## - .. ## - } ## - plugin { ## - acl_shared_dict = proxy::acl ## - } ## - _failed=false echononl "\tConfigure acl (90-acl.conf)" perl -i.ORIG -n -p -e "s#^([ ]*)\#?\ ?(acl\ +=.*)#\1\#\# \2\n\n\1\# Without global ACLs:\n\1acl = vfile\n\n\1\# With global ACLs in /etc/dovecot/acls/ directory:\n\1\#acl = vfile:/etc/dovecot/acls\n\1\#acl = vfile:/etc/dovecot/acls:cache_secs=300#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-acl.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(acl_shared_dict\ +=.*)#\1\#\# \2\n\1acl_shared_dict = proxy::acl#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-acl.conf || _failed=true if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/conf.d/90-acl.conf failed" fi ## - edit /usr/local/dovecot/etc/dovecot/dovecot.conf ## - ## - dict { ## - acl = $db_driver:/usr/local/dovecot/etc/dovecot/sql-dict.conf.ext ## - ... ## - } ## - _failed=false echononl "\tAdjust file dovecot.conf for (dict) acl service" perl -i -n -p -e "s#^([ ]*)(dict\ +{.*)#\1\2\n\1 acl = $db_driver:/usr/local/dovecot/etc/dovecot/sql-dict.conf.ext#g" \ /usr/local/dovecot-${_version}/etc/dovecot/dovecot.conf || _failed=true if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/dovecot.conf failed" fi if $_new ; then if [ "$db_driver" = "pgsql" ]; then ## - Create tables user_shares / anyone_shares ## - echononl "\tCreate table user_share" cat << EOF | psql -U$dbuser $dbname > /dev/null 2>&1 CREATE TABLE IF NOT EXISTS user_shares ( from_user varchar(100) not null, to_user varchar(100) not null, dummy char(1) DEFAULT '1', -- always '1' currently primary key (from_user, to_user) ); COMMENT ON TABLE user_shares IS 'User from_user shares folders to user to_user.'; EOF if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "Creating table user_shares failed" fi echononl "\tCreate table anyone_shares" cat << EOF | psql -U$dbuser $dbname > /dev/null 2>&1 CREATE TABLE IF NOT EXISTS anyone_shares ( from_user varchar(100) not null, dummy char(1) DEFAULT '1', -- always '1' currently primary key (from_user) ); COMMENT ON TABLE anyone_shares IS 'User from_user shares folders to anyone.'; EOF if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "Creating table anyone_shares failed" fi elif [ "$db_driver" = "mysql" ]; then ## - Create table user_shares / anyone_shares ## - echononl "\tCreate table user_share" cat << EOF | mysql -u$dbuser -p$dbpassword $dbname > /dev/null 2>&1 CREATE TABLE IF NOT EXISTS user_shares ( from_user varchar(100) not null, to_user varchar(100) not null, dummy char(1) DEFAULT '1', -- always '1' currently primary key (from_user, to_user) ) COMMENT = 'User from_user shares folders to user to_user.'; EOF if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "Creating table user_shares failed" fi echononl "\tCreate table anyone_shares" cat << EOF | mysql -u$dbuser -p$dbpassword $dbname > /dev/null 2>&1 CREATE TABLE IF NOT EXISTS anyone_shares ( from_user varchar(100) not null, dummy char(1) DEFAULT '1', -- always '1' currently primary key (from_user) ) COMMENT = 'User from_user shares folders to anyone.'; EOF if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "Creating table anyone_shares failed" fi fi fi _failed=false echononl "\tRenew file sql-dict.conf.ext" if [ "$db_driver" = "pgsql" ]; then ## - adjust/renew file /usr/local/dovecot/etc/dovecot/sql-dict.conf.ext ## - cat </usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext ## - if using unix-socket (host=/var/run/postgresql) ensure that ## - coresponding entries in pg_hba.cof fits ## - for example ## - local all all md5 ## - connect = host=$dbhost user=$dbuser password=$dbpassword dbname=$dbname ## - NOTE: ## - ## - All changes on database (CREATE TABLE / CREATE TRIGGER / what else..) ## - need to be done as the dbuser (here postfix) under whom dovecot ## - accesses the database. If not, you have to change the permissiond to allow ## - dovecot dbuser to access the createt table/trigger/... ## - # CREATE TABLE quota2 ( # username varchar(100) not null, # bytes bigint not null default 0, # messages integer not null default 0, # primary key (username) # ); # ## - if using postgres, you need also to create a trigger as follows: ## - ## - first create language plpgsql if not yet created: ## - # CREATE PROCEDURAL LANGUAGE plpgsql; # # CREATE FUNCTION merge_quota2() RETURNS trigger # LANGUAGE plpgsql # AS \$\$ # BEGIN # IF NEW.messages < 0 OR NEW.messages IS NULL THEN # -- ugly kludge: we came here from this function, really do try to insert # IF NEW.messages IS NULL THEN # NEW.messages = 0; # ELSE # NEW.messages = -NEW.messages; # END IF; # return NEW; # END IF; # # LOOP # UPDATE quota2 SET bytes = bytes + NEW.bytes, # messages = messages + NEW.messages # WHERE username = NEW.username; # IF found THEN # RETURN NULL; # END IF; # # BEGIN # IF NEW.messages = 0 THEN # INSERT INTO quota2 (bytes, messages, username) VALUES (NEW.bytes, NULL, NEW.username); # ELSE # INSERT INTO quota2 (bytes, messages, username) VALUES (NEW.bytes, -NEW.messages, NEW.username); # END IF; # return NULL; # EXCEPTION WHEN unique_violation THEN # -- someone just inserted the record, update it # END; # END LOOP; # END; # \$\$; # # # ALTER FUNCTION public.merge_quota2() OWNER TO postfix; # # CREATE TRIGGER mergequota2 # BEFORE INSERT ON quota2 # FOR EACH ROW # EXECUTE PROCEDURE merge_quota2(); map { pattern = priv/quota/storage table = quota2 username_field = username value_field = bytes } map { pattern = priv/quota/messages table = quota2 username_field = username value_field = messages } EOF if [[ "$?" -gt 0 ]]; then _failed=true fi if $plugin_expire ; then cat <> /usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext # CREATE TABLE expires ( # username varchar(100) not null, # mailbox varchar(255) not null, # expire_stamp integer not null, # primary key (username, mailbox) # ); ## - if using postgres, you need also to create a trigger as follows: ## - ## - first create language plpgsql if not yet created: ## - # CREATE LANGUAGE plpgsql; # # CREATE OR REPLACE FUNCTION merge_expires() RETURNS TRIGGER AS \$\$ # BEGIN # UPDATE expires SET expire_stamp = NEW.expire_stamp # WHERE username = NEW.username AND mailbox = NEW.mailbox; # IF FOUND THEN # RETURN NULL; # ELSE # RETURN NEW; # END IF; # END; # \$\$ LANGUAGE plpgsql; # # CREATE TRIGGER mergeexpires BEFORE INSERT ON expires # FOR EACH ROW EXECUTE PROCEDURE merge_expires(); map { pattern = shared/expire/\$user/\$mailbox table = expires value_field = expire_stamp fields { username = \$user mailbox = \$mailbox } } EOF if [[ "$?" -gt 0 ]]; then _failed=true fi fi cat <> /usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext # CREATE TABLE user_shares ( # from_user varchar(100) not null, # to_user varchar(100) not null, # dummy char(1) DEFAULT '1', -- always '1' currently # primary key (from_user, to_user) # ); # COMMENT ON TABLE user_shares IS 'User from_user shares folders to user to_user.'; # # CREATE TABLE anyone_shares ( # from_user varchar(100) not null, # dummy char(1) DEFAULT '1', -- always '1' currently # primary key (from_user) # ); # COMMENT ON TABLE anyone_shares IS 'User from_user shares folders to anyone.'; map { pattern = shared/shared-boxes/user/\$to/\$from table = user_shares value_field = dummy fields { from_user = \$from to_user = \$to } } map { pattern = shared/shared-boxes/anyone/\$from table = anyone_shares value_field = dummy fields { from_user = \$from } } EOF if [[ "$?" -gt 0 ]]; then _failed=true fi if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Recreating file /usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext failed" fi elif [ "$db_driver" = "mysql" ]; then ## - adjust/renew file /usr/local/dovecot/etc/dovecot/sql-dict.conf.ext ## - cat </usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext connect = host=$dbhost user=$dbuser password=$dbpassword dbname=$dbname # CREATE TABLE quota2 ( # username varchar(100) not null, # bytes bigint not null default 0, # messages integer not null default 0, # primary key (username) # ); map { pattern = priv/quota/storage table = quota2 username_field = username value_field = bytes } map { pattern = priv/quota/messages table = quota2 username_field = username value_field = messages } EOF if [[ "$?" -gt 0 ]]; then _failed=true fi if $plugin_expire ; then cat <> /usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext # CREATE TABLE expires ( # username varchar(100) not null, # mailbox varchar(255) not null, # expire_stamp integer not null, # primary key (username, mailbox) # ); map { pattern = shared/expire/\$user/\$mailbox table = expires value_field = expire_stamp fields { username = \$user mailbox = \$mailbox } } EOF if [[ "$?" -gt 0 ]]; then _failed=true fi fi cat <> /usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext # CREATE TABLE user_shares ( # from_user varchar(100) not null, # to_user varchar(100) not null, # dummy char(1) DEFAULT '1', -- always '1' currently # primary key (from_user, to_user) # ) COMMENT = 'User from_user shares folders to user to_user.'; # # CREATE TABLE anyone_shares ( # from_user varchar(100) not null, # dummy char(1) DEFAULT '1', -- always '1' currently # primary key (from_user) # ) COMMENT = 'User from_user shares folders to anyone.'; map { pattern = shared/shared-boxes/user/\$to/\$from table = user_shares value_field = dummy fields { from_user = \$from to_user = \$to } } map { pattern = shared/shared-boxes/anyone/\$from table = anyone_shares value_field = dummy fields { from_user = \$from } } EOF if [[ "$?" -gt 0 ]]; then _failed=true fi if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Recreating file /usr/local/dovecot-${_version}/etc/dovecot/sql-dict.conf.ext failed" fi fi ## - ## - End: Using SQL dictionary ## ------------------------------------------------------------------------ ## ----------------- ## --- Configure managesieve support for dovecot ## - edit /usr/local/dovecot/etc/dovecot/conf.d/20-managesieve.conf ## - ## - service managesieve-login { ## - inet_listener sieve { ## - #address = 127.0.0.1 $ipv4 $ipv6 ## - address = 127.0.0.1 ## - port = 4190 ## - } ## - .. ## - } ## - _failed=false echononl "\tConfigure managesieve 20-managesieve.conf" perl -i.ORIG -n -p -e "s#^([ ]*)\#?\ ?(service managesieve-login\ +{.*)#\1service managesieve-login {#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-managesieve.conf || _failed=true if [[ -n "$ipv6" ]]; then perl -i -n -p -e "s#^([ ]*)\#?\ ?(inet_listener\ +sieve\ +{.*)#\1inet_listener sieve {\n\1 \#address = 127.0.0.1 $ipv4 $ipv6\n\1 address = 127.0.0.1\n\1 port = 4190\n\1}\n\1\#\# \2#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-managesieve.conf || _failed=true else perl -i -n -p -e "s#^([ ]*)\#?\ ?(inet_listener\ +sieve\ +{.*)#\1inet_listener sieve {\n\1 \#address = 127.0.0.1 $ipv4\n\1 address = 127.0.0.1\n\1 port = 4190\n\1}\n\1\#\# \2#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-managesieve.conf || _failed=true fi perl -i -n -p -e "s#^([ ]*\#?\ ?vsz_limit.*)#\1\n}#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-managesieve.conf || _failed=true perl -i -n -p -e "s#^([ ]*)\#?\ ?(service managesieve\ +{.*)#\1service managesieve {#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-managesieve.conf || _failed=true # since divecot 2.2.4: process_count changed to process_limit. # #perl -i -n -p -e "s#^([ ]*\#?\ ?process_count.*)#\1\n}#g" \ # /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-managesieve.conf || _failed=true perl -i -n -p -e "s#^([ ]*\#?\ ?process_limit.*)#\1\n}#g" \ /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-managesieve.conf || _failed=true if ! $_failed ; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Adjusting file /usr/local/dovecot-${_version}/etc/dovecot/conf.d/20-managesieve.conf failed" fi #_set_link="" #echo #echo "Set symlink " #echo -e -n " /usr/local/dovecot --> dovecot-${_version} /usr/local/dovecot? [y/n]: " #read _set_link #if [ "y" = "$_set_link" -o "Y" = "$_set_link" -o "Yes" = "$_set_link" -o "yes" = "$_set_link" ];then # echononl "\tCreate symlink.." # rm -f /usr/local/dovecot # ln -s dovecot-${_version} /usr/local/dovecot # if [ "$?" = 0 ]; then # echo -e "$rc_done" # else # echo -e "$rc_failed" # fatal "Creating Symlink /usr/local/dovecot --> dovecot-${_version} /usr/local/dovecot failed" # fi #fi ## - Add a cronjob to check if certifice/key for dovecot service is-up-to-date ## - echononl "\tCreate cronjob for checking if certifice/key for dovecot service is-up-to-date" if [[ -f "$_backup_crontab_file" ]] ; then if ! grep -e "/root/bin/monitoring/check_cert_for_dovecot.sh" "$_backup_crontab_file" > /dev/null ; then echo "" >> $_backup_crontab_file echo "# - Check if cert/key for dovecot service is up-to-date" >> $_backup_crontab_file echo "# -" >> $_backup_crontab_file echo "46 05 * * * /root/bin/monitoring/check_cert_for_dovecot.sh" >> $_backup_crontab_file crontab $_backup_crontab_file echo -e "$rc_done" else echo -e "$rc_skipped" fi else _crontab_tmp_file=/tmp/crontab_root.$$ crontab -l > $_crontab_tmp_file 2> /dev/null if [[ ! -s $_crontab_tmp_file ]]; then echo "PATH=/usr/local/dovecot/bin:$PATH" > $_crontab_tmp_file fi if ! grep -e "/root/bin/monitoring/check_cert_for_dovecot.sh" $_crontab_tmp_file > /dev/null ; then echo "" >> $_crontab_tmp_file echo "# - Check if cert/key for dovecot service is up-to-date" >> $_crontab_tmp_file echo "# -" >> $_crontab_tmp_file echo "46 05 * * * /root/bin/monitoring/check_cert_for_dovecot.sh" >> $_crontab_tmp_file crontab $_crontab_tmp_file echo -e "$rc_done" else echo -e "$rc_skipped" fi rm -f $_crontab_tmp_file fi echononl "\tRun script 'check_cert_for_dovecot.sh' if possible.." if [[ -x "/root/bin/monitoring/check_cert_for_dovecot.sh" ]] ; then /root/bin/monitoring/check_cert_for_dovecot.sh > $log_file 2>&1 if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "$(cat "$log_file")" fi else echo -e "$rc_skipped" fi blank_line echononl "\tCreate symlink '/usr/local/dovecot' --> 'dovecot-${_version}'.." rm -f /usr/local/dovecot ln -s dovecot-${_version} /usr/local/dovecot if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Creating Symlink /usr/local/dovecot --> dovecot-${_version} /usr/local/dovecot failed" fi #_restart="" #echo #echo -e -n "Start/Restart services (dovecot/postfix)? [y/n]: " #read _restart #if [ "y" = "$_restart" -o "Y" = "$_restart" -o "Yes" = "$_restart" -o "yes" = "$_restart" ];then # echononl "\tStart dovecot service.." # if $systemd_support ; then # systemctl start dovecot # else # /etc/init.d/dovecot start > /dev/null 2>&1 # fi # if [ "$?" = 0 ]; then # echo -e "$rc_done" # else # echo -e "$rc_failed" # error "Starting dovecot service failed" # fi # echononl "\tRestart postfix.." # if $SYSTEMD_EXISTS ; then # systemctl restart postfix # else # /etc/init.d/postfix restart > /dev/null 2>&1 # fi # if [ "$?" = 0 ]; then # echo -e "$rc_done" # else # echo -e "$rc_failed" # fatal "Restarting postfix failed" # fi #fi echononl "\tStart dovecot service.." if $systemd_support ; then systemctl start dovecot else /etc/init.d/dovecot start > /dev/null 2>&1 fi if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "Starting dovecot service failed" fi echononl "\tRestart postfix.." if $SYSTEMD_EXISTS ; then systemctl restart postfix else /etc/init.d/postfix restart > /dev/null 2>&1 fi if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" fatal "Restarting postfix failed" fi blank_line echononl "\tSet '_update=true' in file '$(basename "$conf_file")'.." if grep -q -E "^\s*_update=false" "$conf_file" 2> /dev/null ; then perl -i -n -p -e "s/^\s*_update=.*/_update=true/" "$conf_file" if [ "$?" = 0 ]; then echo -e "$rc_done" else echo -e "$rc_failed" error "Adjusting '"$conf_file"' (set _update=true) failed!" fi else echo -e "$rc_skipped" fi echo -e " \033[33m\033[1mNotice:\033[m The Dovecot Service is configured to support more than 128 simultanously connections. So, you have to \033[1mincrease /proc/sys/fs/inotify/max_user_instances\033[m (default is 128): # echo \"fs.inotify.max_user_instances = 2048\" >> /etc/sysctl.conf # sysctl -p If you are running dovecot on a Virtual Guest System, you have to do that on the Host (Root) System. " clean_up 0