Mailserver Script – Postfix, Dovcot, Spamassassin in 5 Minuten

Nach langem üben und unzähligen Experimenten wurde es mir irgendwann zu blöd das Grundgerüst eines Mailservers per Hand zu installieren. Da ich mich in letzter Zeit ein wenig mit dem Bash-Scripting beschäftigt habe, dachte ich sofort an ein Mailserver-Script. Leider habe ich noch nicht viel in der Bash gescriptet deshalb ist das ganze nicht sonderlich professionell gelöst aber es funktioniert einwandfrei in Debian Lenny, Squeeze und Wheezy ( Squeeze 32/64 bit getestet )

!!!Ohne Erfahrung sollte man das Script auf keinen Fall verwenden!!!
Für das ganze gilt natürlich absolut keine Garantie. Der Server ist zwar dicht aber man sollte vielleicht dennoch ein wenig an den Restrictions feilen. Das ganze dient auch nur um das aufsetzen eines Mailservers zu beschleunigen. Man sollte die Installation und die Konfigurationsdatein zumindest prüfen.

Related:

New MailServer Script which installs Postfix, Postfixadmin, Dovecot, Spamassassin, ClamAV and LLMP.

!!!Läuft nach dem großem Sprung von Dovecot auf 2.2.10 nur noch unter Squeeze und Lenny!!! 8.1.’14 – einige kleine Änderungen

Für den ganzen Spaß benötigt man zusätzlich nur ein SSL-Zertifikat, dass auch z.B selbst gezeichnet sein kann. Vielleicht an anderer Stelle ein kleines HowTo zu StartSSL und CaCert.org, die ersten Anlaufstellen für kostenlose Zertifikate, die auch von modernen Webbrowsern aktzeptiert werden.


#cd /tmp
#nano mailscript.sh

In /tmp/mailscript.sh

#!/bin/bash
red='e[0;31m'
NC='e[0m' # No Color
echo -e "${red}
Copyright (C) 2013 Alexander Krischan

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

I am a Mailserver Script for Postfix, Dovecot, Spamassassin and Spamass-Milter.

Run on a freshly installed server under root, may not work under an already setup server!

Compability: fresh Debian 5,6 or 7

!!!NO WARRANTY!!!"
read -p "Continue? [y/n]: " A
if [ "$A" == "" -o "$A" == "y" ];then
echo "OK."
read -p "Delay warning time?[e.g: 4h]: " B
read -p "Hostname [MX-Record: mail.example.com]: " myhostname
read -p "Domain [e.g: example.com]: " domain
read -p "Mydestination [separate with comma ',']: " destination
read -p "Mynetworks [ Already: 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128, add more? " network
apt-get update && apt-get --yes upgrade
apt-get --yes install nano htop unzip zip aptitude
apt-get --yes install postfix
rm -fr /etc/postfix/main.cf
touch /etc/postfix/main.cf
echo "smtpd_banner = $myhostname ESMTP" >> /etc/postfix/main.cf
echo "biff = no" >> /etc/postfix/main.cf
echo "append_dot_mydomain = no" >> /etc/postfix/main.cf
echo "delay_warning_time = $B" >> /etc/postfix/main.cf
echo "smtpd_require_helo = yes" >> /etc/postfix/main.cf
echo "smtpd_client_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_invalid_hostname, reject_unknown_client, reject_rbl_client sbl-xbl.spamhaus.org" >> /etc/postfix/main.cf
echo "smtpd_sender_restrictions = permit_mynetworks, reject_unknown_address, reject_unknown_sender_domain, reject_non_fqdn_sender" >> /etc/postfix/main.cf
echo "smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination" >> /etc/postfix/main.cf
echo "smtpd_recipient_limit = 250" >> /etc/postfix/main.cf
echo "broken_sasl_auth_clients = yes" >> /etc/postfix/main.cf
echo "myhostname = $myhostname" >> /etc/postfix/main.cf
echo "mydomain = $domain" >> /etc/postfix/main.cf
echo "alias_maps = hash:/etc/aliases" >> /etc/postfix/main.cf
echo "myorigin = $domain" >> /etc/postfix/main.cf
echo "mydestination = $destination" >> /etc/postfix/main.cf
echo "relayhost =" >> /etc/postfix/main.cf
echo "mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 $network" >> /etc/postfix/main.cf
echo "mailbox_size_limit = 0" >> /etc/postfix/main.cf
echo "recipient_delimiter = +" >> /etc/postfix/main.cf
echo "inet_interfaces = all" >> /etc/postfix/main.cf
echo "virtual_mailbox_domains = /etc/postfix/virtual_domains" >> /etc/postfix/main.cf
echo "virtual_mailbox_base = /var/mail/vhosts" >> /etc/postfix/main.cf
echo "virtual_mailbox_maps = hash:/etc/postfix/vmailbox" >> /etc/postfix/main.cf
echo "virtual_alias_maps = hash:/etc/postfix/virtual_alias" >> /etc/postfix/main.cf
echo "virtual_minimum_uid = 100" >> /etc/postfix/main.cf
echo "virtual_uid_maps = static:5000" >> /etc/postfix/main.cf
echo "virtual_gid_maps = static:5000" >> /etc/postfix/main.cf
echo "virtual_transport = dovecot" >> /etc/postfix/main.cf
echo "dovecot_destination_recipient_limit = 1" >> /etc/postfix/main.cf
echo "mailbox_size_limit = 0" >> /etc/postfix/main.cf
echo "smtpd_sasl_auth_enable = yes" >> /etc/postfix/main.cf
echo "smtpd_sasl_type = dovecot" >> /etc/postfix/main.cf
echo "smtpd_sasl_path = private/auth" >> /etc/postfix/main.cf
echo "smtpd_sasl_security_options = noanonymous" >> /etc/postfix/main.cf
echo "smtpd_sasl_local_domain = $domain" >> /etc/postfix/main.cf
groupadd -g 5000 vmail
useradd -s /usr/sbin/nologin -u 5000 -g 5000 vmail
mkdir -p /var/mail/vhosts/"$domain"
chown -R vmail:vmail /var/mail/vhosts
touch /etc/postfix/virtual_domains
touch /etc/postfix/vmailbox
touch /etc/postfix/virtual_alias
postmap /etc/postfix/vmailbox
postmap /etc/postfix/virtual_alias
usermod -aG vmail postfix
touch /var/log/dovecot
chgrp vmail /var/log/dovecot
chmod 660 /var/log/dovecot
invoke-rc.d postfix restart
elif [ "$A" == "n" ];then
echo "Abort."
exit
else
echo "Wrong."
exit
fi

read -p "TLS-Support [y/n]? You will need a valid SSL-Cert: " tls
if [ "$tls" == "y" ];then
read -p "SSL-Cert .pem-File [Name only, saved at: /etc/ssl/certs/]: " pem
read -p "SSL-Cert-Key-File .key-File [Name only, Speicherort: /etc/ssl/private]: " key
echo "smtpd_use_tls=yes" >> /etc/postfix/main.cf
echo "smtpd_tls_security_level = may" >> /etc/postfix/main.cf
echo "smtpd_tls_auth_only = no" >> /etc/postfix/main.cf
echo "smtpd_tls_cert_file=/etc/ssl/certs/$pem" >> /etc/postfix/main.cf
echo "smtpd_tls_key_file=/etc/ssl/private/$key" >> /etc/postfix/main.cf
echo 'smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache' >> /etc/postfix/main.cf
echo "smtpd_tls_received_header = yes" >> /etc/postfix/main.cf
echo "tls_random_source = dev:/dev/urandom" >> /etc/postfix/main.cf
invoke-rc.d postfix restart
else
echo "No TLS-Support, Done."
fi

read -p "Install Dovecot IMAP/POP3 Service? y/n: " dovecot
if [ "$dovecot" == "y" ];then
apt-get --yes install dovecot-imapd dovecot-pop3d
else
echo "Abort."
fi

read -p "Configure Dovecot? [y/n]: " s
if [ "$s" == "y" ];then
read -p "Hostname? - MX-Record: " hostname
read -p "Postmaster-Adress - e.g. postmaster@example.com: " postmaster
echo "protocols = imap imaps pop3 pop3s" > /etc/dovecot/dovecot.conf
echo "disable_plaintext_auth = no" >> /etc/dovecot/dovecot.conf
echo "log_path = /var/log/dovecot" >> /etc/dovecot/dovecot.conf
echo 'log_timestamp = "%Y-%m-%d %H:%M:%S"' >> /etc/dovecot/dovecot.conf
echo "mail_location = maildir:/var/mail/vhosts/%d/%n" >> /etc/dovecot/dovecot.conf
echo "mail_privileged_group = mail" >> /etc/dovecot/dovecot.conf
echo "protocol imap {" >> /etc/dovecot/dovecot.conf
echo "}" >> /etc/dovecot/dovecot.conf
echo "protocol pop3 {" >> /etc/dovecot/dovecot.conf
echo "pop3_uidl_format = %08Xu%08Xv" >> /etc/dovecot/dovecot.conf
echo "}" >> /etc/dovecot/dovecot.conf
echo "protocol managesieve {" >> /etc/dovecot/dovecot.conf
echo "}" >> /etc/dovecot/dovecot.conf
echo "protocol lda {" >> /etc/dovecot/dovecot.conf
echo " hostname = $hostname" >> /etc/dovecot/dovecot.conf
echo " postmaster_address = $postmaster" >> /etc/dovecot/dovecot.conf
echo " auth_socket_path = /var/run/dovecot/auth-master" >> /etc/dovecot/dovecot.conf
echo " mail_plugin_dir = /usr/lib/dovecot/modules/lda" >> /etc/dovecot/dovecot.conf
echo " mail_plugins = sieve" >> /etc/dovecot/dovecot.conf
echo " sieve_extensions = +imapflags" >> /etc/dovecot/dovecot.conf
echo "}" >> /etc/dovecot/dovecot.conf
echo "auth_verbose = yes" >> /etc/dovecot/dovecot.conf
echo "auth default {" >> /etc/dovecot/dovecot.conf
echo " mechanisms = plain login" >> /etc/dovecot/dovecot.conf
echo " userdb passwd-file {" >> /etc/dovecot/dovecot.conf
echo " args = /var/mail/vhosts/%d/passwd" >> /etc/dovecot/dovecot.conf
echo " }" >> /etc/dovecot/dovecot.conf
echo " passdb passwd-file {" >> /etc/dovecot/dovecot.conf
echo " args = /var/mail/vhosts/%d/shadow" >> /etc/dovecot/dovecot.conf
echo " }" >> /etc/dovecot/dovecot.conf
echo " socket listen {" >> /etc/dovecot/dovecot.conf
echo " client {" >> /etc/dovecot/dovecot.conf
echo " path = /var/spool/postfix/private/auth" >> /etc/dovecot/dovecot.conf
echo " mode = 0660" >> /etc/dovecot/dovecot.conf
echo " user = postfix" >> /etc/dovecot/dovecot.conf
echo " group = vmail" >> /etc/dovecot/dovecot.conf
echo " }" >> /etc/dovecot/dovecot.conf
echo " master {" >> /etc/dovecot/dovecot.conf
echo " path =" /var/run/dovecot/auth-master >> /etc/dovecot/dovecot.conf
echo " mode = 0600" >> /etc/dovecot/dovecot.conf
echo " user = vmail" >> /etc/dovecot/dovecot.conf
echo " group = vmail" >> /etc/dovecot/dovecot.conf
echo " }" >> /etc/dovecot/dovecot.conf
echo " }" >> /etc/dovecot/dovecot.conf
echo "}" >> /etc/dovecot/dovecot.conf
echo "plugin" { >> /etc/dovecot/dovecot.conf
echo "}" >> /etc/dovecot/dovecot.conf
invoke-rc.d dovecot restart
else
echo "Abort."
fi

read -p "SSL-Support? [y/n]: " dovessl
if [ "$dovessl" == "y" ];then
echo "ssl = yes" >> /etc/dovecot/dovecot.conf
echo "ssl_cert_file = /etc/ssl/certs/$pem" >> /etc/dovecot/dovecot.conf
echo "ssl_key_file = /etc/ssl/private/$key" >> /etc/dovecot/dovecot.conf
invoke-rc.d dovecot restart
else
echo "No SSL-Support"
fi

read -p "Configure Master.cf for Dovecot? [y/n] " dove
if [ "$dove" == "y" ];then
echo "dovecot unix - n n - - pipe" >> /etc/postfix/master.cf
echo ' flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${recipient}' >> /etc/postfix/master.cf
invoke-rc.d postfix restart
invoke-rc.d dovecot restart
else
echo "Abort."
fi

read -p "Addmailuser-Script? [y/n] " dove
if [ "$dove" == "y" ];then
cp /tmp/addmailuser /usr/local/bin/addmailuser
chmod a+x /usr/local/bin/addmailuser
else
echo "No addmailuser Script. You will have to add your Users manualy."
fi

read -p "Install Spamassassin and Spamass-Milter? [y/n]?: " spam
if [ "$dove" == "y" ];then
apt-get --yes install spamass-milter
groupadd spamd
useradd -g spamd -s /bin/false -d /var/lib/spamassassin spamd
mkdir /var/lib/spamassassin
chown spamd.spamd /var/lib/spamassassin -R
mkdir /var/run/spamassassin
usermod -a -G spamd spamass-milter
echo "# /etc/default/spamassassin" > /etc/default/spamassassin
echo '# Duncan Findlay' >> /etc/default/spamassassin
echo 'ENABLED=1' >> /etc/default/spamassassin
echo 'OPTIONS="--username spamd --nouser-config --max-children 2 --helper-home-dir ${SAHOME} --socketpath=/var/run/spamassassin/spamd.sock --socketowner=spamd --socketgroup=spamd --socketmode=0660"' >> /etc/default/spamassassin
echo 'PIDFILE="/var/run/spamassassin/spamd.pid"' >> /etc/default/spamassassin
echo 'CRON=1' >> /etc/default/spamassassin
echo 'SAHOME="/var/lib/spamassassin"' >> /etc/default/spamassassin
echo '# spamass-milt startup defaults' > /etc/default/spamass-milter
echo 'OPTIONS="-u spamass-milter -m -I -i 127.0.0.1 -- --socket=/var/run/spamassassin/spamd.sock"' >> /etc/default/spamass-milter
echo '# Reject emails with spamassassin scores > 15.' >> /etc/default/spamass-milter
echo '#OPTIONS="-r 15"' >> /etc/default/spamass-milter
echo '# Do not modify Subject:, Content-Type: or body.' >> /etc/default/spamass-milter
echo '#OPTIONS="-m"' >> /etc/default/spamass-milter
else
echo "!!!No Spam Protection!!!"
fi
read -p "Configure Postfix for Spamassassin/Spamass-Miler [y/n]: " conspam
if [ "$conspam" == "y" ];then
echo '#Spamass Milter' >> /etc/postfix/main.cf
echo 'smtpd_milters = unix:/spamass/spamass.sock' >> /etc/postfix/main.cf
echo 'milter_connect_macros = j {daemon_name} v {if_name} _' >> /etc/postfix/main.cf
echo 'milter_default_action = tempfail' >> /etc/postfix/main.cf
else
echo "!!!No Spam Protection!!!"
exit
fi
echo "Done."
exit

 

In /tmp/addmailuser

#!/bin/bash
#
# Script to add users for
# Dovecot/PostFix using Virtual Users

USAGE="Usage: $0 EMAIL [PASSWORD] [BASEDIR]";

if [ ! -n "$1" ]
then
echo $USAGE;
exit 1;
fi

USERNAME=$(echo "$1" | cut -f1 -d@);
DOMAIN=$(echo "$1" | cut -f2 -d@);
ADDRESS=$1;

MAILBOXMAP=$(postconf | grep ^virtual_mailbox_maps | cut -f3 -d' ' | cut -f2 -d:)

if [ -f $MAILBOXMAP ]
then
echo mailbox file exist, checking existing mailboxes
COUNT=$(grep $ADDRESS $MAILBOXMAP | wc -l)
if [ ! $COUNT -eq 0 ]
then
echo Email already exist... breaking!
exit 2;
fi
fi

if [ ! -n "$2" ]
then
echo "Password is not set... creating new one";
PASSWD=$(cat /dev/urandom | tr -dc [:alnum:] | head -c8);
echo -e "email is $ADDRESS, password is set to $PASSWD"
else
PASSWD=$2;
fi

if [ -n "$3" ]
then
if [ ! -d "$3" ]
then
echo $USAGE;
echo "BASEDIR must be a valid directory!";
echo "I would have tried, $(postconf | grep ^virtual_mailbox_base | cut -f3 -d' ')";
exit 2;
else
BASEDIR="$3";
fi
else
BASEDIR="$(postconf | grep ^virtual_mailbox_base | cut -f3 -d' ')";
fi

echo "Adding Postfix user configuration..."
echo -e "$ADDRESSt$DOMAIN/$USERNAME/" >> $MAILBOXMAP
postmap $MAILBOXMAP

if [ $? -eq 0 ]
then

if [ ! -d /$BASEDIR/$DOMAIN/ ]
then
echo domain directory does not exist. creating new one
mkdir -p $BASEDIR/$DOMAIN/
chown -R vmail:vmail $BASEDIR/$DOMAIN/
fi

echo "Adding Dovecot user configuration..."
echo $ADDRESS::5000:5000::$BASEDIR/$DOMAIN/$USERNAME >> $BASEDIR/$DOMAIN/passwd
echo $ADDRESS":"$(dovecotpw -p $PASSWD) >> $BASEDIR/$DOMAIN/shadow
chown root:root $BASEDIR/$DOMAIN/passwd && chmod 600 $BASEDIR/$DOMAIN/passwd
chown root:root $BASEDIR/$DOMAIN/shadow && chmod 600 $BASEDIR/$DOMAIN/shadow
/etc/init.d/postfix reload
fi


 

Rechte vergeben und die Zertifikate kopieren:

#chmod +x /tmp/addmailuser /tmp/mailscript.sh

Nach den Namen der Zertifikate werdet ihr während der Installation gefragt, man sollte sie vorher in /etc/ssl/certs und /etc/ssl/private platzieren. Bei der Postfix Installation unbedingt “Internet-Site” auswählen damit der MTA mit anderen Server kommunizieren kann.

Das Script ausführen:
#./mailscript.sh

Abschließend noch alle Dienste einmal per Hand neustarten:

invoke-rc.d postfix restart && invoke-rc.d dovecot restart && invoke-rc.d spamass-milter restart && invoke-rc.d spamassassin restart

~ Alex

2 thoughts on “Mailserver Script – Postfix, Dovcot, Spamassassin in 5 Minuten

  1. Kritik:
    > echo “smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache” >> /etc/postfix/main.cf
    und
    > echo ” flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${recipient}” >> /etc/postfix/master.cf
    werden von der Shell expandiert, muessen in Ticks ‘ anstatt Anfuehrungszeichen ” eingeschlossen werden. So landet
    > smtpd_tls_session_cache_database = btree:/smtpd_scache
    in der Config, was garantiert verkehrt ist.
    —–
    > [ ! -n “$foo” ]
    entspricht [ -z “$foo” ]
    —–
    Statt
    > echo foo >>file
    > echo $bar >>file
    besser
    > {
    > echo foo
    > echo $bar
    > } >>file
    oder gleich
    > cat <>file
    > foo
    > $bar
    > EOF
    verwenden.
    —–
    Ich bezweifle, dass Lenny service(8) hatte. Das Deutsch/Englisch-Mischmasch verwirrt bestenfalls. Ein rm -rf auf schon bestehende Konfiguration ist unfreundlich, besser mv main.cf{,.old}.
    —–
    Es ist davon abzuraten, das Skript als Installer fuer beliebige Systeme zu verstehen. Insbesondere bestehende UIDs oder Verzeichnisse werden unzureichend beruecksichtigt.

    Edit 0:47
    Achtung, das ach so tolle WordPress hat in meiner ersten Antwort Zeichen kaputt gemacht. Zum Beispiel die Ticks und Anfuehrungszeichen. Ausserdem heisst es unten bei “cat” richtig “cat [groesser als][groesser als]EOF [kleiner als][kleiner als]file”.

    • Hallo, danke für deine Kritik.

      Zuerst mal, wie ganz am Anfang schon erwähnt, ist dieses Script sicher nicht professionell oder 100% Perfekt da dies einer meiner ersten Versuche mit dem Bash-Scripten ist. Deshalb bitte etwas nachsicht 😉

      .)Der Deutsch-Englisch Mischmasch wurde entfernt. Jetzt nur noch Englisch.

      .)Da ich davon ausgehe das dieses Script auf einem frisch installiertem Sytem zum Einsatz kommt ist das rm -fr /etc/postfix/main.cf eigentlich egal…obwohl in der nächsten Zeile das “>” sowieso gereicht hätte.

      .)Die Anführungszeichen wurden entfernt und durch Ticks ersetzt.

      .) Wie der Code in die Config-Dateien eigefügt wird ist im nachhinein doch eigentlich egal, oder?
      Mit deiner Methode wäre es sicher weniger Schreibarbeit gewesen bzw es ist ein wenig eleganter aber sonnst kann ich keinen Vorteil erkennen, du etwa?

      lg und gute Nacht

Leave a Reply

Your email address will not be published. Required fields are marked *