commit ced2a286799d4e4c7b281ba878507cdcb69c3d2d Author: Christoph Date: Sun Oct 22 12:11:03 2017 +0200 Initial commit - merge old projekts 'amavisd-new/', 'dovecot/', 'postfix', 'postfixadmin' and 'roundcube'. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..145f9da --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ + +# - common +*.log +*.swp +conf/*.conf + +# - Postfixadmin +postfixadmin-* + +# - AMaVis /vacation +/dcc* +*.log +*.tar.Z + +# - Dovecot +dovecot* +log* + +# - roundcube +/log/* +roundcubemail-* diff --git a/BAK/install_postfix_base.sh.00 b/BAK/install_postfix_base.sh.00 new file mode 100755 index 0000000..1d91926 --- /dev/null +++ b/BAK/install_postfix_base.sh.00 @@ -0,0 +1,502 @@ +#!/usr/bin/env bash + +_TLS_CERT_DIR=/etc/postfix/ssl +_TLS_CERT_FILE="${_TLS_CERT_DIR}/mailserver.crt" +_TLS_KEY_FILE="${_TLS_CERT_DIR}/mailserver.key" + +_TLS_CA_FILE=/etc/ssl/certs/ca-certificates.crt + + +_HOSTNAME= +_IPV4= +_EXT_IF_IP= + +## - Leave empty, if no IPv6 should be supported +## - +_IPV6= +#_IPV6= + +_ADMIN_EMAIL= + +_SASL_AUTH= +_RELAY_HOST=b.mx.oopen.de +_SASL_USER=anw-urb +_SASL_PASS='OhPie2aethei' + +## --- + + +# - Is this a systemd system? +# - +if [[ "X`which systemd`" = "X" ]]; then + systemd_exists=true +else + systemd_exists=false +fi + + +# - Deinstall debian exim4 packages +# - +_installed_exim_packages=`dpkg -l | grep exim4 | grep -e "^i" | awk '{print$2}'` +installed_exim_packages="bsd-mailx" +for _pkg in $_installed_exim_packages ; do + installed_exim_packages="$_installed_exim_packages $_pkg" +done +apt-get remove --purge -q -y $installed_exim_packages > /dev/null 2>&1 + + +# - Install Postfix from debian packages system +# - +needed_packages="postfix postfix-pcre libsasl2-modules bsd-mailx haveged" +apt-get install -q -y $needed_packages > /dev/null 2>&1 + + +# - Backup existing postfix configuration file +# - +if [[ -f "/etc/postfix/main.cf" ]]; then + cp -a /etc/postfix/main.cf /etc/postfix/main.cf.`date +%Y%m%d-%H%M` +fi + + +# - Creeate nes postfix configuration filr +## - +cat < /etc/postfix/main.cf +# ============ Basic settings ============ + +# Debian specific: Specifying a file name will cause the first +# line of that file to be used as the name. The Debian default +# is /etc/mailname. +#myorigin = /etc/mailname +myorigin = /etc/mailname + +smtpd_banner = \$myhostname ESMTP \$mail_name (Debian/GNU) +biff = no + +# appending .domain is the MUA's job. +append_dot_mydomain = no + +# Uncomment the next line to generate "delayed mail" warnings +#delay_warning_time = 4h + +readme_directory = /usr/share/doc/postfix +html_directory = /usr/share/doc/postfix/html + +## - The Internet protocols Postfix will attempt to use when making +## - or accepting connections. +## - DEFAULT: ipv4 +EOF + +if [ -n "$_IPV6" ]; then + cat <> /etc/postfix/main.cf +inet_protocols = ipv4, ipv6 + +#inet_interfaces = all + +inet_interfaces = 127.0.0.1 + $_IPV4 + $_IPV6 + +myhostname = $_HOSTNAME + +mydestination = + $_HOSTNAME + localhost + +## - The list of "trusted" SMTP clients that have more +## - privileges than "strangers" +## - +mynetworks = + 127.0.0.0/8 + [::ffff:127.0.0.0]/104 + [::1]/128 + ${_IPV4}/32 + [${_IPV6}]/128 + +smtp_bind_address = $_IPV4 +smtp_bind_address6 = $_IPV6 + +EOF +else + cat <> /etc/postfix/main.cf +inet_protocols = ipv4 + +#inet_interfaces = all +inet_interfaces = + 127.0.0.1 + $_IPV4 + +myhostname = $_HOSTNAME + +mydestination = + $_HOSTNAME + localhost + +## - The list of "trusted" SMTP clients that have more +## - privileges than "strangers" +## - +mynetworks = + 127.0.0.0/8 + ${_IPV4}/32 + +smtp_bind_address = $_IPV4 +#smtp_bind_address6 = $_IPV6 + +EOF +fi + +cat <> /etc/postfix/main.cf + +## - The method to generate the default value for the mynetworks parameter. +## - +## - mynetworks_style = host" when Postfix should "trust" only the local machine +## - mynetworks_style = subnet (default value) "when Postfix should "trust" SMTP +## - clients in the same IP subnetworks as the local machine. +## - mynetworks_style = class" when Postfix should "trust" SMTP clients in the same +## - IP class A/B/C networks as the local machine. +## - +#mynetworks_style = host + + +## - The maximal size of any local(8) individual mailbox or maildir file, +## - or zero (no limit). In fact, this limits the size of any file that is +## - written to upon local delivery, including files written by external +## - commands that are executed by the local(8) delivery agent. +## - +mailbox_size_limit = 0 + +## - The maximal size in bytes of a message, including envelope information. +## - +## - we user 50MB +## - +message_size_limit = 52480000 + +## - The system-wide recipient address extension delimiter +## - +recipient_delimiter = + + +## - The alias databases that are used for local(8) delivery. +## - +alias_maps = + hash:/etc/aliases + +## - The alias databases for local(8) delivery that are updated +## - with "newaliases" or with "sendmail -bi". +## - +alias_database = + hash:/etc/aliases + + +## - The maximal time a message is queued before it is sent back as +## - undeliverable. Defaults to 5d (5 days) +## - Specify 0 when mail delivery should be tried only once. +## - +maximal_queue_lifetime = 3d +bounce_queue_lifetime = \$maximal_queue_lifetime + +## - delay_warning_time (default: 0h) +## - +## - The time after which the sender receives a copy of the message +## - headers of mail that is still queued. To enable this feature, +## - specify a non-zero time value (an integral value plus an optional +## - one-letter suffix that specifies the time unit). +## - Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks). +## - The default time unit is h (hours). +delay_warning_time = 1d + + +EOF + +if $_SASL_AUTH ; then + cat <> /etc/postfix/main.cf + +# ============ Relay parameters ============ + +#relayhost = + + +# ============ SASL authentication ============ + +# Enable SASL authentication +smtp_sasl_auth_enable = yes + +# Forwarding to the ip-adress of host b.mx.oopen.de +relayhost = [b.mx.oopen.de] + +# File including login data +smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd + +# Force using a (TLS) security connection +# obsulete - use smtp_tls_security_level instead +#smtp_use_tls = yes +#smtp_tls_enforce_peername = no +smtp_tls_security_level = encrypt + +# Disallow methods that allow anonymous authentication. +smtp_sasl_security_options = noanonymous + + + +# ============ TLS parameters ============ + +## - Aktiviert TLS für den Mailempfang +## - +## - may: +## - Opportunistic TLS. Use TLS if this is supported by the remote +## - SMTP server, otherwise use plaintext +## - +## - This overrides the obsolete parameters smtpd_use_tls and +## - smtpd_enforce_tls. This parameter is ignored with +## - "smtpd_tls_wrappermode = yes". +#smtpd_use_tls=yes +smtp_tls_security_level=encrypt + +EOF + +else + cat <> /etc/postfix/main.cf + +# ============ Relay parameters ============ + +relayhost = + + +# ============ TLS parameters ============ + +## - Aktiviert TLS für den Mailempfang +## - +## - may: +## - Opportunistic TLS. Use TLS if this is supported by the remote +## - SMTP server, otherwise use plaintext +## - +## - This overrides the obsolete parameters smtpd_use_tls and +## - smtpd_enforce_tls. This parameter is ignored with +## - "smtpd_tls_wrappermode = yes". +#smtpd_use_tls=yes +smtp_tls_security_level=may + +EOF +fi + +cat <> /etc/postfix/main.cf +## - Aktiviert TLS für den Mailversand +## - +## - may: +## - Opportunistic TLS: announce STARTTLS support to SMTP clients, +## - but do not require that clients use TLS encryption. +# smtp_use_tls=yes +smtpd_tls_security_level=may + +## - 0 Disable logging of TLS activity. +## - 1 Log TLS handshake and certificate information. +## - 2 Log levels during TLS negotiation. +## - 3 Log hexadecimal and ASCII dump of TLS negotiation process. +## - 4 Also log hexadecimal and ASCII dump of complete transmission after STARTTLS. +## - +smtpd_tls_loglevel = 1 +smtp_tls_loglevel = 1 + +smtpd_tls_cert_file = $_TLS_CERT_FILE +smtpd_tls_key_file = $_TLS_KEY_FILE + +## - File with DH parameters that the Postfix SMTP server should use with EDH ciphers. +## - +## - Dont't forget to create it, e.g with openssl: +## - openssl gendh -out /etc/postfix/ssl/dh_1024.pem -2 1024 +## - +#smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_1024.pem +## - also possible to use 2048 key with that parameter +## - +smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_2048.pem + +## - File with DH parameters that the Postfix SMTP server should use with EDH ciphers. +## - +## - Dont't forget to create it, e.g with openssl: +## - openssl gendh -out /etc/postfix/ssl/dh_512.pem -2 512 +## - +smtpd_tls_dh512_param_file = /etc/postfix/ssl/dh_512.pem + + +## - File containing CA certificates of root CAs trusted to sign either remote SMTP +## - server certificates or intermediate CA certificates. These are loaded into +## - memory !! BEFORE !! the smtp(8) client enters the chroot jail. +## - +smtp_tls_CAfile = $_TLS_CA_FILE + +## - Directory with PEM format certificate authority certificates that the Postfix SMTP +## - client uses to verify a remote SMTP server certificate. Don't forget to create the +## - necessary "hash" links with, for example, " +## - $OPENSSL_HOME/bin/c_rehash /etc/postfix/certs". +## - +## - !! Note !! +## - To use this option in chroot mode, this directory (or a copy) must be inside +## - the chroot jail. +## - +## - Note that a chrooted daemon resolves all filenames relative to the Postfix +## - queue directory (/var/spool/postfix) +## - +#smtpd_tls_CApath = /etc/postfix/certs + + +# Disable SSLv2 SSLv3 - Postfix SMTP server +# +# List of TLS protocols that the Postfix SMTP server will exclude or +# include with opportunistic TLS encryption. +smtpd_tls_protocols = !SSLv2, !SSLv3 +# +# The SSL/TLS protocols accepted by the Postfix SMTP server +# with mandatory TLS encryption. +smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3 + + +# Disable SSLv2 SSLv3 - Postfix SMTP client +# +# List of TLS protocols that the Postfix SMTP client will exclude or +# include with opportunistic TLS encryption. +smtp_tls_protocols = !SSLv2, !SSLv3 +# +# List of SSL/TLS protocols that the Postfix SMTP client will use +# with mandatory TLS encryption +smtp_tls_mandatory_protocols = !SSLv2, !SSLv3 + + +## - Activate des "Ephemeral Elliptic Curve Diffie-Hellman" (EECDH) key exchange +## - openssl > 1.0 +## - +smtpd_tls_eecdh_grade = strong + +# standard list cryptographic algorithm +tls_preempt_cipherlist = yes + +# Disable ciphers which are less than 256-bit: +# +#smtpd_tls_mandatory_ciphers = high +# +# opportunistic +smtpd_tls_ciphers = high + + +# Exclude ciphers +#smtpd_tls_exclude_ciphers = +# RC4 +# aNULL +# SEED-SHA +# EXP +# MD5 +smtpd_tls_exclude_ciphers = + aNULL + eNULL + EXPORT + DES + RC4 + MD5 + PSK + aECDH + EDH-DSS-DES-CBC3-SHA + EDH-RSA-DES-CDC3-SHA + KRB5-DE5, CBC3-SHA + + +smtpd_tls_session_cache_database = btree:\${data_directory}/smtpd_scache +smtp_tls_session_cache_database = btree:\${data_directory}/smtp_scache + +EOF + + +if $_SASL_AUTH ; then + + echo "[$_RELAY_HOST] ${_SASL_USER}@${_RELAY_HOST}:$_SASL_PASS" > /etc/postfix/sasl_passwd + chown root:root /etc/postfix/sasl_passwd + chmod 600 /etc/postfix/sasl_passwd + postmap /etc/postfix/sasl_passwd + chown root:root /etc/postfix/sasl_passwd.db + +fi + +## - /etc/mailname +## - +echo $_HOSTNAME > /etc/mailname + +## - /etc/aliases +## - +cat << EOF > /etc/aliases +# See man 5 aliases for format +mailer-daemon: postmaster +postmaster: root +nobody: root +hostmaster: root +usenet: root +news: root +webmaster: root +www: root +ftp: root +abuse: root +noc: root +security: root + +root: $_ADMIN_EMAIL +EOF + + +## - create directory for certificates and copy certificates +## - and coresponding keys to /etc/postfix/ssl/ +## - +mkdir -p /etc/postfix/ssl + + +## - generate DH parameters that the Postfix SMTP server should use +## - with EDH ciphers (length 512 and 1024 +## - +if [ ! -f /etc/postfix/ssl/dh_512.pem ]; then + openssl gendh -out /etc/postfix/ssl/dh_512.pem -2 512 +fi +if [ ! -f /etc/postfix/ssl/dh_1024.pem ]; then + openssl gendh -out /etc/postfix/ssl/dh_1024.pem -2 1024 +fi +if [ ! -f /etc/postfix/ssl/dh_2048.pem ]; then + openssl gendh -out /etc/postfix/ssl/dh_2048.pem -2 2048 +fi + +if [ ! -h "$_TLS_CERT_FILE" ]; then + ln -s /etc/ssl/certs/ssl-cert-snakeoil.pem $_TLS_CERT_FILE +fi +if [ ! -h "$_TLS_KEY_FILE" ]; then + ln -s /etc/ssl/private/ssl-cert-snakeoil.key $_TLS_KEY_FILE +fi + +## - rebuld alias database +## - +newaliases + +## - restart postfix +## - +if $systemd_exists ; then + systemctl restart postfix +else + /etc/init.d/postfix restart +fi + + +## - Omitt logging into system.log +## - +cat << EOF >> /etc/rsyslog.d/postfix.conf + +# +# Logging for the mail system. Split it up so that +# it is easy to write scripts to parse these files. +# +mail.info -/var/log/mail.info +mail.warn -/var/log/mail.warn +mail.err /var/log/mail.err + +mail.* -/var/log/mail.log +& ~ +EOF + +if $systemd_exists ; then + systemctl restart rsyslog +else + /etc/init.d/rsyslog restart +fi + + +exit diff --git a/BAK/install_postfix_base.sh.01 b/BAK/install_postfix_base.sh.01 new file mode 100755 index 0000000..bb4b2b3 --- /dev/null +++ b/BAK/install_postfix_base.sh.01 @@ -0,0 +1,725 @@ +#!/usr/bin/env bash + +_TLS_CERT_DIR=/etc/postfix/ssl +_TLS_CERT_FILE="${_TLS_CERT_DIR}/mailserver.crt" +_TLS_KEY_FILE="${_TLS_CERT_DIR}/mailserver.key" + +_TLS_CA_FILE=/etc/ssl/certs/ca-certificates.crt + + +_HOSTNAME=o15.oopen.de +_IPV4=83.223.86.96 +_EXT_IF_IP=83.223.86.96 + +## - Leave empty, if no IPv6 should be supported +## - +_IPV6=2a01:30:0:13:5054:ff:fe09:2318 +#_IPV6= + +_ADMIN_EMAIL=admin@oopen.de + +_SASL_AUTH=false +_RELAY_HOST=b.mx.oopen.de +_SASL_USER=anw-urb +_SASL_PASS='OhPie2aethei' + + +# ------------- +# --- Some functions +# ------------- +echononl(){ + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo -e -n "$*\\c" 1>&2 + else + echo -e -n "$*" 1>&2 + fi + rm /tmp/shprompt$$ +} + +fatal(){ + echo "" + echo -e "fataler Fehler: $*" + echo "" + echo -e "\t\033[31m\033[1mInstalllation wird abgebrochen\033[m\033[m" + echo "" + exit 1 +} + +error(){ + echo "" + echo -e "\t[ \033[31m\033[1mFehler\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 "" +} + +echo_done() { + echo -e "\033[80G[ \033[32mdone\033[m ]" +} +echo_ok() { + echo -e "\033[80G[ \033[32mok\033[m ]" +} +echo_warning() { + echo -e "\033[80G[ \033[33m\033[1mwarn\033[m ]" +} +echo_failed(){ + echo -e "\033[80G[ \033[1;31mfailed\033[m ]" +} +echo_skipped() { + echo -e "\033[80G[ \033[33m\033[1mskipped\033[m ]" +} + + +# - Is this a systemd system? +# - +if [[ "X`which systemd`" = "X" ]]; then + systemd_exists=false +else + systemd_exists=true +fi + +echo "" + + +# - Deinstall debian exim4 packages +# - +echononl " Deinstall debian exim4 packages" +_installed_exim_packages=`dpkg -l | grep exim4 | grep -e "^i" | awk '{print$2}'` +for _pkg in $_installed_exim_packages ; do + installed_exim_packages="$installed_exim_packages $_pkg" +done +if [[ -n "$installed_exim_packages" ]] ; then + + if `dpkg -l | grep bsd-mailx | grep -e "^i" > /dev/null 2>&1` ; then + installed_exim_packages="$installed_exim_packages bsd-mailx" + fi + + apt-get remove --purge -qq -y $installed_exim_packages > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + + + +# - Install Postfix from debian packages system +# - +echononl " Install Postfix from debian packages system" +_needed_packages="postfix postfix-pcre libsasl2-modules bsd-mailx haveged" +for _pkg in $_needed_packages ; do + if `dpkg -l | grep $_pkg | grep -e "^i" > /dev/null 2>&1` ; then + continue + else + needed_packages="$needed_packages $_pkg" + fi +done +if [[ -n "$needed_packages" ]]; then + DEBIAN_FRONTEND=noninteractive apt-get -y install $needed_packages > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + + +# - Backup existing postfix configuration file +# - +echononl " Backup existing postfix configuration file" +if [[ -f "/etc/postfix/main.cf" ]]; then + cp -a /etc/postfix/main.cf /etc/postfix/main.cf.`date +%Y%m%d-%H%M` + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + + +# - Creeate new postfix configuration file +# - +echononl " Creeate new postfix configuration file" +cat < /etc/postfix/main.cf +# ============ Basic settings ============ + +# Debian specific: Specifying a file name will cause the first +# line of that file to be used as the name. The Debian default +# is /etc/mailname. +#myorigin = /etc/mailname +myorigin = /etc/mailname + +smtpd_banner = \$myhostname ESMTP \$mail_name (Debian/GNU) +biff = no + +# appending .domain is the MUA's job. +append_dot_mydomain = no + +# Uncomment the next line to generate "delayed mail" warnings +#delay_warning_time = 4h + +readme_directory = /usr/share/doc/postfix +html_directory = /usr/share/doc/postfix/html + +## - The Internet protocols Postfix will attempt to use when making +## - or accepting connections. +## - DEFAULT: ipv4 +EOF + +if [ -n "$_IPV6" ]; then + cat <> /etc/postfix/main.cf +inet_protocols = ipv4, ipv6 + +#inet_interfaces = all + +inet_interfaces = 127.0.0.1 + $_IPV4 + $_IPV6 + +myhostname = $_HOSTNAME + +mydestination = + $_HOSTNAME + localhost + +## - The list of "trusted" SMTP clients that have more +## - privileges than "strangers" +## - +mynetworks = + 127.0.0.0/8 + [::ffff:127.0.0.0]/104 + [::1]/128 + ${_IPV4}/32 + [${_IPV6}]/128 + +smtp_bind_address = $_IPV4 +smtp_bind_address6 = $_IPV6 + +EOF +else + cat <> /etc/postfix/main.cf +inet_protocols = ipv4 + +#inet_interfaces = all +inet_interfaces = + 127.0.0.1 + $_IPV4 + +myhostname = $_HOSTNAME + +mydestination = + $_HOSTNAME + localhost + +## - The list of "trusted" SMTP clients that have more +## - privileges than "strangers" +## - +mynetworks = + 127.0.0.0/8 + ${_IPV4}/32 + +smtp_bind_address = $_IPV4 +#smtp_bind_address6 = $_IPV6 + +EOF +fi + +cat <> /etc/postfix/main.cf + +## - The method to generate the default value for the mynetworks parameter. +## - +## - mynetworks_style = host" when Postfix should "trust" only the local machine +## - mynetworks_style = subnet (default value) "when Postfix should "trust" SMTP +## - clients in the same IP subnetworks as the local machine. +## - mynetworks_style = class" when Postfix should "trust" SMTP clients in the same +## - IP class A/B/C networks as the local machine. +## - +#mynetworks_style = host + + +## - The maximal size of any local(8) individual mailbox or maildir file, +## - or zero (no limit). In fact, this limits the size of any file that is +## - written to upon local delivery, including files written by external +## - commands that are executed by the local(8) delivery agent. +## - +mailbox_size_limit = 0 + +## - The maximal size in bytes of a message, including envelope information. +## - +## - we user 50MB +## - +message_size_limit = 52480000 + +## - The system-wide recipient address extension delimiter +## - +recipient_delimiter = + + +## - The alias databases that are used for local(8) delivery. +## - +alias_maps = + hash:/etc/aliases + +## - The alias databases for local(8) delivery that are updated +## - with "newaliases" or with "sendmail -bi". +## - +alias_database = + hash:/etc/aliases + + +## - The maximal time a message is queued before it is sent back as +## - undeliverable. Defaults to 5d (5 days) +## - Specify 0 when mail delivery should be tried only once. +## - +maximal_queue_lifetime = 3d +bounce_queue_lifetime = \$maximal_queue_lifetime + +## - delay_warning_time (default: 0h) +## - +## - The time after which the sender receives a copy of the message +## - headers of mail that is still queued. To enable this feature, +## - specify a non-zero time value (an integral value plus an optional +## - one-letter suffix that specifies the time unit). +## - Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks). +## - The default time unit is h (hours). +delay_warning_time = 1d + + +EOF + +if $_SASL_AUTH ; then + cat <> /etc/postfix/main.cf + +# ============ Relay parameters ============ + +#relayhost = + + +# ============ SASL authentication ============ + +# Enable SASL authentication +smtp_sasl_auth_enable = yes + +# Forwarding to the ip-adress of host b.mx.oopen.de +relayhost = [b.mx.oopen.de] + +# File including login data +smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd + +# Force using a (TLS) security connection +# obsulete - use smtp_tls_security_level instead +#smtp_use_tls = yes +#smtp_tls_enforce_peername = no +smtp_tls_security_level = encrypt + +# Disallow methods that allow anonymous authentication. +smtp_sasl_security_options = noanonymous + + + +# ============ TLS parameters ============ + +## - Aktiviert TLS für den Mailempfang +## - +## - may: +## - Opportunistic TLS. Use TLS if this is supported by the remote +## - SMTP server, otherwise use plaintext +## - +## - This overrides the obsolete parameters smtpd_use_tls and +## - smtpd_enforce_tls. This parameter is ignored with +## - "smtpd_tls_wrappermode = yes". +#smtpd_use_tls=yes +smtp_tls_security_level=encrypt + +EOF + +else + cat <> /etc/postfix/main.cf + +# ============ Relay parameters ============ + +relayhost = + + +# ============ TLS parameters ============ + +## - Aktiviert TLS für den Mailempfang +## - +## - may: +## - Opportunistic TLS. Use TLS if this is supported by the remote +## - SMTP server, otherwise use plaintext +## - +## - This overrides the obsolete parameters smtpd_use_tls and +## - smtpd_enforce_tls. This parameter is ignored with +## - "smtpd_tls_wrappermode = yes". +#smtpd_use_tls=yes +smtp_tls_security_level=may + +EOF +fi + +cat <> /etc/postfix/main.cf +## - Aktiviert TLS für den Mailversand +## - +## - may: +## - Opportunistic TLS: announce STARTTLS support to SMTP clients, +## - but do not require that clients use TLS encryption. +# smtp_use_tls=yes +smtpd_tls_security_level=may + +## - 0 Disable logging of TLS activity. +## - 1 Log TLS handshake and certificate information. +## - 2 Log levels during TLS negotiation. +## - 3 Log hexadecimal and ASCII dump of TLS negotiation process. +## - 4 Also log hexadecimal and ASCII dump of complete transmission after STARTTLS. +## - +smtpd_tls_loglevel = 1 +smtp_tls_loglevel = 1 + +smtpd_tls_cert_file = $_TLS_CERT_FILE +smtpd_tls_key_file = $_TLS_KEY_FILE + +## - File with DH parameters that the Postfix SMTP server should use with EDH ciphers. +## - +## - Dont't forget to create it, e.g with openssl: +## - openssl gendh -out /etc/postfix/ssl/dh_1024.pem -2 1024 +## - +#smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_1024.pem +## - also possible to use 2048 key with that parameter +## - +smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_2048.pem + +## - File with DH parameters that the Postfix SMTP server should use with EDH ciphers. +## - +## - Dont't forget to create it, e.g with openssl: +## - openssl gendh -out /etc/postfix/ssl/dh_512.pem -2 512 +## - +smtpd_tls_dh512_param_file = /etc/postfix/ssl/dh_512.pem + + +## - File containing CA certificates of root CAs trusted to sign either remote SMTP +## - server certificates or intermediate CA certificates. These are loaded into +## - memory !! BEFORE !! the smtp(8) client enters the chroot jail. +## - +smtp_tls_CAfile = $_TLS_CA_FILE + +## - Directory with PEM format certificate authority certificates that the Postfix SMTP +## - client uses to verify a remote SMTP server certificate. Don't forget to create the +## - necessary "hash" links with, for example, " +## - $OPENSSL_HOME/bin/c_rehash /etc/postfix/certs". +## - +## - !! Note !! +## - To use this option in chroot mode, this directory (or a copy) must be inside +## - the chroot jail. +## - +## - Note that a chrooted daemon resolves all filenames relative to the Postfix +## - queue directory (/var/spool/postfix) +## - +#smtpd_tls_CApath = /etc/postfix/certs + + +# Disable SSLv2 SSLv3 - Postfix SMTP server +# +# List of TLS protocols that the Postfix SMTP server will exclude or +# include with opportunistic TLS encryption. +smtpd_tls_protocols = !SSLv2, !SSLv3 +# +# The SSL/TLS protocols accepted by the Postfix SMTP server +# with mandatory TLS encryption. +smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3 + + +# Disable SSLv2 SSLv3 - Postfix SMTP client +# +# List of TLS protocols that the Postfix SMTP client will exclude or +# include with opportunistic TLS encryption. +smtp_tls_protocols = !SSLv2, !SSLv3 +# +# List of SSL/TLS protocols that the Postfix SMTP client will use +# with mandatory TLS encryption +smtp_tls_mandatory_protocols = !SSLv2, !SSLv3 + + +## - Activate des "Ephemeral Elliptic Curve Diffie-Hellman" (EECDH) key exchange +## - openssl > 1.0 +## - +smtpd_tls_eecdh_grade = strong + +# standard list cryptographic algorithm +tls_preempt_cipherlist = yes + +# Disable ciphers which are less than 256-bit: +# +#smtpd_tls_mandatory_ciphers = high +# +# opportunistic +smtpd_tls_ciphers = high + + +# Exclude ciphers +#smtpd_tls_exclude_ciphers = +# RC4 +# aNULL +# SEED-SHA +# EXP +# MD5 +smtpd_tls_exclude_ciphers = + aNULL + eNULL + EXPORT + DES + RC4 + MD5 + PSK + aECDH + EDH-DSS-DES-CBC3-SHA + EDH-RSA-DES-CDC3-SHA + KRB5-DE5, CBC3-SHA + + +smtpd_tls_session_cache_database = btree:\${data_directory}/smtpd_scache +smtp_tls_session_cache_database = btree:\${data_directory}/smtp_scache + +EOF +echo_ok + +echononl " Configure SASL authentification" +if $_SASL_AUTH ; then + + _failed=false + echo "[$_RELAY_HOST] ${_SASL_USER}@${_RELAY_HOST}:$_SASL_PASS" > /etc/postfix/sasl_passwd + if [[ "$?" != "0" ]]; then + error "Setting \"/etc/postfix/sasl_passwd\" failed! " + _failed=true + fi + chown root:root /etc/postfix/sasl_passwd + if [[ "$?" != "0" ]]; then + error "Setting ownership of \"/etc/postfix/sasl_passwd\" failed! " + _failed=true + fi + chmod 600 /etc/postfix/sasl_passwd + if [[ "$?" != "0" ]]; then + error "Setting permissions on \"/etc/postfix/sasl_passwd\" failed! " + _failed=true + fi + postmap /etc/postfix/sasl_passwd + chown root:root /etc/postfix/sasl_passwd.db + if [[ "$?" != "0" ]]; then + error "Creating \"/etc/postfix/sasl_passwd\" failed! " + _failed=true + fi + chown root:root /etc/postfix/sasl_passwd.db + if [[ "$?" != "0" ]]; then + error "Setting ownership of \"/etc/postfix/sasl_passwd.db\" failed! " + _failed=true + fi + if $_failed ; then + echo_failed + else + echo_ok + fi +else + echo_skipped +fi + +## - /etc/mailname +## - +echononl " Set \"/etc/mailname\"" +echo $_HOSTNAME > /etc/mailname +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +## - /etc/aliases +## - +echononl " Adjust \"/etc/aliases\"" +cat << EOF > /etc/aliases +# See man 5 aliases for format +mailer-daemon: postmaster +postmaster: root +nobody: root +hostmaster: root +usenet: root +news: root +webmaster: root +www: root +ftp: root +abuse: root +noc: root +security: root + +root: $_ADMIN_EMAIL +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + + +## - create directory for certificates and copy certificates +## - and coresponding keys to /etc/postfix/ssl/ +## - +echononl " Create directory for certificates \"/etc/postfix/ssl\"" +if [[ -d "/etc/postfix/ssl" ]] ; then + echo_skipped +else + mkdir -p /etc/postfix/ssl + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +fi + + +## - generate DH parameters that the Postfix SMTP server should use +## - with EDH ciphers (length 512 and 1024 +## - +echononl " Generate DH key length=512 \"/etc/postfix/ssl/dh_512.pem\"" +if [ ! -f /etc/postfix/ssl/dh_512.pem ]; then + openssl gendh -out /etc/postfix/ssl/dh_512.pem -2 512 > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi +echononl " Generate DH key length=1024 \"/etc/postfix/ssl/dh_1024.pem\"" +if [ ! -f /etc/postfix/ssl/dh_1024.pem ]; then + openssl gendh -out /etc/postfix/ssl/dh_1024.pem -2 1024 > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi +echononl " Generate DH key length=2048 \"/etc/postfix/ssl/dh_2048.pem\"" +if [ ! -f /etc/postfix/ssl/dh_2048.pem ]; then + openssl gendh -out /etc/postfix/ssl/dh_2048.pem -2 2048 > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi +echononl " Create Symlink \"$_TLS_CERT_FILE\"" +if [ ! -h "$_TLS_CERT_FILE" ]; then + ln -s /etc/ssl/certs/ssl-cert-snakeoil.pem $_TLS_CERT_FILE + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi +echononl " Create Symlink \"$_TLS_KEY_FILE\"" +if [ ! -h "$_TLS_KEY_FILE" ]; then + ln -s /etc/ssl/private/ssl-cert-snakeoil.key $_TLS_KEY_FILE + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + +## - rebuld alias database +## - +echononl " Rebuld alias database" +newaliases > /dev/null 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +## - restart postfix +## - +echononl " Restart postfix" +if $systemd_exists ; then + systemctl restart postfix > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + /etc/init.d/postfix restart > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +fi + + +## - Omitt logging into system.log +## - +echononl " Create \"/etc/rsyslog.d/postfix.conf\"" +cat << EOF >> /etc/rsyslog.d/postfix.conf + +# +# Logging for the mail system. Split it up so that +# it is easy to write scripts to parse these files. +# +mail.info -/var/log/mail.info +mail.warn -/var/log/mail.warn +mail.err /var/log/mail.err + +mail.* -/var/log/mail.log +& ~ +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +echononl " Restart rsyslog daemon" +if $systemd_exists ; then + systemctl restart rsyslog > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + /etc/init.d/rsyslog restart > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +fi + + +echo "" +exit diff --git a/BAK/install_postfix_relay.sh b/BAK/install_postfix_relay.sh new file mode 100755 index 0000000..cafe72e --- /dev/null +++ b/BAK/install_postfix_relay.sh @@ -0,0 +1,1120 @@ +#!/usr/bin/env bash + +_TLS_CERT_DIR=/etc/postfix/ssl +_TLS_CERT_FILE="${_TLS_CERT_DIR}/mailserver.crt" +_TLS_KEY_FILE="${_TLS_CERT_DIR}/mailserver.key" +# +_TLS_CA_FILE=/etc/ssl/certs/ca-certificates.crt +# +# +#_HOSTNAME=o15.oopen.de +#_IPV4=83.223.86.96 +#_EXT_IF_IP=83.223.86.96 +# +### - Leave empty, if no IPv6 should be supported +### - +#_IPV6=2a01:30:0:13:5054:ff:fe09:2318 +##_IPV6= +# +#_ADMIN_EMAIL=admin@oopen.de + + +# ------------- +# --- Some functions +# ------------- +echononl(){ + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo -e -n "$*\\c" 1>&2 + else + echo -e -n "$*" 1>&2 + fi + rm /tmp/shprompt$$ +} + +fatal(){ + echo "" + echo -e "fatal error: $*" + echo "" + echo -e "\t\033[31m\033[1mInstalllation will be interrupted\033[m\033[m" + echo "" + exit 1 +} + +error(){ + echo "" + echo -e "\t[ \033[31m\033[1mFehler\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 "" +} + +echo_done() { + echo -e "\033[80G[ \033[32mdone\033[m ]" +} +echo_ok() { + echo -e "\033[80G[ \033[32mok\033[m ]" +} +echo_warning() { + echo -e "\033[80G[ \033[33m\033[1mwarn\033[m ]" +} +echo_failed(){ + echo -e "\033[80G[ \033[1;31mfailed\033[m ]" +} +echo_skipped() { + echo -e "\033[80G[ \033[33m\033[1mskipped\033[m ]" +} + + +# - Is this a systemd system? +# - +if [[ "X`which systemd`" = "X" ]]; then + systemd_exists=false +else + systemd_exists=true +fi + +echo "" + +conf_dir=$(dirname $0)/conf +conf_file="${conf_dir}/install_postfix_relay.conf" + +if [[ -f "$conf_file" ]]; then + source $conf_file +fi + +clear +echo -e "\033[21G\033[32mInstallation script for Postfix basic mailsystem \033[m" +echo + +HOSTNAME= +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Insert hostname" +echo "" +if [[ -n "$_HOSTNAME" ]]; then + echononl "hostname [${_HOSTNAME}]: " + read HOSTNAME + if [[ "X${HOSTNAME}" = "X" ]]; then + HOSTNAME=$_HOSTNAME + fi +else + while [[ "X${HOSTNAME}" = "X" ]]; do + echononl "hostname: " + read HOSTNAME + if [[ "X${HOSTNAME}" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mHostname is reqired\033[m\n" + fi + done +fi + +IPV4= +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Insert IPv4 address" +echo "" +if [[ -n "$_IPV4" ]]; then + echononl "IPv4 address [${_IPV4}]: " + read IPV4 + if [[ "X${IPV4}" = "X" ]]; then + IPV4=$_IPV4 + fi +else + while [[ "X${IPV4}" = "X" ]]; do + echononl "IPv4 address: " + read IPV4 + if [[ "X${IPV4}" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mIPv4 address is reqired\033[m\n" + fi + done +fi +IPV6= +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Insert IPv6 address" +echo "Type:" +echo -e "\t\033[33mNone\033[m if IPv6 is not suppoerted" +echo "" +if [[ -n "$_IPV6" ]]; then + [[ "X$_IPV6" = "Xdisabled" ]] && _IPV6=None + echononl "IPv6 address [${_IPV6}]: " + read IPV6 + if [[ "X${IPV6}" = "X" ]]; then + IPV6=$_IPV6 + fi +else + while [[ "X${IPV6}" = "X" ]]; do + echononl "IPv6 address: " + read IPV6 + if [[ "X${IPV6}" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mIPv4 address is reqired\033[m\n" + fi + done +fi +if [ "X$IPV6" = "Xnone" -o "X$IPV6" = "XNone" ]; then + IPV6=disabled +fi + +ADMIN_EMAIL= +echo "" +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Insert e-mail address where messages to local root should be forwarded" +echo "" +echo "" +if [[ -n "$_ADMIN_EMAIL" ]]; then + echononl "Admin e-mail address [$_ADMIN_EMAIL]: " + read ADMIN_EMAIL + if [[ "X${ADMIN_EMAIL}" = "X" ]]; then + ADMIN_EMAIL=$_ADMIN_EMAIL + fi +else + while [[ "X${ADMIN_EMAIL}" = "X" ]]; do + echononl "Admin e-mail address: " + read ADMIN_EMAIL + if [[ "X${ADMIN_EMAIL}" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mAdmin e-mail address is reqired\033[m\n" + fi + done +fi + + +echo "" +echo "" +echo -e "\033[21G\033[32mStart installation/configuration with the following parameters\033[m" +echo "" +echo -e "\tHostname.................: $HOSTNAME" +echo -e "\tIPv4 address.............: $IPV4" +echo -e "\tIPv6 address.............: $IPV6" +echo -e "\tAdmin e-mail.............: $ADMIN_EMAIL" +echo "" +echononl "einverstanden (yes/no): " +read OK +OK=${OK,,} +while [ "X$OK" != "Xyes" -a "X$OK" != "Xno" ]; do + echononl "Wrong entry! [yes/no]: " + read OK + OK=${OK,,} +done +[ $OK = "yes" ] || fatal Repeat with other settings.. + +echo "" +echo "" + +tmp_err_msg=$(mktemp) + +echononl " Save Configuration" +cat << EOF > $conf_file +# --- +# - Parameter Settins Postfix Relay System +# --- + +_HOSTNAME=$HOSTNAME +_IPV4=$IPV4 +_IPV6=$IPV6 +_ADMIN_EMAIL=$ADMIN_EMAIL +_SASL_USER=$SASL_USER +_SASL_PASS=$SASL_PASS +_RELAY_HOST=$RELAY_HOST +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +[[ "$IPV6" = "disabled" ]] && IPV6="" + + +# - Deinstall debian exim4 packages +# - +echononl " Deinstall debian exim4 packages" +_installed_exim_packages=`dpkg -l | grep exim4 | grep -e "^i" | awk '{print$2}'` +for _pkg in $_installed_exim_packages ; do + installed_exim_packages="$installed_exim_packages $_pkg" +done +if [[ -n "$installed_exim_packages" ]] ; then + + if `dpkg -l | grep bsd-mailx | grep -e "^i" > /dev/null 2>&1` ; then + installed_exim_packages="$installed_exim_packages bsd-mailx" + fi + + apt-get remove --purge -qq -y $installed_exim_packages > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + + + +# - Install Postfix from debian packages system +# - +echononl " Install Postfix from debian packages system" +_needed_packages="postfix postfix-pgsql postfix-mysql postfix-pcre libsasl2-modules bsd-mailx haveged" +for _pkg in $_needed_packages ; do + if `dpkg -l | grep $_pkg | grep -e "^i" > /dev/null 2>&1` ; then + continue + else + needed_packages="$needed_packages $_pkg" + fi +done +if [[ -n "$needed_packages" ]]; then + DEBIAN_FRONTEND=noninteractive apt-get -y install $needed_packages > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + + +## - Install Postgrey from debian packages system +## - +echononl " Install Postgrey from debian packages system" +_pkg="postgrey" +if aptitude search $_pkg | grep " $_pkg " | grep -e "^i" > /dev/null 2>&1 ; then + echo_skipped +else + DEBIAN_FRONTEND=noninteractive apt-get -y install $_pkg > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +fi + +echononl " Adjust /etc/default/postgrey" +perl -i -n -p -e "s#^(\s*)(POSTGREY_OPTS=.*)#\#\1\2\nPOSTGREY_OPTS=\"--inet=10023 --delay=149 --auto-whitelist-clients=3 --lookup-by-subnet\"#" \ + /etc/default/postgrey > $tmp_err_msg 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + +echononl " Create /etc/postgrey/whitelist_clients.local (additional whitelist entries)" +cat << EOF > /etc/postgrey/whitelist_clients.local +# For Office 365 - servers: +##/.*outbound.protection.outlook.com\$/ +/^mail-.*\.outbound\.protection\.outlook\.com\$/ +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +echononl " Restart postrey daemon" +if $systemd_exists ; then + systemctl restart postgrey > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + /etc/init.d/postgrey restart > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +fi + + +# - Backup existing postfix configuration file +# - +echononl " Backup existing postfix configuration file" +if [[ -f "/etc/postfix/main.cf" ]]; then + cp -a /etc/postfix/main.cf /etc/postfix/main.cf.`date +%Y%m%d-%H%M` + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + + +# - Creeate new postfix configuration file +# - +echononl " Creeate new postfix configuration file" +cat < /etc/postfix/main.cf +# ============ Basic settings ============ + +# Debian specific: Specifying a file name will cause the first +# line of that file to be used as the name. The Debian default +# is /etc/mailname. +#myorigin = /etc/mailname +myorigin = /etc/mailname + +smtpd_banner = \$myhostname ESMTP \$mail_name (Debian/GNU) +biff = no + +# appending .domain is the MUA's job. +append_dot_mydomain = no + +# Uncomment the next line to generate "delayed mail" warnings +#delay_warning_time = 4h + +readme_directory = /usr/share/doc/postfix +html_directory = /usr/share/doc/postfix/html + +## - The Internet protocols Postfix will attempt to use when making +## - or accepting connections. +## - DEFAULT: ipv4 +EOF + +if [ -n "$IPV6" ]; then + cat <> /etc/postfix/main.cf +inet_protocols = ipv4, ipv6 + +#inet_interfaces = all +inet_interfaces = + 127.0.0.1 + $IPV4 + $IPV6 + +myhostname = $HOSTNAME + +mydestination = + $HOSTNAME + localhost + +## - The list of "trusted" SMTP clients that have more +## - privileges than "strangers" +## - +mynetworks = + 127.0.0.0/8 + [::ffff:127.0.0.0]/104 + [::1]/128 + ${IPV4}/32 + [${IPV6}]/128 + # a.mx.oopen.de + #83.223.86.91 + #[2a01:30:0:13:2f7:50ff:fed2:cef7]/128 + # b.mx.oopen.de + #83.223.86.97 + #[2a01:30:0:13:21f:92ff:fe00:538b] + # d.mx.oopen.de + #83.223.86.92/32 + #[2a01:30:0:13:254:9eff:fed5:e7fd]/128 + +smtp_bind_address = $IPV4 +smtp_bind_address6 = $IPV6 + +EOF +else + cat <> /etc/postfix/main.cf +inet_protocols = ipv4 + +#inet_interfaces = all +inet_interfaces = + 127.0.0.1 + $IPV4 + +myhostname = $HOSTNAME + +mydestination = + $HOSTNAME + localhost + +## - The list of "trusted" SMTP clients that have more +## - privileges than "strangers" +## - +mynetworks = + 127.0.0.0/8 + ${IPV4}/32 + +#smtp_bind_address = $IPV4 +#smtp_bind_address6 = $IPV6 + +EOF +fi + +cat <> /etc/postfix/main.cf + +## - The method to generate the default value for the mynetworks parameter. +## - +## - mynetworks_style = host" when Postfix should "trust" only the local machine +## - mynetworks_style = subnet (default value) "when Postfix should "trust" SMTP +## - clients in the same IP subnetworks as the local machine. +## - mynetworks_style = class" when Postfix should "trust" SMTP clients in the same +## - IP class A/B/C networks as the local machine. +## - +#mynetworks_style = host + + +## - The maximal size of any local(8) individual mailbox or maildir file, +## - or zero (no limit). In fact, this limits the size of any file that is +## - written to upon local delivery, including files written by external +## - commands that are executed by the local(8) delivery agent. +## - +mailbox_size_limit = 0 + +## - The maximal size in bytes of an individual virtual(8) mailbox or +## - maildir file, or zero (no limit). +## - +virtual_mailbox_limit = 0 + +## - The maximal size in bytes of a message, including envelope information. +## - +## - we user 50MB +## - +message_size_limit = 52480000 + +## - The system-wide recipient address extension delimiter +## - +recipient_delimiter = + + +## - The alias databases that are used for local(8) delivery. +## - +alias_maps = + hash:/etc/aliases + +## - The alias databases for local(8) delivery that are updated +## - with "newaliases" or with "sendmail -bi". +## - +alias_database = + hash:/etc/aliases + +## - Optional lookup tables with mappings from recipient address +## - to (message delivery transport, next-hop destination). +## - See transport(5) for details. +## - +transport_maps = + btree:/etc/postfix/transport + btree:/etc/postfix/relay_domains + +## - The maximal time a message is queued before it is sent back as +## - undeliverable. Defaults to 5d (5 days) +## - Specify 0 when mail delivery should be tried only once. +## - +maximal_queue_lifetime = 3d +bounce_queue_lifetime = \$maximal_queue_lifetime + +## - delay_warning_time (default: 0h) +## - +## - The time after which the sender receives a copy of the message +## - headers of mail that is still queued. To enable this feature, +## - specify a non-zero time value (an integral value plus an optional +## - one-letter suffix that specifies the time unit). +## - Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks). +## - The default time unit is h (hours). +delay_warning_time = 1d + +#header_checks = pcre:/etc/postfix/header_checks +prepend_delivered_header = + forward + file + + +## - proxy_read_maps +## - +## - The lookup tables that the proxymap(8) server is allowed to access for the read-only service. +## - +## - Specify zero or more "type:name" lookup tables, separated by whitespace or comma. Table +## - references that don't begin with proxy: are ignored. +## - +#proxy_read_maps = \$local_recipient_maps \$mydestination \$virtual_alias_maps \$virtual_alias_domains \$virtual_mailbox_maps \$virtual_mailbox_domains \$relay_recipient_maps \$relay_domains \$canonical_maps \$sender_canonical_maps \$recipient_canonical_maps \$relocated_maps \$transport_maps \$mynetworks \$sender_bcc_maps \$recipient_bcc_maps \$smtp_generic_maps \$lmtp_generic_maps \$smtpd_sender_login_maps + + +# ============ Relay parameters ============ + +relayhost = +relay_domains = + \$mydestination + btree:/etc/postfix/relay_domains + + +# ============ TLS parameters ============ + +## - supports DNSSEC +## - +## - !! Notice !! +## - In order to support DNSSEC and DANE your resolver MUST support +## - DNSSEC too. +## - +## - If your resolver does not support DNSSEC, install "unbound". +## - +smtp_host_lookup = dns +smtp_dns_support_level = dnssec + +## - Aktiviert TLS für den Mailempfang +## - +## - may: +## - Opportunistic TLS. Use TLS if this is supported by the remote +## - SMTP server, otherwise use plaintext +## - +## - This overrides the obsolete parameters smtpd_use_tls and +## - smtpd_enforce_tls. This parameter is ignored with +## - "smtpd_tls_wrappermode = yes". +#smtpd_use_tls=yes +smtpd_tls_security_level=may + +## - Aktiviert TLS für den Mailversand +## - +## - may: +## - Opportunistic TLS: announce STARTTLS support to SMTP clients, +## - but do not require that clients use TLS encryption. +# smtp_use_tls=yes +#smtp_tls_security_level=may +smtp_tls_security_level=dane + +## - 0 Disable logging of TLS activity. +## - 1 Log TLS handshake and certificate information. +## - 2 Log levels during TLS negotiation. +## - 3 Log hexadecimal and ASCII dump of TLS negotiation process. +## - 4 Also log hexadecimal and ASCII dump of complete transmission after STARTTLS. +## - +smtpd_tls_loglevel = 1 +smtp_tls_loglevel = 1 + +smtpd_tls_cert_file = $_TLS_CERT_FILE +smtpd_tls_key_file = $_TLS_KEY_FILE + +## - File with DH parameters that the Postfix SMTP server should use with EDH ciphers. +## - +## - Dont't forget to create it, e.g with openssl: +## - openssl dhparam -out /etc/postfix/ssl/dh_1024.pem -2 1024 +## - +#smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_1024.pem +## - also possible to use 2048 key with that parameter +## - +smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_2048.pem + +## - File with DH parameters that the Postfix SMTP server should use with EDH ciphers. +## - +## - Dont't forget to create it, e.g with openssl: +## - openssl dhparam -out /etc/postfix/ssl/dh_512.pem -2 512 +## - +smtpd_tls_dh512_param_file = /etc/postfix/ssl/dh_512.pem + + +## - File containing CA certificates of root CAs trusted to sign either remote SMTP +## - server certificates or intermediate CA certificates. These are loaded into +## - memory !! BEFORE !! the smtp(8) client enters the chroot jail. +## - +smtp_tls_CAfile = $_TLS_CA_FILE + +## - Directory with PEM format certificate authority certificates that the Postfix SMTP +## - client uses to verify a remote SMTP server certificate. Don't forget to create the +## - necessary "hash" links with, for example, " +## - $OPENSSL_HOME/bin/c_rehash /etc/postfix/certs". +## - +## - !! Note !! +## - To use this option in chroot mode, this directory (or a copy) must be inside +## - the chroot jail. +## - +## - Note that a chrooted daemon resolves all filenames relative to the Postfix +## - queue directory (/var/spool/postfix) +## - +#smtpd_tls_CApath = /etc/postfix/certs + + +# Disable SSLv2 SSLv3 - Postfix SMTP server +# +# List of TLS protocols that the Postfix SMTP server will exclude or +# include with opportunistic TLS encryption. +smtpd_tls_protocols = !SSLv2, !SSLv3 +# +# The SSL/TLS protocols accepted by the Postfix SMTP server +# with mandatory TLS encryption. +smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3 + + +# Disable SSLv2 SSLv3 - Postfix SMTP client +# +# List of TLS protocols that the Postfix SMTP client will exclude or +# include with opportunistic TLS encryption. +smtp_tls_protocols = !SSLv2, !SSLv3 +# +# List of SSL/TLS protocols that the Postfix SMTP client will use +# with mandatory TLS encryption +smtp_tls_mandatory_protocols = !SSLv2, !SSLv3 + + +## - Activate des "Ephemeral Elliptic Curve Diffie-Hellman" (EECDH) key exchange +## - openssl > 1.0 +## - +smtpd_tls_eecdh_grade = strong + +# standard list cryptographic algorithm +tls_preempt_cipherlist = yes + +# Disable ciphers which are less than 256-bit: +# +#smtpd_tls_mandatory_ciphers = high +# +# opportunistic +smtpd_tls_ciphers = high + + +# Exclude ciphers +#smtpd_tls_exclude_ciphers = +# RC4 +# aNULL +# SEED-SHA +# EXP +# MD5 +smtpd_tls_exclude_ciphers = + aNULL + eNULL + EXPORT + DES + RC4 + MD5 + PSK + aECDH + EDH-DSS-DES-CBC3-SHA + EDH-RSA-DES-CDC3-SHA + KRB5-DE5 + CBC3-SHA + + +smtpd_tls_session_cache_database = btree:\${data_directory}/smtpd_scache +smtp_tls_session_cache_database = btree:\${data_directory}/smtp_scache + + +#======= SASL Authentification ============ +smtpd_sasl_auth_enable = yes +smtpd_sasl_type=cyrus +smtpd_sasl_path=smtpd + +smtpd_sasl_security_options = noanonymous +smtpd_sasl_authenticated_header = yes +broken_sasl_auth_clients = yes + + +## - Optional lookup table with the SASL login names that own +## - sender (MAIL FROM) addresses. +smtpd_sender_login_maps = + + +#======= Virtual mailboxes ============ + +## - Local Mailboxes +## - +virtual_mailbox_base = +virtual_uid_maps = +virtual_gid_maps = + +## - virtual_transport +## - ================= +## - +## - using postfix +## - virtual_transport = virtual +## - +## - using dovecot lda +## - virtual_transport = dovecot +## - +## - using dovecot's lmtp service +## - virtual_transport = lmtp:unix:private/dovecot-lmtp +## - +virtual_transport = virtual + +virtual_mailbox_maps = + +virtual_mailbox_domains = + +## - Optional lookup tables that alias specific mail addresses or domains +## - to other local or remote address. The table format and lookups are +## - documented in virtual(5). For an overview of Postfix address +## - manipulations see the ADDRESS_REWRITING_README document. +## - +virtual_alias_maps = + ## - mailman + #hash:/var/lib/mailman/data/virtual-mailman + +## - Postfix is final destination for the specified list of virtual alias +## - domains, that is, domains for which all addresses are aliased to addresses +## - in other local or remote domains. The SMTP server validates recipient +## - addresses with \$virtual_alias_maps and rejects non-existent recipients. +## - See also the virtual alias domain class in the ADDRESS_CLASS_README file +## - +virtual_alias_domains = + + +#======= Restrictions ============ +smtpd_recipient_restrictions = +# only special accounts (postmaster, abuse and other rolr accounts) + check_recipient_access btree:/etc/postfix/access_recipient-rfc, +# White- / Blacklisting + check_sender_access btree:/etc/postfix/access_sender, + check_recipient_access btree:/etc/postfix/access_recipient, +# permit trusted network (mynetwork) + permit_mynetworks, +# permit our users + permit_sasl_authenticated, +# dont' accept misconfigured Mail + reject_non_fqdn_sender, + reject_non_fqdn_recipient, + reject_unknown_sender_domain, + reject_unknown_recipient_domain, + reject_unlisted_recipient, +# don't accept misconfigured recipients +# RBL check - !! comment out if postcreens postscreen_dnsbl_sites is in use + # Whitelist (configured on a.ns.oopen.de + # in /opt/tinydns/root/zonefiles/dnswl.oopen.de.zone ) + permit_dnswl_client dnswl.oopen.de, + # Blacklists + reject_rbl_client zen.spamhaus.org, + reject_rbl_client ix.dnsbl.manitu.net, + #reject_rbl_client bl.spamcop.net, + # March 1, 2013: NJABL is in the process of being shut down + #reject_rbl_client dnsbl.njabl.org, +# Policyd-Weight + #check_policy_service inet:127.0.0.1:12525, +# Greylisting check + warn_if_reject, + check_policy_service inet:127.0.0.1:10023, +# Reject the request unless one of the following is true: +# +# - Postfix is mail forwarder: the resolved RCPT TO domain matches \$relay_domains +# or a subdomain thereof, and contains no sender-specified routing (user@elsewhere@domain), +# +# +# - Postfix is the final destination: the resolved RCPT TO domain matches +# \$mydestination, \$inet_interfaces, \$proxy_interfaces, \$virtual_alias_domains, +# or \$virtual_mailbox_domains, and contains no sender-specified routing (user@elsewhere@domain). + reject_unverified_recipient, +# permit Backup MX + permit_mx_backup, +# forbid all other relaying + reject_unauth_destination, +# permit, if all restrictions so far passed + permit + + +## - Sinve version 2.11 +## - +smtpd_relay_restrictions = +# only special accounts (postmaster, abuse and other rolr accounts) + check_recipient_access btree:/etc/postfix/access_recipient-rfc, +# White- / Blacklisting + check_sender_access btree:/etc/postfix/access_sender, + check_recipient_access btree:/etc/postfix/access_recipient, +# permit trusted network (mynetwork) + permit_mynetworks, +# permit our users + permit_sasl_authenticated, +# dont' accept misconfigured Mail + reject_non_fqdn_sender, + reject_non_fqdn_recipient, + reject_unknown_sender_domain, + reject_unknown_recipient_domain, + reject_unlisted_recipient, +# don't accept misconfigured recipients +# RBL check - !! comment out if postcreens postscreen_dnsbl_sites is in use + # Whitelist (configured on a.ns.oopen.de + # in /opt/tinydns/root/zonefiles/dnswl.oopen.de.zone ) + permit_dnswl_client dnswl.oopen.de, + # Blacklists + reject_rbl_client zen.spamhaus.org, + reject_rbl_client ix.dnsbl.manitu.net, + #reject_rbl_client bl.spamcop.net, + # March 1, 2013: NJABL is in the process of being shut down + #reject_rbl_client dnsbl.njabl.org, +# Policyd-Weight + #check_policy_service inet:127.0.0.1:12525, +# Greylisting check + warn_if_reject, + check_policy_service inet:127.0.0.1:10023, +# Reject the request unless one of the following is true: +# +# - Postfix is mail forwarder: the resolved RCPT TO domain matches \$relay_domains +# or a subdomain thereof, and contains no sender-specified routing (user@elsewhere@domain), +# +# +# - Postfix is the final destination: the resolved RCPT TO domain matches +# \$mydestination, \$inet_interfaces, \$proxy_interfaces, \$virtual_alias_domains, +# or \$virtual_mailbox_domains, and contains no sender-specified routing (user@elsewhere@domain). + reject_unverified_recipient, +# permit Backup MX + permit_mx_backup, +# forbid all other relaying + reject_unauth_destination, +# permit, if all restrictions so far passed + permit + +EOF +echo_ok + + +## - /etc/mailname +## - +echononl " Set \"/etc/mailname\"" +echo $HOSTNAME > /etc/mailname +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +## - /etc/aliases +## - +echononl " Adjust \"/etc/aliases\"" +cat << EOF > /etc/aliases +# See man 5 aliases for format +mailer-daemon: postmaster +postmaster: root +nobody: root +hostmaster: root +usenet: root +news: root +webmaster: root +www: root +ftp: root +abuse: root +noc: root +security: root + +do-not-reply: /dev/null + +root: $ADMIN_EMAIL +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + + +## - create directory for certificates and copy certificates +## - and coresponding keys to /etc/postfix/ssl/ +## - +echononl " Create directory for certificates \"/etc/postfix/ssl\"" +if [[ -d "/etc/postfix/ssl" ]] ; then + echo_skipped +else + mkdir -p /etc/postfix/ssl + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +fi + + +## - generate DH parameters that the Postfix SMTP server should use +## - with EDH ciphers (length 512 and 1024 +## - +echononl " Generate DH key length=512 \"/etc/postfix/ssl/dh_512.pem\"" +if [ ! -f /etc/postfix/ssl/dh_512.pem ]; then + openssl dhparam -out /etc/postfix/ssl/dh_512.pem -2 512 > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi +echononl " Generate DH key length=1024 \"/etc/postfix/ssl/dh_1024.pem\"" +if [ ! -f /etc/postfix/ssl/dh_1024.pem ]; then + openssl dhparam -out /etc/postfix/ssl/dh_1024.pem -2 1024 > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi +echononl " Generate DH key length=2048 \"/etc/postfix/ssl/dh_2048.pem\"" +if [ ! -f /etc/postfix/ssl/dh_2048.pem ]; then + openssl dhparam -out /etc/postfix/ssl/dh_2048.pem -2 2048 > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi +echononl " Create Symlink \"$_TLS_CERT_FILE\"" +if [ ! -h "$_TLS_CERT_FILE" ]; then + ln -s /etc/ssl/certs/ssl-cert-snakeoil.pem $_TLS_CERT_FILE + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi +echononl " Create Symlink \"$_TLS_KEY_FILE\"" +if [ ! -h "$_TLS_KEY_FILE" ]; then + ln -s /etc/ssl/private/ssl-cert-snakeoil.key $_TLS_KEY_FILE + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + +## - rebuld alias database +## - +echononl " Rebuld alias database" +newaliases > /dev/null 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + + +## - create files +## - +echononl " Create file \"access_recipient-rfc\"" +cat < /etc/postfix/access_recipient-rfc +# if destination is ok, permit +/^postmaster\@/ permit_auth_destination +/^abuse\@/ permit_auth_destination +EOF +postmap btree:/etc/postfix/access_recipient-rfc +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + + +## - Notice: +## - The access_sender list can also be used as white list: +## - backup@b3-bornim.de OK +## - backup_file-ah@oopen.de OK +## - backup_file-spr@oopen.de OK +## - root_file_spr@oopen.de OK +## - backup_anw-urban@oopen.de OK +## - anonymous@bbb-server.b3-bornim.de OK +echononl " Create file \"access_sender\"" +cat < /etc/postfix/access_sender +# - bekannte Virus/Spam Absener blocken +# - +error@mailfrom.com REJECT +EOF +postmap btree:/etc/postfix/access_sender +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +echononl " Create file \"access_recipient\"" +echo > /etc/postfix/access_recipient +postmap btree:/etc/postfix/access_recipient +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +echononl " Create file \"transport\"" +echo > /etc/postfix/transport +postmap btree:/etc/postfix/transport +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +echononl " Create file \"relay_domains\"" +echo > /etc/postfix/relay_domains +postmap btree:/etc/postfix/relay_domains +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +## - restart postfix +## - +echononl " Restart postfix" +if $systemd_exists ; then + systemctl restart postfix > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + /etc/init.d/postfix restart > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +fi + + +## - Omitt logging into system.log +## - +echononl " Create \"/etc/rsyslog.d/postfix.conf\"" +cat << EOF >> /etc/rsyslog.d/postfix.conf + +# +# Logging for the mail system. Split it up so that +# it is easy to write scripts to parse these files. +# +mail.info -/var/log/mail.info +mail.warn -/var/log/mail.warn +mail.err /var/log/mail.err + +mail.* -/var/log/mail.log +& ~ +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +echononl " Restart rsyslog daemon" +if $systemd_exists ; then + systemctl restart rsyslog > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + /etc/init.d/rsyslog restart > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +fi + + +rm $tmp_err_msg +echo "" +exit diff --git a/BAK/install_postfix_relay.sh.00 b/BAK/install_postfix_relay.sh.00 new file mode 100755 index 0000000..8893766 --- /dev/null +++ b/BAK/install_postfix_relay.sh.00 @@ -0,0 +1,1011 @@ +#!/usr/bin/env bash + +_TLS_CERT_DIR=/etc/postfix/ssl +_TLS_CERT_FILE="${_TLS_CERT_DIR}/mailserver.crt" +_TLS_KEY_FILE="${_TLS_CERT_DIR}/mailserver.key" +# +_TLS_CA_FILE=/etc/ssl/certs/ca-certificates.crt +# +# +#_HOSTNAME=o15.oopen.de +#_IPV4=83.223.86.96 +#_EXT_IF_IP=83.223.86.96 +# +### - Leave empty, if no IPv6 should be supported +### - +#_IPV6=2a01:30:0:13:5054:ff:fe09:2318 +##_IPV6= +# +#_ADMIN_EMAIL=admin@oopen.de + + +# ------------- +# --- Some functions +# ------------- +echononl(){ + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo -e -n "$*\\c" 1>&2 + else + echo -e -n "$*" 1>&2 + fi + rm /tmp/shprompt$$ +} + +fatal(){ + echo "" + echo -e "fatal error: $*" + echo "" + echo -e "\t\033[31m\033[1mInstalllation will be interrupted\033[m\033[m" + echo "" + exit 1 +} + +error(){ + echo "" + echo -e "\t[ \033[31m\033[1mFehler\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 "" +} + +echo_done() { + echo -e "\033[80G[ \033[32mdone\033[m ]" +} +echo_ok() { + echo -e "\033[80G[ \033[32mok\033[m ]" +} +echo_warning() { + echo -e "\033[80G[ \033[33m\033[1mwarn\033[m ]" +} +echo_failed(){ + echo -e "\033[80G[ \033[1;31mfailed\033[m ]" +} +echo_skipped() { + echo -e "\033[80G[ \033[33m\033[1mskipped\033[m ]" +} + + +# - Is this a systemd system? +# - +if [[ "X`which systemd`" = "X" ]]; then + systemd_exists=false +else + systemd_exists=true +fi + +echo "" + +conf_dir=$(dirname $0) + +if [[ -f "${conf_dir}/postfix_base.conf" ]]; then + source ${conf_dir}/postfix_base.conf +fi + +clear +echo -e "\033[21G\033[32mInstallation script for Postfix basic mailsystem \033[m" +echo + +HOSTNAME= +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Insert hostname" +echo "" +if [[ -n "$_HOSTNAME" ]]; then + echononl "hostname [${_HOSTNAME}]: " + read HOSTNAME + if [[ "X${HOSTNAME}" = "X" ]]; then + HOSTNAME=$_HOSTNAME + fi +else + while [[ "X${HOSTNAME}" = "X" ]]; do + echononl "hostname: " + read HOSTNAME + if [[ "X${HOSTNAME}" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mHostname is reqired\033[m\n" + fi + done +fi + +IPV4= +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Insert IPv4 address" +echo "" +if [[ -n "$_IPV4" ]]; then + echononl "IPv4 address [${_IPV4}]: " + read IPV4 + if [[ "X${IPV4}" = "X" ]]; then + IPV4=$_IPV4 + fi +else + while [[ "X${IPV4}" = "X" ]]; do + echononl "IPv4 address: " + read IPV4 + if [[ "X${IPV4}" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mIPv4 address is reqired\033[m\n" + fi + done +fi +IPV6= +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Insert IPv6 address" +echo "Type:" +echo -e "\t\033[33mNone\033[m if IPv6 is not suppoerted" +echo "" +if [[ -n "$_IPV6" ]]; then + [[ "X$_IPV6" = "Xdisabled" ]] && _IPV6=None + echononl "IPv6 address [${_IPV6}]: " + read IPV6 + if [[ "X${IPV6}" = "X" ]]; then + IPV6=$_IPV6 + fi +else + while [[ "X${IPV6}" = "X" ]]; do + echononl "IPv6 address: " + read IPV6 + if [[ "X${IPV6}" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mIPv4 address is reqired\033[m\n" + fi + done +fi +if [ "X$IPV6" = "Xnone" -o "X$IPV6" = "XNone" ]; then + IPV6=disabled +fi + +ADMIN_EMAIL= +echo "" +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Insert e-mail address where messages to local root should be forwarded" +echo "" +echo "" +if [[ -n "$_ADMIN_EMAIL" ]]; then + echononl "Admin e-mail address [$_ADMIN_EMAIL]: " + read ADMIN_EMAIL + if [[ "X${ADMIN_EMAIL}" = "X" ]]; then + ADMIN_EMAIL=$_ADMIN_EMAIL + fi +else + while [[ "X${ADMIN_EMAIL}" = "X" ]]; do + echononl "Admin e-mail address: " + read ADMIN_EMAIL + if [[ "X${ADMIN_EMAIL}" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mAdmin e-mail address is reqired\033[m\n" + fi + done +fi + + +echo "" +echo "" +echo -e "\033[21G\033[32mStart installation/configuration with the following parameters\033[m" +echo "" +echo -e "\tHostname.................: $HOSTNAME" +echo -e "\tIPv4 address.............: $IPV4" +echo -e "\tIPv6 address.............: $IPV6" +echo -e "\tAdmin e-mail.............: $ADMIN_EMAIL" +echo "" +echononl "einverstanden (yes/no): " +read OK +OK=${OK,,} +while [ "X$OK" != "Xyes" -a "X$OK" != "Xno" ]; do + echononl "Wrong entry! [yes/no]: " + read OK + OK=${OK,,} +done +[ $OK = "yes" ] || fatal Repeat with other settings.. + +echo "" +echo "" + +echononl " Save Configuration" +cat << EOF > ${conf_dir}/postfix_base.conf +# --- +# - Parametersettins postfix bases system +# --- + +_HOSTNAME=$HOSTNAME +_IPV4=$IPV4 +_IPV6=$IPV6 +_ADMIN_EMAIL=$ADMIN_EMAIL +_SASL_USER=$SASL_USER +_SASL_PASS=$SASL_PASS +_RELAY_HOST=$RELAY_HOST +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +[[ "$IPV6" = "disabled" ]] && IPV6="" + + +# - Deinstall debian exim4 packages +# - +echononl " Deinstall debian exim4 packages" +_installed_exim_packages=`dpkg -l | grep exim4 | grep -e "^i" | awk '{print$2}'` +for _pkg in $_installed_exim_packages ; do + installed_exim_packages="$installed_exim_packages $_pkg" +done +if [[ -n "$installed_exim_packages" ]] ; then + + if `dpkg -l | grep bsd-mailx | grep -e "^i" > /dev/null 2>&1` ; then + installed_exim_packages="$installed_exim_packages bsd-mailx" + fi + + apt-get remove --purge -qq -y $installed_exim_packages > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + + + +# - Install Postfix from debian packages system +# - +echononl " Install Postfix from debian packages system" +_needed_packages="postfix postfix-pcre libsasl2-modules bsd-mailx haveged" +for _pkg in $_needed_packages ; do + if `dpkg -l | grep $_pkg | grep -e "^i" > /dev/null 2>&1` ; then + continue + else + needed_packages="$needed_packages $_pkg" + fi +done +if [[ -n "$needed_packages" ]]; then + DEBIAN_FRONTEND=noninteractive apt-get -y install $needed_packages > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + + +# - Backup existing postfix configuration file +# - +echononl " Backup existing postfix configuration file" +if [[ -f "/etc/postfix/main.cf" ]]; then + cp -a /etc/postfix/main.cf /etc/postfix/main.cf.`date +%Y%m%d-%H%M` + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + + +# - Creeate new postfix configuration file +# - +echononl " Creeate new postfix configuration file" +cat < /etc/postfix/main.cf +# ============ Basic settings ============ + +# Debian specific: Specifying a file name will cause the first +# line of that file to be used as the name. The Debian default +# is /etc/mailname. +#myorigin = /etc/mailname +myorigin = /etc/mailname + +smtpd_banner = \$myhostname ESMTP \$mail_name (Debian/GNU) +biff = no + +# appending .domain is the MUA's job. +append_dot_mydomain = no + +# Uncomment the next line to generate "delayed mail" warnings +#delay_warning_time = 4h + +readme_directory = /usr/share/doc/postfix +html_directory = /usr/share/doc/postfix/html + +## - The Internet protocols Postfix will attempt to use when making +## - or accepting connections. +## - DEFAULT: ipv4 +EOF + +if [ -n "$IPV6" ]; then + cat <> /etc/postfix/main.cf +inet_protocols = ipv4, ipv6 + +#inet_interfaces = all +inet_interfaces = + 127.0.0.1 + $IPV4 + $IPV6 + +myhostname = $HOSTNAME + +mydestination = + $HOSTNAME + localhost + +## - The list of "trusted" SMTP clients that have more +## - privileges than "strangers" +## - +mynetworks = + 127.0.0.0/8 + [::ffff:127.0.0.0]/104 + [::1]/128 + ${IPV4}/32 + [${IPV6}]/128 + # a.mx.oopen.de + #83.223.86.91 + #[2a01:30:0:13:2f7:50ff:fed2:cef7]/128 + # b.mx.oopen.de + #83.223.86.97 + #[2a01:30:0:13:21f:92ff:fe00:538b] + # d.mx.oopen.de + #83.223.86.92/32 + #[2a01:30:0:13:254:9eff:fed5:e7fd]/128 + +smtp_bind_address = $IPV4 +smtp_bind_address6 = $IPV6 + +EOF +else + cat <> /etc/postfix/main.cf +inet_protocols = ipv4 + +#inet_interfaces = all +inet_interfaces = + 127.0.0.1 + $IPV4 + +myhostname = $HOSTNAME + +mydestination = + $HOSTNAME + localhost + +## - The list of "trusted" SMTP clients that have more +## - privileges than "strangers" +## - +mynetworks = + 127.0.0.0/8 + ${IPV4}/32 + +#smtp_bind_address = $IPV4 +#smtp_bind_address6 = $IPV6 + +EOF +fi + +cat <> /etc/postfix/main.cf + +## - The method to generate the default value for the mynetworks parameter. +## - +## - mynetworks_style = host" when Postfix should "trust" only the local machine +## - mynetworks_style = subnet (default value) "when Postfix should "trust" SMTP +## - clients in the same IP subnetworks as the local machine. +## - mynetworks_style = class" when Postfix should "trust" SMTP clients in the same +## - IP class A/B/C networks as the local machine. +## - +#mynetworks_style = host + + +## - The maximal size of any local(8) individual mailbox or maildir file, +## - or zero (no limit). In fact, this limits the size of any file that is +## - written to upon local delivery, including files written by external +## - commands that are executed by the local(8) delivery agent. +## - +mailbox_size_limit = 0 + +## - The maximal size in bytes of a message, including envelope information. +## - +## - we user 50MB +## - +message_size_limit = 52480000 + +## - The system-wide recipient address extension delimiter +## - +recipient_delimiter = + + +## - The alias databases that are used for local(8) delivery. +## - +alias_maps = + hash:/etc/aliases + +## - The alias databases for local(8) delivery that are updated +## - with "newaliases" or with "sendmail -bi". +## - +alias_database = + hash:/etc/aliases + +## - Optional lookup tables with mappings from recipient address +## - to (message delivery transport, next-hop destination). +## - See transport(5) for details. +## - +transport_maps = + btree:/etc/postfix/transport + btree:/etc/postfix/relay_domains + +## - The maximal time a message is queued before it is sent back as +## - undeliverable. Defaults to 5d (5 days) +## - Specify 0 when mail delivery should be tried only once. +## - +maximal_queue_lifetime = 3d +bounce_queue_lifetime = \$maximal_queue_lifetime + +## - delay_warning_time (default: 0h) +## - +## - The time after which the sender receives a copy of the message +## - headers of mail that is still queued. To enable this feature, +## - specify a non-zero time value (an integral value plus an optional +## - one-letter suffix that specifies the time unit). +## - Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks). +## - The default time unit is h (hours). +delay_warning_time = 1d + + +# ============ Relay parameters ============ + +relayhost = +relay_domains = + $mydestination + btree:/etc/postfix/relay_domains + + +# ============ TLS parameters ============ + +## - supports DNSSEC +## - +## - !! Notice !! +## - In order to support DNSSEC and DANE your resolver MUST support +## - DNSSEC too. +## - +## - If your resolver does not support DNSSEC, install "unbound". +## - +smtp_host_lookup = dns +smtp_dns_support_level = dnssec + +## - Aktiviert TLS für den Mailempfang +## - +## - may: +## - Opportunistic TLS. Use TLS if this is supported by the remote +## - SMTP server, otherwise use plaintext +## - +## - This overrides the obsolete parameters smtpd_use_tls and +## - smtpd_enforce_tls. This parameter is ignored with +## - "smtpd_tls_wrappermode = yes". +#smtpd_use_tls=yes +smtpd_tls_security_level=may + + +## - Aktiviert TLS für den Mailversand +## - +## - may: +## - Opportunistic TLS: announce STARTTLS support to SMTP clients, +## - but do not require that clients use TLS encryption. +# smtp_use_tls=yes +#smtp_tls_security_level=may +smtp_tls_security_level=dane + +## - 0 Disable logging of TLS activity. +## - 1 Log TLS handshake and certificate information. +## - 2 Log levels during TLS negotiation. +## - 3 Log hexadecimal and ASCII dump of TLS negotiation process. +## - 4 Also log hexadecimal and ASCII dump of complete transmission after STARTTLS. +## - +smtpd_tls_loglevel = 1 +smtp_tls_loglevel = 1 + +smtpd_tls_cert_file = $_TLS_CERT_FILE +smtpd_tls_key_file = $_TLS_KEY_FILE + +## - File with DH parameters that the Postfix SMTP server should use with EDH ciphers. +## - +## - Dont't forget to create it, e.g with openssl: +## - openssl gendh -out /etc/postfix/ssl/dh_1024.pem -2 1024 +## - +#smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_1024.pem +## - also possible to use 2048 key with that parameter +## - +smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_2048.pem + +## - File with DH parameters that the Postfix SMTP server should use with EDH ciphers. +## - +## - Dont't forget to create it, e.g with openssl: +## - openssl gendh -out /etc/postfix/ssl/dh_512.pem -2 512 +## - +smtpd_tls_dh512_param_file = /etc/postfix/ssl/dh_512.pem + + +## - File containing CA certificates of root CAs trusted to sign either remote SMTP +## - server certificates or intermediate CA certificates. These are loaded into +## - memory !! BEFORE !! the smtp(8) client enters the chroot jail. +## - +smtp_tls_CAfile = $_TLS_CA_FILE + +## - Directory with PEM format certificate authority certificates that the Postfix SMTP +## - client uses to verify a remote SMTP server certificate. Don't forget to create the +## - necessary "hash" links with, for example, " +## - $OPENSSL_HOME/bin/c_rehash /etc/postfix/certs". +## - +## - !! Note !! +## - To use this option in chroot mode, this directory (or a copy) must be inside +## - the chroot jail. +## - +## - Note that a chrooted daemon resolves all filenames relative to the Postfix +## - queue directory (/var/spool/postfix) +## - +#smtpd_tls_CApath = /etc/postfix/certs + + +# Disable SSLv2 SSLv3 - Postfix SMTP server +# +# List of TLS protocols that the Postfix SMTP server will exclude or +# include with opportunistic TLS encryption. +smtpd_tls_protocols = !SSLv2, !SSLv3 +# +# The SSL/TLS protocols accepted by the Postfix SMTP server +# with mandatory TLS encryption. +smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3 + + +# Disable SSLv2 SSLv3 - Postfix SMTP client +# +# List of TLS protocols that the Postfix SMTP client will exclude or +# include with opportunistic TLS encryption. +smtp_tls_protocols = !SSLv2, !SSLv3 +# +# List of SSL/TLS protocols that the Postfix SMTP client will use +# with mandatory TLS encryption +smtp_tls_mandatory_protocols = !SSLv2, !SSLv3 + + +## - Activate des "Ephemeral Elliptic Curve Diffie-Hellman" (EECDH) key exchange +## - openssl > 1.0 +## - +smtpd_tls_eecdh_grade = strong + +# standard list cryptographic algorithm +tls_preempt_cipherlist = yes + +# Disable ciphers which are less than 256-bit: +# +#smtpd_tls_mandatory_ciphers = high +# +# opportunistic +smtpd_tls_ciphers = high + + +# Exclude ciphers +#smtpd_tls_exclude_ciphers = +# RC4 +# aNULL +# SEED-SHA +# EXP +# MD5 +smtpd_tls_exclude_ciphers = + aNULL + eNULL + EXPORT + DES + RC4 + MD5 + PSK + aECDH + EDH-DSS-DES-CBC3-SHA + EDH-RSA-DES-CDC3-SHA + KRB5-DE5 + CBC3-SHA + + +smtpd_tls_session_cache_database = btree:\${data_directory}/smtpd_scache +smtp_tls_session_cache_database = btree:\${data_directory}/smtp_scache + + +#======= SASL Authentification ============ +smtpd_sasl_auth_enable = yes +smtpd_sasl_type=cyrus +smtpd_sasl_path=smtpd + +smtpd_sasl_security_options = noanonymous +smtpd_sasl_authenticated_header = yes +broken_sasl_auth_clients = yes + + +## - Optional lookup table with the SASL login names that own +## - sender (MAIL FROM) addresses. +smtpd_sender_login_maps = + + +#header_checks = pcre:/etc/postfix/header_checks +prepend_delivered_header = + forward + file + + +#======= Restrictions ============ +smtpd_recipient_restrictions = +# only special accounts (postmaster, abuse and other rolr accounts) + check_recipient_access btree:/etc/postfix/access_recipient-rfc, +# White- / Blacklisting + check_sender_access btree:/etc/postfix/access_sender, + check_recipient_access btree:/etc/postfix/access_recipient, +# permit trusted network (mynetwork) + permit_mynetworks, +# permit our users + permit_sasl_authenticated, +# dont' accept misconfigured Mail + reject_non_fqdn_sender, + reject_non_fqdn_recipient, + reject_unknown_sender_domain, + reject_unknown_recipient_domain, + reject_unlisted_recipient, +# don't accept misconfigured recipients +# RBL check - !! comment out if postcreens postscreen_dnsbl_sites is in use + # Whitelist (configured on a.ns.oopen.de + # in /opt/tinydns/root/zonefiles/dnswl.oopen.de.zone ) + permit_dnswl_client dnswl.oopen.de, + # Blacklists + reject_rbl_client zen.spamhaus.org, + reject_rbl_client ix.dnsbl.manitu.net, + #reject_rbl_client bl.spamcop.net, + # March 1, 2013: NJABL is in the process of being shut down + #reject_rbl_client dnsbl.njabl.org, +# Policyd-Weight + #check_policy_service inet:127.0.0.1:12525, +# Greylisting check + warn_if_reject, + check_policy_service inet:127.0.0.1:10023, +# Reject the request unless one of the following is true: +# +# - Postfix is mail forwarder: the resolved RCPT TO domain matches \$relay_domains +# or a subdomain thereof, and contains no sender-specified routing (user@elsewhere@domain), +# +# +# - Postfix is the final destination: the resolved RCPT TO domain matches +# \$mydestination, \$inet_interfaces, \$proxy_interfaces, \$virtual_alias_domains, +# or \$virtual_mailbox_domains, and contains no sender-specified routing (user@elsewhere@domain). + reject_unverified_recipient, +# permit Backup MX + permit_mx_backup, +# forbid all other relaying + reject_unauth_destination, +# permit, if all restrictions so far passed + permit + + +## - Sinve version 2.11 +## - +smtpd_relay_restrictions = +# only special accounts (postmaster, abuse and other rolr accounts) + check_recipient_access btree:/etc/postfix/access_recipient-rfc, +# White- / Blacklisting + check_sender_access btree:/etc/postfix/access_sender, + check_recipient_access btree:/etc/postfix/access_recipient, +# permit trusted network (mynetwork) + permit_mynetworks, +# permit our users + permit_sasl_authenticated, +# dont' accept misconfigured Mail + reject_non_fqdn_sender, + reject_non_fqdn_recipient, + reject_unknown_sender_domain, + reject_unknown_recipient_domain, + reject_unlisted_recipient, +# don't accept misconfigured recipients +# RBL check - !! comment out if postcreens postscreen_dnsbl_sites is in use + # Whitelist (configured on a.ns.oopen.de + # in /opt/tinydns/root/zonefiles/dnswl.oopen.de.zone ) + permit_dnswl_client dnswl.oopen.de, + # Blacklists + reject_rbl_client zen.spamhaus.org, + reject_rbl_client ix.dnsbl.manitu.net, + #reject_rbl_client bl.spamcop.net, + # March 1, 2013: NJABL is in the process of being shut down + #reject_rbl_client dnsbl.njabl.org, +# Policyd-Weight + #check_policy_service inet:127.0.0.1:12525, +# Greylisting check + warn_if_reject, + check_policy_service inet:127.0.0.1:10023, +# Reject the request unless one of the following is true: +# +# - Postfix is mail forwarder: the resolved RCPT TO domain matches \$relay_domains +# or a subdomain thereof, and contains no sender-specified routing (user@elsewhere@domain), +# +# +# - Postfix is the final destination: the resolved RCPT TO domain matches +# \$mydestination, \$inet_interfaces, \$proxy_interfaces, \$virtual_alias_domains, +# or \$virtual_mailbox_domains, and contains no sender-specified routing (user@elsewhere@domain). + reject_unverified_recipient, +# permit Backup MX + permit_mx_backup, +# forbid all other relaying + reject_unauth_destination, +# permit, if all restrictions so far passed + permit + +EOF +echo_ok + + +## - /etc/mailname +## - +echononl " Set \"/etc/mailname\"" +echo $HOSTNAME > /etc/mailname +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +## - /etc/aliases +## - +echononl " Adjust \"/etc/aliases\"" +cat << EOF > /etc/aliases +# See man 5 aliases for format +mailer-daemon: postmaster +postmaster: root +nobody: root +hostmaster: root +usenet: root +news: root +webmaster: root +www: root +ftp: root +abuse: root +noc: root +security: root + +root: $_ADMIN_EMAIL +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + + +## - create directory for certificates and copy certificates +## - and coresponding keys to /etc/postfix/ssl/ +## - +echononl " Create directory for certificates \"/etc/postfix/ssl\"" +if [[ -d "/etc/postfix/ssl" ]] ; then + echo_skipped +else + mkdir -p /etc/postfix/ssl + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +fi + + +## - generate DH parameters that the Postfix SMTP server should use +## - with EDH ciphers (length 512 and 1024 +## - +echononl " Generate DH key length=512 \"/etc/postfix/ssl/dh_512.pem\"" +if [ ! -f /etc/postfix/ssl/dh_512.pem ]; then + openssl gendh -out /etc/postfix/ssl/dh_512.pem -2 512 > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi +echononl " Generate DH key length=1024 \"/etc/postfix/ssl/dh_1024.pem\"" +if [ ! -f /etc/postfix/ssl/dh_1024.pem ]; then + openssl gendh -out /etc/postfix/ssl/dh_1024.pem -2 1024 > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi +echononl " Generate DH key length=2048 \"/etc/postfix/ssl/dh_2048.pem\"" +if [ ! -f /etc/postfix/ssl/dh_2048.pem ]; then + openssl gendh -out /etc/postfix/ssl/dh_2048.pem -2 2048 > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi +echononl " Create Symlink \"$_TLS_CERT_FILE\"" +if [ ! -h "$_TLS_CERT_FILE" ]; then + ln -s /etc/ssl/certs/ssl-cert-snakeoil.pem $_TLS_CERT_FILE + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi +echononl " Create Symlink \"$_TLS_KEY_FILE\"" +if [ ! -h "$_TLS_KEY_FILE" ]; then + ln -s /etc/ssl/private/ssl-cert-snakeoil.key $_TLS_KEY_FILE + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + +## - rebuld alias database +## - +echononl " Rebuld alias database" +newaliases > /dev/null 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + + +## - create files +## - +echononl " Create file \"access_recipient-rfc\"" +cat < /etc/postfix/access_recipient-rfc +# if destination is ok, permit +/^postmaster\@/ permit_auth_destination +/^abuse\@/ permit_auth_destination +EOF +postmap btree:/etc/postfix/access_recipient-rfc +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + + +## - Notice: +## - The access_sender list can also be used as white list: +## - backup@b3-bornim.de OK +## - backup_file-ah@oopen.de OK +## - backup_file-spr@oopen.de OK +## - root_file_spr@oopen.de OK +## - backup_anw-urban@oopen.de OK +## - anonymous@bbb-server.b3-bornim.de OK +echononl " Create file \"access_sender\"" +cat < /etc/postfix/access_sender +# - bekannte Virus/Spam Absener blocken +# - +error@mailfrom.com REJECT +EOF +postmap btree:/etc/postfix/access_sender +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +echononl " Create file \"access_recipient\"" +echo > /etc/postfix/access_recipient +postmap btree:/etc/postfix/access_recipient +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +echononl " Create file \"transport\"" +echo > /etc/postfix/transport +postmap btree:/etc/postfix/transport +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +echononl " Create file \"relay_domains\"" +echo > /etc/postfix/relay_domains +postmap btree:/etc/postfix/relay_domains +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + + +## - Eliminate Sender ip-address, repalce with 127.0.0.1 +## - +#echononl " Eliminate Sender ip-address, repalce with 127.0.0.1" +#echo '/^Received: from (.* \([-._[:alnum:]]+ \[[.[:digit:]]{7,15}\]\)).*?([[:space:]]+).*\(Authenticated sender: ([^)]+)\)(.*)/ REPLACE Received: from [127.0.0.1] (localhost [127.0.0.1])$2(Authenticated sender: $3)$4' > /etc/postfix/header_checks +#if [[ $? -eq 0 ]] ; then +# echo_ok +#else +# echo_failed +#fi + + +## - restart postfix +## - +echononl " Restart postfix" +if $systemd_exists ; then + systemctl restart postfix > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + /etc/init.d/postfix restart > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +fi + + +## - Omitt logging into system.log +## - +echononl " Create \"/etc/rsyslog.d/postfix.conf\"" +cat << EOF >> /etc/rsyslog.d/postfix.conf + +# +# Logging for the mail system. Split it up so that +# it is easy to write scripts to parse these files. +# +mail.info -/var/log/mail.info +mail.warn -/var/log/mail.warn +mail.err /var/log/mail.err + +mail.* -/var/log/mail.log +& ~ +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +echononl " Restart rsyslog daemon" +if $systemd_exists ; then + systemctl restart rsyslog > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + /etc/init.d/rsyslog restart > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +fi + + +echo "" +exit diff --git a/DOC/amavis/amavis_clamav_sa.install b/DOC/amavis/amavis_clamav_sa.install new file mode 100644 index 0000000..72fd707 --- /dev/null +++ b/DOC/amavis/amavis_clamav_sa.install @@ -0,0 +1,1441 @@ +## --------------------------------------------------- ## +## --- Install AMaViS with ClamAV and Spamassassin --- ## +## --------------------------------------------------- ## + +## - mx.warenform.de +## - +_db_type=pgsql +#_db_type=mysql +#_db_type='mysql' +_db_name='postfix' +_db_user='postfix' +_db_pass='CbX8vg347Vvm' +_db_host='/var/run/postgresql' +_db_host='localhost' + +_quarantine_dir=/var/QUARANTINE +## - !! Don't use doppel quotes (") here !! +_quarantine_admin='postmaster\@$mydomain'; +## - +## - END: mx.warenform.de + +## - a.mx.oopen.de +## - +_ipv4_address=83.223.86.91 +_db_type=pgsql +#_db_type=mysql +#_db_type='mysql' +_db_name='postfix' +_db_user='postfix' +_db_pass='FKt4z55FxMZp' +_db_host='/var/run/postgresql' +_db_host='localhost' + +_quarantine_dir=/var/QUARANTINE +## - !! Don't use doppel quotes (") here !! +_quarantine_admin='postmaster\@$mydomain'; +## - +## - END: a.mx.oopen.de + +## - b.mx.oopen.de +## - +_ipv4_address=83.223.86.162 +_quarantine_dir=/var/QUARANTINE +## - !! Don't use doppel quotes (") here !! +_quarantine_admin='postmaster\@$mydomain'; +## - +## - END: b.mx.oopen.de + +## - listserver.so36.net +## - +_ipv4_address=83.223.73.213 + +_quarantine_dir=/var/QUARANTINE +## - !! Don't use doppel quotes (") here !! +_quarantine_admin='postmaster\@$mydomain'; +## - +## - END: listserver.so36.net + +## - d.mx.oopen.de +## - +_ipv4_address=83.223.86.92 + +_quarantine_dir=/var/QUARANTINE +## - !! Don't use doppel quotes (") here !! +_quarantine_admin='postmaster\@$mydomain'; +## - +## - End: d.mx.oopen.de + + +## - mail.interventionistische-linke.org +## - +_ipv4_address=83.223.85.214 +_db_type=pgsql +#_db_type=mysql +#_db_type='mysql' +_db_name='postfix' +_db_user='postfix' +_db_pass='NcXxt7sf7bfV' +_db_host='/var/run/postgresql' +_db_host='localhost' + +_quarantine_dir=/var/QUARANTINE +## - !! Don't use doppel quotes (") here !! +_quarantine_admin='postmaster\@$mydomain'; +## - +## - END: mail.interventionistische-linke.org + +## - mx03.so36.net +## - +_ipv4_address=83.223.73.205 + +_quarantine_dir=/var/QUARANTINE +## - !! Don't use doppel quotes (") here !! +_quarantine_admin='postmaster\@$mydomain'; +## - +## - End: mx03.so36.net + +if [ "$_db_type" = "postgres" -o "$_db_type" = "postgresql" -o "$_db_type" = "pgsql" -o "$_db_type" = "psql" ];then + _db_type=Pg +fi + +## -- wheezy +## - +apt-get install apt-listchanges libnet-ldap-perl libauthen-sasl-perl dspam libsnmp-perl + +## - Package "dspam" is not yet supported by debian jessie +## - +## - jessie +## - +apt-get install apt-listchanges libnet-ldap-perl libauthen-sasl-perl libsnmp-perl + + +## - prerequisites: AMaViS mit Spamassassin und ClamAV +## - + +## - amavis +## - +apt-get install amavisd-new +## - Empfohlen: +apt-get install cabextract clamav clamav-daemon lhasa libzeromq-perl lzop nomarch p7zip rpm spamassassin unrar + + +## - spamassassin +## - +## - debian wheezy +## - +apt-get install -t wheezy-backports spamassassin razor pyzor libio-socket-ssl-perl \ + libdbi-perl libmail-dkim-perl libmail-spf-perl \ + libgeo-ipfree-perl libnet-ident-perl \ + libio-zlib-perl libio-string-perl \ + ftp ncftp less + +## - debian jessie +## - +apt-get install spamassassin razor pyzor libio-socket-ssl-perl \ + libdbi-perl libmail-dkim-perl libmail-spf-perl \ + libgeo-ipfree-perl libnet-ident-perl \ + libio-zlib-perl libio-string-perl \ + ftp ncftp less + + + +## - If MySQL/PostgreSQL was installed from debian package system, install also perl +## - modules "DBI" and DBD::mysql/DBD::Pg from debian package system +## - +if [ "$_db_type" = "Pg" -o "$_db_type" = "postgres" ]; then + apt-get install libdbd-pgsql libdbd-pg-perl libdbi-perl libdbi-dev +else + apt-get install libdbd-mysql libdbd-mysql-perl libdbi-perl libdbi-dev +fi + +## - If MySQL/PostgreSQL was installed from source, install perl modules "DBI" and +## - "DBD::mysql" via cpan +## - +cpan -i DBI +cpan -i DBD::mysql +## - or +cpan -i DBD::Pg + + +## - Clamav +## - + +## - wheezy +## - +apt-get install -t stable-updates clamav clamav-base clamav-daemon clamav-docs \ + clamav-freshclam libclamunrar6 + +## - Jessie +## - +apt-get install clamav clamav-base clamav-daemon clamav-docs \ + clamav-freshclam libclamunrar7 + +#apt-get install clamav clamav-base clamav-daemon clamav-docs \ +# clamav-freshclam libclamunrar6 + +## - It's very important to install the GMP package because it allows +## - freshclam (a ClamAV component) to verify the digital signatures of +## - the virus databases. +## - +#apt-get install libgmp3c2 libgmp3-dev +apt-get install libgmp-dev libgmp10 + + +/etc/init.d/clamav-daemon stop +/etc/init.d/clamav-freshclam stop + +freshclam + +/etc/init.d/clamav-daemon start +/etc/init.d/clamav-freshclam start + + + +## - User/Group Permissions +## - +#usermod -a -G debian-spamd amavis +#usermod -a -G amavis debian-spamd + +## - add user clamav to group amavis in order to giv clamav the needed +## - rights to e-mails +## - +## - Notice !! +## - UNTIL debia wheezy take also care, that option "AllowSupplementaryGroups true" is set +## - (/etc/clamav/clamd.conf) +## - +## - Do NOT set this option on debian jessie or later +## - + f [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi +usermod -a -G amavis clamav +/etc/init.d/clamav-daemon restart +/etc/init.d/clamav-freshclam restart + + + + +## --------------- ## +## --- AMaViS --- ## +## --------------- ## + +## - load some decoders +## +apt-get install tnef zoo cabextract freeze lzop rpm alien \ + tar pax rar unrar p7zip-full zip unzip ripole arj cpio arc \ + bzip2 binutils nomarch p7zip-rar p7zip unrar-free lhasa \ + libzeromq-perl + +## - Debian wheezy - lha is not available on debian wheezy +## - +apt-get install apt-listchanges libnet-ldap-perl \ + libauthen-sasl-perl dspam libsnmp-perl + +## - Debian jessie - dspam is no longer supported +## - +apt-get install apt-listchanges libnet-ldap-perl \ + libauthen-sasl-perl libsnmp-perl lhasa libdigest-sha-perl + + +## - Install via cpan +## - +## - Digest::SHA1 +## - Encode::Detect +## - Net::Patricia +apt-get install g++ +cpan -i CPAN +cpan -i Digest::SHA1 +cpan -i Digest::SHA2 +cpan -i Digest::SHA256 +cpan -i Encode::Detect +cpan -i Net::Patricia + + +## - Quarantine Directories +## - +mkdir -p ${_quarantine_dir}/{spam,virus,banned,bad-headers,spammy} +chown -R amavis:amavis $_quarantine_dir +chmod 750 $_quarantine_dir +chmod 750 ${_quarantine_dir}/{spam,virus,banned,bad-headers,spammy} + + +## - configure amavis in /etc/amavis/conf.d +## - +## - write all changes and customization to a seperate +## - file named "50-user", which will load at end of +## - configuration and overwrites the (debian)-default values +## - +cp /etc/amavis/conf.d/50-user ~/etc_amavis_conf.d_50-user.ORIG + + +## - write file /etc/amavis/conf.d/50-user +## - +cat > /etc/amavis/conf.d/50-user < [1], +# bypass_header_checks_maps => [1], +# final_spam_destiny => D_PASS, +# $final_bad_header_destiny = D_PASS, +#}; + + +## - 7 instances seems to be a good value. +## - +\$max_servers = 7; + + +## - overrides settings in 01-debian +## - + +\$unfreeze = ['unfreeze', 'freeze -d', 'melt', 'fcat']; #disabled (non-free, no security support) +\$unrar = ['rar', 'unrar']; #disabled (non-free, no security support) +\$lha = 'lha'; #disabled (non-free, no security support) +\$tnef = 'tnef'; + + +## - overrides settings in 15-content_filter_mode +## - + +## - Default antivirus checking mode +## - +@bypass_virus_checks_maps = ( + \%bypass_virus_checks, \@bypass_virus_checks_acl, + \$bypass_virus_checks_re); + + +## - Default SPAM checking mode +## - +@bypass_spam_checks_maps = ( + \%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re); + + +## - overrides settings in 20-debian_defaults +## - + + +\$final_virus_destiny = D_DISCARD; # (data not lost, see virus quarantine) +\$final_banned_destiny = D_DISCARD; # D_REJECT when front-end MTA +#\$final_spam_destiny = D_DISCARD; +\$final_spam_destiny = D_BOUNCE; +#\$final_bad_header_destiny = D_PASS; # False-positive prone (for spam) + +\$sa_tag_level_deflt = 2.0; # add spam info headers if at, or above that level +\$sa_tag2_level_deflt = 5.1; # add 'spam detected' headers at that level + +## - user / domain specific settings +## - example for \$sa_tag2_level_deflt: +## - +#\$sa_tag2_level_deflt = { +# # oopen.de +# 'oopen.de'=>'2.1', +# 'ckubu@oopen.de'=>'2.2', +# 'argus@oopen.de'=>'2.3', +# # k8h.de +# 'k8h.de'=>'6.5', +# # default +# '.'=>'5.1' +#}; + +\$sa_kill_level_deflt = 10.31; # reject/bounce/discard/pass +#\$sa_dsn_cutoff_level = 10; # spam level beyond which a DSN is not sent + +## - We will inform the sender about bouncing his mail with a DSN (Delivery +## - StatusNotification). That DSN message will no be send, if the spamvalue +## - exceeds the value of sa_dsn_cutoff_level +## - +\$sa_dsn_cutoff_level = 20; + + +## - change the default server response if mail was blocked +## - because of spam. +## - +## - results in (is an example): +## - : host 127.0.0.1[127.0.0.1] said: 554 5.7.0 Reject, Mailserver +## - at a.mx.oopen.de: identified as SPAM - (in reply to end of DATA command) +## - +%smtp_reason_by_ccat = ( + CC_SPAM, "Mailserver at \$myhostname: identified as SPAM - %x" +); + +\$sa_spam_subject_tag = undef; +#\$sa_spam_subject_tag = '***SPAM*** '; + + +## - QUARANTINE +## - +\$QUARANTINEDIR = "$_quarantine_dir"; +\$quarantine_subdir_levels = 0; + + +## - don't store mails in quarantine directory +## - +#\$virus_quarantine_method = undef; +#\$spam_quarantine_method = undef; +#\$banned_files_quarantine_method = undef; +#\$bad_header_quarantine_method = undef; + +## - store mails in quarantine directory +## - +\$virus_quarantine_method = 'local:virus/virus-%m'; +\$spam_quarantine_method = 'local:spam/spam-%m.gz'; +\$banned_files_quarantine_method = 'local:banned/banned-%m'; +\$bad_header_quarantine_method = 'local:bad-headers/badh-%m'; +\$clean_quarantine_method = undef; +\$archive_quarantine_method = undef; + +#\$virus_admin ="$_quarantine_admin"; +#\$spam_admin = "$_quarantine_admin"; +#\$banned_admin = "$_quarantine_admin"; +#\$bad_header_admin = "$_quarantine_admin"; +\$virus_admin = undef; +\$spam_admin = undef; +\$banned_admin = undef; +\$bad_header_admin = undef; + + +# Pass SPAMMY but quarantine and inform admin +# +\$quarantine_to_maps_by_ccat{+CC_SPAMMY} = \\@spam_quarantine_to_maps ; +\$quarantine_method_by_ccat{+CC_SPAMMY} = 'local:spammy/spammy-%m.gz' ; +\$final_destiny_by_ccat{+CC_SPAMMY} = D_PASS ; +\$admin_maps_by_ccat{+CC_SPAMMY} = sub { ca('spam_admin_maps') }; + + +# Bypass spam checking fro trusted networks using mynetworks +# +# list of trusted IPs: +# +# - b.mx.oopen.de (83.223.86.162 [2a01:30:1fff:a::162]) +# +#\@mynetworks = qw( 127.0.0.0/8 [::1] 83.223.86.162 [2a01:30:1fff:a::162] ); +# +#\$policy_bank{'MYNETS'} = { # clients in @mynetworks +# bypass_spam_checks_maps => [1], # don't spam-check internal mail +# bypass_header_checks_maps => [1], # don't header-check internal mail +# final_spam_destiny => D_PASS, +# final_bad_header_destiny => D_PASS, +# #remove_existing_x_scanned_headers => undef, +# #remove_existing_spam_headers => undef, +#}; +#\$remove_existing_x_scanned_headers = 0; +#\$remove_existing_spam_headers = 0; + +# allow all mail from local IPs: +#\$policy_bank{'MYNETS'} = { # clients in @mynetworks +# bypass_spam_checks_maps => [1], # don't spam-check internal mail +# bypass_header_checks_maps => [1], # don't header-check internal mail +# final_spam_destiny => D_PASS, +# final_bad_header_destiny => D_PASS, +#}; + + +## - Amavisd-New scans all mail passing through it for viruses, but will +## - only hand mail for local delivery off to SA for checking - you tell +## - it which domains are local using the @local_domains_maps variable, +## - which by default is set to the value of $mydomain & its subdomains: +## - +#@local_domains_maps = ( [".$mydomain"] ); + + +## - get rid of "Open Relay" warnings in amavis logfile. +## - +\$interface_policy{'10024'} = 'ORIGINATING'; +\$policy_bank{'ORIGINATING'} = { + originating => 1, # declare that mail was submitted by our smtp client +}; + +## - If you get am error like: +## - +## - amavis[9766]: () (!)DENIED ACCESS from IP $_ipv4_address, policy bank 'ORIGINATING' +## - +## - you must add your ip address to @inet_acl +## - +#@inet_acl = qw( 127.0.0.1 [::1] $_ipv4_address ); +#\$inet_socket_bind = undef; + +EOF + + +if [ "$_db_type" = "Pg" ]; then + + cat >> /etc/amavis/conf.d/50-user <> /etc/amavis/conf.d/50-user <> /etc/amavis/conf.d/50-user < syslog; false (e.g. 0) => logging to file +\$DO_SYSLOG = 1; # (defaults to 0) + +\$syslog_ident = 'amavis'; # Syslog ident string (defaults to 'amavis') +#\$syslog_facility = 'mail'; # Syslog facility as a string +\$syslog_facility = 'local0'; # Syslog facility as a string + # e.g.: mail, daemon, user, local0, ... local7, ... +\$syslog_priority = 'debug'; # Syslog base (minimal) priority as a string, + # choose from: emerg, alert, crit, err, warning, notice, info, + # debug + +# Log file (if not using syslog) +#\$LOGFILE = "/var/log/amavis.log"; # (defaults to empty, no log) + +#NOTE: levels are not strictly observed and are somewhat arbitrary +# 0: startup/exit/failure messages, viruses detected +# 1: args passed from client, some more interesting messages +# 2: virus scanner output, timing +# 3: server, client +# 4: decompose parts +# 5: more debug details +\$log_level = 1; # (defaults to 0), -d + + +## - amavis add a tag "***UNCHECKED***" if mail was not +## - checked. to get rid of that tag add: +## - +\$undecipherable_subject_tag = undef; + + +## - get rid of warning messages to postmaster if content is unchecked (that occurs +## - i.e. if mail is encrypted +## - +delete \$admin_maps_by_ccat{&CC_UNCHECKED}; + + +## - Replace "localhost" in the mailheader +## - +\$localhost_name = "amavis.`hostname -f`"; + +## - DKIM +## - +#\$enable_dkim_verification = 1; # enable DKIM signatures verification +#\$enable_dkim_signing = 1; # load DKIM signing code, keys defined by dkim_key +#dkim_key('oopen.de', 'main', '/etc/amavis/dkim/dkim-key.pem'); +#dkim_key('mbr-berlin.de', 'main', '/etc/amavis/dkim/dkim-key.pem'); +#dkim_key ... +#\@dkim_signature_options_bysender_maps = ( +# { '.' => { ttl => 21*24*3600, c => 'relaxed/simple' } } ); + + + +#------------ Do not modify anything below this line ------------- +1; # ensure a defined return +EOF + +chmod 644 /etc/amavis/conf.d/50-user + + +## - Notice: +## - you can realise domain or email-address specific spam levels. to do so +## - change at /etc/amavis/conf.d/50-user the directive "$sa_tag2_level_deflt" +## - +## - for example set: +## - +## - $sa_tag2_level_deflt = { +## - # warenform.com +## - 'warenform.com'=>'2.1', +## - 'chris@warenform.com'=>'2.2', +## - 'christian@warenform.com'=>'2.3', +## - # asap-log.com +## - 'asap-log.com'=>'6.5', +## - # jongleur-till.de +## - 'jongleur-till.de'=>'6.5', +## - # default +## - '.'=>'5.31' +## - }; + + +## - Configure syslogd matching the configuration od amavisd +## - +cat << EOF > /etc/rsyslog.d/amavis.conf +## - amavis +## - +local0.* -/var/log/amavis.log +& ~ +EOF + +/etc/init.d/rsyslog restart + + +## - forward emails to amavis using "Pre-Queue" Option smtpd_proxy_filter +## - +## - edit /etc/postfix/master.cf and add flags for "smtpd_proxy_filter" (to +## - forward to amavis service on localhost port 10024) and for "content_filter" +## - (to avoid rechecking by "Post-Queue" content_filter) to smtp service +## - +## - smtp inet n - - - - smtpd +## - -o smtpd_proxy_filter=127.0.0.1:10024 +## - -o content_filter= +## - +## - take care, that, in case NOT to reject, amavis fowards the mail to the +## - MTA (Postfix) for delivering. To avoid loops in checking, install a +## - (Postfix) smtpd service on a local Port (10025) without checking anymore +## - +## - to do this edit /etc/postfix/master.cf and add service: +## - +## - localhost:10025 inet n - - - - smtpd +## - -o content_filter= +## - -o smtpd_proxy_filter= +## - -o smtpd_authorized_xforward_hosts=127.0.0.0/8 +## - -o smtpd_client_restrictions= +## - -o smtpd_helo_restrictions= +## - -o smtpd_sender_restrictions= +## - -o smtpd_recipient_restrictions=permit_mynetworks,reject +## - -o smtpd_data_restrictions= +## - -o mynetworks=127.0.0.0/8,<$_ipv4_address/32> +## - -o receive_override_options=no_unknown_recipient_checks +## - +vim /etc/postfix/master.cf + + +## - install logrotate-script for amavis +## - +cat < /etc/logrotate.d/amavis +/var/log/amavis.log { + daily + start 0 + rotate 7 + missingok + compress + delaycompress + notifempty + create 644 amavis amavis + copytruncate +} +EOF + +touch /var/log/amavis.log +chmod 644 /var/log/amavis.log +chown amavis:amavis /var/log/amavis.log + +/etc/init.d/amavis restart +/etc/init.d/postfix stop +/etc/init.d/postfix start + + +## - Add a crontab to cleanup the quarantine folder +## - +crontab -l > /tmp/tmp_crontab + +cat << EOF >> /tmp/tmp_crontab + + +# - Remove old quarantined messages (>30 days). +# - +# - Spam +0 3 * * * find ${_quarantine_dir}/spam -type f -name "spam-*" -mtime +30 -exec rm {} \; +# - Spammy +0 3 * * * find /var/QUARANTINE/spammy -type f -name "spammy-*" -mtime +30 -exec rm {} \; +# - Virus +0 3 * * * find ${_quarantine_dir}/virus -type f -name "virus-*" -mtime +30 -exec rm {} \; +# - Banned files +0 3 * * * find ${_quarantine_dir}/banned -type f -name "banned-*" -mtime +30 -exec rm {} \; +# - Bad headers +0 3 * * * find ${_quarantine_dir}/bad-headers -type f -name "badh-*" -mtime +30 -exec rm {} \; +EOF +crontab /tmp/tmp_crontab +rm /tmp/tmp_crontab + + +## -------------- ## +## --- ClamAV --- ## +## -------------- ## + +## - i prefer to install clamav ( and the update daemon freshclam from +## - debian packages, because of better possibilities to update the programm +## - application. this is useful only if these packages are actual. so i +## - add the following entry to file /etc/apt/sources.list: +## - ## ClamAV +## - http://volatile.debian.org/debian-volatile lenny/volatile main contrib non-free +## + +## - Add cronjob for updating clamav packages +## - +## - 03 0 * * * /usr/bin/apt-get update > /dev/null ; PATH=/bin:/sbin:/usr/bin:/usr/sbin /usr/bin/apt-get -y install clamav clamav-base clamav-docs clamav-daemon clamav-freshclam > /dev/null +## - +crontab -l > /tmp/tmp_crontab +echo "" >> /tmp/tmp_crontab +echo "# - update virus database and software ( clamav)" >> /tmp/tmp_crontab +echo "# -" >> /tmp/tmp_crontab +echo "03 0 * * * /usr/bin/apt-get update > /dev/null ; PATH=/bin:/sbin:/usr/bin:/usr/sbin /usr/bin/apt-get -y install -t stable-updates clamav clamav-base clamav-docs clamav-daemon clamav-freshclam > /dev/null" >> /tmp/tmp_crontab +crontab /tmp/tmp_crontab +rm /tmp/tmp_crontab + + +## - ClamAV Unofficial Signatures +## - +## - Use ClamAV Unofficial Signatures Updater: +## - https://github.com/extremeshok/clamav-unofficial-sigs/releases +## - +## - See readme file: +## - https://github.com/extremeshok/clamav-unofficial-sigs +## - + +apt-get install socat +cpan -i IO::Socket::UNIX + +cd /tmp +git clone https://github.com/extremeshok/clamav-unofficial-sigs.git + +cd clamav-unofficial-sigs + +cp clamav-unofficial-sigs.sh /usr/local/sbin/ +chmod 755 /usr/local/sbin/clamav-unofficial-sigs.sh + +mkdir /var/log/clamav-unofficial-sigs +mkdir /etc/clamav-unofficial-sigs +cp config/* /etc/clamav-unofficial-sigs/ + +cd /etc/clamav-unofficial-sigs/ + +## - For Debian Wheezy (Debian 7) +## - +cp /etc/clamav-unofficial-sigs/os.debian7.conf /etc/clamav-unofficial-sigs/os.conf + +## - Edit /etc/clamav-unofficial-sigs/os.conf and make changes if needed +## - +## - Maybe the following changes are needed: +## - clam_user="clamav" +## - clam_group="clamav" +## - +## - clamd_pid="/var/run/clamav/clamd.pid" +## - +## - clamd_socket="/var/run/clamav/clamd.ctl" +## - +perl -i -n -p -e "s#^([ ]*\ *)(clam_user=.*)#\#\#\1\2\nclam_user=\"clamav\"#" /etc/clamav-unofficial-sigs/os.conf +perl -i -n -p -e "s#^([ ]*\ *)(clam_group=.*)#\#\#\1\2\nclam_group=\"clamav\"#" /etc/clamav-unofficial-sigs/os.conf +perl -i -n -p -e "s#^([ ]*\ *)(clamd_pid=.*)#\#\#\1\2\nclamd_pid=\"/var/run/clamav/clamd.pid\"#" \ + /etc/clamav-unofficial-sigs/os.conf +perl -i -n -p -e "s#^([ ]*\#?\ *)(clamd_socket=.*)#\#\#\1\2\nclamd_socket=\"/var/run/clamav/clamd.ctl\"#" \ + /etc/clamav-unofficial-sigs/os.conf + + +## - For Debian Jessie (Debian 8) +## - +cp /etc/clamav-unofficial-sigs/os.debian8.conf /etc/clamav-unofficial-sigs/os.conf + +## - Edit /etc/clamav-unofficial-sigs/os.conf and make changes if needed +## - +## - Maybe the following changes are needed: +## - clamd_pid="/var/run/clamav/clamd.pid" +## - +## - clamd_restart_opt="systemctl restart clamav-daemon" +## - clamd_reload_opt="systemctl reload clamav-daemon +## - +## - clamd_socket="/var/run/clamav/clamd.ctl" +## - +perl -i -n -p -e "s#^([ ]*\ *)(clamd_pid=.*)#\#\#\1\2\nclamd_pid=\"/var/run/clamav/clamd.pid\"#" \ + /etc/clamav-unofficial-sigs/os.conf +perl -i -n -p -e "s#^([ ]*\#?\ *)(clamd_restart_opt=.*)#\#\#\1\2\nclamd_restart_opt=\"systemctl restart clamav-daemon\"\nclamd_reload_opt=\"systemctl reload clamav-daemon\"#" \ + /etc/clamav-unofficial-sigs/os.conf +perl -i -n -p -e "s#^([ ]*\#?\ *)(clamd_socket=.*)#\#\#\1\2\nclamd_socket=\"/var/run/clamav/clamd.ctl\"#" \ + /etc/clamav-unofficial-sigs/os.conf + + +## - Edit /etc/clamav-unofficial-sigs/user.conf +## - +## - Disable Yara-Rule Project because of a lot of "false positive" matches, +## - for example some pgp/gpg mails matches the Rules: +## - +## - Javascript_exploi~d_obfuscation.yar: possible_includes_base64_packed_functions +## - +## - The following change is required: +## - user_configuration_complete="yes" +## - +perl -i -n -p -e "s#^([ ]*\#\#*\ *)(user_configuration_complete=.*)#\#\# - Disable Yara-Rule set, because (some?) pgp mails where blocked.\n\#\# -\nyararulesproject_enabled=\"no\"\n\n\n\1\2#" \ + /etc/clamav-unofficial-sigs/user.conf + +perl -i -n -p -e "s#^([ ]*\#\#*\ *)(user_configuration_complete=.*)#\#\#\1\2\nuser_configuration_complete=\"yes\"#" \ + /etc/clamav-unofficial-sigs/user.conf + +## - Maybe you want include "MalwarePatrol Free/Delayed" or +## - "SecuriteInfo Free/Delayed" list support. Both are not enabled by default, +## - and for both you have to sign up for an account. Free accounts are +## - available. +## - +## - See Readme.md file for further instructions. +## - + +## - Only if Systemd is used (as in debian 8) +## - +cp /tmp/clamav-unofficial-sigs/systemd/* /etc/systemd/ + + +/usr/local/sbin/clamav-unofficial-sigs.sh --install-cron +/usr/local/sbin/clamav-unofficial-sigs.sh --install-logrotate +/usr/local/sbin/clamav-unofficial-sigs.sh --install-man + + +## - First Usage +## - +## - Run the script once as your superuser to set all the permissions and create the relevant directories +## - +## - Notice! +## - Don't forget to oopen TCP Port 873 and TCP Port 443 + +## - +/usr/local/sbin/clamav-unofficial-sigs.sh + +cd +rm -rf /tmp/clamav-unofficial-sigs + + +## -------------------- ## +## --- Spamassassin --- ## +## -------------------- ## + +apt-get install libimage-info-perl libnet-cidr-lite-perl \ + libdbd-pgsql libgeo-ip-perl geoip-bin libgeoip-dev geoip-database + +apt-get install re2c + + + +## - Pyzor configuration +## - +## - Here we supply the hostname of the Pyzor server to Pyzor (for both the +## - 'root' and 'amavis' users). This will create a .pyzor directory in both +## - user's home directories, and place the server's hostname in a 'servers' file +## - therein: +pyzor discover +su amavis -c 'pyzor discover' + +## -Test the pyzor server for a response: +pyzor ping +su amavis -c 'pyzor ping' + + +## - Pyzor Ping should show 'OK'. If not, then it's possible your firewall is +## - blocking udp replies from 82.94.255.100 or 188.40.77.236 (public.pyzor.org +## - port 24441), or the server may simply be slow to respond (often the case). + +## - I suggest you subscribe to +## - http://lists.sourceforge.net/lists/listinfo/pyzor-announce. + +## - Download a sample spam file. For testing purpose you can feed it to spamassassin: +## - +## - # cp /root/sample-spam.txt /tmp +## - # cd /tmp +## - # su amavis -c 'spamassassin -D /tmp/tmp_crontab +echo "" >> /tmp/tmp_crontab +echo "# - update razor2" >> /tmp/tmp_crontab +echo "# -" >> /tmp/tmp_crontab +echo "33 0 * * * su amavis -lc '/usr/bin/razor-admin -discover'" >> /tmp/tmp_crontab +crontab /tmp/tmp_crontab +rm /tmp/tmp_crontab + + +## - SpamAssassin's main configuration file: +## - +vim /etc/spamassassin/local.cf + + +## - insert/replace the lines +## - +## - # let the body of mails untouched.. +## - # +## - report_safe 0 +## - +## - +## - ## - Possibly optional, possibly not: +## - ## - Depending on your setup, it might be necessary to explicitly set internal_networks +## - ## - and trusted_networks. The trust path tells spamassassin which clients are not trusted. +## - ## - If you are using SpamAssassin version 3.2 or newer, do not include the 127/8 +## - ## - networks shown below. They are automatically included. +## - ## - See http://wiki.apache.org/spamassassin/TrustPath and this thread: +## - ## - +## - # explicitly set our internal_networks (might be the same or similar to mynetworks) +## - clear_internal_networks +## - #internal_networks 178.63.63.151/32 +## - #internal_networks 2a01:4f8:121:c5::2/128 +## - # don't add internal_networks to trusted_networks, but possibly other computers/networks whose mail we trust +## - clear_trusted_networks +## - #- add mx03.so36.net to our trusted networks. +## - trusted_networks 83.223.73.205 +## - trusted_networks 2a01:30:1fff:fd00::205 +## - #- add b.mx.oopen.de to our trusted networks. +## - trusted_networks 83.223.86.162 +## - trusted_networks 2a01:30:1fff:a::162 +## - +## - lock_method flock +## - +## - required_score 5.1 +## - +## - +## - use_bayes 1 +## - bayes_path /var/lib/amavis/.spamassassin/bayes +## - +## - whitelist_from admin@oopen.de +## - +## - bayes_auto_learn 1 +## - bayes_auto_learn_threshold_spam 15.0 +## - #bayes_auto_learn_threshold_spam 10.0 +## - bayes_auto_learn_threshold_nonspam -0.5 +## - +## - ## - NOTE: Since there is a script that runs each day to --force-expire old +## - ## - Bayes tokens "/etc/cron.daily/amavisd-new" (make sure there is if +## - ## - you use this setting!), we can set: +## - ## - +## - bayes_auto_expire 0 +## - +## - ## - Optional: +## - ## - Some people believe auto-whitelist is more of a liability than an asset: +## - use_auto_whitelist 1 +## - auto_whitelist_path /var/lib/amavis/.spamassassin/auto-whitelist +## - +## - ## - Optional: +## - ## - We will normally have DNS available: +## - dns_available yes +## - +## - +## - # Enable or disable network checks +## - skip_rbl_checks 1 +## - use_razor2 1 +## - razor_timeout 8 +## - +## - ##use_dcc 1 +## - ##dcc_home /var/dcc +## - +## - use_pyzor 1 +## - #pyzor_timeout 8 +## - +## - # Mail using locales used in these country codes will not be marked +## - # as being possibly spam in a foreign language. +## - ok_locales all +## - +## - add_header spam Flag _YESNOCAPS_ +## - + + +## - edit /etc/spamassassin/v310.pre +## - +## - enable auto-whitelist checks +## - loadplugin Mail::SpamAssassin::Plugin::AWL +## - +## - enable language guesser +## - loadplugin Mail::SpamAssassin::Plugin::TextCat +## - +vim /etc/spamassassin/v310.pre + + +## - enable nightly cronjob for spamassassin +## - +## - edit /etc/default/spamassassin and set: +## - CRON=1 +## - +perl -i -n -p -e "s#^([ ]*\#?\ *)(CRON\ *=.*)#\#\#\1\2\nCRON=1#" \ + /etc/default/spamassassin + + + +## - add a cronjob for cleaning up bayes +## - +crontab -l > /tmp/tmp_crontab +echo "" >> /tmp/tmp_crontab +echo "# - cleanup sa bayes for espired entries" >> /tmp/tmp_crontab +echo "# -" >> /tmp/tmp_crontab +echo '33 3 * * * su amavis -lc "/usr/bin/sa-learn --sync >/dev/null" ; su amavis -lc "/usr/bin/sa-learn --sync --force-expire >/dev/null"' >> /tmp/tmp_crontab +crontab /tmp/tmp_crontab +rm /tmp/tmp_crontab + + +sa-update + +## - !! Notice !! +## - if su clamav -c 'spamassassin --lint' failed ( with warn +## - message "warn: Use of uninitialized value $type in numeric..") +## - reading "/etc/spamassassin/local.cf": razor_timeout 8, have a look +## - at SpamAssassin/Plugin/Razor2.pm line 118: +## - +## - type => $Mail::SpamAssassin::Conf::CONF_TYPE_DURATIION, +## - +## - Should be: +## - +## - type => $Mail::SpamAssassin::Conf::CONF_TYPE_DURATION, +## - +## - see also: https://issues.apache.org/SpamAssassin/show_bug.cgi?id=7018 +## - +perl -i -n -p -e "s/CONF_TYPE_DURATIION/CONF_TYPE_DURATION/" /usr/share/perl5/Mail/SpamAssassin/Plugin/Razor2.pm + +sa-compile +cd /tmp +su amavis -c 'spamassassin --lint' + +## - it's important, that all completes without error +## - +/etc/init.d/amavis restart + +## - SpamAssassin Rules +## - +## - updates.spamassassin.org is used automatically +## - and you have to do nothing, because "sa-update" +## - has done the update from updates.spamassassin.org. install +## - a cronjob for doing this periodically. for better understanding, +## - do this + +## - first get a gpgkey from updates.spamassassin.org, in order only +## - getting signed update rules +cd /etc/spamassassin +wget http://spamassassin.apache.org/updates/GPG.KEY +sa-update --import GPG.KEY +rm GPG.KEY + +## - create keyfile and add a line for the key-id +## - +## - you can also get the key-id by typing +## - gpg --home /etc/spamassassin/sa-update-keys -kv +## - +echo "5244EC45" > /etc/spamassassin/sa_keys + + +## - create a channel file and add a line with the url +## - +echo "updates.spamassassin.org" > /etc/spamassassin/sa_channel + +## - now you can update: +## - +sa-update --channelfile /etc/spamassassin/sa_channel --gpgkeyfile /etc/spamassassin/sa_keys + + +## - Spamassassin Rules from Heinlein Support +## - +sa-update --nogpg --channel spamassassin.heinlein-support.de + +## - There are hundreds of SpamAssassin rules that help decide what is spam +## - and what is not. Additional rules are available from 3rd parties. I add +## - the safest set of rules from http://www.rulesemporium.com/ which I +## - obtain from another source at http://saupdates.openprotect.com/: +## - +## - !! OUTDATED !! +#cd /etc/spamassassin +#wget http://saupdates.openprotect.com/pub.gpg +#sa-update --import pub.gpg +#rm pub.gpg +#echo "BDE9DC10" >> /etc/spamassassin/sa_keys +#echo "saupdates.openprotect.com" >> /etc/spamassassin/sa_channel + + +## - Spamassassin Rule from eXtreme SHOCK +## - +## - Maintained and provided by https://eXtremeSHOK.com +## - +cd /tmp +git clone https://github.com/extremeshok/spamassassin-extremeshok_fromreplyto +cd spamassassin-extremeshok_fromreplyto + +mkdir /etc/mail/spamassassin/plugins/ +cp plugins/* /etc/mail/spamassassin/plugins/ +cp 01_extremeshok_fromreplyto.cf /etc/mail/spamassassin/01_extremeshok_fromreplyto.cf + +cd +rm -rf /tmp/spamassassin-extremeshok_fromreplyto + + + +## - check the rule. if all is fine there is no output +## - +spamassassin --lint + +## - or check with debug mode +## - +spamassassin -D --lint + +## - create a update-script using sa.update +## - +mkdir -p /root/bin +cat > /root/bin/sa-update.sh < 1 ]]; then + echo "problem with sa-update" +fi + +sa-update --allowplugins --channelfile /etc/spamassassin/sa_channel --gpgkeyfile /etc/spamassassin/sa_keys + +code2=\$? +if [[ \$code2 > 1 ]]; then + echo "problem with sa-update using channelfile.." +fi + + +## - Get rules from heinlein-support.de +## - +## - see: +## - https://www.heinlein-support.de/blog/news/aktuelle-spamassassin-regeln-von-heinlein-support/ +## - +sa-update --nogpg --channel spamassassin.heinlein-support.de +code3=\$? +if [[ \$code3 > 1 ]]; then + echo "problem with sa-update using channel spamassassin.heinlein-support.de.." +fi + + +if [[ \`expr \$code1 + \$code2 + \$code3\` < 4 ]]; then + spamassassin --lint + code4=\$? + if [[ \$code4 = 0 ]]; then + #svc -h /service/spamd + #/etc/init.d/spamassassin restart > /dev/null + /etc/init.d/amavis restart >/dev/null + else + echo "spamassassin failed to lint" + fi +fi + +# Fixup perms -- group and other should be able to read and execute, +# but never write. Works around sa-compile's failure to obey umask. +if [ -d /var/lib/spamassassin ]; then + chown -R debian-spamd:debian-spamd /var/lib/spamassassin + chmod -R go-w,go+rX /var/lib/spamassassin + chmod 700 /var/lib/spamassassin/sa-update-keys + chmod 600 /var/lib/spamassassin/sa-update-keys/* +fi +if [ -d /var/lib/amavis ]; then + chown -R amavis:amavis /var/lib/amavis +fi +EOF + +chmod 755 /root/bin/sa-update.sh + +## - add a cronjob for spamassassin updates +## - +crontab -l > /tmp/tmp_crontab +echo "" >> /tmp/tmp_crontab +echo "# - update spamassassin rules" >> /tmp/tmp_crontab +echo "# -" >> /tmp/tmp_crontab +echo "33 1 * * * /root/bin/sa-update.sh" >> /tmp/tmp_crontab +crontab /tmp/tmp_crontab +rm /tmp/tmp_crontab + + +## - Since we have the Mail::DKIM Perl module installed, we can optionally +## - enable the SpamAssassin DKIM plugin: +## - +## - uncomment the plugin: +## - loadplugin Mail::SpamAssassin::Plugin::DKIM + +vim /etc/spamassassin/v312.pre +## - Save and exit the file, then run --lint: +su amavis -c 'spamassassin --lint' + +## - With SpamAssassin version 3.2 or newer, we can optionally compile +## - some body rules so they execute faster. Start by running sa-compile +## - for the first time and check for errors: +## - +sa-compile + + +## - If it looks like it didn't crash, enable plugin +## - Mail::SpamAssassin::Plugin::Rule2XSBody +## - +vim /etc/spamassassin/v320.pre + +## - uncomment the line: +## - # loadplugin Mail::SpamAssassin::Plugin::Rule2XSBody +## - +## - Save and exit the file, then run --lint: +su amavis -c 'spamassassin --lint' + + + +## - create a update-script that will run sa-compile +## - +mkdir -p /root/bin/ +cat > /root/bin/sa-compile.sh < /dev/null 2>&1 +fi + +code1=\$? +if [[ \$code1 > 0 ]]; then + echo "problem with sa-compile, turning off Rule2XSBody plugin" + sed -i 's/loadplugin Mail::SpamAssassin::Plugin::Rule2XSBody/#loadplugin Mail::SpamAssassin::Plugin::Rule2XSBody/' /etc/spamassassin/v320.pre + test -x /usr/sbin/amavisd-new || exit 0 + /etc/init.d/amavis restart >/dev/null +else + sed -i 's/#\ *loadplugin Mail::SpamAssassin::Plugin::Rule2XSBody/loadplugin Mail::SpamAssassin::Plugin::Rule2XSBody/' /etc/spamassassin/v320.pre + test -x /usr/sbin/amavisd-new || exit 0 + /etc/init.d/amavis restart >/dev/null +fi + +# Fixup perms -- group and other should be able to read and execute, +# but never write. Works around sa-compile's failure to obey umask. +if [ -d /var/lib/spamassassin ]; then + chown -R debian-spamd:debian-spamd /var/lib/spamassassin + chmod -R go-w,go+rX /var/lib/spamassassin + chmod 700 /var/lib/spamassassin/sa-update-keys + chmod 600 /var/lib/spamassassin/sa-update-keys/* +fi +if [ -d /var/lib/amavis ]; then + chown -R amavis:amavis /var/lib/amavis +fi +EOF + +chmod 755 /root/bin/sa-compile.sh + +## - add a cronjob for compiling rules +## - +crontab -l > /tmp/tmp_crontab +echo "" >> /tmp/tmp_crontab +echo "# - compiling rules (SpamAssassin)" >> /tmp/tmp_crontab +echo "# -" >> /tmp/tmp_crontab +echo "53 0 * * * /root/bin/sa-compile.sh" >> /tmp/tmp_crontab +crontab /tmp/tmp_crontab +rm /tmp/tmp_crontab + +## - Install DCC +## - + +## - DCC is available from the Debian archives, but we will get it from the +## - author and compile it from the source code. Installing it from source +## - is a good exercise and we have better control over how it installs. +## - Installing from source allows us to customize the installation for use +## - with amavisd-new. Note that as of version 1.3.0 of DCC +## - http://www.commtouch.com/ has exclusive marketing rights for DCC. If you +## - resell anti-spam solutions that use DCC and you do not provide your DCC +## - data to the public, you will need to pay for DCC. Please read the license. +## - +cd /usr/local/src +mkdir -p dcc +cd dcc +wget http://www.dcc-servers.net/dcc/source/dcc-dccproc.tar.Z +tar xzvf dcc-dccproc.tar.Z + +## - Change to the dcc subdirectory by using the [tab] key command +## - completion shortcut as shown, then ./configure: +cd dcc-dccproc- [tab][enter] + +## - configure and install +## - +./configure --with-uid=amavis && make && make install + +## - Update file ownership: +chown -R amavis:amavis /var/dcc + +## - Test our installation with: +cdcc info + +## - We should get 'requests ok' from the servers (but 'not answering' +## - from 127.0.0.1 is expected). + +## - The instructions say to run cron-dccd each day to clean things up, so we will do that. +## - +## - add a cronjob for cleaning up dcc +## - +crontab -l > /tmp/tmp_crontab +echo "" >> /tmp/tmp_crontab +echo "# - cleaning up dcc (Distributed Checksum Clearinghouses)" >> /tmp/tmp_crontab +echo "# -" >> /tmp/tmp_crontab +echo "13 1 * * * /var/dcc/libexec/cron-dccd" >> /tmp/tmp_crontab +crontab /tmp/tmp_crontab +rm /tmp/tmp_crontab + +## - enable dccifd: +## - + +## - edit /etc/spamassassin/v310.pre +## - uncomment the plugin: +## - loadplugin Mail::SpamAssassin::Plugin::DCC +vim /etc/spamassassin/v310.pre + +## - edit /etc/spamassassin/local.cf +## - +## - add/uncomment: +## - use_dcc 1 +## - dcc_home /var/dcc +## - +vim /etc/spamassassin/local.cf + + +## - edit /var/dcc/dcc_conf +## - +vim /var/dcc/dcc_conf + +## - and change +## - DCCIFD_ENABLE=off +## - to: +## - DCCIFD_ENABLE=on +## - +## - Then change: +## - DBCLEAN_LOGDAYS=14 +## - to: +## - DBCLEAN_LOGDAYS=1 +##- +## -save and exit. +## - + +## - ## - If you choose to allow logging, cron-dccd should delete old log files +## - ## - when it runs. Keep your eye on the files that accumulate in the +## - ## - /var/dcc/log directory. It's your choice, but I personally don't want to +## - ## - monitor the DCC logs, so I turn off logging altogether by deleting the +## - ## - log directory and commenting out the logdir entry in dcc_conf: +## - ## - +## - rm -r /var/dcc/log +## - vim /var/dcc/dcc_conf +## - and comment out: +## - DCCIFD_LOGDIR="$DCCM_LOGDIR" + +## - We will use a supplied script (rcDCC) to automatically +## - start dccifd when we boot up: +## - +cp /var/dcc/libexec/rcDCC /etc/init.d/adcc + +# +update-rc.d adcc defaults +# or within systemd +systemctl enable adcc + +/etc/init.d/adcc start + + +## - Now test it with SpamAssassin: +su amavis -c 'spamassassin -D < /tmp/sample-spam.txt' + +## - Now test that SpamAssassin finds dccifd: +## - +su amavis -c 'spamassassin -D dcc &1 | grep dccifd + +## - You should see: dbg: dcc: dccifd got response: +## - [15744] dbg: dcc: dccifd default local socket chosen: /var/dcc/dccifd +## - [15744] dbg: dcc: connecting to a local socket /var/dcc/dccifd +## - [15744] dbg: dcc: dccifd got response: X-DCC-EATSERVER-Metrics: vserver08 1166; Body=many Fuz1=many Fuz2=many + + +rm /tmp/sample-spam.txt diff --git a/DOC/postfix/etc_postgrey_whitelist_clients.local b/DOC/postfix/etc_postgrey_whitelist_clients.local new file mode 100644 index 0000000..d651fbb --- /dev/null +++ b/DOC/postfix/etc_postgrey_whitelist_clients.local @@ -0,0 +1,3 @@ +# For Office 365 - servers: +##/.*outbound.protection.outlook.com$/ +/^mail-.*\.outbound\.protection\.outlook\.com$/ diff --git a/DOC/postfix/postfix_base_mailsystem.install b/DOC/postfix/postfix_base_mailsystem.install new file mode 100644 index 0000000..5063717 --- /dev/null +++ b/DOC/postfix/postfix_base_mailsystem.install @@ -0,0 +1,461 @@ +## ------------------------------------ ## ## - - ## +## - install postfix base system - ## +## - - ## +## - supports ipv6 - ## +## - - ## +## ------------------------------------ ## + +_TLS_CERT_DIR=/etc/postfix/ssl +_TLS_CERT_FILE="${_TLS_CERT_DIR}/mailserver.crt" +_TLS_KEY_FILE="${_TLS_CERT_DIR}/mailserver.key" + +_TLS_CA_FILE=/etc/ssl/certs/ca-certificates.crt + + +_HOSTNAME= +_IPV4= +## - Leave empty, if no IPv6 should be supported +## - +#_IPV6= +_IPV6= + +_ADMIN_EMAIL= + +_SASL_AUTH= +_RELAY_HOST=b.mx.oopen.de +_SASL_USER= +_SASL_PASS='sasl_password' + + +## - remove exim4 and related if installed and you plan +## - to install an alternative mailer +## - +apt-get remove --purge bsd-mailx exim4 exim4-base exim4-config \ + exim4-daemon-light mailx + + +apt-get install postfix postfix-pcre libsasl2-modules bsd-mailx haveged + +if $_SASL_AUTH ; then + apt-get install libsasl2-modules +fi + +cp -a /etc/postfix/main.cf /etc/postfix/main.cf.ORIG + + +cat < /etc/postfix/main.cf +# ============ Basic settings ============ + +# Debian specific: Specifying a file name will cause the first +# line of that file to be used as the name. The Debian default +# is /etc/mailname. +#myorigin = /etc/mailname +myorigin = /etc/mailname + +smtpd_banner = \$myhostname ESMTP \$mail_name (Debian/GNU) +biff = no + +# appending .domain is the MUA's job. +append_dot_mydomain = no + +# Uncomment the next line to generate "delayed mail" warnings +#delay_warning_time = 4h + +readme_directory = /usr/share/doc/postfix +html_directory = /usr/share/doc/postfix/html + +## - The Internet protocols Postfix will attempt to use when making +## - or accepting connections. +## - DEFAULT: ipv4 +EOF + +if [ -n "$_IPV6" ]; then + cat <> /etc/postfix/main.cf +inet_protocols = ipv4, ipv6 + +#inet_interfaces = all +inet_interfaces = 127.0.0.1 + $_IPV4 + $_IPV6 + +myhostname = $_HOSTNAME + +mydestination = + $_HOSTNAME + localhost + +## - The list of "trusted" SMTP clients that have more +## - privileges than "strangers" +## - +mynetworks = + 127.0.0.0/8 + [::ffff:127.0.0.0]/104 + [::1]/128 + ${_IPV4}/32 + [${_IPV6}]/128 + +smtp_bind_address = $_IPV4 +smtp_bind_address6 = $_IPV6 + +EOF +else + cat <> /etc/postfix/main.cf +inet_protocols = ipv4 + +#inet_interfaces = all +inet_interfaces = + 127.0.0.1 + $_IPV4 + +myhostname = $_HOSTNAME + +mydestination = + $_HOSTNAME + localhost + +## - The list of "trusted" SMTP clients that have more +## - privileges than "strangers" +## - +mynetworks = + 127.0.0.0/8 + ${_IPV4}/32 + +smtp_bind_address = $_IPV4 +#smtp_bind_address6 = $_IPV6 + +EOF +fi + +cat <> /etc/postfix/main.cf + +## - The method to generate the default value for the mynetworks parameter. +## - +## - mynetworks_style = host" when Postfix should "trust" only the local machine +## - mynetworks_style = subnet (default value) "when Postfix should "trust" SMTP +## - clients in the same IP subnetworks as the local machine. +## - mynetworks_style = class" when Postfix should "trust" SMTP clients in the same +## - IP class A/B/C networks as the local machine. +## - +#mynetworks_style = host + + +## - The maximal size of any local(8) individual mailbox or maildir file, +## - or zero (no limit). In fact, this limits the size of any file that is +## - written to upon local delivery, including files written by external +## - commands that are executed by the local(8) delivery agent. +## - +mailbox_size_limit = 0 + +## - The maximal size in bytes of a message, including envelope information. +## - +## - we user 50MB +## - +message_size_limit = 52480000 + +## - The system-wide recipient address extension delimiter +## - +recipient_delimiter = + + +## - The alias databases that are used for local(8) delivery. +## - +alias_maps = + hash:/etc/aliases + +## - The alias databases for local(8) delivery that are updated +## - with "newaliases" or with "sendmail -bi". +## - +alias_database = + hash:/etc/aliases + + +## - The maximal time a message is queued before it is sent back as +## - undeliverable. Defaults to 5d (5 days) +## - Specify 0 when mail delivery should be tried only once. +## - +maximal_queue_lifetime = 3d +bounce_queue_lifetime = \$maximal_queue_lifetime + +## - delay_warning_time (default: 0h) +## - +## - The time after which the sender receives a copy of the message +## - headers of mail that is still queued. To enable this feature, +## - specify a non-zero time value (an integral value plus an optional +## - one-letter suffix that specifies the time unit). +## - Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks). +## - The default time unit is h (hours). +delay_warning_time = 1d + + +EOF + +if $_SASL_AUTH ; then + cat <> /etc/postfix/main.cf + +# ============ Relay parameters ============ + +#relayhost = + + +# ============ SASL authentication ============ + +# Enable SASL authentication +smtp_sasl_auth_enable = yes + +# Forwarding to the ip-adress of host b.mx.oopen.de +relayhost = [b.mx.oopen.de] + +# File including login data +smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd + +# Force using a (TLS) security connection +# obsulete - use smtp_tls_security_level instead +#smtp_use_tls = yes +#smtp_tls_enforce_peername = no +smtp_tls_security_level = encrypt + +# Disallow methods that allow anonymous authentication. +smtp_sasl_security_options = noanonymous + + + +# ============ TLS parameters ============ + +## - Aktiviert TLS für den Mailempfang +## - +## - may: +## - Opportunistic TLS. Use TLS if this is supported by the remote +## - SMTP server, otherwise use plaintext +## - +## - This overrides the obsolete parameters smtpd_use_tls and +## - smtpd_enforce_tls. This parameter is ignored with +## - "smtpd_tls_wrappermode = yes". +#smtpd_use_tls=yes +smtp_tls_security_level=encrypt + +EOF + +else + cat <> /etc/postfix/main.cf + +# ============ Relay parameters ============ + +relayhost = + + +# ============ TLS parameters ============ + +## - Aktiviert TLS für den Mailempfang +## - +## - may: +## - Opportunistic TLS. Use TLS if this is supported by the remote +## - SMTP server, otherwise use plaintext +## - +## - This overrides the obsolete parameters smtpd_use_tls and +## - smtpd_enforce_tls. This parameter is ignored with +## - "smtpd_tls_wrappermode = yes". +#smtpd_use_tls=yes +smtp_tls_security_level=may + +EOF +fi + +cat <> /etc/postfix/main.cf +## - Aktiviert TLS für den Mailversand +## - +## - may: +## - Opportunistic TLS: announce STARTTLS support to SMTP clients, +## - but do not require that clients use TLS encryption. +# smtp_use_tls=yes +smtpd_tls_security_level=may + +## - 0 Disable logging of TLS activity. +## - 1 Log TLS handshake and certificate information. +## - 2 Log levels during TLS negotiation. +## - 3 Log hexadecimal and ASCII dump of TLS negotiation process. +## - 4 Also log hexadecimal and ASCII dump of complete transmission after STARTTLS. +## - +smtpd_tls_loglevel = 1 +smtp_tls_loglevel = 1 + +smtpd_tls_cert_file = $_TLS_CERT_FILE +smtpd_tls_key_file = $_TLS_KEY_FILE + +## - File with DH parameters that the Postfix SMTP server should use with EDH ciphers. +## - +## - Dont't forget to create it, e.g with openssl: +## - openssl gendh -out /etc/postfix/ssl/dh_1024.pem -2 1024 +## - +smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_1024.pem +## - also possible to use 2048 key with that parameter +## - +#smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_2048.pem + +## - File with DH parameters that the Postfix SMTP server should use with EDH ciphers. +## - +## - Dont't forget to create it, e.g with openssl: +## - openssl gendh -out /etc/postfix/ssl/dh_512.pem -2 512 +## - +smtpd_tls_dh512_param_file = /etc/postfix/ssl/dh_512.pem + + +## - File containing CA certificates of root CAs trusted to sign either remote SMTP +## - server certificates or intermediate CA certificates. These are loaded into +## - memory !! BEFORE !! the smtp(8) client enters the chroot jail. +## - +smtp_tls_CAfile = $_TLS_CA_FILE + +## - Directory with PEM format certificate authority certificates that the Postfix SMTP +## - client uses to verify a remote SMTP server certificate. Don't forget to create the +## - necessary "hash" links with, for example, " +## - $OPENSSL_HOME/bin/c_rehash /etc/postfix/certs". +## - +## - !! Note !! +## - To use this option in chroot mode, this directory (or a copy) must be inside +## - the chroot jail. +## - +## - Note that a chrooted daemon resolves all filenames relative to the Postfix +## - queue directory (/var/spool/postfix) +## - +#smtpd_tls_CApath = /etc/postfix/certs + + +# Disable SSLv2 SSLv3 - Postfix SMTP server +# +# List of TLS protocols that the Postfix SMTP server will exclude or +# include with opportunistic TLS encryption. +smtpd_tls_protocols = !SSLv2, !SSLv3 +# +# The SSL/TLS protocols accepted by the Postfix SMTP server +# with mandatory TLS encryption. +smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3 + + +# Disable SSLv2 SSLv3 - Postfix SMTP client +# +# List of TLS protocols that the Postfix SMTP client will exclude or +# include with opportunistic TLS encryption. +smtp_tls_protocols = !SSLv2, !SSLv3 +# +# List of SSL/TLS protocols that the Postfix SMTP client will use +# with mandatory TLS encryption +smtp_tls_mandatory_protocols = !SSLv2, !SSLv3 + + +## - Activate des "Ephemeral Elliptic Curve Diffie-Hellman" (EECDH) key exchange +## - openssl > 1.0 +## - +smtpd_tls_eecdh_grade = strong + +# standard list cryptographic algorithm +tls_preempt_cipherlist = yes + +# Disable ciphers which are less than 256-bit: +# +#smtpd_tls_mandatory_ciphers = high +# +# opportunistic +smtpd_tls_ciphers = high + + +# Exclude ciphers +#smtpd_tls_exclude_ciphers = +# RC4 +# aNULL +# SEED-SHA +# EXP +# MD5 +smtpd_tls_exclude_ciphers = + aNULL + eNULL + EXPORT + DES + RC4 + MD5 + PSK + aECDH + EDH-DSS-DES-CBC3-SHA + EDH-RSA-DES-CDC3-SHA + KRB5-DE5, CBC3-SHA + + +smtpd_tls_session_cache_database = btree:\${data_directory}/smtpd_scache +smtp_tls_session_cache_database = btree:\${data_directory}/smtp_scache + +EOF + +if $_SASL_AUTH ; then + + echo "[$_RELAY_HOST] ${_SASL_USER}@${_RELAY_HOST}:$_SASL_PASS" > /etc/postfix/sasl_passwd + chown root:root /etc/postfix/sasl_passwd + chmod 600 /etc/postfix/sasl_passwd + postmap /etc/postfix/sasl_passwd + +fi + + +## - create directory for certificates and copy certificates +## - and coresponding keys to /etc/postfix/ssl/ +## - +mkdir -p /etc/postfix/ssl +cp /etc/postfix/ssl/ + + +## - generate DH parameters that the Postfix SMTP server should use +## - with EDH ciphers (length 512 and 1024 +## - +openssl gendh -out /etc/postfix/ssl/dh_512.pem -2 512 +openssl gendh -out /etc/postfix/ssl/dh_1024.pem -2 1024 +openssl gendh -out /etc/postfix/ssl/dh_2048.pem -2 2048 + +ln -s /etc/ssl/certs/ssl-cert-snakeoil.pem $_TLS_CERT_FILE +ln -s /etc/ssl/private/ssl-cert-snakeoil.key $_TLS_KEY_FILE + + + +## - /etc/mailname +## - +echo $_HOSTNAME > /etc/mailname + + +## - /etc/aliases +## - +cat << EOF > /etc/aliases +# See man 5 aliases for format +mailer-daemon: postmaster +postmaster: root +nobody: root +hostmaster: root +usenet: root +news: root +webmaster: root +www: root +ftp: root +abuse: root +noc: root +security: root + +root: $_ADMIN_EMAIL +EOF + +## - rebuld alias database +## - +newaliases + + +cat << EOF >> /etc/rsyslog.d/postfix.conf + +# +# Logging for the mail system. Split it up so that +# it is easy to write scripts to parse these files. +# +mail.info -/var/log/mail.info +mail.warn -/var/log/mail.warn +mail.err /var/log/mail.err + +mail.* -/var/log/mail.log +& ~ +EOF + +/etc/init.d/rsyslog restart + + diff --git a/DOC/postfix/postfix_mailsystem.install b/DOC/postfix/postfix_mailsystem.install new file mode 100644 index 0000000..88f5f83 --- /dev/null +++ b/DOC/postfix/postfix_mailsystem.install @@ -0,0 +1,1706 @@ + +## ------------------------------------------------------------ ## +## - - ## +## - install postfix + dovecot + sieve + postfisadmin - ## +## - +roundecube - ## +## - - ## +## - supports ipv6 - ## +## - - ## +## ------------------------------------------------------------ ## + +## - mx.warenform.de +## - +_WEBMAIL_IP_4=83.223.85.154 +_WEBMAIL_IP_6=2a01:30:1fff:6::154 + +_APACHE_CONF_DIR=/usr/local/apache2/conf +_APACHE_VHOST_DIR=${_APACHE_CONF_DIR}/vhosts + +_APACHE_LOG_DIR=/var/log/apache2 + +_ADMIN_EMAIL=argus@oopen.de + +_TLS_CERT_DIR=/etc/postfix/ssl +_TLS_CERT_FILE="${_TLS_CERT_DIR}/mailserver.crt" +_TLS_KEY_FILE="${_TLS_CERT_DIR}/mailserver.key" +_TLS_CHAIN_FILE="${_TLS_CERT_DIR}/SSL123_CA_Bundle.pem" + +_TLS_CA_FILE=/etc/ssl/certs/ca-certificates.crt + + +_HOSTNAME=mx.warenform.de +_IPV4=83.223.86.76 +_IPV6=2a01:30:0:13:231:32ff:fe8b:7763 + +_autoreply_domain='autoreply.warenform.de' +#_pf_admin_version=2.3.7 +# _pf_admin_version=2.91 +_pf_admin_version=3.0.2 + +_db_type='Pg' +#_db_type='mysql' +_db_name='postfix' +_db_user='postfix' +_db_pass='CbX8vg347Vvm' + +## - +## - ENDE: mx.warenform.de + + +## - a.mx.oopen.de +## - +_WEBMAIL_IP_4=83.223.86.91 +_WEBMAIL_IP_6=2a01:30:0:13:2f7:50ff:fed2:cef7 + +_APACHE_CONF_DIR=/usr/local/apache2/conf +_APACHE_VHOST_DIR=${_APACHE_CONF_DIR}/vhosts + +_APACHE_LOG_DIR=/var/log/apache2 + +_ADMIN_EMAIL=argus@oopen.de + +_TLS_CERT_DIR=/etc/postfix/ssl +_TLS_CERT_FILE="${_TLS_CERT_DIR}/mailserver.crt" +_TLS_KEY_FILE="${_TLS_CERT_DIR}/mailserver.key" +_TLS_CHAIN_FILE="${_TLS_CERT_DIR}/sub.class2.server.ca.pem" + +_TLS_CA_FILE=/etc/ssl/certs/ca-certificates.crt + + +_HOSTNAME=a.mx.oopen.de +_IPV4=83.223.86.91 +_IPV6=2a01:30:0:13:2f7:50ff:fed2:cef7 + +_autoreply_domain='autoreply.oopen.de' +#_pf_admin_version=2.3.7 +#_pf_admin_version=2.91 +_pf_admin_version=3.0 + +_db_type='Pg' +#_db_type='mysql' +_db_name='postfix' +_db_user='postfix' +_db_pass='FKt4z55FxMZp' + +## - +## -ENDE: a.mx.oopen.de + + +## - sympa.oopen.de +## - +_WEBMAIL_IP_4=83.223.85.206 +_WEBMAIL_IP_6=2a01:30:0:13:239:a7ff:fe7e:1129 + +_APACHE_CONF_DIR=/usr/local/apache2/conf +_APACHE_VHOST_DIR=${_APACHE_CONF_DIR}/vhosts + +_APACHE_LOG_DIR=/var/log/apache2 + +_ADMIN_EMAIL=argus@oopen.de + +_TLS_CERT_DIR=/etc/postfix/ssl +_TLS_CERT_FILE="${_TLS_CERT_DIR}/mailserver.crt" +_TLS_KEY_FILE="${_TLS_CERT_DIR}/mailserver.key" +_TLS_CHAIN_FILE="${_TLS_CERT_DIR}/sub.class2.server.ca.pem" + +_TLS_CA_FILE=/etc/ssl/certs/ca-certificates.crt + + +_HOSTNAME=sympa.oopen.de +_IPV4=83.223.85.206 +_IPV6=2a01:30:0:13:239:a7ff:fe7e:1129 + +_autoreply_domain='autoreply.oopen.de' +#_pf_admin_version=2.3.7 +_pf_admin_version=2.91 + +_db_type='Pg' +#_db_type='mysql' +_db_name='postfix' +_db_user='postfix' +_db_pass='FKt4z55FxMZp' + +## - +## -ENDE: sympa.oopen.de + + +## - d.mx.oopen.de +## - +_WEBMAIL_IP_4=83.223.86.92 +_WEBMAIL_IP_6=2a01:30:0:13:254:9eff:fed5:e7fd + +_APACHE_CONF_DIR=/usr/local/apache2/conf +_APACHE_VHOST_DIR=${_APACHE_CONF_DIR}/vhosts + +_APACHE_LOG_DIR=/var/log/apache2 + +_ADMIN_EMAIL=argus@oopen.de + +_TLS_CERT_DIR=/etc/postfix/ssl +_TLS_CERT_FILE="${_TLS_CERT_DIR}/mailserver.crt" +_TLS_KEY_FILE="${_TLS_CERT_DIR}/mailserver.key" +_TLS_CHAIN_FILE="${_TLS_CERT_DIR}/sub.class2.server.ca.pem" + +_TLS_CA_FILE=/etc/ssl/certs/ca-certificates.crt + + +_HOSTNAME=d.mx.oopen.de +_IPV4=83.223.86.92 +_IPV6=83.223.86.92 + +_autoreply_domain='autoreply.oopen.de' +#_pf_admin_version=2.3.7 +_pf_admin_version=2.91 + +_db_type='Pg' +#_db_type='mysql' +_db_name='postfix' +_db_user='postfix' +_db_pass='FKt4z55FxMZp' + +## - +## -ENDE: d.mx.oopen.de + + +## - mail.interventionistische-linke.org +## - +_WEBMAIL_IP_4=83.223.85.215 +_WEBMAIL_IP_6=2a01:30:1fff:5::215 + +_APACHE_CONF_DIR=/usr/local/apache2/conf +_APACHE_VHOST_DIR=${_APACHE_CONF_DIR}/vhosts + +_APACHE_LOG_DIR=/var/log/apache2 + +_ADMIN_EMAIL=argus@oopen.de + +_TLS_CERT_DIR=/etc/postfix/ssl +_TLS_CERT_FILE="${_TLS_CERT_DIR}/mailserver.crt" +_TLS_KEY_FILE="${_TLS_CERT_DIR}/mailserver.key" +_TLS_CHAIN_FILE="${_TLS_CERT_DIR}/sub.class2.server.ca.pem" + +_TLS_CA_FILE=/etc/ssl/certs/ca-certificates.crt + + +_HOSTNAME=mail.interventionistische-linke.org +_IPV4=83.223.85.214 +_IPV6=2a01:30:1fff:5::214 + +_autoreply_domain='autoreply.interventionistische-linke.org' +#_pf_admin_version=2.3.7 +_pf_admin_version=2.91 + +_db_type='Pg' +#_db_type='mysql' +_db_name='postfix' +_db_user='postfix' +_db_pass='NcXxt7sf7bfV' + +## - +## -ENDE: mail.interventionistische-linke.org + + +## - listserver.so36.net +## - +_WEBMAIL_IP_4='' +_WEBMAIL_IP_6='' + +_APACHE_CONF_DIR='' +_APACHE_VHOST_DIR='' + +_APACHE_LOG_DIR='' + +_ADMIN_EMAIL=roots@so36.net + +_TLS_CERT_DIR=/etc/postfix/ssl +_TLS_CERT_FILE="${_TLS_CERT_DIR}/mailserver.crt" +_TLS_KEY_FILE="${_TLS_CERT_DIR}/mailserver.key" +_TLS_CHAIN_FILE="${_TLS_CERT_DIR}/sub.class2.server.ca.pem" + +_TLS_CA_FILE=/etc/ssl/certs/ca-certificates.crt + + +_HOSTNAME=listserver.so36.net +_IPV4=83.223.73.213 +_IPV6=2a01:30:1fff:fd00::213 + +_autoreply_domain='' +#_pf_admin_version=2.3.7 +_pf_admin_version='' + +#_db_type=pg +#_db_type='mysql' +_db_name='' +_db_user='' +_db_pass='' + +## - +## -ENDE: listserver.so36.net + + + + +## ------------------------------------------------------------ ## +## - Download debian prerequisites - ## +## ------------------------------------------------------------ ## +## - +## - compiler stuff +## - +apt-get install g++ g++-multilib gcc gcc-multilib cpp make libssl-dev +apt-get install automake autoconf libtool flex bison gnu-standards +apt-get install libdb-dev + + +## - Postgres (if needed) +## - +cat < /etc/apt/sources.list.d/pgdg.list +deb http://apt.postgresql.org/pub/repos/apt/ jessie-pgdg main +EOF + +apt-get update +apt-get install pgdg-keyring +apt-get install postgresql postgresql-client + +## - SSL/TLS support +apt-get install libssl-dev + +## - obtain dovecot from Mercurial repository +apt-get install hgsvn + + +## - Mysql +## - +#apt-get install mysql-server-5.0 mysql-client-5.0 libmysqlclient15-dev + +## - SASL support +## - +#apt-get install libsasl2-dev libsasl2-2 + +## - I think quota is not needed, because quota support is +## - softwareside realised +## - +## - ## - quota support +## - ## - +## - apt-get install quota +## - +## - ## - /etc/fstab +## - ## - +## - ## - proc /proc proc defaults 0 0 +## - ## - none /dev/pts devpts gid=5,mode=620 0 0 +## - ## - /dev/md0 none swap sw 0 0 +## - ## - /dev/md1 /boot ext3 defaults 0 0 +## - ## - /dev/md2 / ext3 defaults,usrquota,grpquota 0 0 +## - ## - /dev/md3 /data ext3 defaults,usrquota,grpquota 0 0 + + +## ------------------------------------------------------------ ## +## - Download sources - ## +## ------------------------------------------------------------ ## + +mkdir -p /usr/local/src/mailsystem/tarballs +cd /usr/local/src/mailsystem/tarballs + +# - postfix +## - +#wget http://de.postfix.org/ftpmirror/official/postfix-2.7.1.tar.gz + +## - postfixadmin (needed for vacation plugin) +## - +#wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin-2.3.7/postfixadmin-2.3.7.tar.gz +#wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin-2.91/postfixadmin-2.91.tar.gz +wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin-${_pf_admin_version}/postfixadmin-${_pf_admin_version}.tar.gz + + + +## ------------------------------------------------------------ ## +## - Install software - ## +## ------------------------------------------------------------ ## + +## --------------------------------- # +## --- install Apapche webserver --- # +## --------------------------------- # + +apt-get install apache2 apache2.2-common apache2-doc apache2-mpm-prefork apache2-utils + + +## - access server-status +## - +## - Allow from 178.63.63.151 127.0.0.1 +## - +vim /etc/apache2/mods-enabled/status.conf + +## - configure ports +## - +## - NameVirtualHost 178.63.63.151:80 +## - Listen 178.63.63.151:80 +## - Listen 127.0.0.1:80 +## - +## - +## - # SSL name based virtual hosts are not yet supported, therefore no +## - # NameVirtualHost statement here +## - NameVirtualHost 178.63.63.151:443 +## - Listen 178.63.63.151:443 +## - +## - +vim /etc/apache2/ports.conf + + +## - configure default site +## - +rm /etc/apache2/sites-enabled/000-default +mv /etc/apache2/sites-available/default /etc/apache2/sites-available/_default +mv /etc/apache2/sites-available/default-ssl /etc/apache2/sites-available/_default-ssl + +mkdir -p /var/www + +## - Apache base configuration +## - +cat < ${_APACHE_VHOST_DIR}/000default.conf + + Options FollowSymLinks + AllowOverride None + ## - Apache httpd 2.2.x + #Order deny,allow + #Deny from all + ## - Apache httpd 2.4.x + Require all denied + + + + AllowOverride None + ## - Apache httpd 2.2.x + #Order deny,allow + #Deny from all + ## - Apache httpd 2.4.x + Require all granted + + +## - the first VirtualHost Directive - All Requests +## - with no concerning VirtualHost Directive will be +## - handelde here + + + ServerAdmin $_ADMIN_EMAIL + + ServerName dummy.warenform.net + + RewriteEngine On + RewriteCond %{HTTP_HOST} .* + RewriteRule (.*) https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L] + + + + + + + ServerAdmin $_ADMIN_EMAIL + + ServerName dummy.warenform.net + + DocumentRoot /var/www/ + + SSLEngine on + + SSLHonorCipherOrder On + SSLCompression Off + SSLProtocol ALL -SSLv2 -SSLv3 + SSLCipherSuite EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH+aRSA+RC4:EECDH:EDH+aRSA:RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS + + Header add Strict-Transport-Security "max-age=15768000" + + SSLCertificateFile ${_APACHE_CONF_DIR}/server.crt + SSLCertificateKeyFile ${_APACHE_CONF_DIR}/server.key + SSLCACertificateFile ${_APACHE_CONF_DIR}/SSL123_CA_Bundle.pem + + + + + + ServerAdmin admin@warenform.net + + ServerName dummy.warenform.net + + + + +## - IPv6 +## - + + + ServerAdmin $_ADMIN_EMAIL + + ServerName dummy.warenform.net + + RewriteEngine On + RewriteCond %{HTTP_HOST} .* + RewriteRule (.*) https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L] + + + + + + + ServerAdmin $_ADMIN_EMAIL + + ServerName dummy.warenform.net + + DocumentRoot /var/www/ + + SSLEngine on + + SSLHonorCipherOrder On + SSLCompression Off + SSLProtocol ALL -SSLv2 -SSLv3 + SSLCipherSuite EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH+aRSA+RC4:EECDH:EDH+aRSA:RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS + + Header add Strict-Transport-Security "max-age=15768000" + + SSLCertificateFile ${_APACHE_CONF_DIR}/server.crt + SSLCertificateKeyFile ${_APACHE_CONF_DIR}/server.key + SSLCACertificateFile ${_APACHE_CONF_DIR}/SSL123_CA_Bundle.pem + + +EOF + +#ln -s ../sites-available/000default.conf /etc/apache2/sites-enabled/ + + +## - enable module ssl +## - +a2enmod ssl + +## - include certificates +## - + +chgrp ssl-cert /etc/ssl/private/20091103-0058-aktionsbuendnis_key.pem +chmod 640 /etc/ssl/private/20091103-0058-aktionsbuendnis_key.pem + +chmod 644 /etc/ssl/certs/20091103-0058-aktionsbuendnis_crt.pem + + +## - enable module ssl +## - +a2enmod rewrite + + +## - enable sites +## - put the VirtualHosts Directives in files living in the +## - directory /etc/apache2/sites-available +## - i.e. you have configured the files +## - - 000default.conf +## - - aktionsbuendnis.oopen.de.conf +## - +#a2ensite 000default.conf aktionsbuendnis.oopen.de.conf +a2ensite 000default.conf + + +## --------------------------------------------------------- # +## --- install PHP (needed for postfixadmin / roundcube) --- # +## --------------------------------------------------------- # + +## - Zusatzinstallation php (fuer: postfixadmin / roundcube) +## - +apt-get install libexpat1 mcrypt imagemagick +mpt-get install libcompress-zlib-perl +apt-get install re2c +apt-get install libmagic-dev + +apt-get install php5 php5-common php5-cli php5-pgsql \ + php5-mcrypt php5-gd php5-imagick php5-curl \ + php-pear php5-suhosin php5-mhash php5-dev \ + php-file php-gettext php-auth + +apt-get install php5-imap uw-mailutils + +## - settings /etc/php5/apache2/php.ini +## - +vim /etc/php5/apache2/php.ini + + memory_limit = 128M + register_globals = Off + session.save_handler = file + error_reporting = E_ALL + safe_mode = Off + session.cache_limiter = nocache + cgi.fix_pathinfo=1 + +apt-get install libmysqlclient15-dev +pecl channel-update pear.php.net +pecl install fileinfo + + +## - already included in php 5.3 +## - +## - #extension=pdo.so +## - #extension=pdo_mysql.so +## - #extension=fileinfo.so +#vim /etc/php5/apache2/php.ini + + + +mkdir -p /var/www/adm.warenform.de + + + +## ----------------------- ## +## --- install postfix --- ## +## ----------------------- ## + +## *************************** ## +## - install from source - ## + +_postfix_version=2.11.5 + +## - postfix user/group anlegen +## - +addgroup --system postfix +addgroup --system postdrop +adduser --system --home /var/spool/postfix --group postfix postfix + +cd /usr/local/src/mailsystem/tarballs +wget http://de.postfix.org/ftpmirror/official/postfix-${_postfix_version}.tar.gz + +cd /usr/local/src/mailsystem +gunzip < tarballs/postfix-${_postfix_version}.tar.gz | tar -xf - + +cd postfix-$_postfix_version + +## - For Postgres (PCRE-support, TLS-support, SASL-support also included) +## - +make makefiles \ + CCARGS="-DHAS_PGSQL -I/usr/include/postgresql -DHAS_PCRE `pcre-config --cflags` -DUSE_TLS -DUSE_SASL_AUTH -DUSE_CYRUS_SASL -I/usr/include/sasl" \ + AUXLIBS="-L/usr/lib/x86_64-linux-gnu -lpg `pcre-config --libs` -lssl -lcrypto -L/usr/lib/x86_64-linux-gnu -lsasl2" + +## - For MySQL installed to /usr/local/Mysql (PCRE-support, TLS-support, SASL-support also included) +## - +make makefiles \ + CCARGS="-DHAS_MYSQL -I/usr/local/mysql/include -DHAS_PCRE `pcre-config --cflags` -DUSE_TLS -DUSE_SASL_AUTH -DUSE_CYRUS_SASL -I/usr/include/sasl" \ + AUXLIBS="-L/usr/local/mysql/lib -lmysqlclient -lz -lm `pcre-config --libs` -lssl -lcrypto -L/usr/lib/x86_64-linux-gnu -lsasl2" +make +make install + +## ************************************** ## +## - install from debian package-system - ## +## - +## - since debian wheezy, postfix-tls is integrated in postfix package +## - + +# - postfix +apt-get install -t jessie-backports postfix postfix-pgsql postfix-pcre +# - mysql +apt-get install -t jessie-backports postfix postfix-mysql postfix-pcre + +## - remove exim4 and related if installed and you plan +## - to install an alternative mailer +## - +apt-get remove --purge bsd-mailx exim4 exim4-base exim4-config \ + exim4-daemon-light mailx + + +apt-get install postfix postfix-pcre libsasl2-modules bsd-mailx haveged + + + +## - !! Notice: +## - +## - If using MySQL and MySQL was installed from source, then +## - remove/check my.cnf file from debian package "mysql-common", +## - which will be installed within postfix-mysql. +## - +## - !! End: Notice + + +## - adjust main.cf +## - + +cp /etc/postfix/main.cf /etc/postfix/main.cf.ORIG + +cat < /etc/postfix/main.cf +# ============ Basic settings ============ + +# Debian specific: Specifying a file name will cause the first +# line of that file to be used as the name. The Debian default +# is /etc/mailname. +#myorigin = /etc/mailname +myorigin = /etc/mailname + +smtpd_banner = \$myhostname ESMTP \$mail_name (Debian/GNU) +biff = no + +# appending .domain is the MUA's job. +append_dot_mydomain = no + +# Uncomment the next line to generate "delayed mail" warnings +#delay_warning_time = 4h + +#readme_directory = no +readme_directory = /usr/share/doc/postfix +html_directory = /usr/share/doc/postfix/html + +## - The Internet protocols Postfix will attempt to use when making +## - or accepting connections. +## - DEFAULT: ipv4 +EOF + +if [ -n "$_IPV6" ]; then + cat <> /etc/postfix/main.cf +inet_protocols = ipv4, ipv6 + +#inet_interfaces = all +inet_interfaces = + 127.0.0.1 + $_IPV4 + $_IPV6 + +myhostname = $_HOSTNAME + +mydestination = + $_HOSTNAME + localhost + +## - The list of "trusted" SMTP clients that have more +## - privileges than "strangers" +## - +mynetworks = + 127.0.0.0/8 + [::ffff:127.0.0.0]/104 + [::1]/128 + ${_IPV4}/32, + [${_IPV6}]/128 + # b.mx.oopen.de + #83.223.86.162/32 + #[2a01:30:1fff:a::162]/128 + +smtp_bind_address = $_IPV4 +smtp_bind_address6 = $_IPV6 + +EOF + +else + cat <> /etc/postfix/main.cf +inet_protocols = ipv4 + +#inet_interfaces = all +inet_interfaces = + 127.0.0.1 + $_IPV4 + +myhostname = $_HOSTNAME + +mydestination = + $_HOSTNAME + localhost + +## - The list of "trusted" SMTP clients that have more +## - privileges than "strangers" +## - +mynetworks = + 127.0.0.0/8 + ${_IPV4}/32 + # b.mx.oopen.de + #83.223.86.162/32 + #[2a01:30:1fff:a::162]/128 + +smtp_bind_address = $_IPV4 +#smtp_bind_address6 = $_IPV6 + +EOF +fi + +cat <> /etc/postfix/main.cf + +## - The method to generate the default value for the mynetworks parameter. +## - +## - mynetworks_style = host" when Postfix should "trust" only the local machine +## - mynetworks_style = subnet (default value) "when Postfix should "trust" SMTP +## - clients in the same IP subnetworks as the local machine. +## - mynetworks_style = class" when Postfix should "trust" SMTP clients in the same +## - IP class A/B/C networks as the local machine. +## - +#mynetworks_style = host + + +## - The maximal size of any local(8) individual mailbox or maildir file, +## - or zero (no limit). In fact, this limits the size of any file that is +## - written to upon local delivery, including files written by external +## - commands that are executed by the local(8) delivery agent. +## - +mailbox_size_limit = 0 + +## - The maximal size in bytes of a message, including envelope information. +## - +## - we user 50MB +## - +message_size_limit = 52480000 + +## - The system-wide recipient address extension delimiter +## - +recipient_delimiter = + + +## - The alias databases that are used for local(8) delivery. +## - +alias_maps = + hash:/etc/aliases + +## - The alias databases for local(8) delivery that are updated +## - with "newaliases" or with "sendmail -bi". +## - +alias_database = + hash:/etc/aliases + +## - Optional lookup tables with mappings from recipient address +## - to (message delivery transport, next-hop destination). +## - See transport(5) for details. +## - +transport_maps = + btree:/etc/postfix/transport + btree:/etc/postfix/relay_domains + +## - The maximal time a message is queued before it is sent back as +## - undeliverable. Defaults to 5d (5 days) +## - Specify 0 when mail delivery should be tried only once. +## - +maximal_queue_lifetime = 3d +bounce_queue_lifetime = \$maximal_queue_lifetime + +## - delay_warning_time (default: 0h) +## - +## - The time after which the sender receives a copy of the message +## - headers of mail that is still queued. To enable this feature, +## - specify a non-zero time value (an integral value plus an optional +## - one-letter suffix that specifies the time unit). +## - Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks). +## - The default time unit is h (hours). +delay_warning_time = 1d + + +#header_checks = pcre:/etc/postfix/header_checks +prepend_delivered_header = + forward + file + + +## - proxy_read_maps +## - +## - The lookup tables that the proxymap(8) server is allowed to access for the read-only service. +## - +## - Specify zero or more "type:name" lookup tables, separated by whitespace or comma. Table +## - references that don't begin with proxy: are ignored. +## - +#proxy_read_maps = \$local_recipient_maps \$mydestination \$virtual_alias_maps \$virtual_alias_domains \$virtual_mailbox_maps \$virtual_mailbox_domains \$relay_recipient_maps \$relay_domains \$canonical_maps \$sender_canonical_maps \$recipient_canonical_maps \$relocated_maps \$transport_maps \$mynetworks \$sender_bcc_maps \$recipient_bcc_maps \$smtp_generic_maps \$lmtp_generic_maps \$smtpd_sender_login_maps + + +# ============ Relay parameters ============ + +relayhost = +relay_domains = + \$mydestination + btree:/etc/postfix/relay_domains + + +# ============ TLS parameters ============ + +## - supports DNSSEC +## - +## - !! Notice !! +## - In order to support DNSSEC and DANE your resolver MUST support +## - DNSSEC too. +## - +## - If your resolver does not support DNSSEC, install "unbound". +## - +smtp_host_lookup = dns +smtp_dns_support_level = dnssec + +## - Aktiviert STARTTLS für den Mailempfang +## - +## - may: +## - Opportunistic TLS. Use TLS if this is supported by the remote +## - SMTP server, otherwise use plaintext +## - +## - This overrides the obsolete parameters smtpd_use_tls and +## - smtpd_enforce_tls. This parameter is ignored with +## - "smtpd_tls_wrappermode = yes". +#smtpd_use_tls=yes +smtpd_tls_security_level=may + +## - Aktiviert STARTTLS für den Mailversand +## - +## - may: +## - Opportunistic TLS: announce STARTTLS support to SMTP clients, +## - but do not require that clients use TLS encryption. +# smtp_use_tls=yes +#smtp_tls_security_level=may +smtp_tls_security_level=dane + +## - 0 Disable logging of TLS activity. +## - 1 Log TLS handshake and certificate information. +## - 2 Log levels during TLS negotiation. +## - 3 Log hexadecimal and ASCII dump of TLS negotiation process. +## - 4 Also log hexadecimal and ASCII dump of complete transmission after STARTTLS. +## - +smtpd_tls_loglevel = 1 +smtp_tls_loglevel = 1 + +smtpd_tls_cert_file = $_TLS_CERT_FILE +smtpd_tls_key_file = $_TLS_KEY_FILE + +## - File with DH parameters that the Postfix SMTP server should use with EDH ciphers. +## - +## - Dont't forget to create it, e.g with openssl: +## - openssl gendh -out /etc/postfix/ssl/dh_1024.pem -2 1024 +## - +#smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_1024.pem +## - also possible to use 2048 key with that parameter +## - +smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_2048.pem + +## - File with DH parameters that the Postfix SMTP server should use with EDH ciphers. +## - +## - Dont't forget to create it, e.g with openssl: +## - openssl gendh -out /etc/postfix/ssl/dh_512.pem -2 512 +## - +smtpd_tls_dh512_param_file = /etc/postfix/ssl/dh_512.pem + + +## - File containing CA certificates of root CAs trusted to sign either remote SMTP +## - server certificates or intermediate CA certificates. These are loaded into +## - memory !! BEFORE !! the smtp(8) client enters the chroot jail. +## - +smtp_tls_CAfile = $_TLS_CA_FILE + +## - Directory with PEM format certificate authority certificates that the Postfix SMTP +## - client uses to verify a remote SMTP server certificate. Don't forget to create the +## - necessary "hash" links with, for example, " +## - $OPENSSL_HOME/bin/c_rehash /etc/postfix/certs". +## - +## - !! Note !! +## - To use this option in chroot mode, this directory (or a copy) must be inside +## - the chroot jail. +## - +## - Note that a chrooted daemon resolves all filenames relative to the Postfix +## - queue directory (/var/spool/postfix) +## - +#smtpd_tls_CApath = /etc/postfix/certs + + +# Disable SSLv2 SSLv3 - Postfix SMTP server +# +# List of TLS protocols that the Postfix SMTP server will exclude or +# include with opportunistic TLS encryption. +smtpd_tls_protocols = !SSLv2, !SSLv3 +# +# The SSL/TLS protocols accepted by the Postfix SMTP server +# with mandatory TLS encryption. +smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3 + + +# Disable SSLv2 SSLv3 - Postfix SMTP client +# +# List of TLS protocols that the Postfix SMTP client will exclude or +# include with opportunistic TLS encryption. +smtp_tls_protocols = !SSLv2, !SSLv3 +# +# List of SSL/TLS protocols that the Postfix SMTP client will use +# with mandatory TLS encryption +smtp_tls_mandatory_protocols = !SSLv2, !SSLv3 + + +## - Activate des "Ephemeral Elliptic Curve Diffie-Hellman" (EECDH) key exchange +## - openssl > 1.0 +## - +smtpd_tls_eecdh_grade = strong + +# standard list cryptographic algorithm +tls_preempt_cipherlist = yes + +# Disable ciphers which are less than 256-bit: +# +#smtpd_tls_mandatory_ciphers = high +# +# opportunistic +smtpd_tls_ciphers = high + + +# Exclude ciphers +#smtpd_tls_exclude_ciphers = +# RC4 +# aNULL +# SEED-SHA +# EXP +# MD5 +smtpd_tls_exclude_ciphers = + aNULL + eNULL + EXPORT + DES + RC4 + MD5 + PSK + aECDH + EDH-DSS-DES-CBC3-SHA + EDH-RSA-DES-CDC3-SHA + KRB5-DE5 + CBC3-SHA + + +smtpd_tls_session_cache_database = btree:\${data_directory}/smtpd_scache +smtp_tls_session_cache_database = btree:\${data_directory}/smtp_scache + + +#======= SASL Authentification ============ +smtpd_sasl_auth_enable = yes +smtpd_sasl_type=dovecot +smtpd_sasl_path=private/dovecot-auth + +smtpd_sasl_security_options = noanonymous +smtpd_sasl_authenticated_header = yes +broken_sasl_auth_clients = yes + + +## - Optional lookup table with the SASL login names that own +## - sender (MAIL FROM) addresses. +smtpd_sender_login_maps = + + +#======= Virtual mailboxes ============ + +## - Local Mailboxes +## - +virtual_mailbox_base = /var/vmail +virtual_uid_maps = static:5000 +virtual_gid_maps = static:5000 + +## - virtual_transport +## - ================= +## - +## - using postfix +## - virtual_transport = virtual +## - +## - using dovecot lda +## - virtual_transport = dovecot +## - +## - using dovecot's lmtp service +## - virtual_transport = lmtp:unix:private/dovecot-lmtp +## - +virtual_transport = virtual + +virtual_mailbox_maps = + +virtual_mailbox_domains = + +## - Optional lookup tables that alias specific mail addresses or domains +## - to other local or remote address. The table format and lookups are +## - documented in virtual(5). For an overview of Postfix address +## - manipulations see the ADDRESS_REWRITING_README document. +## - +virtual_alias_maps = + ## - mailman + #hash:/var/lib/mailman/data/virtual-mailman + +## - Postfix is final destination for the specified list of virtual alias +## - domains, that is, domains for which all addresses are aliased to addresses +## - in other local or remote domains. The SMTP server validates recipient +## - addresses with \$virtual_alias_maps and rejects non-existent recipients. +## - See also the virtual alias domain class in the ADDRESS_CLASS_README file +## - +virtual_alias_domains = + + +#header_checks = pcre:/etc/postfix/header_checks +prepend_delivered_header = forward, file + + +#======= Restrictions ============ +smtpd_recipient_restrictions = +# only special accounts (postmaster, abuse and other rolr accounts) + check_recipient_access btree:/etc/postfix/access_recipient-rfc, +# White- / Blacklisting + check_sender_access btree:/etc/postfix/access_sender, + check_recipient_access btree:/etc/postfix/access_recipient, +# permit trusted network (mynetwork) + permit_mynetworks, +# permit our users + permit_sasl_authenticated, +# dont' accept misconfigured Mail + reject_non_fqdn_sender, + reject_non_fqdn_recipient, + reject_unknown_sender_domain, + reject_unknown_recipient_domain, + reject_unlisted_recipient, +# don't accept misconfigured recipients +# RBL check - !! comment out if postcreens postscreen_dnsbl_sites is in use + # Whitelist (configured on a.ns.oopen.de + # in /opt/tinydns/root/zonefiles/dnswl.oopen.de.zone ) + permit_dnswl_client dnswl.oopen.de, + # Blacklists + reject_rbl_client zen.spamhaus.org, + reject_rbl_client ix.dnsbl.manitu.net, + #reject_rbl_client bl.spamcop.net, + # March 1, 2013: NJABL is in the process of being shut down + #reject_rbl_client dnsbl.njabl.org, +# Policyd-Weight + #check_policy_service inet:127.0.0.1:12525, +# Greylisting check + #warn_if_reject, + #check_policy_service inet:127.0.0.1:10023, +# Reject the request unless one of the following is true: +# +# - Postfix is mail forwarder: the resolved RCPT TO domain matches $relay_domains +# or a subdomain thereof, and contains no sender-specified routing (user@elsewhere@domain), +# +# +# - Postfix is the final destination: the resolved RCPT TO domain matches +# $mydestination, $inet_interfaces, $proxy_interfaces, $virtual_alias_domains, +# or $virtual_mailbox_domains, and contains no sender-specified routing (user@elsewhere@domain). + reject_unverified_recipient, +# permit Backup MX + permit_mx_backup, +# forbid all other relaying + reject_unauth_destination, +# permit, if all restrictions so far passed + permit + + +## - Sinve version 2.11 +## - +smtpd_relay_restrictions = +# only special accounts (postmaster, abuse and other rolr accounts) + check_recipient_access btree:/etc/postfix/access_recipient-rfc, +# White- / Blacklisting + check_sender_access btree:/etc/postfix/access_sender, + check_recipient_access btree:/etc/postfix/access_recipient, +# permit trusted network (mynetwork) + permit_mynetworks, +# permit our users + permit_sasl_authenticated, +# dont' accept misconfigured Mail + reject_non_fqdn_sender, + reject_non_fqdn_recipient, + reject_unknown_sender_domain, + reject_unknown_recipient_domain, + reject_unlisted_recipient, +# don't accept misconfigured recipients +# RBL check - !! comment out if postcreens postscreen_dnsbl_sites is in use + # Whitelist (configured on a.ns.oopen.de + # in /opt/tinydns/root/zonefiles/dnswl.oopen.de.zone ) + permit_dnswl_client dnswl.oopen.de, + # Blacklists + reject_rbl_client zen.spamhaus.org, + reject_rbl_client ix.dnsbl.manitu.net, + #reject_rbl_client bl.spamcop.net, + # March 1, 2013: NJABL is in the process of being shut down + #reject_rbl_client dnsbl.njabl.org, +# Policyd-Weight + #check_policy_service inet:127.0.0.1:12525, +# Greylisting check + #warn_if_reject, + #check_policy_service inet:127.0.0.1:10023, +# Reject the request unless one of the following is true: +# +# - Postfix is mail forwarder: the resolved RCPT TO domain matches $relay_domains +# or a subdomain thereof, and contains no sender-specified routing (user@elsewhere@domain), +# +# +# - Postfix is the final destination: the resolved RCPT TO domain matches +# $mydestination, $inet_interfaces, $proxy_interfaces, $virtual_alias_domains, +# or $virtual_mailbox_domains, and contains no sender-specified routing (user@elsewhere@domain). + reject_unverified_recipient, +# permit Backup MX + permit_mx_backup, +# forbid all other relaying + reject_unauth_destination, +# permit, if all restrictions so far passed + permit + +EOF + + +## - create directory for certificates and copy certificates +## - and coresponding keys to /etc/postfix/ssl/ +## - +mkdir -p /etc/postfix/ssl +cp /etc/postfix/ssl/ + +#mkdir -p /etc/postfix/ssl/certs + +## - generate DH parameters that the Postfix SMTP server should use +## - with EDH ciphers (length 512 and 1024 +## - +openssl gendh -out /etc/postfix/ssl/dh_512.pem -2 512 +openssl gendh -out /etc/postfix/ssl/dh_1024.pem -2 1024 +openssl gendh -out /etc/postfix/ssl/dh_2048.pem -2 2048 + + +## - put all CA root certs you trustet into directory /etc/postfix/certs +## - afterwards create the hashes: +## - c_rehash /etc/postfix/sslcerts +## - +## - +## - create directory for trusted root certificates and copy +## - certificates into it +## - +#mkdir -p /etc/postfix/certs +# +#c_rehash /etc/postfix/certs +# +## - Note that a chrooted daemon resolves all filenames relative to the Postfix +## - queue directory (/var/spool/postfix) +# +#mkdir -p /var/spool/postfix/etc/postfix/ +#cp -a /etc/postfix/certs /var/spool/postfix/etc/postfix/ + + +## - create files +## - +cat < /etc/postfix/access_recipient-rfc +# if destination is ok, permit +/^postmaster\@/ permit_auth_destination +/^abuse\@/ permit_auth_destination +EOF + +postmap btree:/etc/postfix/access_recipient-rfc + +cat < /etc/postfix/access_sender +## - bekannte Virus/Spam Absener blocken +## - +error@mailfrom.com REJECT +EOF + +## - Notice: +## - this (access_sender) list can also be used as white list: +## - backup@b3-bornim.de OK +## - backup_file-ah@oopen.de OK +## - backup_file-spr@oopen.de OK +## - root_file_spr@oopen.de OK +## - backup_anw-urban@oopen.de OK +## - anonymous@bbb-server.b3-bornim.de OK + +postmap btree:/etc/postfix/access_sender + +echo > /etc/postfix/access_recipient +postmap btree:/etc/postfix/access_recipient + +echo > /etc/postfix/transport +postmap btree:/etc/postfix/transport + +echo > /etc/postfix/relay_domains +postmap btree:/etc/postfix/relay_domains + + +## - Eliminate Sender ip-address, repalce with 127.0.0.1 +## - +echo '/^Received: from (.* \([-._[:alnum:]]+ \[[.[:digit:]]{7,15}\]\)).*?([[:space:]]+).*\(Authenticated sender: ([^)]+)\)(.*)/ REPLACE Received: from [127.0.0.1] (localhost [127.0.0.1])$2(Authenticated sender: $3)$4' > /etc/postfix/header_checks + + +## - add to /etc/aliases +## - +## - postmaster: root +## - abuse: root +## - root: argus@oopen.de +## - +## - and execute "newaliases" to generate /etc/aliases.db +## - +newaliases + + +## - Configure rsyslogd to avoid writing into two logfiles (syslog, mail.log) +## - +## - !! APPEND to /etc/rsyslog.d/postfix.conf +## - +cat << EOF >> /etc/rsyslog.d/postfix.conf + +# +# Logging for the mail system. Split it up so that +# it is easy to write scripts to parse these files. +# +mail.info -/var/log/mail.info +mail.warn -/var/log/mail.warn +mail.err /var/log/mail.err + +mail.* -/var/log/mail.log +& ~ +EOF + +/etc/init.d/rsyslog restart + + + +## - Create user and directory for virtual mailboxes +## - +useradd -s /bin/false -d /var/vmail -M -u 5000 vmail +mkdir /var/vmail +chown vmail:vmail /var/vmail +chmod 700 /var/vmail + + +## - Create Listener for user authenticated smtp connection port 587 (submission) +## - and port 465 (smtps) +## - +## - Two posibilities: +## - 1.) Do not filter outgong e-mails +## - 2.) Filter outgoing e-mails (amavis) +## - + +## ------------------------------------------------------- +## - Configure smtps and submission WITHOUT filtering + +## - edit /etc/postfix/master.cf - and add services on +## - submissionport (587) an smtpds (465). on these ports +## - only allow authenticated users +## - +## - submission inet n - - - - smtpd +## - -o smtpd_tls_security_level=encrypt +## - -o smtpd_sasl_auth_enable=yes +## - -o smtpd_client_restrictions=permit_sasl_authenticated,reject +## - # -o milter_macro_daemon_name=ORIGINATING +## - +## - smtps inet n - - - - smtpd +## - -o smtpd_tls_wrappermode=yes +## - -o smtpd_sasl_auth_enable=yes +## - -o smtpd_client_restrictions=permit_sasl_authenticated,reject +## - +vim /etc/postfix/master.cf + +## - End: Configure smtps and submission WITHOUT filtering +## ------------------------------------------------------- + + +## ------------------------------------------------------- +## - Configure smtps and submission WITH filtering + +## - in file /etc/postfix/master.cf +## - +## - 1.) add to smtp entry +## - +## - smtp inet n - - - - smtpd +## - -o smtpd_proxy_filter=127.0.0.1:10024 +## - -o content_filter= +## - +## - 2.) add to / create submisson entry: +## - +## - submission inet n - - - 20 smtpd +## - -o content_filter=amavisfeed:[127.0.0.1]:10024 +## - -o smtpd_tls_security_level=encrypt +## - -o smtpd_sasl_auth_enable=yes +## - -o smtpd_client_restrictions=permit_sasl_authenticated,reject +## - # -o milter_macro_daemon_name=ORIGINATING +## - +## - +## - 3.) add to / create "smtps" entry +## - +## - smtps inet n - - - - smtpd +## - -o content_filter=amavisfeed:[127.0.0.1]:10024 +## - -o smtpd_tls_wrappermode=yes +## - -o smtpd_sasl_auth_enable=yes +## - -o smtpd_client_restrictions=permit_sasl_authenticated,reject +## - # -o milter_macro_daemon_name=ORIGINATING +## - +## - +## - 4.) add entry "amavisfeed" +## - +## - amavisfeed unix - - n - 20 lmtp +## - -o smtp_data_done_timeout=1200 +## - -o smtp_send_xforward_command=yes +## - -o disable_dns_lookups=yes +## - ... +## - + +## - so it looks like: +## - + +smtp inet n - - - - smtpd + -o smtpd_proxy_filter=127.0.0.1:10024 + -o content_filter= + +submission inet n - - - 20 smtpd + -o content_filter=amavisfeed:[127.0.0.1]:10024 + -o smtpd_tls_security_level=encrypt + -o smtpd_sasl_auth_enable=yes + -o smtpd_client_restrictions=permit_sasl_authenticated,reject +# -o milter_macro_daemon_name=ORIGINATING + +smtps inet n - - - - smtpd + -o content_filter=amavisfeed:[127.0.0.1]:10024 + -o smtpd_tls_wrappermode=yes + -o smtpd_sasl_auth_enable=yes + -o smtpd_client_restrictions=permit_sasl_authenticated,reject +# -o milter_macro_daemon_name=ORIGINATING + +amavisfeed unix - - n - 20 lmtp + -o smtp_data_done_timeout=1200 + -o smtp_send_xforward_command=yes + -o disable_dns_lookups=yes + +## - End: Configure smtps and submission WITH filtering +## ------------------------------------------------------- + + +## --------------------------------------------------------- # +## --- Install Greylist-Daemon and configure for Postfix --- # +## --------------------------------------------------------- # + +apt-get install postgrey + +## - configure Postgrey-Daemon +## - +## - the default values are: +## - host: localhost (127.0.0.1) +## - port: 10023 +## - delay: 300 seconds +## - max ge: 35 days +## - +## - --inet=10023 --inet=[HOST:]PORT listen on PORT, localhost if HOST is not specified +## - --delay=N how long to greylist, seconds (default: 300) +## - --max-age=N delete old entries after N days (default: 35) +## - +## - you can also specify whitelists (for client hostnames +## - and recipients) +## - see whitelist_clients and whitelist_recipients in /etc/postgrey +## - +cp /usr/share/postgrey/postgrey-default /etc/default/postgrey + +## - edit /etc/default/postgrey +## - +## - set: +## - POSTGREY_OPTS="--inet=10023 --delay=149" +## - +vim /etc/default/postgrey + + +## - Complement the client whitelist. Put additional entries +## - into file /etc/postgrey/whitelist_clients.local +## - +## - Notice the following Problem +## - A delivery attempt runs into greylisting (because ist the first +## - time) - Thats OK. But the next delivery attempt for just the same +## - e-mail comes from another very different client-ip - and runs into +## - greylisting again, and again, and again.. +## - +## - very different client-ip meens: even if stripping the last byte of +## - the ip-address, postgreys default (--lookup-by-subnet), the rest of +## - the ip-addresse ist still different. +## - +## - +cat << EOF > /etc/postgrey/whitelist_clients.local +# For Office 365 - servers: +##/.*outbound.protection.outlook.com\$/ +/^mail-.*\.outbound\.protection\.outlook\.com\$/ +EOF + + +/etc/init.d/postgrey restart + +## - start at boot time +## - +update-rc.d postgrey defaults + +## - /etc/postfix/main.cf +## - +## - +## - in section Restrictions, parameter smtpd_recipient_restrictions +## - uncomment add +## - +## - ceck_policy_service inet:127.0.0.1:10023,, +## - +## - Notice: +## - you can use the directive "warn_if_reject" just befor the check_policy_service +## - directive and let it +## - To bring postgrey to learn about incomming wanted emails, but not rejecting them +## - by firts arrival, you can use the directive "warn_if_reject" just befor the check_policy_service +## - directive. then the following directive "check_policy_service" will not reject, but +## - only logging. +## - +vim /etc/postfix/main.cf +/etc/init.d/postfix reload + + + +## ------------------------- # +## --- install vacation --- # +## ------------------------- # + + +if [ "$_db_type" = "postgres" -o "$_db_type" = "postgresql" -o "$_db_type" = "pgsql" -o "$_db_type" = "psql" ];then + _db_type=Pg +fi + + +## - install prerequisites +## - +apt-get install libdbi-perl libmime-encwords-perl libemail-valid-perl \ + libmail-sendmail-perl liblog-log4perl-perl libdbd-pg-perl \ + libmail-sender-perl + + +## - If MySQL/Postgres was installed from debian package system, install also perl +## - modules "DBI" and DBD::mysql/DBD::Pg from debian package system +## - +if [ "$_db_type" = "Pg" ]; then + apt-get install libdbd-pgsql libdbd-pg-perl libdbi-perl libdbi-dev +else + apt-get install libdbd-mysql libdbd-mysql-perl libdbi-perl libdbi-dev +fi + +## - If MySQL/PostgresSQL was installed from source, install perl modules "DBI" and +## - "DBD::mysql" via cpan +## - +cpan -i DBI +if [ "$_db_type" = "Pg" ]; then + cpan -i DBD::Pg +else + cpan -i DBD::mysql +fi + +## - create a local accaount +## - +## - this user handles all potentially dangerous mail content - that is why it +## - should be a separate account. +## - +addgroup --system --gid 65501 vacation +adduser --system --home /var/spool/vacation --no-create-home --uid 65501 --gid 65501 --shell /usr/sbin/nologin vacation + +## - create directory /var/spool/vacation +## - +mkdir /var/spool/vacation +chown vacation:vacation /var/spool/vacation + +## - as perl binary, we use the vacation.pl from the postfixadmin distribution. +## - +cd /usr/local/src/mailsystem/tarballs +wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin-${_pf_admin_version}/postfixadmin-${_pf_admin_version}.tar.gz +## - since postfixadmin v. 2.91 , the subject-patch i already included +#wget http://sourceforge.net/p/postfixadmin/patches/_discuss/thread/69a7ce85/b4e9/attachment/vacation.pl_SUBJECT.patch + + +cd /usr/local/src/mailsystem +gunzip < tarballs/postfixadmin-${_pf_admin_version}.tar.gz | tar -xf - + + + +cd /tmp +cp /usr/local/src/mailsystem/postfixadmin-${_pf_admin_version}/VIRTUAL_VACATION/vacation.pl /tmp/ + + +## - Add a patch +## - +## - Add capability to include the subject of the original mail in the subject of the vacation message. +## - A good vacation subject could be: 'Re: $SUBJECT' +## - Also corrected log entry about "Already informed ..." to show the $orig_from, not $email +## - +#wget http://sourceforge.net/p/postfixadmin/patches/_discuss/thread/69a7ce85/b4e9/attachment/vacation.pl_SUBJECT.patch + + +## - Apply the patch +## - +## - !!Note: +## - Patch is already included in version of postfixadmin distribution >= 2.91 +## - +#patch -p0 /tmp/vacation.pl /usr/local/src/mailsystem/tarballs/vacation.pl_SUBJECT.patch + + +## - postfixadmin, version 2.91 is broken if database backend is PostgreSQL +## - +## - I have written a patch, which fixes that errors +## - +## - Note: +## - Patch seems already included in version of postfixadmin distribution >= 2.91 +## - +#patch vacation.pl /usr/local/src/mailsystem/tarballs/vacation-4.0r1.pl_PGSQL.patch + + + +## - Encoding does not work as exspected. +## - +## - NOTE: +## - this IS NOT a fix, but a workaround +## - +perl -i -n -p -e "s/(\s*\'ctype\'\s* =>\s*)\'text\/plain.*$/\1\'text\/plain; charset=iso-8859-1\',/" \ + /tmp/vacation.pl + + +## - Copy vacation.pl into /var/spool/vacation/ +## - + +if [ -f /var/spool/vacation/vacation.pl ]; then + mv /var/spool/vacation/vacation.pl /var/spool/vacation/vacation.pl.`date "+%Y%m%d-%H%M"` +fi +cp vacation.pl /var/spool/vacation/ +chown vacation:vacation /var/spool/vacation/vacation.pl +chmod 700 /var/spool/vacation/vacation.pl +rm /tmp/vacation.pl + + +## - Configure script vacation.pl +## - +## - Notice: +## - the needed tables (named vacation and vacation_notification) are createt throug +## - postfixadmin installation /setup) +## - +## - instead of changing this script, we put the needed entries +## - to file /etc/postfixadmin/vacation.conf: +## - +## - $db_type = '$_db_type'; +## - $db_username = '$_db_user'; +## - $db_password = '$_db_pass'; +## - $db_name = '$_db_name'; +## - $vacation_domain = '$_autoreply_domain'; +## - $syslog = 0; +## - $log_to_file = 1; +## - $logfile = '/var/log/vacation.log'; +## - $log_level = 1; +## - $interval = 60*60*24; +## - + +mkdir /etc/postfixadmin/ +cat < /etc/postfixadmin/vacation.conf +\$db_type = '$_db_type'; +\$db_username = '$_db_user'; +\$db_password = '$_db_pass'; +\$db_name = '$_db_name'; +\$vacation_domain = '$_autoreply_domain'; +\$syslog = 0; +\$log_to_file = 1; +\$logfile = '/var/log/vacation.log'; +\$log_level = 1; +\$interval = 60*60*24; +EOF + + +touch /var/log/vacation.log +chown vacation:vacation /var/log/vacation.log + + +## - Logrotate entry for /var/log/vacation.log +## - +cat < /etc/logrotate.d/vacation +/var/log/vacation.log { + daily + start 0 + rotate 7 + missingok + compress + delaycompress + notifempty + create 640 vacation vacation + copytruncate +} +EOF + + +## - Deprecated - Already fixed in distribution +## - +## - Fix an Error, considering syslog-functionality in vacation.pl +## - +## - replace (line 208) +## - Facility => 'mail', +## - with +## - facility => 'mail', +## - +#perl -i.ORIG -n -p -e "s#^(\s*)Facility(\s+=.*)#\1facility\2#" /var/spool/vacation/vacation.pl + + + +## - create an entry in /etc/hosts for the (non-existant domain) +## - autoreply.warenform.de +## - add: +## - +## - 127.0.0.1 autoreply.warenform.de +## - +perl -i. -n -p -e"s#(^\s*127.0.0.1\s+localhost.*)#\1\n\n127.0.0.1 $_autoreply_domain#" /etc/hosts +vim /etc/hosts + +## - Define the transport type in the Postfix master file +## - /etc/postfix/master.cf +## - +## - vacation unix - n n - - pipe +## - flags=Rq user=vacation argv=/var/spool/vacation/vacation.pl -f ${sender} -- ${recipient} +## - +cat <> /etc/postfix/master.cf + +vacation unix - n n - - pipe + flags=Rq user=vacation argv=/var/spool/vacation/vacation.pl -f \${sender} -- \${recipient} +EOF + + +## - Setup the transport maps file /etc/postfix/transport +## - +## - add line: +## - +## - autoreply.warenform.de vacation: +## - +echo "$_autoreply_domain vacation:" >> /etc/postfix/transport +postmap btree:/etc/postfix/transport + +## - Notice: +## - take care the entry for transport_maps in /etc/postfix/main.cf +## - contains "btree:/etc/postfix/transport" +## - + +/etc/init.d/postfix reload + + + +## --------------------------------------------------- ## +## --- Install AMaViS with ClamAV and Spamassassin --- ## +## --------------------------------------------------- ## + +## - See file: amavis_clamav_sa.install + + +## ------------------------------ ## +## --- install dovecot server --- ## +## ------------------------------ ## + +## - Use: +## - install_update_dovecot.sh +## - +## - (Old) textversion: install_dovecot+mysql.txt + + +## ---------------------------- ## +## --- install postfixadmin --- ## +## ---------------------------- ## + +## - See file: postfixadmin.install + + +## ----------------------------------- ## +## --- install roundcube Webmailer --- ## +## ----------------------------------- ## + +## - See file: roundcube.install + + +## ------------------------------------------------------ ## +## - Mailgraph - a RRDtool frontend for Mail statistics - ## +## ------------------------------------------------------ ## +apt-get install rrdtool librrds-perl libfile-tail-perl + +cd /usr/local/src/mailsystem/tarballs +wget http://mailgraph.schweikert.ch/pub/mailgraph-1.14.tar.gz +gunzip < mailgraph-1.14.tar.gz | tar -xf - + +cd mailgraph-1.14 +cp mailgraph.pl /usr/local/bin/ + +cp mailgraph-init mailgraph-init.ORIG +cp mailgraph-init /etc/init.d/ +chmod 755 /etc/init.d/mailgraph-init + + + +## -------------------------------------- ## +## - some litle tests ## +## -------------------------------------- ## + +## - test smtp (STARTTLS), submission (587) (STARTTLS), smtp (SSL), +## - pop3 (SSL), pop3 (STARTTLS), imap (SSL) and imap (STARTTLS) +## - +openssl s_client -crlf -starttls smtp -connect localhost:25 [-state -debug] +openssl s_client -crlf -starttls smtp -connect localhost:587 +openssl s_client -crlf -connect localhost:465 +openssl s_client -crlf -connect localhost:995 +openssl s_client -crlf -starttls pop3 -connect localhost:110 +openssl s_client -crlf -connect localhost:993 +openssl s_client -crlf -starttls imap -connect localhost:143 + diff --git a/DOC/postfix/postfix_sasl_cyrus_on_relayhost.txt b/DOC/postfix/postfix_sasl_cyrus_on_relayhost.txt new file mode 100644 index 0000000..037d62f --- /dev/null +++ b/DOC/postfix/postfix_sasl_cyrus_on_relayhost.txt @@ -0,0 +1,190 @@ +## - Configure a postfix server to act as relay host for +## - AUTENTiCATED clients +## - +## - see also Postfix SASL Howto: +## - http://www.postfix.org/SASL_README.html +## - http://www.synology-wiki.de/index.php/Mail-Relay_mit_Postfix +## - + + +## - Todo: +## - 1.) Configuring SASL authentication in the Postfix SMTP server +## - - Configuring Cyrus SASL - using accounts are stored in a Cyrus SASL +## - Berkeley DB database +## - 2.) Configuring SASL authentication in the Postfix SMTP/LMTP client + +## - ------------------------------------------------------------- - ## +## - 1. Configuring SASL authentication at the Postfix SMTP server - ## +## - ------------------------------------------------------------- - ## + +## ----------------------------- +## - Create the sasldb2 Database +## - +## - To create and maintain the database, we will user the +## - command-line utility "saslpasswd2". So, we have to install +## - the packages sasl2-bin +## - +apt-get install sasl2-bin + + +## - The sasldb auxprop plugin authenticates SASL clients against credentials +## - that are stored in a Berkeley DB database. The database schema is specific +## - to Cyrus SASL. The database is usually located at /etc/sasldb2 +## - +## - !!!! +## - NOTE: in chrooted postfix, thats if chroot in master.cf is not set (have +## - "-") or is set to yes (have "y"), the database "sasdb2" ist +## - searched in the chrooted path. In debian it is file +## - /var/spool/postfix/etc/sasldb2 +## - !!!! +## - + + +## - Create a new account +## - +## - Note: +## - 1.) usernames of accounts are of the Form: +## - @ and NOT +## - +## - 2.) The database-file defaults to "/etc/sasldb2". But on chrooted +## - postfix (as we have), the database file must placed to +## - /var/spool/postfix/etc/sasldb2 - on default debian postfix +## - install. So use flag "-f" +## - +saslpasswd2 -c -u b.mx.oopen.de -f /var/spool/postfix/etc/sasldb2 + +## - Check with command-line utility "sasldblistusers2" +## - +sasldblistusers2 -f /var/spool/postfix/etc/sasldb2 + + +## ------------------------------------------------ +## - Configure and Enable Cyrus SASL authentication + + +## - in /etc/postfix/main.cf set: +## - +## - smtpd_sasl_type = cyrus +## - +## - # Define the name of the configuration file. Cyrus SASL add's the +## - # suffix ".conf". The location where Cyrus SASL searches for the named +## - # file depends on the Cyrus SASL version and the OS/distribution used. +## - # For debian it is: /etc/postfix/sasl/ +## - smtpd_sasl_path = smtpd +## - +## - # enable SASL authentication +## - smtpd_sasl_auth_enable = yes +## - +## - # Disallow methods that allow anonymous authentication. +## - smtpd_sasl_security_options = noanonymous +## - smtpd_sasl_tls_security_options = $smtpd_sasl_security_options +## - +## - # Do not accept SASL authentication over unencrypted connections +## - smtpd_tls_auth_only = yes +## - +vim /etc/postfix/main.cf + +## - create /etc/postfix/sasl/smtpd.conf +## - +## - pwcheck_method: auxprop +## - auxprop_plugin: sasldb +## - mech_list: PLAIN LOGIN CRAM-MD5 DIGEST-MD5 NTLM +## - +## - Take care only to use provided login mechanisms +## - # saslpluginviewer -x AUXPROP_MECHS +## - +vim /etc/postfix/sasl/smtpd.conf + + +## - To allow (dynamic) ip-adresses to relay, even if they ar blacklistet +## - you can use permit_sasl_authenticated in postfix smtpd_relay_restrictions +## - BEFOR checking against blacklists +## - +## - in /etc/postfix/main.cf set: +## - +## - smtpd_recipient_restrictions = +## - ... +## - # permit trusted network mynetwork +## - permit_mynetworks, +## - # sasl authenticated user (we work as relayhost for some office networks) +## - permit_sasl_authenticated, +## - # dont' accept misconfigured Mail +## - reject_non_fqdn_recipient, +## - reject_unknown_sender_domain, +## - reject_unknown_recipient_domain, +## - reject_unlisted_recipient, +## - # RBL check - !! comment out if postcreens postscreen_dnsbl_sites is in use +## - permit_dnswl_client dnswl.oopen.de, +## - #reject_rbl_client zen.spamhaus.org, +## - reject_rbl_client ix.dnsbl.manitu.net, +## - reject_rbl_client bl.spamcop.net, +## - reject_rbl_client dnsbl.njabl.org, +## - # Policyd-Weight +## - ... +## - +vim /etc/postfix/main.cf + + +## - --------------------------------------------------------------- - ## +## - Configuring SASL authentication in the Postfix SMTP/LMTP client - ## +## - --------------------------------------------------------------- - ## + + +## - Notice: you have to install Pluggable Authentication Modules for SASL +## - for debian: install package libsasl2-modules +## - +apt-get install libsasl2-modules + + +## - Edit file /etc/postfix/main.cf and set: +## - +## - # Enable SASL authentication +## - smtp_sasl_auth_enable = yes +## - +## - # Forwarding to the ip-adress of host b.mx.oopen.de +## - relayhost = [b.mx.oopen.de] +## - +## - # File including login data +## - smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd +## - +## - # Force using a (TLS) security connection +## - # obsulete - use smtp_tls_security_level instead +## - #smtp_use_tls = yes +## - #smtp_tls_enforce_peername = no +## - smtp_tls_security_level = encrypt +## - +## - # Disallow methods that allow anonymous authentication. +## - smtp_sasl_security_options = noanonymous +## - +vim /etc/postfix/main.cf + + +## - Enter SASL account data into file /etc/postfix/sasl_passwd +## - +## - : +## - +## - Note: if relayhost is configured as above, username is of the form +## - @ +## - +vim /etc/postfix/sasl_passwd + +## - Important +## - +## - Keep the SASL client password file in /etc/postfix, and make the file +## - read+write only for root to protect the username/password combinations against +## - other users. The Postfix SMTP client will still be able to read the SASL +## - client passwords. It opens the file as user root before it drops privileges, +## - and before entering an optional chroot jail. +## - +chown root:root /etc/postfix/sasl_passwd +chmod 600 /etc/postfix/sasl_passwd + +## - Create databasefile of /etc/postfix/sasl_passwd +## - +postmap /etc/postfix/sasl_passwd + + +## - Reload postfix +## - +/etc/init.d/postfix reload + diff --git a/DOC/postfix/whitelist_email_domain_postgrey.txt b/DOC/postfix/whitelist_email_domain_postgrey.txt new file mode 100644 index 0000000..8f6081f --- /dev/null +++ b/DOC/postfix/whitelist_email_domain_postgrey.txt @@ -0,0 +1,29 @@ +## - Empfänger Domains oder E-Mailadressen vom Greylisting +## -ausschliessen + +## - Dazu zu sind Einträge in der whitelist_recipients nötig. +## - Das ist die Whitelist für die Empfänger, die dort eingetragenen +## - Domains, Postfächer oder E-Mail-Adressen werden vom Greylisting +## - ausgeschlossen. +## - +## - Die whitelist_recipients sind unter /etc/postgrey zu finden. +## - +vim /etc/postgrey/whitelist_recipients + +## - Beispiel /etc/postgrey/whitelist_recipients: +## - +## - # postgrey whitelist for mail recipients +## - # -------------------------------------- +## - # put this file in /etc/postgrey or specify its path +## - # with --whitelist-recipients=xxx +## - +## - postmaster@ +## - abuse@ +## - +## - # Domain und E-Mail-Adresse vom Greylisting ausschließen +## - oopen.de +## - wolle@k8h.de +## - +## - # Diese Einträge wären ueberflüssig +## - #ckubu-adm@oopen.de +## - #argus@oopen.de diff --git a/DOC/postfix/whitelist_host_ip_address.txt b/DOC/postfix/whitelist_host_ip_address.txt new file mode 100644 index 0000000..d13c1f4 --- /dev/null +++ b/DOC/postfix/whitelist_host_ip_address.txt @@ -0,0 +1,185 @@ +## - To whitelist a server ther a multiple possibilities +## - + +## ----- +## - 1.) +## - +## - To whitelist a server (name or ip-adress) or network , create the file +## - /etc/postfix/rbl_override +## - where you list all IP addresses or host names +## - (one per line!) that you want to whitelist: +## - +## - 1.2.3.4 OK +## - mail.freemailer.tld OK +## - 194.25.134/24 OK +## - ... +## - +vim /etc/postfix/rbl_override + +## - After you've created/modified that file, you must run: +## - +postmap btree:/etc/postfix/rbl_override +#postmap /etc/postfix/rbl_override + +## - Next open +## - /etc/postfix/main.cf +## - and search for the smtpd_recipient_restrictions parameter. +## - Add check_client_access hash:/etc/postfix/rbl_override to +## - that parameter, after reject_unauth_destination, but before +## - the first blacklist. +## - +## - smtpd_recipient_restrictions = +## - ... +## - permit_sasl_authenticated, +## - check_client_access btree:/etc/postfix/rbl_override, +## - #check_client_access hash:/etc/postfix/rbl_override, +## - reject_rbl_client zen.spamhaus.org, +## - ... + + +## - Now restart postfix: +## - +/etc/init.d/postfix restart + + +## ---- +## - Notice: +## - there are also whitelist dns service, like list.dnswl.org +## - see: http://www.dnswl.org/ +## - requesting such a service works the same as requesting a +## - blacklist server like +## - +## - for example the server 194.25.134.17 (one mailserver from t-online) +## - is blacklisted at bl.spamcop.net. that means the request +## - +## - chris@sol:~$ dig 17.134.25.194.bl.spamcop.net +## - +## - results in an ANSWER SECTION like +## - +## - 17.134.25.194.bl.spamcop.net. 2100 IN A 127.0.0.2 +## - +## - ( or using host command: +## - chris@sol:~$ host 17.134.25.194.bl.spamcop.net +## - 17.134.25.194.bl.spamcop.net has address 127.0.0.2 ) +## - +## - in contrast to "not found: 3(NXDOMAIN)" in case of a not blacklistet one +## - +## - +## - That t-online server is also (white-)listed at the at list.dnswl.org and +## - so, the request +## - +## - chris@sol:~$ dig 17.134.25.194.list.dnswl.org +## - +## - results in an ANSWER SECTION like: +## - +## - 17.134.25.194.list.dnswl.org. 12506 IN A 127.0.5.0 +## - +## - or rather +## - chris@sol:~$ host 17.134.25.194.list.dnswl.org +## - 17.134.25.194.list.dnswl.org has address 127.0.5.0 +## - +## - +## ----- + + + +## ----- +## - 2.) +## - +## - You can question more than one blacklist server an also whitelist server, +## - weight the single result and make a decision after getting the all-overresult +## - +## - Do so, use parameters "postscreen_dnsbl_sites and" +## - "postscreen_dnsbl_threshold". +## - +## - +## - Example configuration: +## - +## - postscreen_dnsbl_sites = +## - one.blacklist.server.com*2 +## - another.blacklist.server.com +## - third.blacklist.server.com +## - list.dnswl.org*-3 +## - postscreen_dnsbl_threshold=1 # (the default value) +## - +## - if the requested incomming-ip-adress matches the first blacklist server, +## - you get a result of "2" (because the entry for that blacklict server is +## - weighted with 2). +## - if the requested ip-address matches the second or the third blacklist +## - server the result is each with "1" +## - if the requested ip-address matches the whitelist server, the result +## - is "-3" +## - +## - assuming all servers matches, than the all over result is "2+1+1-3=1". +## - because 1 is equal or grater than "1" (the value of the parameter of +## - "postscreen_dnsbl_threshold"), the concerning the concerning network +## - connection will be dropped. +## - +## - assuming the first and second blacklist server and also the whitelist +## - server matches the concerning the all over result is "2+1-3=0". +## - Because 0 is lower then 1 (the value of the parameter +## - "postscreen_dnsbl_threshold"). the connection will be accepted (at that +## - point) +## - +## - +## - See "man postconf" or site +## - http://www.postfix.org/postconf.5.html for advanced usage +## - +## ----- + + + +## ----- +## - 3.) +## - +## - you can use postfix conf parameter "permit_dnswl_client" +## - in main.cf +## - +## - here is an example using list.dnswl.org +## - +## - smtpd_recipient_restrictions = +## - ... +## - permit_sasl_authenticated, +## - permit_dnswl_client list.dnswl.org, +## - reject_rbl_client someblacklist.example.com, +## - reject_rbl_client moreblacklist.example.com, +## - permit_mynetworks, +## - ... +## - +## - To override only for "low", "med" and "hi" (see +## - http://www.dnswl.org/tech): +## - +## - smtpd_recipient_restrictions = +## - ... +## - permit_sasl_authenticated, +## - permit_dnswl_client list.dnswl.org=127.0.[0..255].[1..3], +## - reject_rbl_client someblacklist.example.com, +## - permit_mynetworks, +## - reject_unauth_destination +## - +## ----- + +## - Notice: +## - +## - I have configured some white list entries d.c.b.a.dnswl.oopen.de. +## - see file /opt/tinydns/root/zonefiles/dnswl.oopen.de.zone on +## - a.ns.oopen.de +## - +## - i.e. to avoid blacklisting t-online servers 194.25.134.*, i added +## - the followig entry +## - +*.134.25.194.dnswl.oopen.de:127.0.0.2:4300 +## - +## - i added also a concerning TXT record (not needed): +## - '*.134.25.194.dnswl.oopen.de:T-Online:4300 +## - +## - concernin entry in smtpd_recipient_restrictions of main.cf: +## - +## - ... +## - # RBL check - !! comment out if postcreens postscreen_dnsbl_sites is in use +## - # Whitelist (configured on a.ns.oopen.de +## - # in /opt/tinydns/root/zonefiles/dnswl.oopen.de.zone ) +## - permit_dnswl_client dnswl.oopen.de, +## - # Blacklists +## - reject_rbl_client zen.spamhaus.org, +## - reject_rbl_client ix.dnsbl.manitu.net, +## - ... diff --git a/DOC/roundcube/Environments/postfixadmin.env.a.mx.oopen.de b/DOC/roundcube/Environments/postfixadmin.env.a.mx.oopen.de new file mode 100644 index 0000000..313ebf1 --- /dev/null +++ b/DOC/roundcube/Environments/postfixadmin.env.a.mx.oopen.de @@ -0,0 +1,58 @@ +## - Postfixadmin environment for server +## - +## - a.mx.oopen.de (adm.oopen.de) +## - + +## ------------------------------------- +## - a.mx.oopen.de (adm.oopen.de) + +HOSTNAME=adm.oopen.de +DOMAIN=oopen.de +ADMIN_EMAIL="admin\@oopen.de" + +APACHE_CONF_DIR=/usr/local/apache2/conf +APACHE_VHOST_DIR=/usr/local/apache2/conf/vhosts +APACHE_BASE_WEBDIR=/var/www +APACHE_LOG_DIR=/var/log/apache2 + +APACHE_USER=www-data +APACHE_GROUP=www-data + +_use_mod_php=false + +APACHE_SERVER_CERT=server.crt +APACHE_SERVER_KEY=server.key + +## - Leave empty if not needed +## - +CERT_ChainFile=sub.class2.server.ca.pem + + +## - adm.oopen.de +IPV4=83.223.86.91 +IPV6=2a01:30:0:13:2f7:50ff:fed2:cef7 + +#_pf_admin_version=2.91 +_pf_admin_version=3.0 + +#_db_type='mysql' +_db_type='pgsql' + +_db_name='postfix' +_db_user='postfix' +_db_pass='FKt4z55FxMZp' +#_db_host='localhost' +_db_host='/var/run/postgresql' + +# _encrypt=md5crypt +_encrypt=cleartext + +_spam_folder=Spam + +_autoreply_domain='autoreply.oopen.de' +vacation_user=vacation +vacation_group=vacation + +deleted_maildirs="/var/deleted-maildirs" +deleted_maildomains="/var/deleted-maildomains" + diff --git a/DOC/roundcube/Environments/postfixadmin.env.c.mx.oopen.de b/DOC/roundcube/Environments/postfixadmin.env.c.mx.oopen.de new file mode 100644 index 0000000..a0cbbb8 --- /dev/null +++ b/DOC/roundcube/Environments/postfixadmin.env.c.mx.oopen.de @@ -0,0 +1,60 @@ +## - Postfixadmin environment for server +## - +## - c.mx.oopen.de (adm.initiativenserver.de) +## - + +## ------------------------------- +## - c.mx.oopen.de (adm.initiativenserver.de) + +HOSTNAME=adm.initiativenserver.de +DOMAIN=initiativenserver.de +ADMIN_EMAIL="admin\@initiativenserver.de" + +APACHE_CONF_DIR=/usr/local/apache2/conf +APACHE_VHOST_DIR=/usr/local/apache2/conf/vhosts +APACHE_BASE_WEBDIR=/var/www +APACHE_LOG_DIR=/var/log/apache2 + +APACHE_USER=www-data +APACHE_GROUP=www-data + +_use_mod_php=false + +APACHE_SERVER_CERT=server.crt +APACHE_SERVER_KEY=server.key + +## - Leave empty if not needed +## - +CERT_ChainFile=SSL123_CA_Bundle.pem + + +IPV4=83.223.85.101 +IPV6=2a01:30:1fff:3::101 + +_pf_admin_version=code-1676-trunk + +#_db_type='pgsql' +_db_type='mysql' +_db_name='postfix' +_db_user='postfix' +_db_pass='AeB4kohyie5rahJ7' +#_db_host='/var/run/postgresql' +_db_host='localhost' + +_mysql_rootuser=root +_mysql_rootpass=buz111 + + +# _encrypt=md5crypt +_encrypt=cleartext + +#_spam_folder=Spam +_spam_folder=Junk + +_autoreply_domain='autoreply.initiativenserver.de' +vacation_user=vacation +vacation_group=vacation + +deleted_maildirs="/var/deleted-maildirs" +deleted_maildomains="/var/deleted-maildomains" + diff --git a/DOC/roundcube/Environments/postfixadmin.env.mail.interventionistische-linke.org b/DOC/roundcube/Environments/postfixadmin.env.mail.interventionistische-linke.org new file mode 100644 index 0000000..38dbd9e --- /dev/null +++ b/DOC/roundcube/Environments/postfixadmin.env.mail.interventionistische-linke.org @@ -0,0 +1,65 @@ +## - Postfixadmin environment for server +## - +## - adm.interventionistische-linke.org +## - + +## -------------------------------------------------------------------------- +## - mail.interventionistische-linke.org (adm.interventionistische-linke.org) + +HOSTNAME=adm.interventionistische-linke.org +DOMAIN=interventionistische-linke.org +ADMIN_EMAIL="support\@interventionistische-linke.org" + +APACHE_CONF_DIR=/usr/local/apache2/conf +APACHE_VHOST_DIR=/usr/local/apache2/conf/vhosts +APACHE_BASE_WEBDIR=/var/www +APACHE_LOG_DIR=/var/log/apache2 + +APACHE_USER=www-data +APACHE_GROUP=www-data + +_use_mod_php=false + +APACHE_SERVER_CERT=server.crt +APACHE_SERVER_KEY=server.key + +## - Leave empty if not needed +## - +CERT_ChainFile=sub.class2.server.ca.pem + +IPV4=83.223.85.215 +IPV6=2a01:30:1fff:5::215 + +_pf_admin_version=2.91 + +#_db_type='mysql' +_db_type='pgsql' + +_db_name='postfix' +_db_user='postfix' +_db_pass='NcXxt7sf7bfV' +#_db_host='localhost' +_db_host='/var/run/postgresql' + +_encrypt=md5crypt +#_encrypt=cleartext + +_spam_folder=Spam + +_autoreply_domain='autoreply.interventionistische-linke.org' +vacation_user=vacation +vacation_group=vacation + +deleted_maildirs="/data/deleted-maildirs" +deleted_maildomains="/data/deleted-maildomains" + +_welcome_email=" +Hallo, + +Deine neue E-Mail Adresse ist eingerichtet. + +- IL - Interventionistische Linke + +-- +e: support@interventionistische-linke.org" + diff --git a/DOC/roundcube/Environments/postfixadmin.env.mx.warenform.de b/DOC/roundcube/Environments/postfixadmin.env.mx.warenform.de new file mode 100644 index 0000000..742859e --- /dev/null +++ b/DOC/roundcube/Environments/postfixadmin.env.mx.warenform.de @@ -0,0 +1,68 @@ +## - Postfixadmin environment for server +## - +## - mx.warenform.de (adm.warenform.de) +## - + +## ------------------------------------- +## - mx.warenform.de (adm.warenform.de) + +HOSTNAME=adm.warenform.de +DOMAIN=warenform.de +ADMIN_EMAIL="admin\@warenform.de" + +APACHE_CONF_DIR=/usr/local/apache2/conf +APACHE_VHOST_DIR=/usr/local/apache2/conf/vhosts +APACHE_BASE_WEBDIR=/var/www +APACHE_LOG_DIR=/var/log/apache2 + +APACHE_USER=www-data +APACHE_GROUP=www-data + +_use_mod_php=false + +APACHE_SERVER_CERT=server.crt +APACHE_SERVER_KEY=server.key + +## - Leave empty if not needed +## - +CERT_ChainFile=SSL123_CA_Bundle.pem + +IPV4=83.223.85.154 +IPV6=2a01:30:1fff:6::154 + +#_pf_admin_version=2.3.7 +_pf_admin_version=2.91 + +#_db_type='mysql' +_db_type='pgsql' + +_db_name='postfix' +_db_user='postfix' +_db_pass='CbX8vg347Vvm' +#_db_host='localhost' +_db_host='/var/run/postgresql' + +# _encrypt=md5crypt +_encrypt=cleartext + +_spam_folder=Spam + +_autoreply_domain='autoreply.warenform.de' +vacation_user=vacation +vacation_group=vacation + +deleted_maildirs="/var/deleted-maildirs" +deleted_maildomains="/var/deleted-maildomains" + +_welcome_email=" +Hallo, + +Ihre neue E-Mail Adresse ist eingerichtet. + +Das WARENFORM-Team + +-- +WARENFORM | Phone: +49 30 / 61 65 17 52 -0 +Dresdner Str. 11 | Fax: +49 30 / 61 65 17 52 -66 +D-10999 Berlin | http://www.warenform.net" + diff --git a/DOC/roundcube/Environments/postfixadmin.env.rage.so36.net b/DOC/roundcube/Environments/postfixadmin.env.rage.so36.net new file mode 100644 index 0000000..f8234ac --- /dev/null +++ b/DOC/roundcube/Environments/postfixadmin.env.rage.so36.net @@ -0,0 +1,65 @@ +## - Postfixadmin environment for server +## - +## - rage.so36.net (adm.so36.net) +## - + +## ------------------------------- +## - rage.so36.net (adm.so36.net) + +HOSTNAME=adm.so36.net +DOMAIN=so36.net +ADMIN_EMAIL="support\@so36.net" + +APACHE_CONF_DIR=/etc/apache2 +APACHE_VHOST_DIR=/etc/apache2/sites-available +APACHE_BASE_WEBDIR=/var/www +APACHE_LOG_DIR=/var/log/apache2 + +APACHE_USER=www-data +APACHE_GROUP=www-data + +_use_mod_php=false + +APACHE_SERVER_CERT=server.crt +APACHE_SERVER_KEY=server.key + +## - Leave empty if not needed +## - +CERT_ChainFile=sub.class2.server.ca.pem + +IPV4=83.223.73.193 +IPV6=2a01:30:1fff:fd00::193 + +_pf_admin_version=2.3.7 + +#_db_type='mysql' +_db_type='pgsql' + +_db_name='postfix' +_db_user='postfix' +_db_pass='9jKqFHNGrgFb' +#_db_host='localhost' +_db_host='/var/run/postgresql' + +_encrypt=md5crypt +#_encrypt=cleartext + +_spam_folder=Spam + +_autoreply_domain='autoreply.so36.net' +vacation_user=vacation +vacation_group=vacation + +deleted_maildirs="/data/deleted-maildirs" +deleted_maildomains="/data/deleted-maildomains" + +_welcome_email=" +Hallo, + +Deine neue E-Mail Adresse ist eingerichtet. + +- so36.NET + +-- +e: support@so36.net" + diff --git a/DOC/roundcube/Environments/roundcube.env.webmail.initiativenserver.de b/DOC/roundcube/Environments/roundcube.env.webmail.initiativenserver.de new file mode 100644 index 0000000..b220de8 --- /dev/null +++ b/DOC/roundcube/Environments/roundcube.env.webmail.initiativenserver.de @@ -0,0 +1,69 @@ +## - Rounfcube environment for server +## - +## - c.mx.oopen.de (webmail.initiativenserver.de) +## - + +## - webmail.initiativenserver.de +## - +SRC_BASE_DIR=/usr/local/src/mailsystem +SRC_ARCHIVE_DIR=${SRC_BASE_DIR}/tarballs + +ROUNDCUBE_VERSION=1.1.3 + +SPAM_FOLDER_NAME=Junk + +WEBSITE=webmail.initiativenserver.de + +IPV4=83.223.85.101 +IPV6=2a01:30:1fff:3::101 + +WEBMASTER_EMAIL=admin@oopen.de +WEBMAIL_BASEDIR=/var/www/webmail.initiativenserver.de +WEBMAIL_TMPDIR=${WEBMAIL_BASEDIR}/temp + +WEBSERVER_USER=www-data +WEBSERVER_GROUP=www-data + +APACHE_LOG_DIR=${WEBMAIL_BASEDIR}/logs + +APACHE_SERVER_CERT=server.crt +APACHE_SERVER_KEY=server.key + +## - Leave empty if not needed +## - +CERT_ChainFile=sub.class2.server.ca.pem + + +## - apache installed from debian package system ? +## - +_apache_debian=false + +## - if installed from source, specify vhost directory +## - +_vhost_dir=/usr/local/apache2/conf/vhosts +_apache_cert_dir=/usr/local/apache2/conf + +if $_apache_debian ; then + _vhost_dir=/etc/apache2/sites-available + _apache_cert_dir=/etc/apache2 +fi + +_SSLCertificateChainFile="" +if [ -n "$CERT_ChainFile" ];then + _SSLCertificateChainFile="SSLCertificateChainFile ${_apache_cert_dir}/$CERT_ChainFile" +fi + +_autoreply_domain=autoreply.oopen.de + +#_db_type=pgsql +_db_type=mysql + +_db_host=localhost +_db_user=roundcube +_db_pass=re6Xe8Fereejai3D + +#_mysql_rootuser=root +#_mysql_rootpass= +## - +## - END: webmail.initiativenserver.de + diff --git a/DOC/roundcube/Environments/roundcube.env.webmail.interventionistische-linke.org b/DOC/roundcube/Environments/roundcube.env.webmail.interventionistische-linke.org new file mode 100644 index 0000000..f2cf7f3 --- /dev/null +++ b/DOC/roundcube/Environments/roundcube.env.webmail.interventionistische-linke.org @@ -0,0 +1,69 @@ +## - Rounfcube environment for server +## - +## - webmail.interventionistische-linke.org (webmail.interventionistische-linke.org) +## - + +## - webmail.interventionistische-linke.org +## - +SRC_BASE_DIR=/usr/local/src/mailsystem +SRC_ARCHIVE_DIR=${SRC_BASE_DIR}/tarballs + +ROUNDCUBE_VERSION=1.1.3 + +SPAM_FOLDER_NAME=SPAM + +WEBSITE=webmail.interventionistische-linke.org + +IPV4=83.223.73.211 +IPV6=2a01:30:1fff:fd00::194 + +WEBMASTER_EMAIL=admin@oopen.de +WEBMAIL_BASEDIR=/var/www/webmail.interventionistische-linke.org +WEBMAIL_TMPDIR=${WEBMAIL_BASEDIR}/temp + +WEBSERVER_USER=www-data +WEBSERVER_GROUP=www-data + +APACHE_LOG_DIR=${WEBMAIL_BASEDIR}/logs + +APACHE_SERVER_CERT=server.crt +APACHE_SERVER_KEY=server.key + +## - Leave empty if not needed +## - +CERT_ChainFile=sub.class2.server.ca.pem + + +## - apache installed from debian package system ? +## - +_apache_debian=true + +## - if installed from source, specify vhost directory +## - +_vhost_dir=/usr/local/apache2/conf/vhosts +_apache_cert_dir=/usr/local/apache2/conf + +if $_apache_debian ; then + _vhost_dir=/etc/apache2/sites-available + _apache_cert_dir=/etc/apache2 +fi + +_SSLCertificateChainFile="" +if [ -n "$CERT_ChainFile" ];then + _SSLCertificateChainFile="SSLCertificateChainFile ${_apache_cert_dir}/$CERT_ChainFile" +fi + +_autoreply_domain=autoreply.interventionistische-linke.org + +_db_type=pgsql +#_db_type=mysql + +_db_host=localhost +_db_user=roundcube +_db_pass=MjXQJpR9SvcX + +#_mysql_rootuser=root +#_mysql_rootpass= +## - +## - END: webmail.interventionistische-linke.org + diff --git a/DOC/roundcube/Environments/roundcube.env.webmail.oopen.de b/DOC/roundcube/Environments/roundcube.env.webmail.oopen.de new file mode 100644 index 0000000..5b7cdca --- /dev/null +++ b/DOC/roundcube/Environments/roundcube.env.webmail.oopen.de @@ -0,0 +1,74 @@ +## - Rounfcube environment for server +## - +## - a.mx.oopen.de (webmail.oopen.de) +## - + +## ---------------------- +## - webmail.oopen.de +## - +SRC_BASE_DIR=/usr/local/src/mailsystem +SRC_ARCHIVE_DIR=${SRC_BASE_DIR}/tarballs + +ROUNDCUBE_VERSION=1.2.2 + +SPAM_FOLDER_NAME=Spam + +WEBSITE=webmail.oopen.de + +IPV4=83.223.86.91 +IPV6=2a01:30:0:13:2f7:50ff:fed2:cef7 + +WEBMASTER_EMAIL=admin@oopen.de +WEBMAIL_BASEDIR=/var/www/webmail.oopen.de +WEBMAIL_TMPDIR=${WEBMAIL_BASEDIR}/temp + +WEBSERVER_USER=www-data +WEBSERVER_GROUP=www-data + +APACHE_LOG_DIR=${WEBMAIL_BASEDIR}/logs + +#APACHE_SERVER_CERT=webmail.oopen.de-bundle.crt +#APACHE_SERVER_KEY=webmail.oopen.de.key +APACHE_SERVER_CERT=server-bundle.crt +APACHE_SERVER_KEY=server.key + +_use_mod_php=false + +## - Leave empty if not needed +## - +#CERT_ChainFile= + + +## - apache installed from debian package system ? +## - +_apache_debian=false + +## - if installed from source, specify vhost directory +## - +_vhost_dir=/usr/local/apache2/conf/vhosts +_apache_cert_dir=/usr/local/apache2/conf + +if $_apache_debian ; then + _vhost_dir=/etc/apache2/sites-available + _apache_cert_dir=/etc/apache2 +fi + +_SSLCertificateChainFile="" +if [ -n "$CERT_ChainFile" ];then + _SSLCertificateChainFile="SSLCertificateChainFile ${_apache_cert_dir}/$CERT_ChainFile" +fi + +_autoreply_domain=autoreply.oopen.de + +_db_type=pgsql +#_db_type=mysql + +_db_host=localhost +_db_user=roundcube +_db_pass=3Dsz3j5R +_db_name=roundcubemail + +#_mysql_rootuser=root +#_mysql_rootpass= +## - +## - END: webmail.oopen.de diff --git a/DOC/roundcube/Environments/roundcube.env.webmail.so36.net b/DOC/roundcube/Environments/roundcube.env.webmail.so36.net new file mode 100644 index 0000000..df1ba81 --- /dev/null +++ b/DOC/roundcube/Environments/roundcube.env.webmail.so36.net @@ -0,0 +1,69 @@ +## - Rounfcube environment for server +## - +## - rage.so36.net (webmail.so36.net) +## - + +## - webmail.oopen.de +## - +SRC_BASE_DIR=/usr/local/src/mailsystem +SRC_ARCHIVE_DIR=${SRC_BASE_DIR}/tarballs + +ROUNDCUBE_VERSION=1.1.3 + +SPAM_FOLDER_NAME=SPAM + +WEBSITE=webmail.so36.net + +IPV4=83.223.73.211 +IPV6=2a01:30:1fff:fd00::194 + +WEBMASTER_EMAIL=roots@so36.net +WEBMAIL_BASEDIR=/var/www/webmail.so36.net +WEBMAIL_TMPDIR=${WEBMAIL_BASEDIR}/temp + +WEBSERVER_USER=www-data +WEBSERVER_GROUP=www-data + +APACHE_LOG_DIR=${WEBMAIL_BASEDIR}/logs + +APACHE_SERVER_CERT=server.crt +APACHE_SERVER_KEY=server.key + +## - Leave empty if not needed +## - +CERT_ChainFile=sub.class2.server.ca.pem + + +## - apache installed from debian package system ? +## - +_apache_debian=true + +## - if installed from source, specify vhost directory +## - +_vhost_dir=/usr/local/apache2/conf/vhosts +_apache_cert_dir=/usr/local/apache2/conf + +if $_apache_debian ; then + _vhost_dir=/etc/apache2/sites-available + _apache_cert_dir=/etc/apache2 +fi + +_SSLCertificateChainFile="" +if [ -n "$CERT_ChainFile" ];then + _SSLCertificateChainFile="SSLCertificateChainFile ${_apache_cert_dir}/$CERT_ChainFile" +fi + +_autoreply_domain=autoreply.so36.net + +_db_type=pgsql +#_db_type=mysql + +_db_host=localhost +_db_user=roundcube +_db_pass=MjXQJpR9SvcX + +#_mysql_rootuser=root +#_mysql_rootpass= +## - +## - END: webmail.so36.net + diff --git a/DOC/roundcube/Environments/roundcube.env.webmail.warenform.de b/DOC/roundcube/Environments/roundcube.env.webmail.warenform.de new file mode 100644 index 0000000..88e782a --- /dev/null +++ b/DOC/roundcube/Environments/roundcube.env.webmail.warenform.de @@ -0,0 +1,72 @@ +## - Rounfcube environment for server +## - +## - mx.warenform.de (webmail.warenform.de) +## - + +## ---------------------- +## - webmail.warenform.de +## - +SRC_BASE_DIR=/usr/local/src/mailsystem +SRC_ARCHIVE_DIR=${SRC_BASE_DIR}/tarballs + +#ROUNDCUBE_VERSION=0.9.5 +ROUNDCUBE_VERSION=1.0.1 + +SPAM_FOLDER_NAME=SPAM + +WEBSITE=webmail.warenform.de + +IPV4=83.223.85.154 +IPV6=2a01:30:1fff:6::154 + +WEBMASTER_EMAIL=admin@warenform.de +WEBMAIL_BASEDIR=/var/www/webmail.warenform.de +WEBMAIL_TMPDIR=${WEBMAIL_BASEDIR}/temp + +WEBSERVER_USER=www-data +WEBSERVER_GROUP=www-data + +APACHE_LOG_DIR=/var/log/apache2 + +APACHE_SERVER_CERT=server.crt +APACHE_SERVER_KEY=server.key + +_use_mod_php=false + +## - Leave empty if not needed +## - +CERT_ChainFile=SSL123_CA_Bundle.pem + + +## - apache installed from debian package system ? +## - +_apache_debian=false + +## - if installed from source, specify vhost directory +## - +_vhost_dir=/usr/local/apache2/conf/vhosts +_apache_cert_dir=/usr/local/apache2/conf + +if $_apache_debian ; then + _vhost_dir=/etc/apache2/sites-available + _apache_cert_dir=/etc/apache2 +fi + +_SSLCertificateChainFile="" +if [ -n "$CERT_ChainFile" ];then + _SSLCertificateChainFile="SSLCertificateChainFile ${_apache_cert_dir}/$CERT_ChainFile" +fi + +_autoreply_domain=autoreply.warenform.de + +_db_type=pgsql +#_db_type=mysql + +_db_host=localhost +_db_user=roundcube +_db_pass=Hoo5heis +_db_name=roundcubemail + +#_mysql_rootuser=root +#_mysql_rootpass= + diff --git a/DOC/roundcube/Environments/roundcube.env.webmail2.initiativenserver.de b/DOC/roundcube/Environments/roundcube.env.webmail2.initiativenserver.de new file mode 100644 index 0000000..eae98f5 --- /dev/null +++ b/DOC/roundcube/Environments/roundcube.env.webmail2.initiativenserver.de @@ -0,0 +1,69 @@ +## - Rounfcube environment for server +## - +## - c.mx.oopen.de (webmail2.initiativenserver.de) +## - + +## - webmail2.initiativenserver.de +## - +SRC_BASE_DIR=/usr/local/src/mailsystem +SRC_ARCHIVE_DIR=${SRC_BASE_DIR}/tarballs + +ROUNDCUBE_VERSION=1.1.3 + +SPAM_FOLDER_NAME=Junk + +WEBSITE=webmail2.initiativenserver.de + +IPV4=83.223.85.101 +IPV6=2a01:30:1fff:3::101 + +WEBMASTER_EMAIL=admin@oopen.de +WEBMAIL_BASEDIR=/var/www/webmail2.initiativenserver.de +WEBMAIL_TMPDIR=${WEBMAIL_BASEDIR}/temp + +WEBSERVER_USER=www-data +WEBSERVER_GROUP=www-data + +APACHE_LOG_DIR=${WEBMAIL_BASEDIR}/logs + +APACHE_SERVER_CERT=server.crt +APACHE_SERVER_KEY=server.key + +## - Leave empty if not needed +## - +CERT_ChainFile=sub.class2.server.ca.pem + + +## - apache installed from debian package system ? +## - +_apache_debian=false + +## - if installed from source, specify vhost directory +## - +_vhost_dir=/usr/local/apache2/conf/vhosts +_apache_cert_dir=/usr/local/apache2/conf + +if $_apache_debian ; then + _vhost_dir=/etc/apache2/sites-available + _apache_cert_dir=/etc/apache2 +fi + +_SSLCertificateChainFile="" +if [ -n "$CERT_ChainFile" ];then + _SSLCertificateChainFile="SSLCertificateChainFile ${_apache_cert_dir}/$CERT_ChainFile" +fi + +_autoreply_domain=autoreply.oopen.de + +#_db_type=pgsql +_db_type=mysql + +_db_host=localhost +_db_user=roundcube +_db_pass=re6Xe8Fereejai3D + +#_mysql_rootuser=root +#_mysql_rootpass= +## - +## - END: webmail2.initiativenserver.de + diff --git a/DOC/roundcube/Environments/roundcube.env.webmail2.oopen.de b/DOC/roundcube/Environments/roundcube.env.webmail2.oopen.de new file mode 100644 index 0000000..96433c4 --- /dev/null +++ b/DOC/roundcube/Environments/roundcube.env.webmail2.oopen.de @@ -0,0 +1,72 @@ +## - Rounfcube environment for server +## - +## - a.mx.oopen.de (webmail2.oopen.de) +## - + +## ---------------------- +## - webmail2.oopen.de +## - +SRC_BASE_DIR=/usr/local/src/mailsystem +SRC_ARCHIVE_DIR=${SRC_BASE_DIR}/tarballs + +ROUNDCUBE_VERSION=1.1.4 + +SPAM_FOLDER_NAME=Spam + +WEBSITE=webmail2.oopen.de + +IPV4=83.223.85.165 +IPV6=2a01:30:1fff:9::165 + +WEBMASTER_EMAIL=admin@oopen.de +WEBMAIL_BASEDIR=/var/www/webmail2.oopen.de +WEBMAIL_TMPDIR=${WEBMAIL_BASEDIR}/temp + +WEBSERVER_USER=www-data +WEBSERVER_GROUP=www-data + +APACHE_LOG_DIR=${WEBMAIL_BASEDIR}/logs + +APACHE_SERVER_CERT=wildcard.oopen.de-bundle.crt +APACHE_SERVER_KEY=wildcard.oopen.de.key + +_use_mod_php=false + +## - Leave empty if not needed +## - +#CERT_ChainFile= + + +## - apache installed from debian package system ? +## - +_apache_debian=false + +## - if installed from source, specify vhost directory +## - +_vhost_dir=/usr/local/apache2/conf/vhosts +_apache_cert_dir=/usr/local/apache2/conf + +if $_apache_debian ; then + _vhost_dir=/etc/apache2/sites-available + _apache_cert_dir=/etc/apache2 +fi + +_SSLCertificateChainFile="" +if [ -n "$CERT_ChainFile" ];then + _SSLCertificateChainFile="SSLCertificateChainFile ${_apache_cert_dir}/$CERT_ChainFile" +fi + +_autoreply_domain=autoreply.oopen.de + +_db_type=pgsql +#_db_type=mysql + +_db_host=localhost +_db_user=roundcube +_db_pass=3Dsz3j5R +_db_name=roundcubemail2 + +#_mysql_rootuser=root +#_mysql_rootpass= +## - +## - END: webmail2.oopen.de diff --git a/DOC/roundcube/Environments/roundcube.env.webmail2.warenform.de b/DOC/roundcube/Environments/roundcube.env.webmail2.warenform.de new file mode 100644 index 0000000..fb54819 --- /dev/null +++ b/DOC/roundcube/Environments/roundcube.env.webmail2.warenform.de @@ -0,0 +1,71 @@ +## - Rounfcube environment for server +## - +## - mx.warenform.de (webmail2.warenform.de) +## - + +## ---------------------- +## - webmail.warenform.de +## - +SRC_BASE_DIR=/usr/local/src/mailsystem +SRC_ARCHIVE_DIR=${SRC_BASE_DIR}/tarballs + +ROUNDCUBE_VERSION=1.1.1 + +SPAM_FOLDER_NAME=SPAM + +WEBSITE=webmail2.warenform.de + +IPV4=83.223.85.154 +IPV6=2a01:30:1fff:6::154 + +WEBMASTER_EMAIL=admin@warenform.de +WEBMAIL_BASEDIR=/var/www/webmail2.warenform.de +WEBMAIL_TMPDIR=${WEBMAIL_BASEDIR}/temp + +WEBSERVER_USER=www-data +WEBSERVER_GROUP=www-data + +APACHE_LOG_DIR=/var/log/apache2 + +APACHE_SERVER_CERT=server.crt +APACHE_SERVER_KEY=server.key + +_use_mod_php=false + +## - Leave empty if not needed +## - +#CERT_ChainFile=SSL123_CA_Bundle.pem + + +## - apache installed from debian package system ? +## - +_apache_debian=false + +## - if installed from source, specify vhost directory +## - +_vhost_dir=/usr/local/apache2/conf/vhosts +_apache_cert_dir=/usr/local/apache2/conf + +if $_apache_debian ; then + _vhost_dir=/etc/apache2/sites-available + _apache_cert_dir=/etc/apache2 +fi + +_SSLCertificateChainFile="" +if [ -n "$CERT_ChainFile" ];then + _SSLCertificateChainFile="SSLCertificateChainFile ${_apache_cert_dir}/$CERT_ChainFile" +fi + +_autoreply_domain=autoreply.warenform.de + +_db_type=pgsql +#_db_type=mysql + +_db_host=localhost +_db_user=roundcube +_db_pass=Hoo5heis +_db_name=roundcubemail2 + +#_mysql_rootuser=root +#_mysql_rootpass= + diff --git a/DOC/roundcube/roundcube.install b/DOC/roundcube/roundcube.install new file mode 100644 index 0000000..cba9705 --- /dev/null +++ b/DOC/roundcube/roundcube.install @@ -0,0 +1,2122 @@ + +## ----------------------------------- ## +## --- install roundcube Webmailer --- ## +## ----------------------------------- ## + +## ---------------------- +## - webmail.warenform.de +## - + +. roundcube.env.webmail.warenform.de + +## - +## - END: webmail.warenform.de +## ---------------------------- + + +## ------------------ +## - webmail.oopen.de +## - + +. roundcube.env.webmail.oopen.de + +## - +## - END: webmail.oopen.de +## ----------------------- + + +## --------------------------------------- +## - webmail.interventionistische-linke.org +## - + +. roundcube.env.webmail.interventionistische-linke.org + +## - +## - END: webmail.interventionistische-linke.org +## --------------------------------------------- + + +## ---------------------------- +## - Begin Installation + +## - REQUIREMENTS +## - ============ +## - +## - * The Apache, Lighttpd, Cherokee or Hiawatha web server +## - * .htaccess support allowing overrides for DirectoryIndex +## - * PHP Version 5.2.1 or greater including +## - - PCRE, DOM, JSON, XML, Session, Sockets (required) +## - - libiconv (recommended) +## - - mbstring, fileinfo, mcrypt (optional) +## - * PEAR packages distributed with Roundcube or external: +## - - MDB2 2.5.0 or newer +## - - Mail_Mime 1.8.1 or newer +## - - Mail_mimeDecode 1.5.5 or newer +## - - Net_SMTP 1.4.2 or newer +## - - Net_IDNA2 0.1.1 or newer +## - - Auth_SASL 1.0.6 or newer +## - * php.ini options (see .htaccess file): +## - - error_reporting E_ALL & ~E_NOTICE (or lower) +## - - memory_limit > 16MB (increase as suitable to support large attachments) +## - - file_uploads enabled (for attachment upload features) +## - - session.auto_start disabled +## - - zend.ze1_compatibility_mode disabled +## - - suhosin.session.encrypt disabled +## - - mbstring.func_overload disabled +## - - magic_quotes_runtime disabled +## - - magic_quotes_sybase disabled +## - * PHP compiled with OpenSSL to connect to IMAPS and to use the spell checker +## - * A MySQL (4.0.8 or newer), PostgreSQL, MSSQL database engine +## - or the SQLite extension for PHP +## - * One of the above databases with permission to create tables +## - * An SMTP server (recommended) or PHP configured for mail delivery + +## - install php PEAR packages +## - +## - !! Take care to do this for all php installations (PHP 5.5/5.6/..) +## - + +_php_major_versions=`find /usr/local/ -maxdepth 1 -mindepth 1 -type l -name "php-*" -print | cut -d "-" -f2 | sort` +for _version in $_php_major_versions ; do + rm /usr/local/php + ln -s /usr/local/php-$_version /usr/local/php + + pear install MDB2 + + if [ "$_db_type" = "pgsql" ]; then + pear install MDB2_Driver_pgsql + elif [ "$_db_type" = "mysql" ];then + pear install MDB2_Driver_mysql + pear install MDB2_Driver_mysqli + else + echo -e "\n\t[ ERROR ]: Unknown database type \"$_db_type\"\n\n" + fi + + pear install Mail_Mime + pear install Mail_mimeDecode + pear install Net_SMTP + #pear install Net_IDNA2 + pear install channel://pear.php.net/Net_IDNA2-0.1.1 + #pear install Auth_SASL + #pear install Auth_SASL2 + pear install channel://pear.php.net/Auth_SASL2-0.1.0 + +done + +mkdir -p $WEBMAIL_BASEDIR/{sessions,tmp,temp,logs} +chown ${WEBSERVER_USER}:${WEBSERVER_GROUP} ${WEBMAIL_BASEDIR}/{sessions,tmp} + + + +if ! $_use_mod_php ; then + mkdir -p ${WEBMAIL_BASEDIR}/conf + chown root:$WEBSERVER_USER ${WEBMAIL_BASEDIR}/conf + chmod 750 ${WEBMAIL_BASEDIR}/conf + + _php_major_versions=`find /usr/local/ -maxdepth 1 -mindepth 1 -type l -name "php-*" -print | cut -d "-" -f2 | sort` + for _version in $_php_major_versions ; do + cp /usr/local/php-${_version}/etc/php.ini ${WEBMAIL_BASEDIR}/conf/php.ini-$_version + + chown root:$WEBSERVER_USER ${WEBMAIL_BASEDIR}/conf/php.ini-$_version + chmod 640 ${WEBMAIL_BASEDIR}/conf/php.ini-$_version + + cat < ${WEBMAIL_BASEDIR}/conf/fcgid-$_version +#!/bin/sh +export PHPRC="${WEBMAIL_BASEDIR}/conf/" +export TMPDIR="${WEBMAIL_BASEDIR}/tmp" +# PHP child process management (PHP_FCGI_CHILDREN) should +# always be disabled with mod_fcgid, which will only route one +# request at a time to application processes it has spawned; +# thus, any child processes created by PHP will not be used +# effectively. (Additionally, the PHP child processes may not +# be terminated properly.) By default, and with the environment +# variable setting PHP_FCGI_CHILDREN=0, PHP child process +# management is disabled. +PHP_FCGI_CHILDREN=0 +export PHP_FCGI_CHILDREN + +exec /usr/local/php-${_version}/bin/php-cgi +EOF + + chown root:$WEBSERVER_USER ${WEBMAIL_BASEDIR}/conf/fcgid-$_version + chmod 750 ${WEBMAIL_BASEDIR}/conf/fcgid-$_version + done + + ln -s php.ini-$_version ${WEBMAIL_BASEDIR}/conf/php.ini + ln -s fcgid-$_version ${WEBMAIL_BASEDIR}/conf/fcgid + + cat << EOF > ${WEBMAIL_BASEDIR}/conf/changes.php.ini.txt +error_log = "${WEBMAIL_BASEDIR}/logs/php_errors.log" +sys_temp_dir = "${WEBMAIL_BASEDIR}/tmp" +upload_tmp_dir = "${WEBMAIL_BASEDIR}/tmp" +session.save_path = "${WEBMAIL_BASEDIR}/sessions" +soap.wsdl_cache_dir = "${WEBMAIL_BASEDIR}/tmp" +EOF + + touch ${WEBMAIL_BASEDIR}/logs/php_errors.log + chown ${WEBSERVER_USER}:${WEBSERVER_GROUP} ${WEBMAIL_BASEDIR}/logs/php_errors.log + + _php_ini_file="${WEBMAIL_BASEDIR}/conf/php.ini-*" + + _key=error_log + _val="${WEBMAIL_BASEDIR}/logs/php_errors.log" + if grep -e "^\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + #sed -i "0,/^\([ \t]*${_key}[ \t]*=.*\)/ s##;\1\n${_key} = \"${_val}\"#" $_php_ini_file + perl -i -n -p -e "s#^(\s*${_key}\s*=.*)#;\1\n${_key} = ${_val}#" $_php_ini_file + _retval=$? + elif grep -e "^\s*;\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + sed -i "0,/^\([ \t]*;[ \t]*${_key}[ \t]*=.*\)/ s##\1\n${_key} = \"${_val}\"\n#" $_php_ini_file + _retval=$? + fi + + _key="sys_temp_dir" + _val="${WEBMAIL_BASEDIR}/tmp" + _key="sys_temp_dir" + _val="${WEBMAIL_BASEDIR}/tmp" + if grep -e "^\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + #sed -i "0,/^\([ \t]*${_key}[ \t]*=.*\)/ s##;\1\n${_key} = \"${_val}\"#" $_php_ini_file + perl -i -n -p -e "s#^(\s*${_key}\s*=.*)#;\1\n${_key} = ${_val}#" $_php_ini_file + _retval=$? + elif grep -e "^\s*;\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + sed -i "0,/^\([ \t]*;[ \t]*${_key}[ \t]*=.*\)/ s##\1\n${_key} = \"${_val}\"\n#" $_php_ini_file + _retval=$? + fi + + _key="upload_tmp_dir" + _val="${WEBMAIL_BASEDIR}/tmp" + if grep -e "^\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + #sed -i "0,/^\([ \t]*${_key}[ \t]*=.*\)/ s##;\1\n${_key} = \"${_val}\"#" $_php_ini_file + perl -i -n -p -e "s#^(\s*${_key}\s*=.*)#;\1\n${_key} = ${_val}#" $_php_ini_file + _retval=$? + elif grep -e "^\s*;\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + sed -i "0,/^\([ \t]*;[ \t]*${_key}[ \t]*=.*\)/ s##\1\n${_key} = \"${_val}\"\n#" $_php_ini_file + _retval=$? + fi + + _key="session.save_path" + _val="${WEBMAIL_BASEDIR}/sessions" + if grep -e "^\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + #sed -i "0,/^\([ \t]*${_key}[ \t]*=.*\)/ s##;\1\n${_key} = \"${_val}\"#" $_php_ini_file + perl -i -n -p -e "s#^(\s*${_key}\s*=.*)#;\1\n${_key} = ${_val}#" $_php_ini_file + _retval=$? + elif grep -e "^\s*;\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + sed -i "0,/^\([ \t]*;[ \t]*${_key}[ \t]*=.*\)/ s##\1\n${_key} = \"${_val}\"\n#" $_php_ini_file + _retval=$? + fi + + _key="soap.wsdl_cache_dir" + _val="${WEBMAIL_BASEDIR}/tmp" + if grep -e "^\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + #sed -i "0,/^\([ \t]*${_key}[ \t]*=.*\)/ s##;\1\n${_key} = \"${_val}\"#" $_php_ini_file + perl -i -n -p -e "s#^(\s*${_key}\s*=.*)#;\1\n${_key} = ${_val}#" $_php_ini_file + _retval=$? + elif grep -e "^\s*;\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + sed -i "0,/^\([ \t]*;[ \t]*${_key}[ \t]*=.*\)/ s##\1\n${_key} = \"${_val}\"\n#" $_php_ini_file + _retval=$? + fi + +fi + + + + + + + + + +## - create vhost entry for webmail.warenform.de +## - +if [ -f ${_vhost_dir}/${WEBSITE}.conf ];then + mv ${_vhost_dir}/${WEBSITE}.conf ${_vhost_dir}/${WEBSITE}.conf.`date +%Y%m%d-%H%M` +fi + +cat < ${_vhost_dir}/${WEBSITE}.conf +# -- $WEBSITE -- # + + + + ServerAdmin $WEBMASTER_EMAIL + + ServerName $WEBSITE + + RewriteEngine on + RewriteCond %{HTTPS} !=on + RewriteRule (.*) https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L] + + CustomLog ${APACHE_LOG_DIR}/${WEBSITE}-access.log combined + ErrorLog ${APACHE_LOG_DIR}/${WEBSITE}-error.log + + + + + + + ServerAdmin $WEBMASTER_EMAIL + + ServerName $WEBSITE + +EOF + +if $_use_mod_php ; then + cat <> ${_vhost_dir}/${WEBSITE}.conf + ## - its allowed to overwrite by .htaccess + ## - + php_value error_reporting "E_ALL & ~E_NOTICE" + + ## - Overwriting by .htaccess NOT allowd + ## - + php_admin_value upload_tmp_dir "${WEBMAIL_BASEDIR}/tmp/" + php_admin_flag log_errors on + php_admin_value error_log "${WEBMAIL_BASEDIR}/logs/php_error.log" + php_admin_value session.save_path "${WEBMAIL_BASEDIR}/sessions" + + DocumentRoot "${WEBMAIL_BASEDIR}/htdocs/" +EOF +else + cat <> ${_vhost_dir}/${WEBSITE}.conf + DocumentRoot "${WEBMAIL_BASEDIR}/htdocs/" + + Require all granted + FCGIWrapper ${WEBMAIL_BASEDIR}/conf/fcgid .php + + SetHandler fcgid-script + + Options +ExecCGI + +EOF +fi +cat <> ${_vhost_dir}/${WEBSITE}.conf + + SSLEngine on + + ## - HTTP Strict Transport Security (HSTS) + ## - + ## - HSTS tells a browser that the website should only be accessed through + ## - a secure connection. The HSTS header will be remembered by a standard + ## compliant browser for max-age seconds. + ## - + ## - Remember this settings for 1 year + ## - + Header add Strict-Transport-Security "max-age=31536000" + + SSLCertificateFile ${_apache_cert_dir}/$APACHE_SERVER_CERT + SSLCertificateKeyFile ${_apache_cert_dir}/$APACHE_SERVER_KEY + $_SSLCertificateChainFile + + CustomLog ${APACHE_LOG_DIR}/${WEBSITE}-access.log combined + ErrorLog ${APACHE_LOG_DIR}/${WEBSITE}-error.log + + + + +## - IPv6 +## - + + + ServerAdmin $WEBMASTER_EMAIL + + ServerName $WEBSITE + + RewriteEngine on + RewriteCond %{HTTPS} !=on + RewriteRule (.*) https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L] + + CustomLog ${APACHE_LOG_DIR}/${WEBSITE}-access.log combined + ErrorLog ${APACHE_LOG_DIR}/${WEBSITE}-error.log + + + + + + + ServerAdmin $WEBMASTER_EMAIL + + ServerName $WEBSITE + +EOF + +if $_use_mod_php ; then + + cat <> ${_vhost_dir}/${WEBSITE}.conf + ## - its allowed to overwrite by .htaccess + ## - + php_value error_reporting "E_ALL & ~E_NOTICE" + + ## - Overwriting by .htaccess NOT allowd + ## - + php_admin_value upload_tmp_dir "${WEBMAIL_BASEDIR}/tmp/" + php_admin_flag log_errors on + php_admin_value error_log "${WEBMAIL_BASEDIR}/logs/php_error.log" + php_admin_value session.save_path "${WEBMAIL_BASEDIR}/sessions" + + DocumentRoot "${WEBMAIL_BASEDIR}/htdocs/" +EOF +else + cat <> ${_vhost_dir}/${WEBSITE}.conf + DocumentRoot "${WEBMAIL_BASEDIR}/htdocs/" + + Require all granted + FCGIWrapper ${WEBMAIL_BASEDIR}/conf/fcgid .php + + SetHandler fcgid-script + + Options +ExecCGI + +EOF +fi +cat <> ${_vhost_dir}/${WEBSITE}.conf + + SSLEngine on + + ## - HTTP Strict Transport Security (HSTS) + ## - + ## - HSTS tells a browser that the website should only be accessed through + ## - a secure connection. The HSTS header will be remembered by a standard + ## compliant browser for max-age seconds. + ## - + ## - Remember this settings for 1 year + ## - + Header add Strict-Transport-Security "max-age=31536000" + + SSLCertificateFile ${_apache_cert_dir}/$APACHE_SERVER_CERT + SSLCertificateKeyFile ${_apache_cert_dir}/$APACHE_SERVER_KEY + $_SSLCertificateChainFile + + CustomLog ${APACHE_LOG_DIR}/${WEBSITE}-access.log combined + ErrorLog ${APACHE_LOG_DIR}/${WEBSITE}-error.log + + +EOF + + +## - install roundcube +## - +cd $SRC_ARCHIVE_DIR +if [ ! -f roundcubemail-${ROUNDCUBE_VERSION}.tar.gz ]; then + wget http://downloads.sourceforge.net/project/roundcubemail/roundcubemail/${ROUNDCUBE_VERSION}/roundcubemail-${ROUNDCUBE_VERSION}.tar.gz +fi + +cd $SRC_BASE_DIR +if [ -d roundcubemail-${ROUNDCUBE_VERSION} ];then + mv roundcubemail-${ROUNDCUBE_VERSION} roundcubemail-${ROUNDCUBE_VERSION}.`date +%Y%m%d-%H%M` +fi +gunzip < ${SRC_ARCHIVE_DIR}/roundcubemail-${ROUNDCUBE_VERSION}.tar.gz | tar -xf - + +mkdir -p $WEBMAIL_BASEDIR +cp -a ${SRC_BASE_DIR}/roundcubemail-${ROUNDCUBE_VERSION} $WEBMAIL_BASEDIR/ +chown -R root:root $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION} + +#mkdir -p $WEBMAIL_BASEDIR/{sessions,tmp,temp,logs} +#if [ -h "${WEBMAIL_BASEDIR}/htdocs" ]; then +# rm ${WEBMAIL_BASEDIR}/htdocs +#elif [ -d "${WEBMAIL_BASEDIR}/htdocs" ]; then +# mv ${WEBMAIL_BASEDIR}/htdocs ${WEBMAIL_BASEDIR}/htdocs.`date +%Y%m%d-%H%M` +#elif [ -f "${WEBMAIL_BASEDIR}/htdocs" ]; then +# mv ${WEBMAIL_BASEDIR}/htdocs ${WEBMAIL_BASEDIR}/htdocs.`date +%Y%m%d-%H%M` +#fi + +ln -s roundcubemail-${ROUNDCUBE_VERSION} ${WEBMAIL_BASEDIR}/htdocs + +########################### + +chown -R ${WEBSERVER_USER}:${WEBSERVER_GROUP} $WEBMAIL_BASEDIR/{sessions,temp,tmp,logs} + +if $_apache_debian ; then + ## - add to /etc/apache2/ports.conf + ## - + ## - NameVirtualHost 46.4.73.217:80 + ## - NameVirtualHost [2a01:4f8:140:34c1::4]:80 + ## - Listen 46.4.73.217:80 + ## - Listen [2a01:4f8:140:34c1::4]:80 + ## - + ## - .. + ## - NameVirtualHost 46.4.73.217:443 + ## - NameVirtualHost [2a01:4f8:140:34c1::4]:443 + ## - Listen 46.4.73.217:443 + ## - Listen [2a01:4f8:140:34c1::4]:443 + ## - + ## - .. + vim /etc/apache2/ports.conf + + + ## - enable site webmail.warenform.de + ## - + a2ensite ${WEBSITE}.conf + /etc/init.d/apache2 reload +else + /etc/init.d/apache2 restart +fi + +## - install a cronjob for cleaning up tmp-directory +## - +crontab -l > /tmp/tmp_crontab +echo "" >> /tmp/tmp_crontab +echo "## - cleanup temp directory of the webmailer" >> /tmp/tmp_crontab +echo "## -" >> /tmp/tmp_crontab +echo "23 3 * * * find $WEBMAIL_BASEDIR/tmp -type f -mtime +1 -exec rm -f {} \;" >> /tmp/tmp_crontab +crontab /tmp/tmp_crontab +rm /tmp/tmp_crontab + + +## - logrotate logfiles from webmailer, locatet at $WEBMAIL_BASEDIR/logs +## - +cat < /etc/logrotate.d/roundcube +$WEBMAIL_BASEDIR/logs/errors +$WEBMAIL_BASEDIR/logs/sql +$WEBMAIL_BASEDIR/logs/sendmail +$WEBMAIL_BASEDIR/logs/*.log { + daily + start 0 + rotate 7 + missingok + notifempty + compress + delaycompress + create 640 www-data www-data + copytruncate +} +EOF + + +## - + + +## - Datenbank etstellen: +## - +## - MySQL/PostgreSQL Datenbank erstellen +## - +## - + +if [ "$_db_type" = "mysql" ]; then + if ! mysql -u$_mysql_rootuser -p$_mysql_rootpass -N -s -e \ + "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '$_db_name'" 2>/dev/null \ + | grep $_db_name > /dev/null 2>&1 ; then + mysql -u$_mysql_rootuser -p$_mysql_rootpass -N -s -e \ + "CREATE DATABASE IF NOT EXISTS $_db_name CHARACTER SET utf8 COLLATE utf8_general_ci" + mysql -u$_mysql_rootuser -p$_mysql_rootpass -N -s -e \ + "GRANT ALL ON $_db_name.* TO '$_db_user'@'localhost' IDENTIFIED BY '$_db_pass'" + mysql -u$_mysql_rootuser -p$_mysql_rootpass -N -s -e "FLUSH PRIVILEGES" + fi +elif [ "$_db_type" = "pgsql" ]; then + count=`su - postgres -c "psql -q -A -t -l" | grep -c -e "^$_db_name"` + if [ $count -eq 0 ];then + echo "CREATE ROLE $_db_user WITH LOGIN NOCREATEDB NOCREATEROLE NOSUPERUSER ENCRYPTED PASSWORD '$_db_pass'" \ + | su - postgres -c "psql" > /dev/null + su - postgres -c "createdb -E utf8 -O $_db_user $_db_name" + fi +fi + + +## - run roundcube installer in webbrowser +## - +## - change: +## - +## - General configuration: +## - +## - temp_dir -> $WEBMAIL_TMPDIR +## - i.e. /var/www/webmail2.oopen.de/temp/ +## - +## - Logging and Debugging: + +## - log_dir -> /logs/ +## - i.e. /var/www/webmail2.oopen.de/logs/ +## - +## - Database setup as needed +## - +## - IMAP Settings: +## - +## - default_host -> localhost +## - default_port -> 143 +## - junk_mbox -> as needed i.e. Spam +## - +## - SMTP Settings +## - +## - smtp_server -> localhost +## - smtp_port -> 25 +## - smtp_user/smtp_pass -> [x] Use the current IMAP username and password for SMTP authentication +## - +## - Display settings & user prefs +## - +## - language -> de_DE +## - skin -> classic +## - +http://${WEBSITE}/installer +cat <>$WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/config.inc.php + +// ================================== +// Added after basic installation +// ================================== + +// ---------------------------------- +// SYSTEM +// ---------------------------------- + +// Allow browser-autocompletion on login form. +// 0 - disabled, 1 - username and host only, 2 - username, host, password +\$config['login_autocomplete'] = 1; + +// Path to a local mime magic database file for PHPs finfo extension. +// Set to null if the default path should be used. +\$config['mime_magic'] = '/usr/share/misc/magic'; + + +// ---------------------------------- +// USER PREFERENCES +// ---------------------------------- + +// Clear Trash on logout +\$config['logout_purge'] = true; + +// 'Delete always' +// This setting reflects if mail should be always deleted +// when moving to Trash fails. This is necessary in some setups +// when user is over quota and Trash is included in the quota. +\$config['delete_always'] = true; + +EOF + + +## - edit $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}//program/localization/de_DE/labels.inc +## - $labels['welcome'] = 'Login $product'; +## - +vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}//program/localization/de_DE/labels.inc + +## - to display/print the logo if a message is printed +## - +## - edit skins/default/print.css +## - +## - add to section "#header" +## - visibility: hidden; +## - + + +## -------- +## - Enable Spellchecking +## - +## - i.e for languages +## - English Deutsch Dansk Français Italiano Español +## - +apt-get install aspell-en aspell-de aspell-da aspell-es aspell-fr aspell-it + +## - In config.inc.pgp add/change: +## - +## - // Make use of the built-in spell checker. It is based on GoogieSpell. +## - // Since Google only accepts connections over https your PHP installatation +## - // requires to be compiled with Open SSL support +## - $config['enable_spellcheck'] = true; +## - +## - // Set the spell checking engine. Possible values: +## - // - 'googie' - the default +## - // - 'pspell' - requires the PHP Pspell module and aspell installed +## - // - 'enchant' - requires the PHP Enchant module +## - // - 'atd' - install your own After the Deadline server or check with the people at http://www.afterthedeadline.com before using their API +## - // Since Google shut down their public spell checking service, you need to +## - // connect to a Nox Spell Server when using 'googie' here. Therefore specify the 'spellcheck_uri' +## - //$config['spellcheck_engine'] = 'googie'; +## - $config['spellcheck_engine'] = 'pspell'; +## - +## - // These languages can be selected for spell checking. +## - // Configure as a PHP style hash array: array('en'=>'English', 'de'=>'Deutsch'); +## - // Leave empty for default set of available language. +## - // +## - // Take care tha dictionaries for aspell ar installed ! +## - // for debian: +## - // apt-get install aspell-en aspell-de aspell-da aspell-es aspell-fr aspell-it +## - $config['enable_spellcheck'] = true; +## - $config['spellcheck_engine'] = 'pspell'; +## - $config['spellcheck_languages'] = array( +## - 'en' => 'English', +## - 'de' => 'Deutsch', +## - 'da' => 'Dansk', +## - 'fr' => 'Français', +## - 'it' => 'Italiano', +## - 'es' => 'Español', +## - ); +## - // Makes that words with all letters capitalized will be ignored (e.g. GOOGLE) +## - $config['spellcheck_ignore_caps'] = true; +## - +## - // Makes that words with numbers will be ignored (e.g. g00gle) +## - $config['spellcheck_ignore_nums'] = true; +## - +## - // Makes that words with symbols will be ignored (e.g. g@@gle) +## - $config['spellcheck_ignore_syms'] = true; +## - +cat <>$WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/config.inc.php + +// ---------------------------------- +// USER INTERFACE +// ---------------------------------- + +// Make use of the built-in spell checker. It is based on GoogieSpell. +// Since Google only accepts connections over https your PHP installatation +// requires to be compiled with Open SSL support +\$config['enable_spellcheck'] = true; + +// Enables spellchecker exceptions dictionary. +// Setting it to 'shared' will make the dictionary shared by all users. +\$config['spellcheck_dictionary'] = false; + +// Set the spell checking engine. Possible values: +// - 'googie' - the default +// - 'pspell' - requires the PHP Pspell module and aspell installed +// - 'enchant' - requires the PHP Enchant module +// - 'atd' - install your own After the Deadline server or check with the people at http://www.afterthedeadline.com before using their API +// Since Google shut down their public spell checking service, you need to +// connect to a Nox Spell Server when using 'googie' here. Therefore specify the 'spellcheck_uri' +\$config['spellcheck_engine'] = 'pspell'; + +// For locally installed Nox Spell Server or After the Deadline services, +// please specify the URI to call it. +// Get Nox Spell Server from http://orangoo.com/labs/?page_id=72 or +// the After the Deadline package from http://www.afterthedeadline.com. +// Leave empty to use the public API of service.afterthedeadline.com +\$config['spellcheck_uri'] = ''; + +// These languages can be selected for spell checking. +// Configure as a PHP style hash array: array('en'=>'English', 'de'=>'Deutsch'); +// Leave empty for default set of available language. +// +// Take care tha dictionaries for aspell ar installed ! +// for debian: +// apt-get install aspell-en aspell-de aspell-da aspell-es aspell-fr aspell-it +\$config['spellcheck_languages'] = array( + 'en' => 'English', + 'de' => 'Deutsch', + 'da' => 'Dansk', + 'fr' => 'Français', + 'it' => 'Italiano', + 'es' => 'Español', +); +// Makes that words with all letters capitalized will be ignored (e.g. GOOGLE) +\$config['spellcheck_ignore_caps'] = true; + +// Makes that words with numbers will be ignored (e.g. g00gle) +\$config['spellcheck_ignore_nums'] = true; + +// Makes that words with symbols will be ignored (e.g. g@@gle) +\$config['spellcheck_ignore_syms'] = true; + +EOF + + +## - Notice: +## - +## - - robots.txt +## - - favicon.ico + + +## -------------------------------------------- # +## --- Install Plugin Manager for Roundcube --- # +## -------------------------------------------- # + +## - Download base plugins from: +## - http://myroundcube.com/myroundcube-plugins/plugin-manager +## - +## - See also: +## - https://code.google.com/p/myroundcube/ +## - + +## - unzip downloaded plugins.zip file into plugin folder +## - of roundcube installation. + +## - register plugin, add "plugin_manager" to array plugins +## - $rcmail_config['plugins'] = array('plugin_manager'); +## - +vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/main.inc.php + +## - Notice: +## - This install also plugins: +## - - codemirror_ui +## - - db_version +## - - http_request +## - - plugin_manager +## - - qtip +## - - settings + + +## ------------------------------- # +## --- Install plugin lang_sel --- # +## ------------------------------- # + +## - Download Plugin from roundcube webmail interface +## - +## - Settings -> Plugins downloads +## - +## - Unpack to "$WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/" directory +## - + +cp $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/lang_sel/config.inc.php.dist \ + $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/lang_sel/config.inc.php + + +## ---------- +## --- Provied Language selection on logon screen - ## +## ---------- + +## - !! +## - +## - For that to work, plugin's "settings" and "lang_sel" must be present +## - if not yet authenticated (logged in into roundcube) + + +## - Notice! +## - Currently (at time of that installation) pluginmanager in conjunction with +## - plugins 'lang_sel' and 'settings' does not work as exspected: +## - +## - $rcmail_config['plugin_manager_unauth'] = array( +## - .. +## - 'settings' => true, +## - 'lang_sel' => true, +## - ); +## - +## - +## - $rcmail_config['plugin_manager_defaults'] = array( +## - ... +## - 'globalplugins' => array( +## - 'settings' => array('protected' => true, 'active' => true), +## - 'lang_sel' => array('protected' => true, 'active' => true), +## - .. +## - +## - Configuring that way, a language selection is shown. but the selected language +## - IS NOT loaded. +## - +## - But if registering within roundcube providing a Language selection on logon screen +## - works fine WITH loadind the selected language: +## - +## - Comment out all settings in plugin_manager concerning plugins 'lang_sel' and +## - settings +## - +vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/plugin_manager/config.inc.php +## - +## - Afterwards register plugins in roundcube( maybe the registration order in that array +## - is : +## - +## - $rcmail_config['plugins'] = array('settings', 'lang_sel','plugin_manager'); +## - +vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/main.inc.php + + +## -------------------------------- # +## --- Install plugin vkeyboard --- # +## -------------------------------- # + +## - Download Plugin from roundcube webmail interface +## - +## - Settings -> Plugins downloads +## - +## - Unpack to "$WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/" directory +## - + + +## --------------------------------- # +## --- Install plugin timepicker --- # +## --------------------------------- # + +## - Download Plugin from roundcube webmail interface +## - +## - Settings -> Plugins downloads +## - +## - Unpack to "$WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/" directory +## - + + +## ----------------------------------- # +## --- Install plugin idle_timeout --- # +## ----------------------------------- # + +## - Download Plugin from roundcube webmail interface +## - +## - Settings -> Plugins downloads +## - +## - Unpack to "$WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/" directory +## - +cp $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/idle_timeout/config.inc.php.dist \ + $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/idle_timeout/config.inc.php + +## - Edit plugins configuration file (config.inc.php) +## - +## - add/change: +## - +## - $rcmail_config['idle_timeout_warning'] = 28; +## - $rcmail_config['idle_timeout_logout'] = 2; +## - +vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/idle_timeout/config.inc.php + + +## ----------------------------------------------- # +## --- integrate password plugin for roundcube --- # +## ----------------------------------------------- # + +cp $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/password/config.inc.php.dist \ + $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/password/config.inc.php + +## - edit $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/password/config.inc.php +## - +## - adjust: +## - +## - $rcmail_config['password_driver'] = 'sql'; +## - $rcmail_config['password_confirm_current'] = true; +## - +## - NOTE: The database configuration data from POSTFIX Dateabase are needed !! +## - Put in your database credentials +## - +## - $rcmail_config['password_db_dsn'] = '${_db_type}://${_db_user}:${_db_pass}@localhost/${_db_name}'; +## - +## - $rcmail_config['password_query'] = 'UPDATE mailbox SET password=%p WHERE username=%u'; +## - +vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/password/config.inc.php + + +## ------------------------------------------ # +## --- integrate acl plugin for roundcube --- # +## ------------------------------------------ # + +cp $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/acl/config.inc.php.dist \ + $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/acl/config.inc.php + +## - edit $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/acl/config.inc.php +## - +## - change: +## - $rcmail_config['acl_advanced_mode'] = true; +## - +vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/acl/config.inc.php + + +## - Note: register plugin either with plugin_manager or with roundcube methode NOT BOTH + + +## - register acl plugin with plugin_manager +## - +## - edit: $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/plugin_manager/config.inc.php +## - +## - add to array $rcmail_config['plugin_manager_defaults'] (Section globalplugins) +## - after line "'globalplugins' => array(" +## - +## - 'acl' => array('protected' => true, 'active' => true), +## - +vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/plugin_manager/config.inc.php + + +## - register acl plugin with roundcube +## - +## - edit $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/main.inc.php +## - +## - add "acl" to array plugins +## - $rcmail_config['plugins'] = array('global_alias','contextmenue', 'password', 'acl'); +## - +vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/main.inc.php + + +## -------------------------------------------------- # +## --- integrate managesieve plugin for roundcube --- # +## -------------------------------------------------- # + + +cp $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/managesieve/config.inc.php.dist \ + $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/managesieve/config.inc.php + +## - edit $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/managesieve/config.inc.php +## - +## - adjust the following variables: +## - $rcmail_config['managesieve_port'] = 4190; +## - $rcmail_config['managesieve_default'] = '/usr/local/dovecot/etc/dovecot/sieve/move-spam.sieve'; +## - +## - +vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/managesieve/config.inc.php + + + +## ---------------------- +## - Install contextmenue +## - + + + + +## ---------------------------------- # +## --- Install plugin markasjunk2 --- # +## ---------------------------------- # + +cd $WEBMAIL_BASEDIR +rm markasjunk2.tar.gz +wget http://www.tehinterweb.co.uk/roundcube/plugins/markasjunk2.tar.gz + +gunzip < $WEBMAIL_BASEDIR/markasjunk2.tar.gz | tar -C $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins -xf - + +cp $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/markasjunk2/config.inc.php.dist \ + $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/markasjunk2/config.inc.php + +## ---------------------------------------------------------------------- +## ---------------------------------------------------------------------- +## ---------------------------------------------------------------------- + + +## ---------------------- +## - Install global_alias +## - + +cp -a $WEBMAIL_TMPDIR/plugins/global_alias $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/ + +cp -a $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/global_alias/config.inc.php.dist \ + $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/global_alias/config.inc.php + + +## - Note: register plugin either with plugin_manager or with roundcube methode NOT BOTH + + +## - register global_alias plugin with plugin_manager +## - +## - edit: $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/plugin_manager/config.inc.php +## - +## - add to array $rcmail_config['plugin_manager_defaults'] (Section globalplugins) +## - after line "'globalplugins' => array(" +## - +## - 'global_alias' => array( +## - 'protected' => true, +## - /* +## - 'hosts' => array('mail4us.net', 'svn.mail4us.net'), +## - */ +## - 'hosts' => false, +## - 'active' => true +## - ), +## - +vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/plugin_manager/config.inc.php + + +## - register global_alias with roundcube +## - +## - edit $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/main.inc.php +## - +## - register plugin, add "global_alias" to array plugins +## - $rcmail_config['plugins'] = array('global_alias'); +## - +vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/main.inc.php + + +## ----------------------------------------------- # +## --- integrate calendar plugin for roundcube --- # +## ----------------------------------------------- # + +## - requirements: +## - - plugin jqueryui +## - - plugin qtip +## - - plugin http_auth +## - - plugin jscolor +## - + +## ------------------- +## - Install http_auth +## - + +## - Download within the plugin manager +## - +cp -a ${WEBMAIL_BASEDIR}/plugins/http_auth $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/ + + +## ------------------- +## - Install jscolor +## - + +## - Download within the plugin manager +## - +cp -a $WEBMAIL_BASEDIR/plugins/jscolor $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/ + + +## - create configuration file +## - +cp -a $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/jscolor/config.inc.php.dist \ + $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/jscolor/config.inc.php + + + +## ------------------ +## - Install calendar +## - +cp -a $WEBMAIL_BASEDIR/plugins/calendar $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/ + +cp -a $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/calendar/config.inc.php.dist \ + $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/calendar/config.inc.php + + +## - edit $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/calendar/config.inc.php +## - +## - adjust the following variables: +## - $rcmail_config['calendar_admin'] = 'ckubu@oopen.de'; +## - +## - # Notice: make this folder writable for webserver user +## - # +## - $rcmail_config['cal_tempdir'] = '$WEBMAIL_BASEDIR/temp'; i.e. /var/www/webmail.oopen.de/temp +## - $rcmail_config['backend'] = "database"; +## - +## - +## - # smtp login data needed for cronjob "reminders.php" +## - # +## - $rcmail_config['cron_log'] = true; +## - $rcmail_config['cron_smtp_user'] = 'adm@oopen.de'; //smtp user +## - $rcmail_config['cron_smtp_pass'] = 'EadGl15E'; //smtp password +## - $rcmail_config['cron_rc_url'] = 'http://webmail.oopen.de/'; //trailing slash !!! +## - $rcmail_config['cron_ip'] = '127.0.0.1'; //please use real IP +## - $rcmail_config['cron_sender'] = 'noreply@oopen.de'; +## - +vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/calendar/config.inc.php + +chown $WEBSERVER_USER:$WEBSERVER_GROUP $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/calendar/temp + +## - create tables for calendar plugin in roundcube database +## - you will find needed sql-statements in directora calendar/SQL +## - +## - !! Do that as roundcube user !! +## - if not, you have to adjust ownerchip of tables and sequences afterwards +## - ALTER TABLE OWNER TO ; +## - ALTER SEQUENCE OWNER TO ; +## - + + +## - Trigger cronjob for sending reminders +## - +## - +## - */5 * * * * su $WEBSERVER_USER -c"php5 -d suhosin.session.encrypt=off $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins//calendar/cron/reminders.php" > /dev/null +## - +## - !! Notice +## - +## - I have compiled and installed php from source code. so i ha to change +## - my crontab rule because of errors ("Class rcmail not found" or +## - "Location not found" to +## - +## - */5 * * * * su www-data -c "cd /var/www/webmail.initiativenserver.de/htdocs/plugins/calendar/cron ; /usr/local/php/bin/php -d suhosin.session.encrypt=off -f reminders.php" +## - +crontab -l > /tmp/tmp_crontab +echo "" >> /tmp/tmp_crontab +echo "## - Trigger cronjob for sending reminders (calendar plugin roundcube)" >> /tmp/tmp_crontab +echo "## -" >> /tmp/tmp_crontab +echo "*/5 * * * * su $WEBSERVER_USER -c\"php5 -d suhosin.session.encrypt=off $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins//calendar/cron/reminders.php > /dev/null" >> /tmp/tmp_crontab +crontab /tmp/tmp_crontab +rm /tmp/tmp_crontab + + +## - Note: register plugin either with plugin_manager or with roundcube methode NOT BOTH + +## - register calendar plugin with plugin_manager +## - +## - edit: $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/plugin_manager/config.inc.php +## - +## - add to array $rcmail_config['plugin_manager_defaults'] (Section calendaring) +## - after line "'calendar' => array(" +## - +## - 'calendar' => array( +## - 'label_name' => 'calendar.pluginname', +## - 'label_description' => 'calendar.plugindescription', +## - 'buttons' => array('#calendar_button', '#rcmrowcalendarlink', '#rcmrowcalendarcategories', '#rcmrowcalendarfeeds'), +## - 'reload' => true, +## - 'config' => './?_task=settings&_action=edit-prefs&_section=calendarlink&_framed=1', +## - 'section' => 'calendarlink', +## - 'uninstall' => true, +## - 'uninstall_request' => array( +## - 'action' => 'plugin.calendar_uninstall', +## - 'method' => 'post', +## - ), +## - 'active' => true +## - ), +## - +vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/plugin_manager/config.inc.php + + +## - register calendar plugin without using plugin_manager +## - +## - edit $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/main.inc.php +## - +## - add "calendar" to array plugins +## - $rcmail_config['plugins'] = array('global_alias','contextmenue', 'password', 'acl', 'calendar') +## - +vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/main.inc.php + + + +## ----------------------- +## - Install calendar_plus +## - + + + +## ----------------- +## - Install carddav +## - + + + +## ---------------------- +## - Install carddav_plus +## - + + + +## --------------------------------------------------- # +## --- Install vacation plugin bhusigen rc-vacation -- # +## --------------------------------------------------- # + +## - see: https://github.com/bhuisgen/rc-vacation/ + +## - Download from site https://github.com/bhuisgen/rc-vacation/ and +## - store archive in $WEBMAIL_BASEDIR +## - +cd $WEBMAIL_BASEDIR +rm rc-vacation-master.zip +wget -O rc-vacation-master.zip https://github.com/bhuisgen/rc-vacation/archive/master.zip + +cd $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins +unzip $WEBMAIL_BASEDIR/rc-vacation-master.zip +ln -s rc-vacation-master $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/vacation + + +## - +## - or use git to get the sources directly: +## - +cd $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins +git clone https://github.com/bhuisgen/rc-vacation.git + +ln -s rc-vacation vacation + +cp $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/vacation/config.inc.php.dist \ + $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/vacation/config.inc.php + + +if [ "$_db_type" = "pgsql" ];then + + ## -------------------------------------------------------------- ## + ## - !! That (very long) part concerns to PostgeSQL Database !! - ## + ## -------------------------------------------------------------- ## + + ## - Note: In the following sql statements set the correct AUTOREPLY domain !! + ## - Also chnage the database parameters as yor needs + ## - + ## - edit configuration $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/vacation/config.inc.php + ## - + ## - $rcmail_config['vacation_gui_vacationforwarder'] = TRUE; + ## - $rcmail_config['vacation_forwarder_multiple'] = TRUE; + ## - $rcmail_config['vacation_forwarder_separator'] = ','; + ## - + ## - $rcmail_config['vacation_driver'] = 'sql'; + ## - + ## - #configure your database connection to POSTFIX database + ## - $rcmail_config['vacation_sql_dsn'] = '${_db_type}://${_db_user}:${_db_pass}@localhost/${_db_name}'; + ## - + ## - + ## - # !! NOTE: You have to create postgres function udf_forwarders_out and + ## - # udf_forwarders_in to get the following SQL statements working + ## - # + ## - /* - OLD: vcation.pl included in posfixadmin until version 2.3.7 + ## - $rcmail_config['vacation_sql_read'] = + ## - array("SELECT subject AS vacation_subject, body AS vacation_message, " . + ## - "CASE WHEN vacation.active = TRUE THEN 1 ELSE 0 END AS vacation_enable, " . + ## - "udf_forwarders_out(%username,'$_autoreply_domain',',') AS vacation_forwarder FROM vacation,alias " . + ## - "WHERE email=%username AND address=%username AND vacation.domain=%email_domain;" + ## - ); + ## - */ + ## - /* - NEW: vcation.pl included in posfixadmin since version 2.91 + ## - $rcmail_config['vacation_sql_read'] = + ## - array("SELECT subject AS vacation_subject, body AS vacation_message, date_part('epoch',activefrom)::int AS vacation_start, date_part('epoch',activeuntil)::int AS vacation_end, " . + ## - "CASE WHEN vacation.active = TRUE THEN 1 ELSE 0 END AS vacation_enable, " . + ## - "udf_forwarders_out(%username,'autoreply.oopen.de',',') AS vacation_forwarder FROM vacation,alias " . + ## - "WHERE email=%username AND address=%username AND vacation.domain=%email_domain;" + ## - ); + ## - */ + ## - + ## - + ## - /* !! Wichtig: + ## - Nur wenn rcmail_config['vacation_gui_vacationforwarder'] = FALSE + ## - */ + ## - + ## - + ## - /* - OLD: vcation.pl included in posfixadmin until version 2.3.7 + ## - $rcmail_config['vacation_gui_vacationforwarder'] = FALSE; + ## - $rcmail_config['vacation_sql_write'] = + ## - array("DELETE FROM vacation WHERE email=%email AND " . + ## - "domain=%email_domain;", + ## - "DELETE from vacation_notification WHERE on_vacation=%email;", + ## - "INSERT INTO vacation (email,domain,subject,body,created," . + ## - "active) VALUES (%email,%email_domain,%vacation_subject," . + ## - "%vacation_message,NOW(),udf_set_active(%vacation_enable));", + ## - "UPDATE alias SET goto = udf_forwarders_in(udf_forwarders_out(%email,'$_autoreply_domain',',')," . + ## - "%email,'$_autoreply_domain',',',udf_set_active(%vacation_enable))" . + ## - ", modified = NOW() " . + ## - " WHERE address = %email" + ## - + ## - ); + ## - */ + ## - /* - NEW: vcation.pl included in posfixadmin since version 2.91 + ## - --------------------------------------------------------------- + ## - $rcmail_config['vacation_gui_vacationforwarder'] = FALSE; + ## - $rcmail_config['vacation_sql_write'] = + ## - array("DELETE FROM vacation WHERE email=%email AND domain=%email_domain;", + ## - "DELETE from vacation_notification WHERE on_vacation=%email;", + ## - "INSERT INTO vacation (email,domain,subject,body,activefrom,activeuntil,interval_time,created,active) " . + ## - "VALUES (%email,%email_domain,%vacation_subject,%vacation_message," . + ## - "to_timestamp(%vacation_start - extract(timezone from current_timestamp))," . + ## - "to_timestamp(%vacation_end + 86399 - extract(timezone from current_timestamp))," . + ## - "86400,NOW(),udf_set_active(%vacation_enable));", + ## - "UPDATE alias SET goto = udf_forwarders_in(udf_forwarders_out(%email,'$_autoreply_domain',',')," . + ## - "%email,'$_autoreply_domain',',',udf_set_active(%vacation_enable))" . + ## - ", modified = NOW() " . + ## - " WHERE address = %email" + ## - + ## - ); + ## - */ + ## - + ## - + ## - /* !! Wichtig: + ## - Nur wenn rcmail_config['vacation_gui_vacationforwarder'] = TRUE + ## - */ + ## - + ## - /* - OLD: vcation.pl included in posfixadmin until version 2.3.7 + ## - ------------------------------------------------------------- + ## - $rcmail_config['vacation_gui_vacationforwarder'] = TRUE; + ## - $rcmail_config['vacation_sql_write'] = + ## - array("DELETE FROM vacation WHERE email=%email AND " . + ## - "domain=%email_domain;", + ## - "DELETE from vacation_notification WHERE on_vacation=%email;", + ## - "INSERT INTO vacation (email,domain,subject,body,created," . + ## - "active) VALUES (%email,%email_domain,%vacation_subject," . + ## - "%vacation_message,NOW(),udf_set_active(%vacation_enable));", + ## - "UPDATE alias SET goto = udf_forwarders_in(%vacation_forwarder," . + ## - "%email,'$_autoreply_domain',',',udf_set_active(%vacation_enable))" . + ## - ", modified = NOW() " . + ## - " WHERE address = %email" + ## - + ## - ); + ## - */ + ## - /* - NEW: vcation.pl included in posfixadmin since version 2.91 + ## - --------------------------------------------------------------- + ## - $rcmail_config['vacation_gui_vacationforwarder'] = TRUE; + ## - $rcmail_config['vacation_sql_write'] = + ## - array("DELETE FROM vacation WHERE email=%email AND domain=%email_domain;", + ## - "DELETE from vacation_notification WHERE on_vacation=%email;", + ## - "INSERT INTO vacation (email,domain,subject,body,activefrom,activeuntil,interval_time,created,active) " . + ## - "VALUES (%email,%email_domain,%vacation_subject,%vacation_message," . + ## - "to_timestamp(%vacation_start - extract(timezone from current_timestamp))," . + ## - "to_timestamp(%vacation_end + 86399 - extract(timezone from current_timestamp))," . + ## - "86400,NOW(),udf_set_active(%vacation_enable));", + ## - "UPDATE alias SET goto = udf_forwarders_in(%vacation_forwarder," . + ## - "%email,'$_autoreply_domain',',',udf_set_active(%vacation_enable))" . + ## - ", modified = NOW() " . + ## - " WHERE address = %email" + ## - ); + ## - */ + + ## - + vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/vacation/config.inc.php + + + ## - create postfix trigger function udf_forwarders_out: + ## - + cat < /tmp/postgres.forwarders_out.sql +CREATE LANGUAGE plpgsql; + +CREATE FUNCTION udf_forwarders_out(email_str text, vacation_domain text, list_seperator character) RETURNS text + LANGUAGE plpgsql + AS \$\$ + DECLARE + forward_str text; + local_email_part TEXT; + domain_email_part TEXT; + BEGIN + + -- get list of forwarders + -- + SELECT goto INTO forward_str FROM alias WHERE address=email_str; + + -- entferne mailbox emailadresse + -- + forward_str = replace(forward_str, email_str, '' ); + + -- entferne vacation adresse + -- + local_email_part = substring(email_str, 1, position('@' in email_str) - 1); + domain_email_part = substring(email_str, position('@' in email_str) + 1 ); + forward_str = replace(forward_str, local_email_part || '#' || domain_email_part || '@' || vacation_domain, ''); + + -- enferne doppelte seperatorzeichen + -- + WHILE position( list_seperator || list_seperator in forward_str ) > 0 LOOP + forward_str = replace(forward_str, list_seperator || list_seperator , ''); + END LOOP; + + -- entferne erstes zeichen wenn es das seperatorzeichen ist + -- + IF substring(forward_str,1,1) = list_seperator THEN + forward_str = substring(forward_str from 2); + END IF; + + + -- entferne letztes zeichen wenn es das seperatorzeichen ist + -- + IF substring(forward_str from char_length(forward_str)) = list_seperator THEN + forward_str = substring(forward_str, 1, char_length(forward_str) - 1); + END IF; + + + -- forward_str = substring(forward_str from char_length(forward_str)); + + RETURN forward_str; + END; + \$\$; +EOF + + ## - create function + ## - + ## - Note 1. + ## - if datbase language plpgsql already exists, an error occurs. but you can + ## - savely ignore that error + ## - + ## - Note 2. + ## - if you create the function not as postfix database user, you have to + ## - give the permission afterwards: + ## - ALTER FUNCTION public.udf_forwarders_out(email_str text, vacation_domain text, list_seperator character) OWNER TO postfix; + ## - But we will use the db postfix user (here also named postfix) + ## - + psql -Upostfix postfix < /tmp/postgres.forwarders_out.sql + + rm /tmp/postgres.forwarders_out.sql + + + ## - create sql file for installing function udf_set_active: + ## - + cat < /tmp/postgres.set_active.sql +CREATE LANGUAGE plpgsql; + +CREATE FUNCTION udf_set_active(vacation_enable text) RETURNS boolean + LANGUAGE plpgsql + AS \$\$ + DECLARE + return_val boolean; + BEGIN + + return_val = 't'; + + IF vacation_enable = '' THEN + return_val = 'f'; + END IF; + + IF vacation_enable = '0' THEN + return_val = 'f'; + END IF; + + IF lower(vacation_enable) = 'false' THEN + return_val = 'f'; + END IF; + + RETURN return_val; + END; + \$\$; +EOF + + ## - create function udf_set_active + ## - + ## - Note 1. + ## - if datbase language plpgsql already exists, an error occurs. but you can + ## - savely ignore that error + ## - + ## - Note 2. + ## - if you create the function not as postfix database user, you have to + ## - give the permission afterwards: + ## - ALTER FUNCTION public.udf_forwarders_in(forewarders_str text, email_str text, vacation_domain text, list_seperator character, vacation_enable boolean) OWNER TO postfix; + ## - But we will use the db postfix user (here also named postfix) + ## - + psql -Upostfix postfix < /tmp/postgres.set_active.sql + + rm /tmp/postgres.set_active.sql + + + ## - create postfix database function udf_forwarders_in: + ## - + cat < /tmp/postgres.forwarders_in.sql +CREATE LANGUAGE plpgsql; + +CREATE FUNCTION udf_forwarders_in(forewarders_str text, email_str text, vacation_domain text, list_seperator character, vacation_enable boolean) RETURNS text + LANGUAGE plpgsql + AS \$\$ + DECLARE + return_str text; + local_email_part TEXT; + domain_email_part TEXT; + BEGIN + + return_str = email_str; + + IF vacation_enable THEN + local_email_part = substring(email_str, 1, position('@' in email_str) - 1); + domain_email_part = substring(email_str, position('@' in email_str) + 1 ); + return_str = return_str || list_seperator || local_email_part || '#' || domain_email_part || '@' || vacation_domain; + END IF; + + IF char_length(forewarders_str) > 7 THEN + return_str = return_str || list_seperator || forewarders_str; + END IF; + + RETURN return_str; + END; + \$\$; +EOF + + ## - create function udf_forwarders_in + ## - + ## - Note 1. + ## - if datbase language plpgsql already exists, an error occurs. but you can + ## - savely ignore that error + ## - + ## - Note 2. + ## - if you create the function not as postfix database user, you have to + ## - give the permission afterwards: + ## - ALTER FUNCTION public.udf_forwarders_in(forewarders_str text, email_str text, vacation_domain text, list_seperator character, vacation_enable boolean) OWNER TO postfix; + ## - But we will use the db postfix user (here also named postfix) + ## - + psql -Upostfix postfix < /tmp/postgres.forwarders_in.sql + + rm /tmp/postgres.forwarders_in.sql + +elif [ "$_db_type" = "mysql" ];then + + ## ---------------------------------------------------------- ## + ## - !! That (very long) part concerns to MySQL Database !! - ## + ## ---------------------------------------------------------- ## + + ## - Note: In the following sql statements set the correct AUTOREPLY domain !! + ## - Also chnage the database parameters as yor needs + ## - + ## - edit configuration $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/vacation/config.inc.php + ## - + ## - $rcmail_config['vacation_gui_vacationforwarder'] = FALSE; + ## - $rcmail_config['vacation_forwarder_multiple'] = FALSE; + ## - $rcmail_config['vacation_forwarder_separator'] = ','; + ## - + ## - $rcmail_config['vacation_driver'] = 'sql'; + ## - + ## - #configure your database connection to POSTFIX database + ## - $rcmail_config['vacation_sql_dsn'] = '${_db_type}://${_db_user}:${_db_pass}@localhost/${_db_name}'; + ## - + ## - # !! NOTE: You have to create myql functions FORWARDERS_OUT and + ## - # FORWARDERS_IN to get the following SQL read statement working + ## - # + ## - + ## - // read data queries + ## - /* - OLD: vcation.pl included in posfixadmin until version 2.3.7 + ## - $rcmail_config['vacation_sql_read'] = + ## - array("SELECT subject AS vacation_subject, body AS vacation_message, " . + ## - "vacation.active AS vacation_enable, FORWARDERS_OUT(%username,'$_autoreply_domain',',') AS vacation_forwarder FROM vacation,alias " . + ## - "WHERE email=%username AND address=%username AND vacation.domain=%email_domain;" + ## - ); + ## - *) + ## - /* - NEW: vcation.pl included in posfixadmin since version 2.91 */ + ## - $rcmail_config['vacation_sql_read'] = + ## - array("SELECT subject AS vacation_subject, body AS vacation_message," . + ## - "UNIX_TIMESTAMP(activefrom) AS vacation_start," . + ## - "UNIX_TIMESTAMP(activeuntil) AS vacation_end," . + ## - "vacation.active AS vacation_enable," . + ## - "FORWARDERS_OUT(%username,'autoreply.initiativenserver.de',',') AS vacation_forwarder " . + ## - "FROM vacation,alias " . + ## - "WHERE email=%username AND address=%username AND vacation.domain=%email_domain;" + ## - ); + ## - + ## - + ## - // write data queries + ## - /* !! Wichtig: + ## - Nur wenn rcmail_config['vacation_gui_vacationforwarder'] = FALSE + ## - */ + ## - + ## - /* - OLD: vcation.pl included in posfixadmin until version 2.3.7 + ## - $rcmail_config['vacation_gui_vacationforwarder'] = FALSE; + ## - $rcmail_config['vacation_sql_write'] = + ## - array("DELETE FROM vacation WHERE email=%email AND " . + ## - "domain=%email_domain;", + ## - "DELETE from vacation_notification WHERE on_vacation=%email;", + ## - "INSERT INTO vacation (email,domain,subject,body,created," . + ## - "active) VALUES (%email,%email_domain,%vacation_subject," . + ## - "%vacation_message,NOW(),%vacation_enable);", + ## - "UPDATE alias SET goto = FORWARDERS_IN(FORWARDERS_OUT(%email,'$_autoreply_domain',',')," . + ## - "%email,'$_autoreply_domain',',',%vacation_enable)" . + ## - ", modified = NOW() " . + ## - " WHERE address = %email" + ## - ); + ## - /* + ## - + ## - /* - NEW: vcation.pl included in posfixadmin since version 2.91 */ + ## - /* + ## - $rcmail_config['vacation_gui_vacationforwarder'] = FALSE; + ## - $rcmail_config['vacation_sql_write'] = + ## - array("DELETE FROM vacation WHERE email=%email AND domain=%email_domain;", + ## - "DELETE from vacation_notification WHERE on_vacation=%email;", + ## - "INSERT INTO vacation (email,domain,subject,body,activefrom,activeuntil,interval_time,created,active) " . + ## - "VALUES (%email,%email_domain,%vacation_subject,%vacation_message," . + ## - "CONCAT(DATE(FROM_UNIXTIME(%vacation_start)), ' 00:00:00')," . + ## - "CONCAT(DATE(FROM_UNIXTIME(%vacation_end)), ' 23:59:59')," . + ## - "86400,NOW(),%vacation_enable);", + ## - "UPDATE alias SET goto = FORWARDERS_IN(FORWARDERS_OUT(%email,'autoreply.initiativenserver.de',',')," . + ## - "%email,'autoreply.initiativenserver.de',',',%vacation_enable)" . + ## - ", modified = NOW() " . + ## - " WHERE address = %email" + ## - ); + ## - */ + ## - + ## - /* !! Wichtig: + ## - Nur wenn rcmail_config['vacation_gui_vacationforwarder'] = TRUE + ## - */ + ## - + ## - /* + ## - + ## - /* - OLD: vcation.pl included in posfixadmin until version 2.3.7 + ## - $rcmail_config['vacation_gui_vacationforwarder'] = TRUE; + ## - $rcmail_config['vacation_sql_write'] = + ## - array("DELETE FROM vacation WHERE email=%email AND " . + ## - "domain=%email_domain;", + ## - "DELETE from vacation_notification WHERE on_vacation=%email;", + ## - "INSERT INTO vacation (email,domain,subject,body,created," . + ## - "active) VALUES (%email,%email_domain,%vacation_subject," . + ## - "%vacation_message,NOW(),%vacation_enable);", + ## - "UPDATE alias SET goto = FORWARDERS_IN(%vacation_forwarder," . + ## - "%email,'autoreply.initiativenserver.de',',',%vacation_enable)" . + ## - ", modified = NOW() " . + ## - " WHERE address = %email" + ## - ); + ## - */ + ## - + ## - /* - NEW: vcation.pl included in posfixadmin since version 2.91 */ + ## - $rcmail_config['vacation_gui_vacationforwarder'] = TRUE; + ## - $rcmail_config['vacation_sql_write'] = + ## - array("DELETE FROM vacation WHERE email=%email AND domain=%email_domain;", + ## - "DELETE from vacation_notification WHERE on_vacation=%email;", + ## - "INSERT INTO vacation (email,domain,subject,body,activefrom,activeuntil,interval_time,created,active) " . + ## - "VALUES (%email,%email_domain,%vacation_subject,%vacation_message," . + ## - "CONCAT(DATE(FROM_UNIXTIME(%vacation_start)), ' 00:00:00')," . + ## - "CONCAT(DATE(FROM_UNIXTIME(%vacation_end)), ' 23:59:59')," . + ## - "86400,NOW(),%vacation_enable);", + ## - "UPDATE alias SET goto = FORWARDERS_IN(%vacation_forwarder," . + ## - "%email,'autoreply.initiativenserver.de',',',%vacation_enable)" . + ## - ", modified = NOW() " . + ## - " WHERE address = %email" + ## - ); + ## - + ## - + vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/vacation/config.inc.php + + + ## - create function FORWARDERS_OUT: + ## - + cat < /tmp/FORWARDERS_OUT.sql +DROP FUNCTION IF EXISTS FORWARDERS_OUT ; + +DELIMITER | + +CREATE FUNCTION FORWARDERS_OUT (email_str TEXT, vacation_domain TEXT , list_seperator CHAR) + RETURNS TEXT + DETERMINISTIC + BEGIN + DECLARE forward_str TEXT; + DECLARE local_email_part TEXT; + DECLARE domain_email_part TEXT; + DECLARE first_char CHAR; + DECLARE last_char CHAR; + + -- get list of forwarders + -- + SELECT goto INTO forward_str FROM alias WHERE address=email_str; + + -- entferne mailbox emailadresse + -- + SET forward_str = REPLACE(forward_str, email_str, '' ); + -- SELECT REPLACE(forward_str, email_str, '' ) INTO forward_str; + + -- entferne vacation adresse + -- + SET local_email_part = SUBSTRING(email_str,1, LOCATE('@',email_str) - 1); + SET domain_email_part = SUBSTRING(email_str, LOCATE('@',email_str) + 1, LENGTH(email_str)); + SET forward_str = REPLACE(forward_str, CONCAT(local_email_part, "#" ,domain_email_part,"@", vacation_domain), ''); + -- SELECT REPLACE(forward_str, CONCAT(list_seperator,list_seperator), list_seperator) INTO forward_str; + + -- enferne doppelte seperatorzeichen + -- + WHILE LOCATE(CONCAT(list_seperator,list_seperator) , forward_str) DO + SET forward_str = REPLACE(forward_str, CONCAT(list_seperator,list_seperator), list_seperator); + -- SELECT REPLACE(forward_str, CONCAT(list_seperator,list_seperator), list_seperator) INTO forward_str; + END WHILE ; + + -- entferne erstes zeichen wenn es das seperatorzeichen ist + -- + IF LEFT(forward_str,1) = list_seperator THEN + SET forward_str = SUBSTRING(forward_str FROM 2); + -- SELECT SUBSTRING(forward_str FROM 2) INTO forward_str; + END IF; + + -- entferne letztes zeichen wenn es das seperatorzeichen ist + -- + IF RIGHT(forward_str,1) = list_seperator THEN + SET forward_str = SUBSTRING(forward_str , 1, LENGTH(forward_str) - 1); + -- SELECT SUBSTRING(forward_str , 1, LENGTH(forward_str) - 1) INTO forward_str; + END IF; + + RETURN forward_str; + END | + +DELIMITER ; +EOF + + ## - create function + ## - + ## - Note 1. + ## - Create function as postfix database user + ## - + ## - The postfix databaseuser wil need 'Super_priv'. At MySQL monitor + ## - (as mysql admin user i.e. root) type: + ## - UPDATE user SET Super_priv = 'Y' WHERE User = 'postfix'; + ## - + ## - Note 2. + ## - You can verify on mysql monitor (database postfix) with: + ## - SHOW FUNCTION STATUS; + ## - or see the code: + ## - SHOW CREATE FUNCTION FORWARDERS_OUT; + ## - + mysql -upostfix -p postfix < /tmp/FORWARDERS_OUT.sql + + rm /tmp/FORWARDERS_OUT.sql + + + ## - create database function FORWARDERS_IN: + ## - + cat < /tmp/FORWARDERS_IN.sql +DROP FUNCTION IF EXISTS FOWARDERS_IN ; + +DELIMITER | + +CREATE FUNCTION FORWARDERS_IN (forewarders_str TEXT, + email_str TEXT, + vacation_domain TEXT , + list_seperator CHAR , + vacation_enable BOOLEAN) + RETURNS TEXT + DETERMINISTIC + BEGIN + DECLARE return_str TEXT; + DECLARE local_email_part TEXT; + DECLARE domain_email_part TEXT; + + + SET return_str = email_str; + + IF vacation_enable THEN + SET local_email_part = SUBSTRING(email_str,1, LOCATE('@',email_str) - 1); + SET domain_email_part = SUBSTRING(email_str, LOCATE('@',email_str) + 1, LENGTH(email_str)); + SET return_str = CONCAT(return_str, list_seperator, local_email_part, "#" ,domain_email_part,"@", vacation_domain); + END IF; + + IF LENGTH(forewarders_str) > 2 THEN + SET return_str = CONCAT(return_str, list_seperator, forewarders_str); + END IF; + + RETURN return_str; + END | + +DELIMITER ; +EOF + + + ## - create function FOWARDERS_IN + ## - + ## - Note 1. + ## - Create function as postfix database user + ## - + ## - The postfix databaseuser wil need 'Super_priv'. At MySQL monitor + ## - (as mysql admin user i.e. root) type: + ## - UPDATE user SET Super_priv = 'Y' WHERE User = 'postfix'; + ## - + ## - Note 2. + ## - You can verify on mysql monitor (database postfix) with: + ## - SHOW FUNCTION STATUS; + ## - or see the code: + ## - SHOW CREATE FUNCTION FOWARDERS_IN; + ## - + + mysql -upostfix -p postfix < /tmp/FORWARDERS_IN.sql + + rm /tmp/FORWARDERS_IN.sql + +else + echo -e "\n\t[ ERROR ]: Unknown database type \"$_db_type\"" +fo + + + +## - Since version 0.9.0, due to changes in the way roundcube access database, the +## - vacation plugin doesn'work anymore. At least this plugins are affected: +## - - vacation plugin +## - - aliases plugin +## - - forward plugin +## - +## - To Fix that issue, in file lib/drivers/sql.php replace +## - all occurences of +## - +## - $db = new rcube_mdb2($dsn, '', FALSE); +## - +## - with: +## - +## - if (!class_exists('rcube_db')) { +## - $db = new rcube_mdb2($dsn, '', FALSE); +## - } else { +## - $db = rcube_db::factory($dsn, '', FALSE); +## - } +## - + +## - !! Notice: already fixed since in actual plugin distribution !! +## - +#perl -i.ORIG -n -p -e "s#^(\s*)(\\\$db\ +=\ +new rcube_mdb2\(\\\$dsn.*)#\1//!\2\n\1if (!class_exists('rcube_db')) {\n\1 \\\$db = new rcube_mdb2(\\\$dsn, '', FALSE);\n\1} else {\n\1 \\\$db = rcube_db::factory(\\\$dsn, '', FALSE);\n\1}\n#g" \ +# $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/vacation/lib/drivers/sql.php + + +## - Note: register plugin either with plugin_manager or with roundcube methode NOT BOTH + + +## - register vacation plugin with plugin_manager +## - +## - edit: $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/plugin_manager/config.inc.php +## - +## - add to array $rcmail_config['plugin_manager_defaults'] (Section globalplugins) +## - after line "'globalplugins' => array(" +## - +## - 'vacation' => array('protected' => true, 'active' => true), +## - +vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/plugin_manager/config.inc.php + + +## - register vacation plugin with roundcube +## - +## - edit $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/main.inc.php +## - +## - add "rc-vacation" to array plugins +## - $rcmail_config['plugins'] = array('global_alias','contextmenue', 'password', 'acl', 'calendar', 'managesieve', 'markasjunk2', 'vkeyboard', 'vacation'); +## - +vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/main.inc.php + + +## ------------------------------------------------------------------- ## + +## ------------------------------------------- # +## --- Install vacation plugin for roundcube - # +## --- vacation-1.9.9 - # +## ------------------------------------------- # + +cd /var/www/webmail.warenform.de/htdocs/plugins/ +unzip /usr/local/src/mailsystem/tarballs/vacation-1.9.9.zip + +## - Enable the vacation plugin in config/main.inc.php. +## - +## - add 'vacation' to the array in $rcmail_config['plugins'] +## - +## - $rcmail_config['plugins'] = array('acl','password', 'vacation', 'jqueryui', 'calendar') +## - +vim /var/www/webmail.warenform.de/htdocs/config/main.inc.php + + +## - Edit config.ini to configure vacation plugin +## - +## - add lines +## - + +cat <> /var/www/webmail.warenform.de/htdocs/plugins/vacation/config.ini +[localhost] +driver = "virtual" + +; Specifies a DSN (see db.inc.php) that has access to the dbase specified +; below. -- Optional. +; +dsn = "${_db_type}://${_db_user}:${_db_pass}@localhost/${_db_name}" + +; Applies to Postfix SMTP-server only. See +; http://www.postfix.org/VIRTUAL_README.html#autoreplies. +; This must match the transport in +; /etc/postfix/transport and /etc/postfix/master.cf -- Required +; +transport = "$_autoreply_domain" + +; Database used by the mailserver. The vacation and virtual alias tables must exist +; in this database. -- Required. +dbase = "postfix" + +; Always maintain an \$email -> \$email alias in the alias table. Defaults +; to true if omitted. -- Optional. +; +always_keep_copy = true + +; Parameters used by the SQL-Queries +; %e = email address, +; %d = domainname, +; %i = domain_id, +; %m is required as the Roundcube database should be different from the mailserver's database. +; %g = goto . +; The latter is used for the transport. %g will expands to john@domain.org@\$transport + +; Query to retrieve aliases for the current user. -- Required. +; +##!select_query = "SELECT destination FROM %m.virtual_aliases WHERE source='%e' AND destination='%g'" +select_query = "SELECT goto FROM alias WHERE address='%e' AND goto='%g'"; + +; Aliases are recreated when saving vacation settings. -- Required. +; +##!delete_query = "DELETE FROM %m.virtual_aliases WHERE domain_id=%i AND source='%e'" +delete_query = "DELETE FROM alias WHERE domain='%d' AND address ='%e'"; + +; Query to create new aliases. -- Required. +; +##!insert_query = "INSERT INTO %m.virtual_aliases (domain_id,source,destination) VALUES (%i,'%e','%g')" +insert_query = "INSERT INTO alias (address,goto,domain,active) VALUES ('%e','%g','%d',true)" + +; Required if you use a domain_id for storing the domain's in the alias table. +; +##!domain_lookup_query = "SELECT id FROM postfix.virtual_domains WHERE name='%d'" + +; Creates /etc/postfixadmin/vacation.conf which has database configuration +; for the vacation.pl script. -- Optional. +; +; It uses the selected DSN to create the file. Make sure this file is only readable +; by the vacation user after it's created. +; If unset or false, you must edit vacation.pl manually and set database accordingly. +; +createvacationconf = false + +; If vacation/auto-reply gets disabled, should we delete the subject/body set +; by the end-user? -- Optional. Defaults to true. +; +always_keep_message = true + +; If set to True, the end-user will not be able to set forwards. Defaults to false. Optional +disable_forward = False + +EOF + +perl -i -n -p -e"s#^(\s*)(subject\s*=\s*.+)#\#\1\2\n\1subject = \"Abwesenheitsnachricht\"#" \ + /var/www/webmail.warenform.de/htdocs/plugins/vacation/config.ini + +cp /var/www/webmail.warenform.de/htdocs/plugins/vacation/default.txt /var/www/webmail.warenform.de/htdocs/plugins/vacation/default.txt.ORIG +cat</var/www/webmail.warenform.de/htdocs/plugins/vacation/default.txt +Hallo, + +ich bin vom bis nicht im Büro. In dringenden Fällen melden Sie sich bitte bei . + +MfG + +EOF + + +## - RECOMMEND: if you don't want to display the forward fieldset, then +## - comment out the concerning code in vacation.php and replace with a +## - hidden field to realise, that always a copy is send to the concerning +## - email address +## - +## - comment out line 160 to 188 (incl.): +## - +## - $out .= '
' . $this->gettext('forward') . ''; +## - +## - // Keep a local copy of the mail +## - $field_id = 'vacation_keepcopy'; +## - $input_localcopy = new html_checkbox(array('name' => '_vacation_keepcopy', 'id' => $field_id, 'value' => 1)); +## - $out .= sprintf("

 %s

\n", +## - $field_id, +## - rep_specialchars_output($this->gettext('keepcopy')), +## - $input_localcopy->show($settings['keepcopy'])); +## - +## - +## - +## - // Information on the forward in a seperate fieldset. +## - if (! isset($this->inicfg['disable_forward']) || ( isset($this->inicfg['disable_forward']) && $this->inicfg['disable_forward']==false)) +## - { +## - $out .= '

' . $this->gettext('separate_forward') . '

'; +## - +## - // Forward mail to another account +## - $field_id = 'vacation_forward'; +## - $input_autoresponderforward = new html_inputfield(array('name' => '_vacation_forward', 'id' => $field_id, 'size' => 90)); +## - $out .= sprintf("

 %s

\n", +## - $field_id, +## - rep_specialchars_output($this->gettext('forwardingaddresses')), +## - $input_autoresponderforward->show($settings['forward'])); +## - +## - +## - } +## - $out .= "
\n"; +## - +## - replace with: +## - +## - // ckubu 20111202 +## - // dont't show forward fieldset +## - $field_id = 'vacation_keepcopy'; +## - $out .= sprintf("", $field_id); +## - + + +## - that vacation plugin doesn't work with postgres database out of the box. some changes +## - on lib/virtual.class.php is needed +## - +cat < /tmp/vacation-1.9.9-virtual.class.diff +50a51,52 +> /* CHANGED ckubu: that doesn't work with postgres database backend +> +52a55,58 +> */ +> $sql = sprintf("SELECT subject,body,active FROM vacation WHERE email='%s'", +> Q($this->user->data['username'])); +> +65a72,74 +> +> /* CHANGED ckubu: that doesn't work with postgres database backend +> +66a76,77 +> */ +> $vacArr['enabled'] = ($row['active'] == 't') && ($fwdArr['enabled'] == 1); +85a97,98 +> /* CHANGED ckubu: that doesn't work with postgres database backend +> +86a100,101 +> */ +> $sql = sprintf("UPDATE vacation SET created=now(),active=false WHERE email='%s'", Q($this->user->data['username'])); +112a128,130 +> +> /* CHANGED ckubu: that doesn't work with postgres database backend +> +113a132,133 +> */ +> $sql = "INSERT INTO vacation (email,subject,body,domain,created,active) VALUES (?,?,?,?,NOW(),true)"; +114a135,137 +> +> /* CHANGED ckubu: that doesn't work with postgres database backend +> +115a139,140 +> */ +> $sql = "UPDATE vacation SET email=?,subject=?,body=?,domain=?,active=true WHERE email=?"; +280c305 +< ?> +\ Kein Zeilenumbruch am Dateiende. +--- +> ?> +EOF + +cp $WEBMAIL_BASEDIR/htdocs/plugins/vacation/lib/virtual.class.php \ + $WEBMAIL_BASEDIR/htdocs/plugins/vacation/lib/virtual.class.php.ORIG + +patch -p0 $WEBMAIL_BASEDIR/htdocs/plugins/vacation/lib/virtual.class.php \ + /tmp/vacation-1.9.9-virtual.class.diff + + + +## - the output of the vacation plugin is blso roken. for now, we will correct that +## - in a very very simple way, only for usability.. +## - +cp -a $WEBMAIL_BASEDIR/htdocs/plugins/vacation/skins/default \ + $WEBMAIL_BASEDIR/htdocs/plugins/vacation/skins/default.ORIG + +cat < $WEBMAIL_BASEDIR/htdocs/plugins/vacation/skins/default/vacation.css +#vacationpage +{ + width: 800px; + margin-left: 15px; + margin-top: 95px; + border: 1px solid #999999; +} + +#pagecontent { + position: absolute; + top: 85px; + left: 20px; + bottom: 20px; + width: 800px; + +} + +#pagecontent label { + float:left; + /*width:20%;*/ + + margin-right:0.5em; + padding-top:0.2em; + text-align:left; + vertical-align: top; + color:#666666; +font-size:11px; +font-weight:bold; +} +EOF + +## ------------------------------------------------- # +## --- ENDE: Install vacation plugin for roundcube - # +## --- vacation-1.9.9 - # +## ------------------------------------------------- # + +## ------------------------------------------------------------------- ## + + + diff --git a/DOC/roundcube/roundcube.reset_admin.txt b/DOC/roundcube/roundcube.reset_admin.txt new file mode 100644 index 0000000..f36039e --- /dev/null +++ b/DOC/roundcube/roundcube.reset_admin.txt @@ -0,0 +1,12 @@ +## - To reset Plugin Manager ‘superadmin’ account do the following +## - + +- Logout from Roundcube and close your browser to make sure all sessions are ended. + +- Delete the [md5-hash].myrc file in the root of the Roundcube installation folder. + +- DROP table ‘plugin_manager’ from roundcube SQL database. + +- Remove entry ‘myrc_plugin_manager’ from ‘system’ table. + +- Login to Roundcube. diff --git a/DOC/roundcube/roundcube_plugin.install b/DOC/roundcube/roundcube_plugin.install new file mode 100644 index 0000000..2efcdf5 --- /dev/null +++ b/DOC/roundcube/roundcube_plugin.install @@ -0,0 +1,805 @@ + +## ---------------------- +## - webmail.warenform.de +## - + +. roundcube.env.webmail.warenform.de + +## - +## - END: webmail.warenform.de +## ---------------------------- + +## ---------------------- +## - webmail2.warenform.de +## - + +. roundcube.env.webmail2.warenform.de + +## - +## - END: webmail.warenform.de +## ---------------------------- + +## ---------------------- +## - webmail.so36.net +## - + +. roundcube.env.webmail.so36.net + +## - +## - END: webmail.so36.net +## ---------------------------- + +## ---------------------- +## - webmail.interventionistische-linke.org +## - + +. roundcube.env.webmail.interventionistische-linke.org + +## - +## - END: webmail.interventionistische-linke.org +## ---------------------------- + +## ---------------------- +## - webmail.initiativenserver.de +## - + +. roundcube.env.webmail.initiativenserver.de + +## - +## - END: webmail.interventionistische-linke.org +## ---------------------------- + +## ---------------------- +## - webmail2.initiativenserver.de +## - + +. roundcube.env.webmail2.initiativenserver.de + +## - +## - END: webmail.interventionistische-linke.org +## ---------------------------- + +## ---------------------- +## - webmail2.oopen.de +## - + +. roundcube.env.webmail2.oopen.de + +## - +## - END: webmail.oopen.de +## ---------------------------- + +## ---------------------- +## - webmail.oopen.de +## - + +. roundcube.env.webmail.oopen.de + +## - +## - END: webmail.oopen.de +## ---------------------------- + + + + + +## ----------------------------------------------- # +## --- integrate jqueryui plugin for roundcube --- # +## ----------------------------------------------- # + +## - jqueryui plugin comes with roundcube core distribution. So you have +## - only to register it. + +## - register jqueryui plugin with roundcube +## - +## - edit $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/config.inc.php +## - +## - add "login_lang" to array plugins +## - $config['plugins'] = array('jqueryui'); +## - +vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/config.inc.php + + + +## ----------------------------------------------- # +## --- integrate password plugin for roundcube --- # +## ----------------------------------------------- # + +cp $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/password/config.inc.php.dist \ + $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/password/config.inc.php + +## - edit $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/password/config.inc.php +## - +## - adjust: +## - +## - $config['password_driver'] = 'sql'; +## - $config['password_confirm_current'] = true; +## - +## - $config['password_minimum_length'] = 8; +## - $config['password_require_nonalpha'] = true; +## - +## - NOTE: The database configuration data from POSTFIX Dateabase are needed !! +## - Put in your database credentials +## - +## - $config['password_db_dsn'] = '${_db_type}://${_db_user}:${_db_pass}@localhost/${_db_name}'; +## - +## - $config['password_query'] = 'UPDATE mailbox SET password=%p WHERE username=%u'; +## - +vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/password/config.inc.php + +## - register password plugin with roundcube +## - +## - edit $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/config.inc.php +## - +## - add "password" to array plugins +## - $config['plugins'] = array('jqueryui', 'password'); +## - +vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/config.inc.php + + + +## --------------------------------------------------- # +## --- Install vacation plugin bhusigen rc-vacation -- # +## --------------------------------------------------- # + +## - see: https://github.com/bhuisgen/rc-vacation/ + +## - requirements, if using datepicker: +## - - plugin jqueryui + +## - Download from site https://github.com/bhuisgen/rc-vacation/ and +## - store archive in $WEBMAIL_BASEDIR +## - +cd $WEBMAIL_BASEDIR +rm rc-vacation-master.zip +wget -O rc-vacation-master.zip https://github.com/bhuisgen/rc-vacation/archive/master.zip + +cd $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins +unzip $WEBMAIL_BASEDIR/rc-vacation-master.zip +ln -s rc-vacation-master $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/vacation + +cp $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/vacation/config.inc.php.dist \ + $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/vacation/config.inc.php + +if [ "$_db_type" = "pgsql" ];then + + ## -------------------------------------------------------------- ## + ## - !! That (very long) part concerns to PostgeSQL Database !! - ## + ## -------------------------------------------------------------- ## + + ## - Note: In the following sql statements set the correct AUTOREPLY domain !! + ## - Also chnage the database parameters as yor needs + ## - + ## - edit configuration $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/vacation/config.inc.php + ## - + ## - $rcmail_config['vacation_gui_vacationdate'] = TRUE; + ## - $rcmail_config['vacation_subject_default'] = 'Re: $SUBJECT'; + ## - + ## - $rcmail_config['vacation_gui_vacationforwarder'] = FALSE; + ## - + ## - $rcmail_config['vacation_dateformat'] = 'Y-m-d' ; + ## - $rcmail_config['vacation_jquery_calendar'] = TRUE; + ## - $rcmail_config['vacation_jquery_dateformat'] = 'yy-m-d'; + ## - + ## - $rcmail_config['vacation_forwarder_multiple'] = FALSE; + ## - $rcmail_config['vacation_forwarder_separator'] = ','; + ## - + ## - $rcmail_config['vacation_driver'] = 'sql'; + ## - + ## - #configure your database connection to POSTFIX database + ## - $rcmail_config['vacation_sql_dsn'] = '${_db_type}://${_db_user}:${_db_pass}@localhost/${_db_name}'; + ## - + ## - + ## - # !! NOTE: You have to create postgres function udf_forwarders_out and + ## - # udf_forwarders_in to get the following SQL statements working + ## - # + ## - + ## - // read data queries + ## - $rcmail_config['vacation_sql_read'] = + ## - array( + ## - "SELECT + ## - subject AS vacation_subject, + ## - body AS vacation_message, + ## - date(activefrom) AS vacation_start, + ## - date(activeuntil) AS vacation_end, + ## - CASE WHEN vacation.active = TRUE THEN true ELSE false END AS vacation_enable, + ## - udf_forwarders_out(%username,'$_autoreply_domain',',') AS vacation_forwarder + ## - FROM vacation,alias + ## - WHERE email=%username AND address=%username AND vacation.domain=%email_domain;" + ## - ); + ## - + ## - + ## - // write data queries + ## - /* !! Wichtig: + ## - Nur wenn rcmail_config['vacation_gui_vacationforwarder'] = FALSE + ## - + ## - NOTE: interval_time wird statisch gesetzt auf 86400 (1 Tag) + ## - */ + ## - $rcmail_config['vacation_sql_write'] = + ## - array("DELETE FROM vacation WHERE email=%email AND domain=%email_domain;", + ## - "DELETE from vacation_notification WHERE on_vacation=%email;", + ## - "INSERT INTO vacation (email,domain,subject,body,activefrom,activeuntil,interval_time,created,active) " . + ## - "VALUES (%email,%email_domain,%vacation_subject,%vacation_message," . + ## - "to_timestamp(%vacation_start - extract(timezone from current_timestamp))," . + ## - "to_timestamp(%vacation_end + 86399 - extract(timezone from current_timestamp))," . + ## - "86400,NOW(),udf_set_active(%vacation_enable));", + ## - "UPDATE alias SET goto = udf_forwarders_in(udf_forwarders_out(%email,'$_autoreply_domain',',')," . + ## - "%email,'$_autoreply_domain',',',udf_set_active(%vacation_enable))" . + ## - ", modified = NOW() " . + ## - " WHERE address = %email" + ## - + ## - ); + ## - + ## - /* !! Wichtig: + ## - Nur wenn rcmail_config['vacation_gui_vacationforwarder'] = TRUE + ## - + ## - NOTE: interval_time wird statisch gesetzt auf 86400 (1 Tag) + ## - */ + ## - /* + ## - $rcmail_config['vacation_sql_write'] = + ## - array("DELETE FROM vacation WHERE email=%email AND domain=%email_domain;", + ## - "DELETE from vacation_notification WHERE on_vacation=%email;", + ## - "INSERT INTO vacation (email,domain,subject,body,activefrom,activeuntil,interval_time,created,active) " . + ## - "VALUES (%email,%email_domain,%vacation_subject,%vacation_message," . + ## - "to_timestamp(%vacation_start - extract(timezone from current_timestamp))," . + ## - "to_timestamp(%vacation_end + 86399 - extract(timezone from current_timestamp))," . + ## - "86400,NOW(),udf_set_active(%vacation_enable));", + ## - "UPDATE alias SET goto = udf_forwarders_in(%vacation_forwarder," . + ## - "%email,'$_autoreply_domain',',',udf_set_active(%vacation_enable))" . + ## - ", modified = NOW() " . + ## - " WHERE address = %email" + ## - ); + ## - + ## - !! Notice !! + ## - Replace '$_autoreply_domain' string with the true vaction domain. + ## - + ## - i.e for oopen.de: :1,$s/\$_autoreply_domain/autoreply.oopen.de/gc + ## - + vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/vacation/config.inc.php + + + ## - create postfix trigger function udf_forwarders_out: + ## - + cat < /tmp/postgres.forwarders_out.sql +CREATE LANGUAGE plpgsql; + +CREATE FUNCTION udf_forwarders_out(email_str text, vacation_domain text, list_seperator character) RETURNS text + LANGUAGE plpgsql + AS \$\$ + DECLARE + forward_str text; + local_email_part TEXT; + domain_email_part TEXT; + BEGIN + + -- get list of forwarders + -- + SELECT goto INTO forward_str FROM alias WHERE address=email_str; + + -- entferne mailbox emailadresse + -- + forward_str = replace(forward_str, email_str, '' ); + + -- entferne vacation adresse + -- + local_email_part = substring(email_str, 1, position('@' in email_str) - 1); + domain_email_part = substring(email_str, position('@' in email_str) + 1 ); + forward_str = replace(forward_str, local_email_part || '#' || domain_email_part || '@' || vacation_domain, ''); + + -- enferne doppelte seperatorzeichen + -- + WHILE position( list_seperator || list_seperator in forward_str ) > 0 LOOP + forward_str = replace(forward_str, list_seperator || list_seperator , ''); + END LOOP; + + -- entferne erstes zeichen wenn es das seperatorzeichen ist + -- + IF substring(forward_str,1,1) = list_seperator THEN + forward_str = substring(forward_str from 2); + END IF; + + + -- entferne letztes zeichen wenn es das seperatorzeichen ist + -- + IF substring(forward_str from char_length(forward_str)) = list_seperator THEN + forward_str = substring(forward_str, 1, char_length(forward_str) - 1); + END IF; + + + -- forward_str = substring(forward_str from char_length(forward_str)); + + RETURN forward_str; + END; + \$\$; +EOF + + ## - create function + ## - + ## - Note 1. + ## - if datbase language plpgsql already exists, an error occurs. but you can + ## - savely ignore that error + ## - + ## - Note 2. + ## - if you create the function not as postfix database user, you have to + ## - give the permission afterwards: + ## - ALTER FUNCTION public.udf_forwarders_out(email_str text, vacation_domain text, list_seperator character) OWNER TO postfix; + ## - But we will use the db postfix user (here also named postfix) + ## - + psql -Upostfix postfix < /tmp/postgres.forwarders_out.sql + + rm /tmp/postgres.forwarders_out.sql + + + ## - create sql file for installing function udf_set_active: + ## - + cat < /tmp/postgres.set_active.sql +CREATE LANGUAGE plpgsql; + +CREATE FUNCTION udf_set_active(vacation_enable text) RETURNS boolean + LANGUAGE plpgsql + AS \$\$ + DECLARE + return_val boolean; + BEGIN + + return_val = 't'; + + IF vacation_enable = '' THEN + return_val = 'f'; + END IF; + + IF vacation_enable = '0' THEN + return_val = 'f'; + END IF; + + IF lower(vacation_enable) = 'false' THEN + return_val = 'f'; + END IF; + + RETURN return_val; + END; + \$\$; +EOF + + ## - create function udf_set_active + ## - + ## - Note 1. + ## - if datbase language plpgsql already exists, an error occurs. but you can + ## - savely ignore that error + ## - + ## - Note 2. + ## - if you create the function not as postfix database user, you have to + ## - give the permission afterwards: + ## - ALTER FUNCTION public.udf_forwarders_in(forewarders_str text, email_str text, vacation_domain text, list_seperator character, vacation_enable boolean) OWNER TO postfix; + ## - But we will use the db postfix user (here also named postfix) + ## - + psql -Upostfix postfix < /tmp/postgres.set_active.sql + + rm /tmp/postgres.set_active.sql + + + ## - create postfix database function udf_forwarders_in: + ## - + cat < /tmp/postgres.forwarders_in.sql +CREATE LANGUAGE plpgsql; + +CREATE FUNCTION udf_forwarders_in(forewarders_str text, email_str text, vacation_domain text, list_seperator character, vacation_enable boolean) RETURNS text + LANGUAGE plpgsql + AS \$\$ + DECLARE + return_str text; + local_email_part TEXT; + domain_email_part TEXT; + BEGIN + + return_str = email_str; + + IF vacation_enable THEN + local_email_part = substring(email_str, 1, position('@' in email_str) - 1); + domain_email_part = substring(email_str, position('@' in email_str) + 1 ); + return_str = return_str || list_seperator || local_email_part || '#' || domain_email_part || '@' || vacation_domain; + END IF; + + IF char_length(forewarders_str) > 7 THEN + return_str = return_str || list_seperator || forewarders_str; + END IF; + + RETURN return_str; + END; + \$\$; +EOF + + ## - create function udf_forwarders_in + ## - + ## - Note 1. + ## - if datbase language plpgsql already exists, an error occurs. but you can + ## - savely ignore that error + ## - + ## - Note 2. + ## - if you create the function not as postfix database user, you have to + ## - give the permission afterwards: + ## - ALTER FUNCTION public.udf_forwarders_in(forewarders_str text, email_str text, vacation_domain text, list_seperator character, vacation_enable boolean) OWNER TO postfix; + ## - But we will use the db postfix user (here also named postfix) + ## - + psql -Upostfix postfix < /tmp/postgres.forwarders_in.sql + + rm /tmp/postgres.forwarders_in.sql + +elif [ "$_db_type" = "mysql" ];then + + ## ---------------------------------------------------------- ## + ## - !! That (very long) part concerns to MySQL Database !! - ## + ## ---------------------------------------------------------- ## + + ## - Note: In the following sql statements set the correct AUTOREPLY domain !! + ## - Also chnage the database parameters as yor needs + ## - + ## - edit configuration $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/vacation/config.inc.php + ## - + ## - $rcmail_config['vacation_gui_vacationforwarder'] = FALSE; + ## - $rcmail_config['vacation_forwarder_multiple'] = FALSE; + ## - $rcmail_config['vacation_forwarder_separator'] = ','; + ## - + ## - $rcmail_config['vacation_driver'] = 'sql'; + ## - + ## - #configure your database connection to POSTFIX database + ## - $rcmail_config['vacation_sql_dsn'] = '${_db_type}://${_db_user}:${_db_pass}@localhost/${_db_name}'; + ## - + ## - # !! NOTE: You have to create myql functions FORWARDERS_OUT and + ## - # FORWARDERS_IN to get the following SQL read statement working + ## - # + ## - + ## - // read data queries + ## - /* - OLD: vcation.pl included in posfixadmin until version 2.3.7 + ## - $rcmail_config['vacation_sql_read'] = + ## - array("SELECT subject AS vacation_subject, body AS vacation_message, " . + ## - "vacation.active AS vacation_enable, FORWARDERS_OUT(%username,'$_autoreply_domain',',') AS vacation_forwarder FROM vacation,alias " . + ## - "WHERE email=%username AND address=%username AND vacation.domain=%email_domain;" + ## - ); + ## - *) + ## - /* - NEW: vcation.pl included in posfixadmin since version 2.91 */ + ## - $rcmail_config['vacation_sql_read'] = + ## - array("SELECT subject AS vacation_subject, body AS vacation_message," . + ## - "UNIX_TIMESTAMP(activefrom) AS vacation_start," . + ## - "UNIX_TIMESTAMP(activeuntil) AS vacation_end," . + ## - "vacation.active AS vacation_enable," . + ## - "FORWARDERS_OUT(%username,'$_autoreply_domain',',') AS vacation_forwarder " . + ## - "FROM vacation,alias " . + ## - "WHERE email=%username AND address=%username AND vacation.domain=%email_domain;" + ## - ); + ## - + ## - + ## - // write data queries + ## - /* !! Wichtig: + ## - Nur wenn rcmail_config['vacation_gui_vacationforwarder'] = FALSE + ## - */ + ## - + ## - /* - OLD: vcation.pl included in posfixadmin until version 2.3.7 + ## - $rcmail_config['vacation_gui_vacationforwarder'] = FALSE; + ## - $rcmail_config['vacation_sql_write'] = + ## - array("DELETE FROM vacation WHERE email=%email AND " . + ## - "domain=%email_domain;", + ## - "DELETE from vacation_notification WHERE on_vacation=%email;", + ## - "INSERT INTO vacation (email,domain,subject,body,created," . + ## - "active) VALUES (%email,%email_domain,%vacation_subject," . + ## - "%vacation_message,NOW(),%vacation_enable);", + ## - "UPDATE alias SET goto = FORWARDERS_IN(FORWARDERS_OUT(%email,'$_autoreply_domain',',')," . + ## - "%email,'$_autoreply_domain',',',%vacation_enable)" . + ## - ", modified = NOW() " . + ## - " WHERE address = %email" + ## - ); + ## - /* + ## - + ## - /* - NEW: vcation.pl included in posfixadmin since version 2.91 */ + ## - /* + ## - $rcmail_config['vacation_gui_vacationforwarder'] = FALSE; + ## - $rcmail_config['vacation_sql_write'] = + ## - array("DELETE FROM vacation WHERE email=%email AND domain=%email_domain;", + ## - "DELETE from vacation_notification WHERE on_vacation=%email;", + ## - "INSERT INTO vacation (email,domain,subject,body,activefrom,activeuntil,interval_time,created,active) " . + ## - "VALUES (%email,%email_domain,%vacation_subject,%vacation_message," . + ## - "CONCAT(DATE(FROM_UNIXTIME(%vacation_start)), ' 00:00:00')," . + ## - "CONCAT(DATE(FROM_UNIXTIME(%vacation_end)), ' 23:59:59')," . + ## - "86400,NOW(),%vacation_enable);", + ## - "UPDATE alias SET goto = FORWARDERS_IN(FORWARDERS_OUT(%email,'$_autoreply_domain',',')," . + ## - "%email,'$_autoreply_domain',',',%vacation_enable)" . + ## - ", modified = NOW() " . + ## - " WHERE address = %email" + ## - ); + ## - */ + ## - + ## - /* !! Wichtig: + ## - Nur wenn rcmail_config['vacation_gui_vacationforwarder'] = TRUE + ## - */ + ## - + ## - /* + ## - + ## - /* - OLD: vcation.pl included in posfixadmin until version 2.3.7 + ## - $rcmail_config['vacation_gui_vacationforwarder'] = TRUE; + ## - $rcmail_config['vacation_sql_write'] = + ## - array("DELETE FROM vacation WHERE email=%email AND " . + ## - "domain=%email_domain;", + ## - "DELETE from vacation_notification WHERE on_vacation=%email;", + ## - "INSERT INTO vacation (email,domain,subject,body,created," . + ## - "active) VALUES (%email,%email_domain,%vacation_subject," . + ## - "%vacation_message,NOW(),%vacation_enable);", + ## - "UPDATE alias SET goto = FORWARDERS_IN(%vacation_forwarder," . + ## - "%email,'$_autoreply_domain',',',%vacation_enable)" . + ## - ", modified = NOW() " . + ## - " WHERE address = %email" + ## - ); + ## - */ + ## - + ## - /* - NEW: vcation.pl included in posfixadmin since version 2.91 */ + ## - $rcmail_config['vacation_gui_vacationforwarder'] = TRUE; + ## - $rcmail_config['vacation_sql_write'] = + ## - array("DELETE FROM vacation WHERE email=%email AND domain=%email_domain;", + ## - "DELETE from vacation_notification WHERE on_vacation=%email;", + ## - "INSERT INTO vacation (email,domain,subject,body,activefrom,activeuntil,interval_time,created,active) " . + ## - "VALUES (%email,%email_domain,%vacation_subject,%vacation_message," . + ## - "CONCAT(DATE(FROM_UNIXTIME(%vacation_start)), ' 00:00:00')," . + ## - "CONCAT(DATE(FROM_UNIXTIME(%vacation_end)), ' 23:59:59')," . + ## - "86400,NOW(),%vacation_enable);", + ## - "UPDATE alias SET goto = FORWARDERS_IN(%vacation_forwarder," . + ## - "%email,'$_autoreply_domain',',',%vacation_enable)" . + ## - ", modified = NOW() " . + ## - " WHERE address = %email" + ## - ); + ## - + ## - + vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/vacation/config.inc.php + + + ## - create function FORWARDERS_OUT: + ## - + cat < /tmp/FORWARDERS_OUT.sql +DROP FUNCTION IF EXISTS FORWARDERS_OUT ; + +DELIMITER | + +CREATE FUNCTION FORWARDERS_OUT (email_str TEXT, vacation_domain TEXT , list_seperator CHAR) + RETURNS TEXT + DETERMINISTIC + BEGIN + DECLARE forward_str TEXT; + DECLARE local_email_part TEXT; + DECLARE domain_email_part TEXT; + DECLARE first_char CHAR; + DECLARE last_char CHAR; + + -- get list of forwarders + -- + SELECT goto INTO forward_str FROM alias WHERE address=email_str; + + -- entferne mailbox emailadresse + -- + SET forward_str = REPLACE(forward_str, email_str, '' ); + -- SELECT REPLACE(forward_str, email_str, '' ) INTO forward_str; + + -- entferne vacation adresse + -- + SET local_email_part = SUBSTRING(email_str,1, LOCATE('@',email_str) - 1); + SET domain_email_part = SUBSTRING(email_str, LOCATE('@',email_str) + 1, LENGTH(email_str)); + SET forward_str = REPLACE(forward_str, CONCAT(local_email_part, "#" ,domain_email_part,"@", vacation_domain), ''); + -- SELECT REPLACE(forward_str, CONCAT(list_seperator,list_seperator), list_seperator) INTO forward_str; + + -- enferne doppelte seperatorzeichen + -- + WHILE LOCATE(CONCAT(list_seperator,list_seperator) , forward_str) DO + SET forward_str = REPLACE(forward_str, CONCAT(list_seperator,list_seperator), list_seperator); + -- SELECT REPLACE(forward_str, CONCAT(list_seperator,list_seperator), list_seperator) INTO forward_str; + END WHILE ; + + -- entferne erstes zeichen wenn es das seperatorzeichen ist + -- + IF LEFT(forward_str,1) = list_seperator THEN + SET forward_str = SUBSTRING(forward_str FROM 2); + -- SELECT SUBSTRING(forward_str FROM 2) INTO forward_str; + END IF; + + -- entferne letztes zeichen wenn es das seperatorzeichen ist + -- + IF RIGHT(forward_str,1) = list_seperator THEN + SET forward_str = SUBSTRING(forward_str , 1, LENGTH(forward_str) - 1); + -- SELECT SUBSTRING(forward_str , 1, LENGTH(forward_str) - 1) INTO forward_str; + END IF; + + RETURN forward_str; + END | + +DELIMITER ; +EOF + + ## - create function + ## - + ## - Note 1. + ## - Create function as postfix database user + ## - + ## - The postfix databaseuser wil need 'Super_priv'. At MySQL monitor + ## - (as mysql admin user i.e. root) type: + ## - UPDATE user SET Super_priv = 'Y' WHERE User = 'postfix'; + ## - + ## - Note 2. + ## - You can verify on mysql monitor (database postfix) with: + ## - SHOW FUNCTION STATUS; + ## - or see the code: + ## - SHOW CREATE FUNCTION FORWARDERS_OUT; + ## - + mysql -upostfix -p postfix < /tmp/FORWARDERS_OUT.sql + + rm /tmp/FORWARDERS_OUT.sql + + + ## - create database function FORWARDERS_IN: + ## - + cat < /tmp/FORWARDERS_IN.sql +DROP FUNCTION IF EXISTS FOWARDERS_IN ; + +DELIMITER | + +CREATE FUNCTION FORWARDERS_IN (forewarders_str TEXT, + email_str TEXT, + vacation_domain TEXT , + list_seperator CHAR , + vacation_enable BOOLEAN) + RETURNS TEXT + DETERMINISTIC + BEGIN + DECLARE return_str TEXT; + DECLARE local_email_part TEXT; + DECLARE domain_email_part TEXT; + + + SET return_str = email_str; + + IF vacation_enable THEN + SET local_email_part = SUBSTRING(email_str,1, LOCATE('@',email_str) - 1); + SET domain_email_part = SUBSTRING(email_str, LOCATE('@',email_str) + 1, LENGTH(email_str)); + SET return_str = CONCAT(return_str, list_seperator, local_email_part, "#" ,domain_email_part,"@", vacation_domain); + END IF; + + IF LENGTH(forewarders_str) > 2 THEN + SET return_str = CONCAT(return_str, list_seperator, forewarders_str); + END IF; + + RETURN return_str; + END | + +DELIMITER ; +EOF + + + ## - create function FOWARDERS_IN + ## - + ## - Note 1. + ## - Create function as postfix database user + ## - + ## - The postfix databaseuser wil need 'Super_priv'. At MySQL monitor + ## - (as mysql admin user i.e. root) type: + ## - UPDATE user SET Super_priv = 'Y' WHERE User = 'postfix'; + ## - + ## - Note 2. + ## - You can verify on mysql monitor (database postfix) with: + ## - SHOW FUNCTION STATUS; + ## - or see the code: + ## - SHOW CREATE FUNCTION FOWARDERS_IN; + ## - + + mysql -upostfix -p postfix < /tmp/FORWARDERS_IN.sql + + rm /tmp/FORWARDERS_IN.sql + +else + echo -e "\n\t[ ERROR ]: Unknown database type \"$_db_type\"" +fo + + +## - register vacation plugin with roundcube +## - +## - edit $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/config.inc.php +## - +## - add "rc-vacation" to array plugins +## - $rcmail_config['plugins'] = array('jquery', 'password', 'vacation'); +## - +vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/config.inc.php + + + +## -------------------------------------------------------- # +## --- Install plugin language selector on login screen --- # +## -------------------------------------------------------- # + +## - see: https://github.com/hassansin/roundcube-login-language/ + +## - Download from site https://github.com/hassansin/roundcube-login-language/ and +## - store archive in $WEBMAIL_BASEDIR +## - +cd $WEBMAIL_BASEDIR +rm login-language-master.zip +wget -O login-language-master.zip https://github.com/hassansin/roundcube-login-language/archive/master.zip + +cd $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins +unzip $WEBMAIL_BASEDIR/login-language-master.zip +ln -s roundcube-login-language-master/ $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/login_lang + +cp $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/login_lang/config.inc.php.dist \ + $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/login_lang/config.inc.php + + +## - edit config.php and set default language selection +## - +## - $config['language_dropdown_selected'] = 'de_DE'; +## - +vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/login_lang/config.inc.php + + +## - register language selector plugin with roundcube +## - +## - edit $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/config.inc.php +## - +## - add "login_lang" to array plugins +## - $config['plugins'] = array('login_lang', 'jqueryui', 'password', 'vacation'); +## - +vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/config.inc.php + + + +## -------------------------------------------------- # +## --- integrate ContextMenu plugin for roundcube --- # +## -------------------------------------------------- # + +## - see: https://github.com/JohnDoh/Roundcube-Plugin-Context-Menu + +## - Download from site https://github.com/bhuisgen/rc-vacation/ and +## - store archive in $WEBMAIL_BASEDIR +## - +cd $WEBMAIL_BASEDIR +rm Roundcube-Plugin-Context-Menu-master.zip +wget -O Roundcube-Plugin-Context-Menu-master.zip https://github.com/JohnDoh/Roundcube-Plugin-Context-Menu/archive/master.zip + +cd $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins +unzip $WEBMAIL_BASEDIR/Roundcube-Plugin-Context-Menu-master.zip +ln -s Roundcube-Plugin-Context-Menu-master $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/contextmenu + + +## - register ContextMenu plugin with roundcube +## - +## - edit $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/config.inc.php +## - +## - add "login_lang" to array plugins +## - $config['plugins'] = array('login_lang', 'jqueryui', 'password', 'vacation', 'contextmenu'); +## - +vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/config.inc.php + + + + +## ---------------------------------- # +## --- Install plugin markasjunk2 --- # +## ---------------------------------- # + +cd $WEBMAIL_BASEDIR +rm Roundcube-Plugin-Mark-as-Junk-2-master.zip +wget -O Roundcube-Plugin-Mark-as-Junk-2-master.zip https://github.com/JohnDoh/Roundcube-Plugin-Mark-as-Junk-2/archive/master.zip + +cd $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins +unzip $WEBMAIL_BASEDIR/Roundcube-Plugin-Mark-as-Junk-2-master.zip +ln -s Roundcube-Plugin-Mark-as-Junk-2-master $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/markasjunk2 + +cp $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/markasjunk2/config.inc.php.dist \ + $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/plugins/markasjunk2/config.inc.php + + +## - register markasjunk2 plugin with roundcube +## - +## - edit $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/config.inc.php +## - +## - add "login_lang" to array plugins +## - $config['plugins'] = array('login_lang', 'jqueryui', 'password', 'vacation', 'contextmenu','markasjunk2'); +## - +vim $WEBMAIL_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/config.inc.php + + + + + diff --git a/README.dovecot.systemd b/README.dovecot.systemd new file mode 100644 index 0000000..6d2aeaa --- /dev/null +++ b/README.dovecot.systemd @@ -0,0 +1,21 @@ + + +Debian Jessie comes with systemd so you really should not use initscript anymore but +switch to systemd for starting dovecot. There is systemd service description file available +for you in case your vendor does not provide it in the package: + +https://github.com/dovecot/core/blob/master/dovecot.service.in + +-- + +> i use ./configure with +> --with-systemdsystemunitdir=/etc/systemd/system/ and that installs the +> systemd.service and socket + +That's what I missed, thank you a lot. And service seems to handle +correctly restarts + +Also use: + --with-rundir=/var/run/dovecot + +-- diff --git a/README.install b/README.install new file mode 100644 index 0000000..baa872b --- /dev/null +++ b/README.install @@ -0,0 +1,51 @@ +# - Install complete Mailsystem +# - =========================== +# - +# - postfix +# - vacation, postfixadmin +# - amavisd-new +# - dovecot +# - roundcube +# - opendekim +# - +# - Assuming the following services are installed (and running) correctly: +# - apache2 webservice +# - PHP engine +# - Let's encrypt (dehydrated - optional +# - + +1.) Install Postfix + - run script 'install_postfix_advanced.sh' + if running the forst time, configuration file conf/install_postfix_advanced.conf + will be created automatically. + choose 'complete Mailserver (with mailboxes)' + + +2.) Install vacation and postfixadmin + - create configuration file 'install_postfixadmin.conf' + cp -a conf/install_postfixadmin.conf.sample conf/install_postfixadmin.conf + - adjust config file 'conf/install_postfixadmin.conf' to your needs + - run script 'install_postfixadmin.sh' + + +3.) Install AMaViS + - run script 'install_amavis.sh'. + if running the forst time, configuration file conf/install_amavis.sh.conf + will be created automatically. + + +4.) Install dovecot + - create configuration file 'install_update_dovecot.conf' + cp -a conf install_update_dovecot.conf.sample install_update_dovecot.conf + - adjust configuration file 'install_update_dovecot.conf' to your needs + - run script 'install_update_dovecot.sh' + +5.) Install roundcube webmailer + - create configuration file 'install_upgrade_roundcube.conf' + sp -a install_upgrade_roundcube.conf.sample install_upgrade_roundcube.conf + - adjust config file 'install_upgrade_roundcube.conf' to your needs + run script 'install_roundcube.sh'. + + +6.) Install OpenDKIM + - run script 'install_opendkim.sh'. diff --git a/conf/install_postfix_advanced.conf.sample b/conf/install_postfix_advanced.conf.sample new file mode 100644 index 0000000..705c153 --- /dev/null +++ b/conf/install_postfix_advanced.conf.sample @@ -0,0 +1,17 @@ +# ---------------------------------------------------- +# --- +# - Parameter Settings Postfix Bases System +# - +# - Note: You need not to create a configuration file, +# - the installation script will do that. +# --- +# ---------------------------------------------------- + +_HOSTNAME= +_IPV4= +_IPV6= +_ADMIN_EMAIL= +_SASL_AUTH= +_SASL_USER= +_SASL_PASS= +_RELAY_HOST= diff --git a/conf/install_postfix_base.conf.sample b/conf/install_postfix_base.conf.sample new file mode 100644 index 0000000..705c153 --- /dev/null +++ b/conf/install_postfix_base.conf.sample @@ -0,0 +1,17 @@ +# ---------------------------------------------------- +# --- +# - Parameter Settings Postfix Bases System +# - +# - Note: You need not to create a configuration file, +# - the installation script will do that. +# --- +# ---------------------------------------------------- + +_HOSTNAME= +_IPV4= +_IPV6= +_ADMIN_EMAIL= +_SASL_AUTH= +_SASL_USER= +_SASL_PASS= +_RELAY_HOST= diff --git a/conf/install_postfixadmin.conf.sample b/conf/install_postfixadmin.conf.sample new file mode 100644 index 0000000..80afd3b --- /dev/null +++ b/conf/install_postfixadmin.conf.sample @@ -0,0 +1,260 @@ +# ----------------------------------------------- +# - Configuration for postfixadmin install script +# ----------------------------------------------- + +# - Version of Postfix Admin +# - +PF_ADMIN_VERSION= + +# - Name of the website - usualy 'webmail..' +# - +WEBSITE_NAME="" + +# - IPv4 Address +# - +IPV4="" + +# - IPv6 Address +# - +IPV6="" + +# - Is apache installed from debian package system ? +# - +# - Boolean, possible values are 'true', 'false' +# - +# - Defaults to 'false' +# +#APACHE_DEBIAN_INSTALLATION="" + +# - Apache User +# - +# - If ommitted, script tries to determine the user under which user the webserver +# - is running. If that fails, parameter defaults to 'www-data' +# - +#HTTP_USER="" + +# - Apache Group +# - +# - If ommitted, script tries to determine the user under which group the webserver +# - is running. If that fails, parameter defaults to 'www-data' +# - +#HTTP_GROUP="" + +# - Webmasters E-Mail Address +# - +# - Defaults to 'admin@.' +# - +#WEBMASTER_EMAIL="" + +# - Base Directory of Roundcube Website +# - +# - Note: it's not the 'DocumentRoot' directory, but the directory where +# - the 'DocumentRoot' Directory lives. +# - +# - Defaults to '/var/www/$WEBSITE_NAME' +# - +#WEBSITE_BASEDIR="" + +# - Directory, where apache places the log-files for thw webmailers site. +# - +# - Defaults to '/var/log/apache2' +# - +#APACHE_LOG_DIR="" + +# - Directory where certificate and key for the roundcube website +# - are stored. +# - +# - Example: +# - APACHE_CERT_DIR="/var/lib/dehydrated/certs/$WEBSITE_NAME" +# - +# - Defaults to +# - '/etc/apache2' if apache is installed from debian package system +# - '/usr/local/apache2/conf' otherwise +# - +APACHE_CERT_DIR="" + +# - Certificate for the Rounfcube Website +# - +# - Example: +# - APACHE_SERVER_CERT="fullchain.pem" +# - +# - Defaults to 'server-bundle.crt' +# - +APACHE_SERVER_CERT="" + +# - Key File for the Rounfcube Website +# - +# - Example: +# - APACHE_SERVER_KEY="privkey.pem" +# - +# - Defaults to 'server.key' +# - +APACHE_SERVER_KEY="" + +# - Certification Chain File +# - +# - Deprecated since Apache 2.4 - Leave empty if not present +# - +#CERT_ChainFile="" + +# - Type of PHP installation. +# - +# - Possible values are: 'php_fpm' , 'fcgid' , 'mod_php +# - +# - defaults to 'php_fpm'' +# - +#PHP_TYPE="" + +# - Directory where apache vhosts definitions live. +# - +# - Defaults to +# - '/etc/apache2/sites-available' if installed from debain package system +# - '/usr/local/apache2/conf/vhosts' otherwise +# - +#APACHE_VHOST_DIR="" + +# - Hostname for vacation / absence messages +# - +# - Defaults to 'autoreply.. +# - +#AUTOREPLY_HOSTNAME="" + + + +# - Is MySQL installed from debian package system? +# - +# - Only needed, if DB_TYPE is set to 'mysql' +# - +# - Defaults to 'false' +# - +#MYSQL_DEBIAN_INSTALLATION="" + +# - mysql_credential_args (root access to MySQL Database) +# - +# - Example +# - mysql_credential_args="--login-path=local" +# - mysql_credential_args="--defaults-file=/etc/mysql/debian.cnf" (Debian default) +# - mysql_credential_args="--defaults-file=/usr/local/mysql/sys-maint.cnf" +# - +# - Defaults to: +# - '/etc/mysql/debian.cnf' if MySQL is installed from debian package system +# - '/usr/local/mysql/sys-maint.cnf' otherwise +# - +#MYSQL_CREDENTIALS="" + + +# - The wa passwords will be encrypted. +# - +# - $CONF['encrypt'] +# - +# - Possible values: +# - md5crypt = internal postfix admin md5 +# - md5 = md5 sum of the password +# - cleartext = clear text passwords +# - mysql_encrypt = useful for PAM integration +# - +# - authlib = support for courier-authlib style passwords - also set $CONF['authlib_default_flavor'] +# - dovecot:CRYPT-METHOD = use dovecotpw -s 'CRYPT-METHOD'. Example: dovecot:CRAM-MD5 +# - IMPORTANT: +# - - don't use dovecot:* methods that include the username in the hash - you won't be able +# - to login to PostfixAdmin in this case +# - - you'll need at least dovecot 2.1 for salted passwords ('doveadm pw' 2.0.x doesn't support the '-t' option) +# - - dovecot 2.0.0 - 2.0.7 is not supported +# - +ENCRYPTION_METHOD="cleartext" +#ENCRYPTION_METHOD="dovecot:CRAM-MD5" + +# - If you use the dovecot encryption method: where is the dovecotpw binary located? +# - +# - Defaults to '/usr/local/dovecot/bin/doveadm pw' +# - +#DOVEADM_PW="" + +# - Directory where deleted mailbox will be saved +# - +# - defaults to '/var/deleted-maildirs' +# - +#DELETED_MAILBOX_DIR= + +# - Directory where deleted domains will be saved +# - +# - defaults to '/var/deleted-maildomains' +# - +#DELETED_DOMAINS_DIR= + +# - Welcome Message +# - This message is send to every newly created mailbox. +# - +WELCOME_MESSAGE=" +Hallo, + +Ihre/Deine neue E-Mail Adresse ist eingerichtet. + +O.OPEN + +-- +O.OPEN | Phone: +49 30 / 290 484 91 +Erkelenzdamm 21 | Fax: +49 30 / 290 484 99 +D-10999 Berlin | E-MAIL: oo@oopen.de +" + + +# ========== +# - Settings Postfix Database +# ========== + +# - Type of Postfix database +# - +# - Possible values are 'pgsql' (PostgeSQL) or 'mysql' (MySQL) +# - +POSTFIX_DB_TYPE="pgsql" + +# - Host of Postfix Database +# - +# - Defaults to 'localhost' +# - +#POSTFIX_DB_HOST="" + +# - Unix socket where PostgreSQL is listening +# - +# - Only possible, for postgreSQL +# - +# - Defaults to '/var/run/postgresql' +# - +#POSTFIX_DB_SOCKET="" + +# - Name of Postfix Database +# - +# - Defaults to 'postfix' +# - +#POSTFIX_DB_NAME= + +# - User of Postfix Database +# - +# - used for setting $config['password_db_dsn'] +# - +# - Defaults to 'postfix' +# - +#POSTFIX_DB_USER="" + +# - Password of Postfix Database +# - +POSTFIX_DB_PASS='' + + +# ========== +# - vacation +# ========== + +# - Vacation User +# - +# - Defaults to 'vacation' +# - +#VACATION_USER="" + +# - Vacation Group +# - +# - Defaults to '' +# - +#VACATION_GROUP="vacation" + diff --git a/install_amavis.sh b/install_amavis.sh new file mode 100755 index 0000000..0ae8811 --- /dev/null +++ b/install_amavis.sh @@ -0,0 +1,3734 @@ +#!/usr/bin/env bash + +_QUARANTINE_ADMIN='postmaster\@$mydomain' +QUARANTINE_ADMIN=$_QUARANTINE_ADMIN + + +# ------------- +# --- Some functions +# ------------- +echononl(){ + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo -e -n "$*\\c" 1>&2 + else + echo -e -n "$*" 1>&2 + fi + rm /tmp/shprompt$$ +} + +fatal(){ + echo "" + echo -e "fatal error: $*" + echo "" + echo -e "\t\033[31m\033[1mInstalllation will be interrupted\033[m\033[m" + echo "" + exit 1 +} + +error(){ + echo "" + echo -e "\t[ \033[31m\033[1mFehler\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 "" +} + +echo_done() { + echo -e "\033[80G[ \033[32mdone\033[m ]" +} +echo_ok() { + echo -e "\033[80G[ \033[32mok\033[m ]" +} +echo_warning() { + echo -e "\033[80G[ \033[33m\033[1mwarn\033[m ]" +} +echo_failed(){ + echo -e "\033[80G[ \033[1;31mfailed\033[m ]" +} +echo_skipped() { + echo -e "\033[80G[ \033[33m\033[1mskipped\033[m ]" +} + + +# - Is this a systemd system? +# - +if [[ "X`which systemd`" = "X" ]]; then + systemd_exists=false +else + systemd_exists=true +fi + +echo "" + + +script_dir="$(realpath $(dirname $0))" +conf_file="${script_dir}/conf/install_amavis.conf" + +if [[ -f "$conf_file" ]]; then + source $conf_file +fi + +#clear +#echo "" +#echo -e "\033[32m--\033[m" +#echo "" +#echononl "Run with Install Script with previous settings (yes/no): " +#read OK +#OK=${OK,,} +#if [[ "X$OK" = "X" ]] ; then +# OK=yes +#fi +#while [ "X$OK" != "Xyes" -a "X$OK" != "Xno" ]; do +# echononl "Wrong entry! [yes/no]: " +# read OK +# OK=${OK,,} +#done +#[[ $OK = yes ]] && skip_interactive_use=true +# +#if $skip_interactive_use ; then +# +#HOSTNAME=$_HOSTNAME +#IPV4=$_IPV4 +#IPV6=$_IPV6 +# +#QUARANTINE_DIR=$_QUARANTINE_DIR +#QUARANTINE_ADMIN=$_QUARANTINE_ADMIN +# +#DB_IN_USE=$_DB_IN_USE +#DB_TYPE=$_DB_TYPE +#DB_HOST=$_DB_HOST +#DB_NAME=$_DB_NAME +#DB_USER=$_DB_USER +#DB_PASS=$_DB_PASS +#INSTALL_CLAMAV_UNOFFICIAL_SIGS=$_INSTALL_CLAMAV_UNOFFICIAL_SIGS +#MALWARE_PATROL_IN_USE=$_MALWARE_PATROL_IN_USE +#MALWERE_PATROL_FREE=$_MALWERE_PATROL_FREE +#MP_RECEIPT_NUMBER=$_MP_RECEIPT_NUMBER +#SECURITE_INFO_IN_USE=$_SECURITE_INFO_IN_USE +#SI_AUTHORISATION_SIGNATURE=$_SI_AUTHORISATION_SIGNATURE +# +#else +#clear +#echo -e "\033[21G\033[32mInstallation script for AMaViS, Spamassassin and ClamAV\033[m" +#echo + +clear +echo -e "\033[21G\033[32mInstallation script for AMaViS, Spamassassin and ClamAV\033[m" +echo + + +HOSTNAME= +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Insert hostname" +echo "" +if [[ -n "$_HOSTNAME" ]]; then + echononl "hostname [${_HOSTNAME}]: " + read HOSTNAME + if [[ "X${HOSTNAME}" = "X" ]]; then + HOSTNAME=$_HOSTNAME + fi +else + while [[ "X${HOSTNAME}" = "X" ]]; do + echononl "hostname: " + read HOSTNAME + if [[ "X${HOSTNAME}" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mHostname is reqired\033[m\n" + fi + done +fi + + +IPV4= +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Insert IPv4 address" +echo "" +if [[ -n "$_IPV4" ]]; then + echononl "IPv4 address [${_IPV4}]: " + read IPV4 + if [[ "X${IPV4}" = "X" ]]; then + IPV4=$_IPV4 + fi +else + while [[ "X${IPV4}" = "X" ]]; do + echononl "IPv4 address: " + read IPV4 + if [[ "X${IPV4}" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mIPv4 address is reqired\033[m\n" + fi + done +fi +IPV6= +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Insert IPv6 address" +echo "Type:" +echo -e "\t\033[33mNone\033[m if IPv6 is not suppoerted" +echo "" +if [[ -n "$_IPV6" ]]; then + [[ "X$_IPV6" = "Xdisabled" ]] && _IPV6=None + echononl "IPv6 address [${_IPV6}]: " + read IPV6 + if [[ "X${IPV6}" = "X" ]]; then + IPV6=$_IPV6 + fi +else + while [[ "X${IPV6}" = "X" ]]; do + echononl "IPv6 address: " + read IPV6 + if [[ "X${IPV6}" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mIPv4 address is reqired\033[m\n" + fi + done +fi +if [ "X$IPV6" = "Xnone" -o "X$IPV6" = "XNone" ]; then + IPV6=disabled +fi + + +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Insert quarantine directory" +echo "" +echo "" +QUARANTINE_DIR= +if [[ -n "$_QUARANTINE_DIR" ]] ; then + while [[ "X$QUARANTINE_DIR" = "X" ]]; do + echononl "Quarantine Directory [$_QUARANTINE_DIR]: " + read QUARANTINE_DIR + if [[ "X$QUARANTINE_DIR" = "X" ]]; then + QUARANTINE_DIR=$_QUARANTINE_DIR + fi + done +else + + while [[ "X$QUARANTINE_DIR" = "X" ]]; do + echononl "Quarantine Directory: " + read QUARANTINE_DIR + if [[ "X$QUARANTINE_DIR" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mQuarantine Directory is reqired\033[m\n" + fi + done +fi + +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Should ClamAV unofficial Singatures be installed?" +echo "" +if [[ -z "$_INSTALL_CLAMAV_UNOFFICIAL_SIGS" ]]; then + echononl "Install ClamAV unofficial Singatures (yes/no): " +else + if $_INSTALL_CLAMAV_UNOFFICIAL_SIGS ; then + echononl "Install ClamAV unofficial Singatures [yes]: " + else + echononl "Install ClamAV unofficial Singatures [no]: " + fi +fi +read _TMP_INSTALL_CUS +_TMP_INSTALL_CUS=${_TMP_INSTALL_CUS,,} +while [ "X$_TMP_INSTALL_CUS" != "Xyes" -a "X$_TMP_INSTALL_CUS" != "Xno" ]; do + if [[ -z "$_INSTALL_CLAMAV_UNOFFICIAL_SIGS" ]]; then + echononl "Wrong entry! (yes/no): " + read _TMP_INSTALL_CUS + _TMP_INSTALL_CUS=${_TMP_INSTALL_CUS,,} + else + if [ "X$_TMP_INSTALL_CUS" != "Xyes" -a "X$_TMP_INSTALL_CUS" != "Xno" ]; then + if $_INSTALL_CLAMAV_UNOFFICIAL_SIGS ; then + _TMP_INSTALL_CUS=yes + else + _TMP_INSTALL_CUS=no + fi + fi + fi +done +if [[ "$_TMP_INSTALL_CUS" = "yes" ]] ; then + INSTALL_CLAMAV_UNOFFICIAL_SIGS=true +else + INSTALL_CLAMAV_UNOFFICIAL_SIGS=false +fi + +if $INSTALL_CLAMAV_UNOFFICIAL_SIGS ; then + echo "" + echo -e "\033[32m--\033[m" + echo "" + echo "Load MalwarePatrol Signatures (https://www.malwarepatrol.net)?" + echo "" + echo "Note: You have to sign up for an account. For a free account thats here:" + echo " https://www.malwarepatrol.net/signup-free.shtml" + echo "" + if [[ -z "$_MALWARE_PATROL_IN_USE" ]]; then + echononl "Load MalwarePatrol Singatures (yes/no): " + else + if $_MALWARE_PATROL_IN_USE ; then + echononl "Load MalwarePatrol Singatures [yes]: " + else + echononl "Load MalwarePatrol Singatures [no]: " + fi + fi + read _TMP_LOAD_MP + _TMP_LOAD_MP=${_TMP_LOAD_MP,,} + while [ "X$_TMP_LOAD_MP" != "Xyes" -a "X$_TMP_LOAD_MP" != "Xno" ]; do + if [[ -z "$_MALWARE_PATROL_IN_USE" ]]; then + echononl "Wrong entry! (yes/no): " + read _TMP_LOAD_MP + _TMP_LOAD_MP=${_TMP_LOAD_MP,,} + else + if [ "X$_TMP_LOAD_MP" != "Xyes" -a "X$_TMP_LOAD_MP" != "Xno" ]; then + if [[ "X$_TMP_LOAD_MP" = "X" ]]; then + if $_MALWARE_PATROL_IN_USE ; then + _TMP_LOAD_MP=yes + else + _TMP_LOAD_MP=no + fi + else + if $_MALWARE_PATROL_IN_USE ; then + echononl "Wrong entry! [yes]: " + else + echononl "Wrong entry! [no]: " + fi + read _TMP_LOAD_MP + fi + + fi + fi + done + if [[ "$_TMP_LOAD_MP" = "yes" ]] ; then + MALWARE_PATROL_IN_USE=true + else + MALWARE_PATROL_IN_USE=false + fi + + + if $MALWARE_PATROL_IN_USE ; then + + echo "" + echo "" + echo "Are you using a free account from MalwarePatrol?" + echo "" + echo "" + + if [[ -z "$_MALWERE_PATROL_FREE" ]] ; then + echononl " Using fgree acount from MalwarePatrol? (yes/no): " + else + if $_MALWERE_PATROL_FREE ; then + echononl "Using free acount from MalwarePatrol? [yes]: " + else + echononl "Using free acount from MalwarePatrol? [no]: " + fi + fi + read _TMP_FREE_MP + _TMP_FREE_MP=${_TMP_FREE_MP,,} + while [ "X$_TMP_FREE_MP" != "Xyes" -a "X$_TMP_FREE_MP" != "Xno" ]; do + if [[ -z "$_MALWERE_PATROL_FREE" ]]; then + echononl "Wrong entry! (yes/no): " + read _TMP_FREE_MP + _TMP_FREE_MP=${_TMP_FREE_MP,,} + else + if [ "X$_TMP_FREE_MP" != "Xyes" -a "X$_TMP_FREE_MP" != "Xno" ]; then + if [[ "X$_TMP_FREE_MP" = "X" ]]; then + if $_MALWERE_PATROL_FREE ; then + _TMP_FREE_MP=yes + else + _TMP_FREE_MP=no + fi + else + if $_MALWERE_PATROL_FREE ; then + echononl "Wrong entry! [yes]: " + else + echononl "Wrong entry! [no]: " + fi + read _TMP_FREE_MP + fi + fi + fi + done + if [[ "$_TMP_FREE_MP" = "yes" ]] ; then + MALWERE_PATROL_FREE=true + else + MALWERE_PATROL_FREE=false + fi + + + echo "" + echo -e "\033[32m--\033[m" + echo "" + echo "Insert receipt number for MalwarePatrol Account" + echo "" + echo "" + MP_RECEIPT_NUMBER= + if [[ -n "$_MP_RECEIPT_NUMBER" ]] ; then + while [[ "X$MP_RECEIPT_NUMBER" = "X" ]]; do + echononl "MalwarePatrol receipt number [$_MP_RECEIPT_NUMBER]: " + read MP_RECEIPT_NUMBER + if [[ "X$MP_RECEIPT_NUMBER" = "X" ]]; then + MP_RECEIPT_NUMBER=$_MP_RECEIPT_NUMBER + fi + done + else + + while [[ "X$MP_RECEIPT_NUMBER" = "X" ]]; do + echononl "MalwarePatrol receipt number: " + read MP_RECEIPT_NUMBER + if [[ "X$MP_RECEIPT_NUMBER" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mMalwarePatrol receipt number is reqired\033[m\n" + fi + done + fi + + + fi + + + echo "" + echo -e "\033[32m--\033[m" + echo "" + echo "Load SecuriteInfo Signatures (https://www.securiteinfo.com)?" + echo "" + echo "Note: You have to sign up for an account. For a free account thats here:" + echo " https://www.securiteinfo.com/clients/customers/signup" + echo "" + if [[ -z "$_SECURITE_INFO_IN_USE" ]]; then + echononl "Load SecuriteInfo Singatures (yes/no): " + else + if $_SECURITE_INFO_IN_USE ; then + echononl "Load SecuriteInfo Singatures [yes]: " + else + echononl "Load SecuriteInfo Singatures [no]: " + fi + fi + read _TMP_LOAD_SI + _TMP_LOAD_SI=${_TMP_LOAD_SI,,} + while [ "X$_TMP_LOAD_SI" != "Xyes" -a "X$_TMP_LOAD_SI" != "Xno" ]; do + if [[ -z "$_SECURITE_INFO_IN_USE" ]]; then + echononl "Wrong entry! (yes/no): " + read _TMP_LOAD_SI + _TMP_LOAD_SI=${_TMP_LOAD_SI,,} + else + if [ "X$_TMP_LOAD_SI" != "Xyes" -a "X$_TMP_LOAD_SI" != "Xno" ]; then + if [[ "X$_TMP_LOAD_SI" = "X" ]]; then + if $_SECURITE_INFO_IN_USE ; then + _TMP_LOAD_SI=yes + else + _TMP_LOAD_SI=no + fi + else + if $_SECURITE_INFO_IN_USE ; then + echononl "Wrong entry! [yes]: " + else + echononl "Wrong entry! [no]: " + fi + read _TMP_LOAD_SI + fi + fi + fi + done + if [[ "$_TMP_LOAD_SI" = "yes" ]] ; then + SECURITE_INFO_IN_USE=true + else + SECURITE_INFO_IN_USE=false + fi + + if $SECURITE_INFO_IN_USE ; then + echo "" + echo -e "\033[32m--\033[m" + echo "" + echo "Insert SecuriteInfo Authorisation Signature" + echo "" + echo "" + SI_AUTHORISATION_SIGNATURE= + if [[ -n "$_SI_AUTHORISATION_SIGNATURE" ]] ; then + while [[ "X$SI_AUTHORISATION_SIGNATURE" = "X" ]]; do + echononl "SecuriteInfo Authorisation Signature [$(echo ${_SI_AUTHORISATION_SIGNATURE:0:4})..$(echo ${_SI_AUTHORISATION_SIGNATURE: -4})]: " + read SI_AUTHORISATION_SIGNATURE + if [[ "X$SI_AUTHORISATION_SIGNATURE" = "X" ]]; then + SI_AUTHORISATION_SIGNATURE=$_SI_AUTHORISATION_SIGNATURE + fi + done + else + + while [[ "X$SI_AUTHORISATION_SIGNATURE" = "X" ]]; do + echononl "SecuriteInfo Authorisation Signature: " + read SI_AUTHORISATION_SIGNATURE + if [[ "X$SI_AUTHORISATION_SIGNATURE" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mSecuriteInfo Authorisation Signature is reqired\033[m\n" + fi + done + fi + fi + +fi + + + +if [[ -n "$_DB_IN_USE" ]]; then + DB_IN_USE=$_DB_IN_USE +else + DB_IN_USE=false +fi +DB_TYPE="" +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Are a database for lookup loca domains in use?" +echo "" +if [[ "$_DB_TYPE" = "MySQL" ]] ; then + echo -e "\033[37m\033[1m[1] MySQL\033[m" +else + echo "[1] MySQL" +fi +if [[ "$_DB_TYPE" = "PostgreSQL" ]] ; then + echo -e "[2] \033[37m\033[1mPostgeSQL\033[m" +else + echo "[2] PostgeSQL" +fi +if ! $DB_IN_USE ; then + echo -e "[3] \033[37m\033[1mSkip (No Database in use)\033[m" +else + echo "[3] Skip (No Database in use)" +fi +echo "" +echo "Type a number or press to choose highlighted value" +echo "" +echononl "Eingabe: " +while [ "$DB_TYPE" != "MySQL" -a "$DB_TYPE" != "PostgreSQL" -a "$DB_TYPE" != "None" ];do + read OPTION + case $OPTION in + 1) + DB_TYPE="MySQL" + DB_IN_USE=true + ;; + 2) + DB_TYPE="PostgreSQL" + DB_IN_USE=true + ;; + 3) + DB_TYPE="None" + DB_IN_USE=false + ;; + '') DB_TYPE=$_DB_TYPE + ;; + *) + echo "" + echo -e "\tFalsche Eingabe ! [ 1 = MySQL ; 2 = PostgreSQL , 3 = Skip] or type " + echo "" + echononl "Eingabe: " + ;; + esac +done + +if $DB_IN_USE ; then + + echo "" + echo "" + echo "Insert Database Host" + echo "" + DB_HOST= + if [[ -n "$_DB_HOST" ]] ; then + while [[ "X$DB_HOST" = "X" ]]; do + echononl "Database Host [$_DB_HOST]: " + read DB_HOST + if [[ "X$DB_HOST" = "X" ]]; then + DB_HOST=$_DB_HOST + fi + done + else + + while [[ "X$DB_HOST" = "X" ]]; do + echononl "Database Host: " + read DB_HOST + if [[ "X$DB_HOST" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mA Database Host is reqired\033[m\n" + fi + done + fi + + echo "" + echo "" + echo "Insert Database Name" + echo "" + DB_NAME= + if [[ -n "$_DB_NAME" ]] ; then + while [[ "X$DB_NAME" = "X" ]]; do + echononl "Database Name [$_DB_NAME]: " + read DB_NAME + if [[ "X$DB_NAME" = "X" ]]; then + DB_NAME=$_DB_NAME + fi + done + else + + while [[ "X$DB_NAME" = "X" ]]; do + echononl "Database Name: " + read DB_NAME + if [[ "X$DB_NAME" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mA Database Name is reqired\033[m\n" + fi + done + fi + + echo "" + echo "" + echo "Insert Database User" + echo "" + DB_USER= + if [[ -n "$_DB_USER" ]] ; then + while [[ "X$DB_USER" = "X" ]]; do + echononl "Database User [$_DB_USER]: " + read DB_USER + if [[ "X$DB_USER" = "X" ]]; then + DB_USER=$_DB_USER + fi + done + else + + while [[ "X$DB_USER" = "X" ]]; do + echononl "Database User: " + read DB_USER + if [[ "X$DB_USER" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mA Database User is reqired\033[m\n" + fi + done + fi + + echo "" + echo "" + echo "Insert Database Password" + echo "" + DB_PASS= + if [[ -n "$_DB_PASS" ]] ; then + while [[ "X$DB_PASS" = "X" ]]; do + echononl "Database Password [$_DB_PASS]: " + read DB_PASS + if [[ "X$DB_PASS" = "X" ]]; then + DB_PASS=$_DB_PASS + fi + done + else + + while [[ "X$DB_PASS" = "X" ]]; do + echononl "Database Password: " + read DB_PASS + if [[ "X$DB_PASS" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mA Database Password is reqired\033[m\n" + fi + done + fi + +else + DB_HOST=$_DB_HOST + DB_NAME=$_DB_NAME + DB_USER=$_DB_USER + DB_PASS=$_DB_PASS +fi + +#fi # if $skip_interactive_use + +clear +echo "" +echo "" +echo -e "\033[21G\033[32mStart Installation/Configuration of AMaViS with the following parameters\033[m" +echo "" +echo -e "\tHostname...............................: $HOSTNAME" +echo -e "\tIPv4 address...........................: $IPV4" +echo -e "\tIPv6 address...........................: $IPV6" +echo -e "\tQuarantine Directory ..................: $QUARANTINE_DIR" +echo "" +echo -e "\tInstall ClamAv Unoffical Sigs .........: $QUARANTINE_DIR" +if $INSTALL_CLAMAV_UNOFFICIAL_SIGS ; then + echo -e "\tInstall Signatures from MalwarePatrol..: $MALWARE_PATROL_IN_USE" + if $MALWARE_PATROL_IN_USE ; then + echo -e "\t Free MalwarePatrol account..........: $MALWERE_PATROL_FREE" + echo -e "\t MalwarePatrol receipt number........: $MP_RECEIPT_NUMBER" + fi + echo -e "\tInstall Signatures from SecuriteInfo...: $SECURITE_INFO_IN_USE" + if $SECURITE_INFO_IN_USE ; then + echo -e "\t SecuriteInfo auth signature.........: $(echo ${SI_AUTHORISATION_SIGNATURE:0:4})..$(echo ${SI_AUTHORISATION_SIGNATURE: -4})" + fi +fi +echo "" +echo -e "\tDatabase in use........................: $INSTALL_CLAMAV_UNOFFICIAL_SIGS" +if $DB_IN_USE ; then + echo -e "\t Database type.......................: $DB_TYPE" + echo -e "\t Database host.......................: $DB_HOST" + echo -e "\t Database name.......................: $DB_NAME" + echo -e "\t Database user.......................: $DB_USER" + echo -e "\t Database password...................: $DB_PASS" +fi +warn "Don't forget to oopen TCP Port 873 and TCP Port 443.\n\n It's needed by ClamAV Unofficial Signatures Installation" +echo "" +echononl "einverstanden (yes/no): " +read OK +OK=${OK,,} +while [ "X$OK" != "Xyes" -a "X$OK" != "Xno" ]; do + echononl "Wrong entry! [yes/no]: " + read OK + OK=${OK,,} +done +[ $OK = "yes" ] || fatal Repeat with other settings.. + + +echo "" +echo "" + +echononl " Save Configuration" +cat << EOF > $conf_file +# --- +# - Parametersettins postfix bases system +# --- + +_HOSTNAME=$HOSTNAME +_IPV4=$IPV4 +_IPV6=$IPV6 + +_QUARANTINE_DIR=$QUARANTINE_DIR +_QUARANTINE_ADMIN=$QUARANTINE_ADMIN + +_DB_IN_USE=$DB_IN_USE +_DB_TYPE=$DB_TYPE +_DB_HOST=$DB_HOST +_DB_NAME=$DB_NAME +_DB_USER=$DB_USER +_DB_PASS=$DB_PASS +_INSTALL_CLAMAV_UNOFFICIAL_SIGS=$INSTALL_CLAMAV_UNOFFICIAL_SIGS +_MALWARE_PATROL_IN_USE=$MALWARE_PATROL_IN_USE +_MALWERE_PATROL_FREE=$MALWERE_PATROL_FREE +_MP_RECEIPT_NUMBER=$MP_RECEIPT_NUMBER +_SECURITE_INFO_IN_USE=$SECURITE_INFO_IN_USE +_SI_AUTHORISATION_SIGNATURE=$SI_AUTHORISATION_SIGNATURE +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +tmp_err_msg=$(mktemp) + + +# ------------------------------- +#ommit=true +#if ! $ommit ; then + + + +echo +echo -e "\033[37m\033[1mSome pre-installation tasks..\033[m" +echo +# - Install Prerequisites from debian package system +# - +echononl " Install prerequisites from debian package system" +_needed_packages_base="libnet-ldap-perl \ + libauthen-sasl-perl \ + libsnmp-perl \ + libdbd-mysql \ + libdbd-mysql-perl \ + libdbd-pgsql \ + libdbd-pg-perl \ + libdbi-perl \ + libdbi-dev \ + g++ \ + cpanminus" +for _pkg in $_needed_packages_base ; do + if aptitude search "$_pkg" | grep " $_pkg " | grep -e "^i" > /dev/null 2>&1 ; then + continue + else + needed_packages_base="$needed_packages_base $_pkg" + fi +done +if [[ -n "$needed_packages_base" ]]; then + DEBIAN_FRONTEND=noninteractive apt-get -y install $needed_packages_base > /dev/null 2> "$tmp_err_msg" + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + echo_skipped +fi + +echononl " Install database related CPAN Modules" +installation_failed=false +_needed_cpan_modules="CPAN + DBI + DBD::mysql + DBD::Pg" +for _module in $_needed_cpan_modules ; do + cpanm -q --skip-installed $_module > "$tmp_err_msg" 2>&1 + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi +done +if ! $installation_failed ; then + echo_ok +fi + +## - Install package amavisd-new NOW, because we need at least the existence +## - of the AmaViS user (amavis) befor finally installation and configuration +## - of AmaViS itself. +## - +echononl " Install packages \"amavisd-new\"" +_pkg=amavisd-new +if aptitude search "$_pkg" | grep " $_pkg " | grep -e "^i" > /dev/null 2>&1 ; then + echo_skipped +else + DEBIAN_FRONTEND=noninteractive apt-get -y install $_pkg > "$tmp_err_msg" 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +fi + + + +echo +echo -e "\033[37m\033[1mGoing to install Spamassassin..\033[m" +echo +echononl " Install packages needed for Spamassassin" +_needed_packages_spamassassin="spamassassin razor \ + pyzor \ + libio-socket-ssl-perl \ + libdbi-perl \ + libmail-dkim-perl \ + libmail-spf-perl \ + libgeo-ipfree-perl \ + libnet-ident-perl \ + libio-zlib-perl \ + libio-string-perl \ + libimage-info-perl \ + libnet-cidr-lite-perl \ + libgeo-ip-perl \ + geoip-bin \ + libgeoip-dev \ + geoip-database \ + re2c \ + ftp \ + ncftp \ + less" +for _pkg in $_needed_packages_spamassassin ; do + if aptitude search $_pkg | grep " $_pkg " | grep -e "^i" > /dev/null 2>&1 ; then + continue + else + needed_packages_spamassassin="$needed_packages_spamassassin $_pkg" + fi +done +if [[ -n "$needed_packages_spamassassin" ]]; then + DEBIAN_FRONTEND=noninteractive apt-get -y install $needed_packages_spamassassin > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + echo_skipped +fi + +## - Download a sample spam file. For testing purpose you can feed it to spamassassin: +## - +## - # cp /root/sample-spam.txt /tmp +## - # cd /tmp +## - # su amavis -c 'spamassassin -D $tmp_err_msg +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +cp -a /tmp/sample-spam.txt /root > $tmp_err_msg 2>&1 +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +if ! $installation_failed ; then + echo_ok +fi + + +echo "" +echo -e " \033[37m\033[1mConfigure Pyzor..\033[m" + +info "Open firewall outgoing port 2441 for Pyzor" + +## - Pyzor configuration +## - +## - Here we supply the hostname of the Pyzor server to Pyzor (for both the +## - 'root' and 'amavis' users). This will create a .pyzor directory in both +## - user's home directories, and place the server's hostname in a 'servers' file +## - therein: +## - +echononl " Run pyzor discover (places server's hostname in file ~/.pyzor/servers)" +installation_failed=false +pyzor discover > /dev/null 2> $tmp_err_msg +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +su amavis -c 'pyzor discover' > /dev/null 2> $tmp_err_msg +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +if ! $installation_failed ; then + echo_ok +fi + +## - Pyzor Ping should show 'OK'. If not, then it's possible your firewall is +## - blocking udp replies from 82.94.255.100 or 188.40.77.236 (public.pyzor.org +## - port 24441), or the server may simply be slow to respond (often the case). +## - +echononl " Ping test for server's hostname" +installation_failed=false +if ! pyzor ping 2> $tmp_err_msg | grep "'OK'" > /dev/null 2>&1 ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +if ! su amavis -c 'pyzor ping' 2> $tmp_err_msg | grep "'OK'" > /dev/null 2>&1 ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +if ! $installation_failed ; then + echo_ok +fi + +echo "" +echo -e " \033[37m\033[1mConfigure Razor2..\033[m" + +info "Open firewall outgoing port 2703 for Razor2" + +_date="$(date +%Y-%m-%d-%H%M)" + +## - This next section gets Razor2 up and running and copies its files where +## - both root and amavis expect to find them. +## - +## - SpamAssassin is designed to enable each user to have their own settings and +## - data. This section will make both users happy. +## - +## - This is because if we are debugging SpamAssassin or Razor or Pyzor or DCC, +## - we want to be able to do so with spamassassin -D $tmp_err_msg 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + echo_skipped +fi + + +echononl " Backup directory \"/root/.razor.\"" +if [[ -d /root/.razor ]] ; then + mv /root/.razor /root/.razor."${_date}" > $tmp_err_msg 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + echo_skipped +fi + +## - Razor2 (Spamassassin Plugin) +## - +## - Razor configuration +## - +## - This next section configures Razor; sets the exclusive "razorhome" and +## - makes both root and amavis happy in their attempts to figure out "where +## - in the heck are the Razor2 configuration files"? +## - +echononl " Create \"razor-agent.conf\" in (user root)" +razor-admin -create > $tmp_err_msg 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + +## - Registers a new identity, used for authenticating with Razor Nomination Servers. +## - Identities are a user + password pair stored in "/identity-" +## - +echononl " Registers a new identity (user root)" +razor-admin -register > $tmp_err_msg 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + +## - Now edit root's razor configuration file: +## - +## - and change the line: +## - debuglevel = 3 +## - to: +## - debuglevel = 0 +## - +echononl " Adjust /root/.razor/razor-agent.conf" +perl -i -n -p -e "s#^(\s*)(debuglevel\s*=).*#\1\2 0#" /root/.razor/razor-agent.conf > $tmp_err_msg 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + + +## - Backup razor's configuration directory of user amavis if exists +## - +_home_amavais=$(realpath ~amavis) +echononl " Backup directory \"${_home_amavais}/.razor\"" +if [[ -d "${_home_amavais}/.razor" ]] ; then + mv ${_home_amavais}/.razor ${_home_amavais}/.razor."${_date}" + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + echo_skipped +fi + +## - Copy root's .razor directory and files to the amavis user's home directory +## - +echononl " Copy root's razor configuration to user \"amavis\" (${_home_amavais}/.razor)" +installation_failed=false +cp -r /root/.razor ${_home_amavais}/ > $tmp_err_msg 2>&1 +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +chown -R amavis:amavis ${_home_amavais}/.razor > $tmp_err_msg 2>&1 +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +if ! $installation_failed ; then + echo_ok + if [[ -d "${_home_amavais}/.razor.${_date}" ]] ; then + echononl " Delete previous created backup \"${_home_amavais}/.razor.${_date}\"" + rm -r "${_home_amavais}/.razor.${_date}" > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi + fi + if [[ -d "/root/.razor.${_date}" ]] ; then + echononl " Delete previous created backup \"/root/.razor.${_date}\"" + rm -r "/root/.razor.${_date}" > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi + fi +fi + + +## - Aadd a cronjob for razor2 updates +## - +## - +echononl " add a cronjob for razor2 updates" +if ! grep -i -E "/usr/bin/razor-admin\s+-discover" /var/spool/cron/crontabs/root > /dev/null 2>&1; then + installation_failed=false + crontab -l > /tmp/tmp_crontab 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + + cat << EOF >> /tmp/tmp_crontab + +# - Update razor2 +# - +33 0 * * * su amavis -lc '/usr/bin/razor-admin -discover' +EOF + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + crontab /tmp/tmp_crontab > /dev/null 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + rm /tmp/tmp_crontab > /dev/null 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + if ! $installation_failed ; then + echo_ok + fi +else + echo_skipped +fi + + +echo "" +echo -e " \033[37m\033[1mConfigure Distributed Checksum Clearinghouses (DCC)..\033[m" + +info "Open firewall outgoing port UDP 6277 and if DCC Server is running\n also in- and outfoing port TCP 6277." + + +if ps -ax | grep /var/dcc/libexec/dccifd | grep -v grep > /dev/null 2>&1 ; then + echononl " An instance off dccifd ist already running. Stop it now." + installation_failed=false + if $systemd_exists ; then + systemctl stop adcc > /dev/null 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + else + /etc/init.d/adcc stop > /dev/null 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + fi + if ! $installation_failed ; then + echo_ok + fi +fi + +_dcc_src_dir="$script_dir" +_archiv=dcc-dccproc.tar.Z +echononl " Create archive directory \"$_dcc_src_dir\"" +mkdir -p "$_dcc_src_dir" > $tmp_err_msg 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + +echononl " Download archide \"$_archiv\"" +wget -O ${_dcc_src_dir}/$_archiv http://www.dcc-servers.net/dcc/source/$_archiv > $tmp_err_msg 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + +echononl " Determin archiv directory.." +archiv_dir="${_dcc_src_dir}/$(dirname $(tar -tzf ${_dcc_src_dir}/$_archiv | head -n 1) 2> $tmp_err_msg)" +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + +echononl " Backup directory \"$archiv_dir\" if exists" +if [[ -d "$archiv_dir" ]]; then + mv "${archiv_dir}" "${archiv_dir}.$(date +%Y-%m-%d-%H%M)" > $tmp_err_msg 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + echo_skipped +fi + +echononl " Unpack \"${_dcc_src_dir}/$_archiv\"" +tar xzvf ${_dcc_src_dir}/$_archiv -C $_dcc_src_dir > $tmp_err_msg 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + +echononl " Change into directory \"$archiv_dir\"" +cd $archiv_dir +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + +echononl " Configure dcc" +./configure --with-uid=amavis > $tmp_err_msg 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + +echononl " Compile dcc" +make > $tmp_err_msg 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + +_lib_dir_dcc=/var/dcc +echononl " Backup directory \"${_lib_dir_dcc}\" if exists" +if [[ -d "$_lib_dir_dcc" ]]; then + mv "${_lib_dir_dcc}" "${_lib_dir_dcc}.$(date +%Y-%m-%d-%H%M)" > $tmp_err_msg 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + echo_skipped +fi + +echononl " Install dcc" +make install > $tmp_err_msg 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + + +## - Update file ownership: +#echononl " Update directory/file ownership of /var/dcc" +#chown -R amavis:amavis /var/dcc > $tmp_err_msg 2>&1 +#make install > $tmp_err_msg 2>&1 +#if [[ $? -eq 0 ]] ; then +# echo_ok +#else +# echo_failed +# error "$(cat $tmp_err_msg)" +#fi + + + +## - Add cronjob for updating and cleaning up dcc +## - +## - +echononl " Add a cronjob for updating and cleaning up dcc" +if ! grep -i -E "/var/dcc/libexec/cron-dccd" /var/spool/cron/crontabs/root > /dev/null 2>&1; then + installation_failed=false + crontab -l > /tmp/tmp_crontab 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + + cat << EOF >> /tmp/tmp_crontab + +# - Cleaning up dcc (Distributed Checksum Clearinghouses) +# - +13 1 * * * /var/dcc/libexec/cron-dccd + +EOF + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + crontab /tmp/tmp_crontab > /dev/null 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + rm /tmp/tmp_crontab > /dev/null 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + if ! $installation_failed ; then + echo_ok + fi +else + echo_skipped +fi + +_config_file=/var/dcc/dcc_conf +installation_failed=false +echononl " Adjust configuration file \"${_config_file}\"" +perl -i -n -p -e "s#^([ ]*\ *)(DCCIFD_ENABLE\s*=.*)#\#\#\1\2\nDCCIFD_ENABLE=on#" \ + $_config_file > $tmp_err_msg 2>&1 +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +perl -i -n -p -e "s#^([ ]*\ *)(DBCLEAN_LOGDAYS\s*=.*)#\#\#\1\2\nDBCLEAN_LOGDAYS=1#" \ + $_config_file > $tmp_err_msg 2>&1 +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +if ! $installation_failed ; then + echo_ok +fi + +echononl " Install start script (rcDCC) to automatically start dccifd at boot time" +installation_failed=false +cp /var/dcc/libexec/rcDCC /etc/init.d/adcc > /dev/null 2> $tmp_err_msg +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +if $systemd_exists ; then + systemctl enable adcc > /dev/null 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi +else + update-rc.d adcc defaults > /dev/null 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi +fi +if ! $installation_failed ; then + echo_ok +fi + + +echononl " Start daemon dccifd" +if $systemd_exists ; then + systemctl start adcc > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + /etc/init.d/adcc start > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +fi + +info "You can test DCC with command \033[37m\033[1mcdcc info\033[m\n\n You should get 'requests ok' from the servers but 'not answering' from 127.0.0.1 is expected." + + +#fi # if $ommit ; then +# ------------------------------- + +echo "" +echo -e " \033[37m\033[1mConfigure Spamassassin..\033[m" + +## - Backup existing SpamAssassin's main configuration file /etc/spamassassin/local.cf +## - +_config_file=/etc/spamassassin/local.cf +_date="$(date +%Y-%m-%d-%H%M)" +if [[ ! -f "${_config_file}.ORIG" ]]; then + echononl " Save installation version of ${_config_file} (Suffix \".ORIF\")" + cp -a "$_config_file" "${_config_file}.ORIG" > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + echononl " Backup $_config_file" + cp -a "$_config_file" "${_config_file}.${_date}" 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +fi + +echononl " Determin IP-Addresses for trusted systems" +TRUSTED_MAIL_SYSTEMS="a.mx.oopen.de b.mx.oopen.de c.mx.oopen.de d.mx.oopen.de" +_msg_trusted="clear_trusted_networks +" +_msg_internal="clear_internal_networks +" +for _mx_server in $TRUSTED_MAIL_SYSTEMS ; do + + installation_failed=false + if [[ "$_mx_server" = "$HOSTNAME" ]]; then + _msg_trusted="$_msg_trusted +# - $HOSTNAME +#trusted_networks $IPV4" + _msg_internal="$_msg_internal +# - $HOSTNAME +#internal_networks $IPV4" + if [[ -n "$IPV6" ]]; then + _msg_trusted="$_msg_trusted +#trusted_networks $IPV6" + _msg_internal="$_msg_internal +#internal_networks $IPV6" + fi + continue + fi + + _ipv4_server_addr="$(dig +short $_mx_server A)" + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + _ipv6_server_addr="$(dig +short $_mx_server AAAA)" + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + + if ! $installation_failed ; then + if [[ -n "$_ipv4_server_addr" ]] ; then + _msg_trusted="$_msg_trusted +# - $_mx_server +trusted_networks $_ipv4_server_addr" + _msg_internal="$_msg_internal +# - $_mx_server +internal_networks $_ipv4_server_addr" + + if [[ -n "$_ipv6_server_addr" ]]; then + _msg_trusted="$_msg_trusted +trusted_networks $_ipv6_server_addr" + _msg_internal="$_msg_internal +internal_networks $_ipv6_server_addr" + + fi + fi + fi +done +if ! $installation_failed ; then + echo_ok +fi + +## - Create new configuration file /etc/spamassassin/local.cf +## - +## - see also perldoc Mail::SpamAssassin::Conf +## - + +echononl " Create new configuration file /etc/spamassassin/local.cf" +cat << EOF > /etc/spamassassin/local.cf 2>$tmp_err_msg +# This is the right place to customize your installation of SpamAssassin. +# +# See 'perldoc Mail::SpamAssassin::Conf' for details of what can be +# tweaked. +# +# Only a small subset of options are listed below +# +########################################################################### + +# Add *****SPAM***** to the Subject header of spam e-mails +# +# rewrite_header Subject *****SPAM***** + + +# Save spam messages as a message/rfc822 MIME attachment instead of +# modifying the original message (0: off, 2: use text/plain instead) +# +# report_safe 1 +report_safe 0 + + +# Set which networks or hosts are considered 'trusted' by your mail +# server (i.e. not spammers) +# +# +# Our own IP's +# +# Notice: i decided not to trust our own ip's, because i want +# to filter also mails from local users out + +EOF +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi + +echo "$_msg_trusted" >> /etc/spamassassin/local.cf +echo "" >> /etc/spamassassin/local.cf +echo "$_msg_internal" >> /etc/spamassassin/local.cf + +cat << EOF >> /etc/spamassassin/local.cf 2>$tmp_err_msg + + +# Set file-locking method (flock is not safe over NFS, but is faster) +# +# lock_method flock +lock_method flock + + +# Set the threshold at which a message is considered spam (default: 5.0) +# +# required_score 5.0 +required_score 5.1 + + +# Use Bayesian classifier (default: 1) +# +# use_bayes 1 +use_bayes 1 +bayes_path /var/lib/amavis/.spamassassin/bayes + + +# Bayesian classifier auto-learning (default: 1) +# +# bayes_auto_learn 1 +bayes_auto_learn_threshold_spam 10.0 +bayes_auto_learn_threshold_nonspam -0.5 + + +# NOTE: Since there is a script that runs each day to --force-expire old +# Bayes tokens "/etc/cron.daily/amavisd-new" (make sure there is if +# you use this setting!), we can set: +# +bayes_auto_expire 0 + + +# Set headers which may provide inappropriate cues to the Bayesian +# classifier +# +# bayes_ignore_header X-Bogosity +# bayes_ignore_header X-Spam-Flag +# bayes_ignore_header X-Spam-Status +bayes_ignore_header X-Bogosity +bayes_ignore_header X-Spam-Flag +bayes_ignore_header X-Spam-Status + + +# Optional: +# Some people believe auto-whitelist is more of a liability than an asset: +# +#use_auto_whitelist 1 +#auto_whitelist_path /var/lib/amavis/.spamassassin/auto-whitelist + + +# Optional: +# We will normally have DNS available: +# +dns_available yes + + +# Enable or disable network checks +# +skip_rbl_checks 1 +use_razor2 1 +razor_timeout 8 + +use_dcc 1 +dcc_home /var/dcc + +use_pyzor 1 +pyzor_timeout 8 + +# Mail using locales used in these country codes will not be marked +# as being possibly spam in a foreign language. +# +ok_locales all + + +# Local delivery uses this flag to distinguish between possible spam +# and ham +# +# Again: in our setup wee NEED to set the spam flag +# +add_header spam Flag _YESNOCAPS_ + + +# Some shortcircuiting, if the plugin is enabled +# +ifplugin Mail::SpamAssassin::Plugin::Shortcircuit +# +# default: strongly-whitelisted mails are *really* whitelisted now, if the +# shortcircuiting plugin is active, causing early exit to save CPU load. +# Uncomment to turn this on +# +# shortcircuit USER_IN_WHITELIST on +# shortcircuit USER_IN_DEF_WHITELIST on +# shortcircuit USER_IN_ALL_SPAM_TO on +# shortcircuit SUBJECT_IN_WHITELIST on +shortcircuit USER_IN_WHITELIST on +shortcircuit USER_IN_DEF_WHITELIST on +shortcircuit USER_IN_ALL_SPAM_TO on +shortcircuit SUBJECT_IN_WHITELIST on + +# the opposite; blacklisted mails can also save CPU +# +# shortcircuit USER_IN_BLACKLIST on +# shortcircuit USER_IN_BLACKLIST_TO on +# shortcircuit SUBJECT_IN_BLACKLIST on +shortcircuit USER_IN_BLACKLIST on +shortcircuit USER_IN_BLACKLIST_TO on +shortcircuit SUBJECT_IN_BLACKLIST on + +# if you have taken the time to correctly specify your "trusted_networks", +# this is another good way to save CPU +# +# shortcircuit ALL_TRUSTED on +shortcircuit ALL_TRUSTED on + +# and a well-trained bayes DB can save running rules, too +# +# shortcircuit BAYES_99 spam +# shortcircuit BAYES_00 ham +shortcircuit BAYES_99 spam +shortcircuit BAYES_00 ham + +endif # Mail::SpamAssassin::Plugin::Shortcircuit +EOF +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +if ! $installation_failed ; then + echo_ok +fi + +if [[ -f "${_config_file}.${_date}" ]]; then + if diff "${_config_file}" "${_config_file}.${_date}" ; then + info "${_config_file} has not changed.\n\t Removing previos created backup.." + rm "${_config_file}.${_date}" + fi +fi + + +# - Adjust /etc/spamassassin/v310.pre +# - +_config_file=/etc/spamassassin/v310.pre +_date="$(date +%Y-%m-%d-%H%M)" +_backup_file="" +if [[ ! -f "${_config_file}.ORIG" ]]; then + echononl " Save installation version of ${_config_file} (Suffix \".ORIF\")" + cp -a "$_config_file" "${_config_file}.ORIG" > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi + _backup_file="${_config_file}.ORIG" +else + echononl " Backup $_config_file" + cp -a "$_config_file" "${_config_file}.${_date}" 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi + _backup_file="${_config_file}.${_date}" +fi + +installation_failed=false +_adjusted=false +echononl " Adjust configuration file \"${_config_file}\"" +if ! grep -i -E "\s*^loadplugin Mail::SpamAssassin::Plugin::AWL" $_config_file > /dev/null 2>&1 ; then + perl -i -n -p -e "s#^([ ]*\ *)(\#loadplugin Mail::SpamAssassin::Plugin::AWL.*)#\1\2\nloadplugin Mail::SpamAssassin::Plugin::AWL#" \ + $_config_file > $tmp_err_msg 2>&1 + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + _adjusted=true +fi +if ! grep -i -E "\s*^loadplugin Mail::SpamAssassin::Plugin::TextCat" $_config_file > /dev/null 2>&1 ; then + perl -i -n -p -e "s#^([ ]*\ *)(\#loadplugin Mail::SpamAssassin::Plugin::TextCat.*)#\1\2\nloadplugin Mail::SpamAssassin::Plugin::TextCat#" \ + $_config_file > $tmp_err_msg 2>&1 + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + _adjusted=true +fi +if ! grep -i -E "\s*^loadplugin Mail::SpamAssassin::Plugin::DCC" $_config_file > /dev/null 2>&1 ; then + perl -i -n -p -e "s#^([ ]*\ *)(\#loadplugin Mail::SpamAssassin::Plugin::DCC.*)#\1\2\nloadplugin Mail::SpamAssassin::Plugin::DCC#" \ + $_config_file > $tmp_err_msg 2>&1 + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + _adjusted=true +fi +if ! $installation_failed ; then + if $_adjusted ; then + echo_ok + else + echo_skipped + [[ -f "$_backup_file" ]] && rm "$_backup_file" + fi +fi + + +# - Adjust /etc/spamassassin/v312.pre +# - +_config_file=/etc/spamassassin/v312.pre +_date="$(date +%Y-%m-%d-%H%M)" +_backup_file="" +if [[ ! -f "${_config_file}.ORIG" ]]; then + echononl " Save installation version of ${_config_file} (Suffix \".ORIG\")" + cp -a "$_config_file" "${_config_file}.ORIG" > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + _backup_file=${_config_file}.ORIG + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + echononl " Backup $_config_file" + cp -a "$_config_file" "${_config_file}.${_date}" 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + _backup_file=${_config_file}.${_date} + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +fi + +installation_failed=false +_adjusted=false +echononl " Adjust configuration file \"${_config_file}\"" +if ! grep -i -E "\s*^loadplugin Mail::SpamAssassin::Plugin::DKIM" $_config_file > /dev/null 2>&1 ; then + perl -i -n -p -e "s#^([ ]*\ *)(\#\s*loadplugin Mail::SpamAssassin::Plugin::DKIM.*)#\1\2\nloadplugin Mail::SpamAssassin::Plugin::DKIM#" \ + $_config_file > $tmp_err_msg 2>&1 + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + _adjusted=true +fi +if ! $installation_failed ; then + if $_adjusted ; then + echo_ok + else + echo_skipped + [[ -f "$_backup_file" ]] && rm "$_backup_file" + fi +fi + + +# - Adjust /etc/spamassassin/v320.pre +# - +_config_file=/etc/spamassassin/v320.pre +_date="$(date +%Y-%m-%d-%H%M)" +_backup_file="" +if [[ ! -f "${_config_file}.ORIG" ]]; then + echononl " Save installation version of ${_config_file} (Suffix \".ORIG\")" + cp -a "$_config_file" "${_config_file}.ORIG" > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi + _backup_file="${_config_file}.ORIG" +else + echononl " Backup $_config_file" + cp -a "$_config_file" "${_config_file}.${_date}" 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi + _backup_file="${_config_file}.${_date}" +fi + +installation_failed=false +_adjusted=false +echononl " Adjust configuration file \"${_config_file}\"" +if ! grep -i -E "\s*^loadplugin Mail::SpamAssassin::Plugin::Rule2XSBody" $_config_file > /dev/null 2>&1 ; then + perl -i -n -p -e "s#^([ ]*\ *)(\#\s*loadplugin Mail::SpamAssassin::Plugin::Rule2XSBody.*)#\1\2\nloadplugin Mail::SpamAssassin::Plugin::Rule2XSBody#" \ + $_config_file > $tmp_err_msg 2>&1 + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + _adjusted=true +fi +if ! $installation_failed ; then + if $_adjusted ; then + echo_ok + else + echo_skipped + [[ -f "$_backup_file" ]] && rm "$_backup_file" + fi +fi + + +# - Enable nightly cronjob for spamassassin +# - +# - edit /etc/default/spamassassin and set: +# - CRON=1 +# - +_config_file=/etc/default/spamassassin +installation_failed=false +echononl " Adjust \"$_config_file\" (set CRON=1)" +if ! grep -i -E "\s*^CRON\s*=\s*1" $_config_file > /dev/null 2>&1 ; then + perl -i -n -p -e "s#^([ ]*\#?\ *)(CRON\ *=.*)#\#\#\1\2\nCRON=1#" $_config_file > $tmp_err_msg 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + echo_skipped +fi + +# - Add a cronjob for cleaning up bayes +# - +echononl " Add a cronjob for updating clamav (and freshclam) packages" +if ! grep -i -E "/usr/bin/sa-learn\s+--sync" /var/spool/cron/crontabs/root > /dev/null 2> $tmp_err_msg ; then + installation_failed=false + crontab -l > /tmp/tmp_crontab 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + + cat << EOF >> /tmp/tmp_crontab + +# - Cleanup sa bayes for espired entries +# - +33 3 * * * su amavis -lc "/usr/bin/sa-learn --sync >/dev/null" ; su amavis -lc "/usr/bin/sa-learn --sync --force-expire >/dev/null" + +EOF + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + crontab /tmp/tmp_crontab > /dev/null 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + rm /tmp/tmp_crontab > /dev/null 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + if ! $installation_failed ; then + echo_ok + fi +else + echo_skipped +fi + +# - !! Notice !! +# - if su clamav -c 'spamassassin --lint' failed ( with warn +# - message "warn: Use of uninitialized value $type in numeric..") +# - reading "/etc/spamassassin/local.cf": razor_timeout 8, have a look +# - at SpamAssassin/Plugin/Razor2.pm line 118: +# - +# - type => $Mail::SpamAssassin::Conf::CONF_TYPE_DURATIION, +# - +# - Should be: +# - +# - type => $Mail::SpamAssassin::Conf::CONF_TYPE_DURATION, +# - +# - see also: https://issues.apache.org/SpamAssassin/show_bug.cgi?id=7018 +# - +_file=/usr/share/perl5/Mail/SpamAssassin/Plugin/Razor2.pm +if [[ ! -f ${_file}.ORIG ]] ; then + echononl " Save \"${_file}\" (suffix \".ORIG\")" + cp -a ${_file} ${_file}.ORIG > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +fi +echononl " Repair \"${_file}\"" +if grep CONF_TYPE_DURATIION $_file > /dev/null 2> $tmp_err_msg ; then + perl -i -n -p -e "s/CONF_TYPE_DURATIION/CONF_TYPE_DURATION/" $_file > $tmp_err_msg 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + echo_skipped +fi + + +echononl " Run \"sa-update\"" +sa-update -v > $tmp_err_msg 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + if grep "Update finished, no fresh updates were available" $tmp_err_msg > /dev/null 2>&1 ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +fi +echononl " Run \"sa-compile\"" +sa-compile > $tmp_err_msg 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + +# - Test Installation. It's important, that all completes without error +# - +installation_failed=false +echononl " Test Installation. It's important, that all completes without error." +_pwd=$(pwd) +cd /tmp > /dev/null 2>&1 +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +su amavis -c 'spamassassin --lint' > /dev/null 2>&1 +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +cd "$_pwd" > /dev/null 2>&1 +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +if ! $installation_failed ; then + echo_ok +fi + + +# - SpamAssassin Rules +# - +# - updates.spamassassin.org is used automatically +# - and you have to do nothing, because "sa-update" +# - has done the update from updates.spamassassin.org. install +# - a cronjob for doing this periodically. for better understanding, +# - i added that rules (from spamassassin.apache.org) here +# - +# - Add SpamAssassin Rules from spamassassin.apache.org +# - +installation_failed=false +echononl " Add SpamAssassin Rules from spamassassin.apache.org" +wget -O /etc/spamassassin/GPG.KEY https://spamassassin.apache.org/updates/GPG.KEY > /dev/null 2> $tmp_err_msg +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +sa-update --import /etc/spamassassin/GPG.KEY > /dev/null 2> $tmp_err_msg +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +rm /etc/spamassassin/GPG.KEY +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +if ! grep 5244EC45 /etc/spamassassin/sa_keys > /dev/null 2>&1 ; then + echo "5244EC45" >> /etc/spamassassin/sa_keys + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi +fi +if ! grep updates.spamassassin.org /etc/spamassassin/sa_channel > /dev/null 2>&1 ; then + echo "updates.spamassassin.org" >> /etc/spamassassin/sa_channel + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi +fi +if ! $installation_failed ; then + echo_ok +fi + + +echononl " Update Rules" +sa-update -v --channelfile /etc/spamassassin/sa_channel --gpgkeyfile /etc/spamassassin/sa_keys > $tmp_err_msg 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + if grep "Update finished, no fresh updates were available" $tmp_err_msg > /dev/null 2>&1 ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +fi + + +echononl " Add Rules from Heinlein Support" +sa-update -v --nogpg --channel spamassassin.heinlein-support.de > $tmp_err_msg 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + if grep "Update finished, no fresh updates were available" $tmp_err_msg > /dev/null 2>&1 ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +fi + +echononl " Compile Rules (sa-compile) again" +sa-compile > $tmp_err_msg 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + +# - Test Installation. It's important, that all completes without error +# - +installation_failed=false +echononl " Test Installation. It's important, that all completes without error." +_pwd=$(pwd) +cd /tmp > /dev/null 2>&1 +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +su amavis -c 'spamassassin --lint' > /dev/null 2>&1 +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +cd "$_pwd" > /dev/null 2>&1 +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +if ! $installation_failed ; then + echo_ok +fi + + +# - Create a update-script using sa.update +# - +if [[ ! -d "/root/bin" ]]; then + echononl " Create directory \"/root/bin\"" + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +fi + +echononl " Create an update-script using sa.update" +cat > /root/bin/sa-update.sh < 1 ]]; then + echo "problem with sa-update" +fi + +sa-update --allowplugins --channelfile /etc/spamassassin/sa_channel --gpgkeyfile /etc/spamassassin/sa_keys + +code2=\$? +if [[ \$code2 > 1 ]]; then + echo "problem with sa-update using channelfile.." +fi + + +## - Get rules from heinlein-support.de +## - +## - see: +## - https://www.heinlein-support.de/blog/news/aktuelle-spamassassin-regeln-von-heinlein-support/ +## - +sa-update --nogpg --channel spamassassin.heinlein-support.de +code3=\$? +if [[ \$code3 > 1 ]]; then + echo "problem with sa-update using channel spamassassin.heinlein-support.de.." +fi + + +if [[ \`expr \$code1 + \$code2 + \$code3\` < 4 ]]; then + spamassassin --lint + code4=\$? + if [[ \$code4 = 0 ]]; then + #svc -h /service/spamd + #/etc/init.d/spamassassin restart > /dev/null + /etc/init.d/amavis restart >/dev/null + else + echo "spamassassin failed to lint" + fi +fi + +# Fixup perms -- group and other should be able to read and execute, +# but never write. Works around sa-compile's failure to obey umask. +if [ -d /var/lib/spamassassin ]; then + chown -R debian-spamd:debian-spamd /var/lib/spamassassin + chmod -R go-w,go+rX /var/lib/spamassassin + chmod 700 /var/lib/spamassassin/sa-update-keys + chmod 600 /var/lib/spamassassin/sa-update-keys/* +fi +if [ -d /var/lib/amavis ]; then + chown -R amavis:amavis /var/lib/amavis +fi +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +echononl " Make \"/root/bin/sa-update.sh\" executable" +chmod 755 /root/bin/sa-update.sh > /dev/null 2> $tmp_err_msg +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + +# - Add a cronjob for spamassassin updates +# - +echononl " Add a cronjob for spamassassin updates" +if ! grep -i -E "/root/bin/sa-update.sh" /var/spool/cron/crontabs/root > /dev/null 2>&1; then + installation_failed=false + crontab -l > /tmp/tmp_crontab 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + + cat << EOF >> /tmp/tmp_crontab + +# - Update spamassassin rules +# - +33 1 * * * /root/bin/sa-update.sh + +EOF + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + crontab /tmp/tmp_crontab > /dev/null 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + rm /tmp/tmp_crontab > /dev/null 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + if ! $installation_failed ; then + echo_ok + fi +else + echo_skipped +fi + + + + +# - Create an update-script that will run sa-compile +# - +if [[ ! -d "/root/bin" ]]; then + echononl " Create directory \"/root/bin\"" + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +fi + +echononl " Create an update-script running sa-compile" +cat > /root/bin/sa-compile.sh < /dev/null 2>&1 +fi + +code1=\$? +if [[ \$code1 > 0 ]]; then + echo "problem with sa-compile, turning off Rule2XSBody plugin" + sed -i 's/loadplugin Mail::SpamAssassin::Plugin::Rule2XSBody/#loadplugin Mail::SpamAssassin::Plugin::Rule2XSBody/' /etc/spamassassin/v320.pre + test -x /usr/sbin/amavisd-new || exit 0 + /etc/init.d/amavis restart >/dev/null +else + sed -i 's/#\ *loadplugin Mail::SpamAssassin::Plugin::Rule2XSBody/loadplugin Mail::SpamAssassin::Plugin::Rule2XSBody/' /etc/spamassassin/v320.pre + test -x /usr/sbin/amavisd-new || exit 0 + /etc/init.d/amavis restart >/dev/null +fi + +# Fixup perms -- group and other should be able to read and execute, +# but never write. Works around sa-compile's failure to obey umask. +if [ -d /var/lib/spamassassin ]; then + chown -R debian-spamd:debian-spamd /var/lib/spamassassin + chmod -R go-w,go+rX /var/lib/spamassassin + chmod 700 /var/lib/spamassassin/sa-update-keys + chmod 600 /var/lib/spamassassin/sa-update-keys/* +fi +if [ -d /var/lib/amavis ]; then + chown -R amavis:amavis /var/lib/amavis +fi +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +echononl " Make \"/root/bin/sa-compile.sh\" executable" +chmod 755 /root/bin/sa-compile.sh > /dev/null 2> $tmp_err_msg +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + +# - Add a cronjob for compiling rules +# - +echononl " Add a cronjob for compiling rules" +if ! grep -i -E "/root/bin/sa-compile.sh" /var/spool/cron/crontabs/root > /dev/null 2>&1; then + installation_failed=false + crontab -l > /tmp/tmp_crontab 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + + cat << EOF >> /tmp/tmp_crontab + +# - Compiling rules (SpamAssassin) +# - +53 0 * * * /root/bin/sa-compile.sh + +EOF + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + crontab /tmp/tmp_crontab > /dev/null 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + rm /tmp/tmp_crontab > /dev/null 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + if ! $installation_failed ; then + echo_ok + fi +else + echo_skipped +fi + +echononl " Restart spamassassin" +if $systemd_exists ; then + systemctl restart spamassassin > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + /etc/init.d/spamassassin restart > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +fi + + + + + +info "You can test spamassassin by typing:\n\n \033[37m\033[1msu amavis -lc 'spamassassin -D /dev/null 2>&1 ; then + continue + else + needed_packages_clamav="$needed_packages_clamav $_pkg" + fi +done +if [[ -n "$needed_packages_clamav" ]]; then + DEBIAN_FRONTEND=noninteractive apt-get -y install $needed_packages_clamav > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + echo_skipped +fi + + +# - Add user clamav to group amavis in order to giv clamav the needed +# - rights to e-mails +# - +echononl " Add user clamv to group amavis" +usermod -a -G amavis clamav > /dev/null 2> $tmp_err_msg +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + + +echononl " Stop ClamAv daemon.." +if $systemd_exists ; then + systemctl stop clamav-daemon > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + /etc/init.d/clamav-daemon stop /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +fi + +echononl " Stop ClamAv freshclam.." +if $systemd_exists ; then + systemctl stop clamav-freshclam + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + /etc/init.d/clamav-freshclam stop /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +fi + +echononl " Initial run of freshclam.." +freshclam > /dev/null 2> $tmp_err_msg +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + +echononl " Start ClamAv daemon.." +if $systemd_exists ; then + systemctl start clamav-daemon > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + /etc/init.d/clamav-daemon start /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +fi + +echononl " Start ClamAv freshclam.." +if $systemd_exists ; then + systemctl start clamav-freshclam + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + /etc/init.d/clamav-freshclam start /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +fi + + +## - Add cronjob for updating clamav (and freshclam) packages +## - +## - +echononl " Add a cronjob for updating clamav (and freshclam) packages" +if ! grep -i -E "/usr/bin/apt-get\s+.*clamav-daemon" /var/spool/cron/crontabs/root > /dev/null 2>&1; then + installation_failed=false + crontab -l > /tmp/tmp_crontab 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + + cat << EOF >> /tmp/tmp_crontab + +# - Update clamav (and freshclam) software packages +# - +03 0 * * * /usr/bin/apt-get update > /dev/null ; PATH=/bin:/sbin:/usr/bin:/usr/sbin /usr/bin/apt-get -y install -t stable-updates clamav clamav-base clamav-docs clamav-daemon clamav-freshclam > /dev/null + +EOF + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + crontab /tmp/tmp_crontab > /dev/null 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + rm /tmp/tmp_crontab > /dev/null 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + if ! $installation_failed ; then + echo_ok + fi +else + echo_skipped +fi + + +if $INSTALL_CLAMAV_UNOFFICIAL_SIGS ; then + + ## - ClamAV Unofficial Signatures + ## - + ## - Use ClamAV Unofficial Signatures Updater: + ## - https://github.com/extremeshok/clamav-unofficial-sigs/releases + ## - + ## - See readme file: + ## - https://github.com/extremeshok/clamav-unofficial-sigs + ## - + echo "" + echo -e " \033[37m\033[1mClamAV Unofficial Signatures..\033[m" + + + echononl " Install (debian package) socat" + _pkg=socat + if aptitude search " $_pkg " | grep " $_pkg " | grep -e "^i" > /dev/null 2>&1 ; then + echo_skipped + else + DEBIAN_FRONTEND=noninteractive apt-get -y install $_pkg > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi + fi + + echononl " Install CPAN Module IO::Socket::UNIX" + _module="IO::Socket::UNIX" + cpanm -q --skip-installed $_module > $tmp_err_msg 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi + + + echononl " Cloning repository \"clamav-unofficial-sigs.git\".." + installation_failed=false + if [[ -d "/tmp/clamav-unofficial-sigs" ]]; then + rm -rf "/tmp/clamav-unofficial-sigs" > $tmp_err_msg 2>&1 + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + fi + git clone https://github.com/extremeshok/clamav-unofficial-sigs.git /tmp/clamav-unofficial-sigs > $tmp_err_msg 2>&1 + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + if ! $installation_failed ; then + echo_ok + fi + + echononl " Copy \"clamav-unofficial-sigs.sh\" to /usr/local/sbin/" + cp -a /tmp/clamav-unofficial-sigs/clamav-unofficial-sigs.sh /usr/local/sbin/ > $tmp_err_msg 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi + + echononl " Make /usr/local/sbin/clamav-unofficial-sigs.sh executable" + chmod 755 /usr/local/sbin/clamav-unofficial-sigs.sh > $tmp_err_msg 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi + + _create_dirs="/var/log/clamav-unofficial-sigs /etc/clamav-unofficial-sigs" + for _create_dir in $_create_dirs ; do + echononl " Create directory \"${_create_dir}\"" + if [[ -d "$_create_dir" ]]; then + echo_skipped + else + mkdir "$_create_dir" > $tmp_err_msg 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi + fi + done + + echononl " Copy Configuration files to /etc/clamav-unofficial-sigs" + cp -a /tmp/clamav-unofficial-sigs/config/* /etc/clamav-unofficial-sigs > $tmp_err_msg 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi + + ## - For Debian Jessie (Debian 8) + ## - + echononl " At directory /etc/clamav-unofficial-sigs copy os.debian8.conf to os.conf" + cp /etc/clamav-unofficial-sigs/os.debian8.conf /etc/clamav-unofficial-sigs/os.conf > $tmp_err_msg 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi + + ## - Edit /etc/clamav-unofficial-sigs/os.conf and make changes if needed + ## - + ## - Maybe the following changes are needed: + ## - clam_user="clamav" + ## - clam_group="clamav" + ## - + ## - clamd_pid="/var/run/clamav/clamd.pid" + ## - + ## - clamd_restart_opt="systemctl restart clamav-daemon" + ## - clamd_reload_opt="systemctl reload clamav-daemon" + ## - or if debian 7 + ## - clamd_restart_opt="service clamav-daemon restart" + ## - clamd_reload_opt="service clamav-daemon reload" + ## - + ## - clamd_socket="/var/run/clamav/clamd.ctl" + ## - + echononl " Adjust /etc/clamav-unofficial-sigs/os.conf" + installation_failed=false + perl -i -n -p -e "s#^([ ]*\ *)(clam_user=.*)#\#\#\1\2\nclam_user=\"clamav\"#" \ + /etc/clamav-unofficial-sigs/os.conf > $tmp_err_msg 2>&1 + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + perl -i -n -p -e "s#^([ ]*\ *)(clam_group=.*)#\#\#\1\2\nclam_group=\"clamav\"#" \ + /etc/clamav-unofficial-sigs/os.conf > $tmp_err_msg 2>&1 + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + perl -i -n -p -e "s#^([ ]*\ *)(clamd_pid=.*)#\#\#\1\2\nclamd_pid=\"/var/run/clamav/clamd.pid\"#" \ + /etc/clamav-unofficial-sigs/os.conf > $tmp_err_msg 2>&1 + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + + if $systemd_exists ; then + perl -i -n -p -e "s#^([ ]*\#?\ *)(clamd_restart_opt=.*)#\#\#\1\2\nclamd_restart_opt=\"systemctl restart clamav-daemon\"\nclamd_reload_opt=\"systemctl reload clamav-daemon\"#" \ + /etc/clamav-unofficial-sigs/os.conf > $tmp_err_msg 2>&1 + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + else + perl -i -n -p -e "s#^([ ]*\#?\ *)(clamd_restart_opt=.*)#\#\#\1\2\nclamd_restart_opt=\"service clamav-daemon restart\"\nclamd_reload_opt=\"service clamav-daemon reload\"#" \ + /etc/clamav-unofficial-sigs/os.conf > $tmp_err_msg 2>&1 + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + fi + perl -i -n -p -e "s#^([ ]*\#?\ *)(clamd_socket=.*)#\#\#\1\2\nclamd_socket=\"/var/run/clamav/clamd.ctl\"#" \ + /etc/clamav-unofficial-sigs/os.conf > $tmp_err_msg 2>&1 + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + if ! $installation_failed ; then + echo_ok + fi + + echononl " Adjust /etc/clamav-unofficial-sigs/user.conf" + + cat << EOF >> /etc/clamav-unofficial-sigs/user.conf 2> $tmp_err_msg + +# -------------------------------------- +# --- Begin: User specific modifications +# --- Inserted by install-script "$(basename "$0")" at $(date +"%Y-%m-%d %H:%M") +EOF + + if $MALWARE_PATROL_IN_USE || $SECURITE_INFO_IN_USE ; then + + if $MALWARE_PATROL_IN_USE ; then + + cat << EOF >> /etc/clamav-unofficial-sigs/user.conf 2> $tmp_err_msg + +malwarepatrol_receipt_code="$MP_RECEIPT_NUMBER" +malwarepatrol_list="clamav_basic" +EOF + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + + + if $MALWERE_PATROL_FREE ; then + cat << EOF >> /etc/clamav-unofficial-sigs/user.conf 2> $tmp_err_msg +malwarepatrol_product_code="8" +malwarepatrol_free="yes" +EOF + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + else + cat << EOF >> /etc/clamav-unofficial-sigs/user.conf 2> $tmp_err_msg +malwarepatrol_product_code="15" +malwarepatrol_free="no" +EOF + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + fi + fi # if $MALWARE_PATROL_IN_USE + + if $SECURITE_INFO_IN_USE ; then + cat << EOF >> /etc/clamav-unofficial-sigs/user.conf 2> $tmp_err_msg + +securiteinfo_authorisation_signature="$SI_AUTHORISATION_SIGNATURE" +EOF + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + fi # if $SECURITE_INFO_IN_USE + fi #if $MALWARE_PATROL_IN_USE || $SECURITE_INFO_IN_USE + cat << EOF >> /etc/clamav-unofficial-sigs/user.conf 2> $tmp_err_msg + +# - Disable Yara-Rule set, because (some?) pgp mails where blocked. +# - +yararulesproject_enabled="no" + +user_configuration_complete="yes" + +# --- End: User specific modifications" +# ------------------------------------- +EOF + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + if ! $installation_failed ; then + echo_ok + fi + + + echononl " Copy Systemd Configurations to /etc/systemd" + cp /tmp/clamav-unofficial-sigs/systemd/* /etc/systemd/ > $tmp_err_msg 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi + + echononl " Adjust /etc/systemd/clamav-unofficial-sigs.service" + perl -i -n -p -e "s#^([ ]*\ *)(ExecStart=.*)#\#\#\1\2\nExecStart=/usr/local/sbin/clamav-unofficial-sigs.sh#" \ + /etc/systemd/clamav-unofficial-sigs.service > $tmp_err_msg 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi + + + echononl " Install Cron configs" + /usr/local/sbin/clamav-unofficial-sigs.sh --install-cron > $tmp_err_msg 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi + echononl " Install logrotate configuration" + /usr/local/sbin/clamav-unofficial-sigs.sh --install-logrotate > $tmp_err_msg 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi + echononl " Install man (help) file" + /usr/local/sbin/clamav-unofficial-sigs.sh --install-man > $tmp_err_msg 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi + + echo " First Usage to initialise ClamAV unofficial sigs" + echo -n " see /var/log/clamav-unofficial-sigs/clamav-unofficial-sigs.log" + /usr/local/sbin/clamav-unofficial-sigs.sh > $tmp_err_msg 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi + + + echononl " Remove git repository /tmp/clamav-unofficial-sigs" + rm -rf /tmp/clamav-unofficial-sigs > $tmp_err_msg 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi + +fi # if $INSTALL_CLAMAV_UNOFFICIAL_SIGS + + + +# --- +# --- Install AMaVis +# --- + +echo +echo -e "\033[37m\033[1mGoing to install AMaVis..\033[m" +echo +echononl " Install packages needed for AMaVis" +_needed_packages_amavis="amavisd-new" +for _pkg in $_needed_packages_amavis ; do + if aptitude search $_pkg | grep " $_pkg " | grep -e "^i" > /dev/null 2>&1 ; then + continue + else + needed_packages_amavis="$needed_packages_amavis $_pkg" + fi +done +if [[ -n "$needed_packages_amavis" ]]; then + DEBIAN_FRONTEND=noninteractive apt-get -y install $needed_packages_amavis > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + echo_skipped +fi + +echononl " Install some decoders needed for AMaVis" +_needed_decoders_amavis=" + alien \ + arc \ + arj \ + binutils \ + bzip2 \ + cabextract \ + cpio\ + lhasa \ + lzop \ + liblz4-tool \ + lrzip \ + melt \ + nomarch \ + pax \ + p7zip \ + p7zip-full \ + p7zip-rar \ + rpm \ + tar \ + tnef \ + ripole \ + rar \ + unrar \ + unrar-free \ + unzip \ + zip \ + zoo" + + #libzeromq-perl \ + #freeze \ +for _pkg in $_needed_decoders_amavis ; do + if aptitude search $_pkg | grep " $_pkg " | grep -e "^i" > /dev/null 2>&1 ; then + continue + else + needed_decoders_amavis="$needed_decoders_amavis $_pkg" + fi +done +if [[ -n "$needed_decoders_amavis" ]]; then + DEBIAN_FRONTEND=noninteractive apt-get -y install $needed_decoders_amavis > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + echo_skipped +fi + +echononl " Install CPAN Modules mostly needed for decoding" +installation_failed=false +_needed_cpan_modules=" + Digest::SHA1 + Digest::SHA2 + Digest::SHA256 + Encode::Detect + Net::Patricia" +for _module in $_needed_cpan_modules ; do + cpanm -q --skip-installed $_module > "$tmp_err_msg" 2>&1 + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi +done +if ! $installation_failed ; then + echo_ok +fi + + +## - Quarantine Directories +## - +echo "" +echononl " Create Quarantine Directories" +mkdir -p ${QUARANTINE_DIR}/{spam,virus,banned,bad-headers,spammy} > /dev/null 2> $tmp_err_msg +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + +echononl " Set Permissions on Quarantine Directories" +installation_failed=false +chown -R amavis:amavis $QUARANTINE_DIR +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +chmod 750 $QUARANTINE_DIR +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +chmod 750 ${QUARANTINE_DIR}/{spam,virus,banned,bad-headers,spammy} > /dev/null 2> $tmp_err_msg +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +if ! $installation_failed ; then + echo_ok +fi + + +## - Configure amavis in /etc/amavis/conf.d +## - +## - write all changes and customization to a seperate +## - file named "50-user", which will load at end of +## - configuration and overwrites the (debian)-default values +## - + +_config_file=/etc/amavis/conf.d/50-user +_date="$(date +%Y-%m-%d-%H%M)" +if [[ ! -f "/etc/amavis/$(basename ${_config_file}).ORIG" ]]; then + echononl " Save installation version of ${_config_file} (Suffix \".ORIF\")" + cp -a "$_config_file" "/etc/amavis/$(basename ${_config_file}).ORIG" > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + echononl " Backup $_config_file" + cp -a "$_config_file" "/etc/amavis/$(basename ${_config_file}).${_date}" 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +fi + + +echononl " Create new configuration \"/etc/amavis/conf.d/50-user\"" +installation_failed=false +cat << EOF > /etc/amavis/conf.d/50-user +use strict; + +# +# Place your configuration directives here. They will override those in +# earlier files. +# +# See /usr/share/doc/amavisd-new/ for documentation and examples of +# the directives you can use in this file +# + +# Ports to listen on +# +# 10024: default listening port +# 10026: used for whitelisting IP's (trusted networks) +# +# Notice: take care, to configure postfix sending mails from +# trusted networks to port 10026 +# +# Example for postfix configuration: +# +# /etc/postfix/amavis_client_whitelist: +# 83.223.73.205/32 FILTER amavisfeed:[127.0.0.1]:10026 +# 2a01:30:1fff:fd00::205/128 FILTER amavisfeed:[127.0.0.1]:10026 +# +# /etc/postfix/main.cf +# ... +# smtpd_client_restrictions = +# check_client_access cidr:/etc/postfix/amavis_client_whitelist +# ... +# +# !! Only possible if using postfix with conten_filter instead of !! +# !! smtpd_proxy_filter - see master.cf !! +# +# +#$inet_socket_port = [10024, 10026]; + +# Bypass spam checking fro trusted networks +# +#\$interface_policy{'10026'} = 'TRUSTED'; +#\$policy_bank{'TRUSTED'} = { +# bypass_spam_checks_maps => [1], +# bypass_header_checks_maps => [1], +# final_spam_destiny => D_PASS, +# $final_bad_header_destiny = D_PASS, +#}; + + +## - 7 instances seems to be a good value. +## - +\$max_servers = 7; + + +## - overrides settings in 01-debian +## - + +\$unfreeze = ['unfreeze', 'freeze -d', 'melt', 'fcat']; #disabled (non-free, no security support) +\$unrar = ['rar', 'unrar']; #disabled (non-free, no security support) +\$lha = 'lha'; #disabled (non-free, no security support) +\$tnef = 'tnef'; + + +## - overrides settings in 15-content_filter_mode +## - + +## - Default antivirus checking mode +## - +@bypass_virus_checks_maps = ( + \%bypass_virus_checks, \@bypass_virus_checks_acl, + \$bypass_virus_checks_re); + + +## - Default SPAM checking mode +## - +@bypass_spam_checks_maps = ( + \%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re); + + +## - overrides settings in 20-debian_defaults +## - + + +\$final_virus_destiny = D_DISCARD; # (data not lost, see virus quarantine) +\$final_banned_destiny = D_DISCARD; # D_REJECT when front-end MTA +#\$final_spam_destiny = D_DISCARD; +\$final_spam_destiny = D_BOUNCE; +#\$final_bad_header_destiny = D_PASS; # False-positive prone (for spam) + +\$sa_tag_level_deflt = 2.0; # add spam info headers if at, or above that level +\$sa_tag2_level_deflt = 5.1; # add 'spam detected' headers at that level + +## - user / domain specific settings +## - example for \$sa_tag2_level_deflt: +## - +#\$sa_tag2_level_deflt = { +# # oopen.de +# 'oopen.de'=>'2.1', +# 'ckubu@oopen.de'=>'2.2', +# 'argus@oopen.de'=>'2.3', +# # k8h.de +# 'k8h.de'=>'6.5', +# # default +# '.'=>'5.1' +#}; + +\$sa_kill_level_deflt = 10.31; # reject/bounce/discard/pass +#\$sa_dsn_cutoff_level = 10; # spam level beyond which a DSN is not sent + +## - We will inform the sender about bouncing his mail with a DSN (Delivery +## - StatusNotification). That DSN message will no be send, if the spamvalue +## - exceeds the value of sa_dsn_cutoff_level +## - +\$sa_dsn_cutoff_level = 20; + + +## - change the default server response if mail was blocked +## - because of spam. +## - +## - results in (is an example): +## - : host 127.0.0.1[127.0.0.1] said: 554 5.7.0 Reject, Mailserver +## - at a.mx.oopen.de: identified as SPAM - (in reply to end of DATA command) +## - +%smtp_reason_by_ccat = ( + CC_SPAM, "Mailserver at \$myhostname: identified as SPAM - %x" +); + +\$sa_spam_subject_tag = undef; +#\$sa_spam_subject_tag = '***SPAM*** '; + + +## - QUARANTINE +## - +\$QUARANTINEDIR = "$QUARANTINE_DIR"; +\$quarantine_subdir_levels = 0; + + +## - don't store mails in quarantine directory +## - +#\$virus_quarantine_method = undef; +#\$spam_quarantine_method = undef; +#\$banned_files_quarantine_method = undef; +#\$bad_header_quarantine_method = undef; + +## - store mails in quarantine directory +## - +\$virus_quarantine_method = 'local:virus/virus-%m'; +\$spam_quarantine_method = 'local:spam/spam-%m.gz'; +\$banned_files_quarantine_method = 'local:banned/banned-%m'; +\$bad_header_quarantine_method = 'local:bad-headers/badh-%m'; +\$clean_quarantine_method = undef; +\$archive_quarantine_method = undef; + +#\$virus_admin ="$QUARANTINE_ADMIN"; +#\$spam_admin = "$QUARANTINE_ADMIN"; +#\$banned_admin = "$QUARANTINE_ADMIN"; +#\$bad_header_admin = "$QUARANTINE_ADMIN"; +\$virus_admin = undef; +\$spam_admin = undef; +\$banned_admin = undef; +\$bad_header_admin = undef; + + +# Pass SPAMMY but quarantine and inform admin +# +\$quarantine_to_maps_by_ccat{+CC_SPAMMY} = \\@spam_quarantine_to_maps ; +\$quarantine_method_by_ccat{+CC_SPAMMY} = 'local:spammy/spammy-%m.gz' ; +\$final_destiny_by_ccat{+CC_SPAMMY} = D_PASS ; +\$admin_maps_by_ccat{+CC_SPAMMY} = sub { ca('spam_admin_maps') }; + + +# Bypass spam checking fro trusted networks using mynetworks +# +# list of trusted IPs: +# +# - $HOSTNAME ($IPV4 [${IPV6}]) +# +#\@mynetworks = qw( 127.0.0.0/8 [::1] 83.223.86.162 [2a01:30:1fff:a::162] ); +# +#\$policy_bank{'MYNETS'} = { # clients in @mynetworks +# bypass_spam_checks_maps => [1], # don't spam-check internal mail +# bypass_header_checks_maps => [1], # don't header-check internal mail +# final_spam_destiny => D_PASS, +# final_bad_header_destiny => D_PASS, +# #remove_existing_x_scanned_headers => undef, +# #remove_existing_spam_headers => undef, +#}; +#\$remove_existing_x_scanned_headers = 0; +#\$remove_existing_spam_headers = 0; + +# allow all mail from local IPs: +#\$policy_bank{'MYNETS'} = { # clients in @mynetworks +# bypass_spam_checks_maps => [1], # don't spam-check internal mail +# bypass_header_checks_maps => [1], # don't header-check internal mail +# final_spam_destiny => D_PASS, +# final_bad_header_destiny => D_PASS, +#}; + + +## - Amavisd-New scans all mail passing through it for viruses, but will +## - only hand mail for local delivery off to SA for checking - you tell +## - it which domains are local using the @local_domains_maps variable, +## - which by default is set to the value of \$mydomain & its subdomains: +## - +#@local_domains_maps = ( ["."] ); + + +## - get rid of "Open Relay" warnings in amavis logfile. +## - +\$interface_policy{'10024'} = 'ORIGINATING'; +\$policy_bank{'ORIGINATING'} = { + originating => 1, # declare that mail was submitted by our smtp client +}; + +## - If you get am error like: +## - +## - amavis[9766]: () (!)DENIED ACCESS from IP $IPV4, policy bank 'ORIGINATING' +## - +## - you must add your ip address to @inet_acl +## - +#@inet_acl = qw( 127.0.0.1 [::1] $IPV4 ); +#\$inet_socket_bind = undef; + +EOF +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi + +if [[ "$DB_TYPE" = "PostgreSQL" ]]; then + + cat >> /etc/amavis/conf.d/50-user <> /etc/amavis/conf.d/50-user <> /etc/amavis/conf.d/50-user < syslog; false (e.g. 0) => logging to file +\$DO_SYSLOG = 1; # (defaults to 0) + +\$syslog_ident = 'amavis'; # Syslog ident string (defaults to 'amavis') +#\$syslog_facility = 'mail'; # Syslog facility as a string +\$syslog_facility = 'local0'; # Syslog facility as a string + # e.g.: mail, daemon, user, local0, ... local7, ... +\$syslog_priority = 'debug'; # Syslog base (minimal) priority as a string, + # choose from: emerg, alert, crit, err, warning, notice, info, + # debug + +# Log file (if not using syslog) +#\$LOGFILE = "/var/log/amavis.log"; # (defaults to empty, no log) + +#NOTE: levels are not strictly observed and are somewhat arbitrary +# 0: startup/exit/failure messages, viruses detected +# 1: args passed from client, some more interesting messages +# 2: virus scanner output, timing +# 3: server, client +# 4: decompose parts +# 5: more debug details +\$log_level = 1; # (defaults to 0), -d + + +## - amavis add a tag "***UNCHECKED***" if mail was not +## - checked. to get rid of that tag add: +## - +\$undecipherable_subject_tag = undef; + + +## - get rid of warning messages to postmaster if content is unchecked (that occurs +## - i.e. if mail is encrypted +## - +delete \$admin_maps_by_ccat{&CC_UNCHECKED}; + + +## - Replace "localhost" in the mailheader +## - +\$localhost_name = "amavis.${HOSTNAME}"; + +## - DKIM +## - +#\$enable_dkim_verification = 1; # enable DKIM signatures verification +#\$enable_dkim_signing = 1; # load DKIM signing code, keys defined by dkim_key +#dkim_key('oopen.de', 'main', '/etc/amavis/dkim/dkim-key.pem'); +#dkim_key('mbr-berlin.de', 'main', '/etc/amavis/dkim/dkim-key.pem'); +#dkim_key ... +#\@dkim_signature_options_bysender_maps = ( +# { '.' => { ttl => 21*24*3600, c => 'relaxed/simple' } } ); + + + +#------------ Do not modify anything below this line ------------- +1; # ensure a defined return +EOF +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +if ! $installation_failed ; then + echo_ok +fi + +if [[ -f "/etc/amavis/$(basename ${_config_file}).${_date}" ]]; then + if diff "${_config_file}" "/etc/amavis/$(basename ${_config_file}).${_date}" > /dev/null 2>&1 ; then + info "${_config_file} has not changed.\n\t Removing previos created backup.." + rm "/etc/amavis/$(basename ${_config_file}).${_date}" + fi +fi + +echononl " Set permissions on \"/etc/amavis/conf.d/50-user\"" +chmod 644 /etc/amavis/conf.d/50-user > /dev/null 2> $tmp_err_msg +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + + +## - Configure syslogd matching the configuration od amavisd +## - +echononl " Configure syslogd matching the configuration of amavis" +cat << EOF > /etc/rsyslog.d/amavis.conf +## - amavis +## - +local0.* -/var/log/amavis.log +& ~ +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +echononl " Create empty file \"/var/log/amavis.log\"" +touch /var/log/amavis.log > /dev/null 2> $tmp_err_msg +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + +echononl " Set permissions on \"/var/log/amavis.log\"" +installation_failed=false +chmod 644 /var/log/amavis.log > /dev/null 2> $tmp_err_msg +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +chown amavis:amavis /var/log/amavis.log> /dev/null 2> $tmp_err_msg +if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" +fi +if ! $installation_failed ; then + echo_ok +fi + + +echononl " Restart syslog daemon (rsyslog)" +if $systemd_exists ; then + systemctl restart rsyslog > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + /etc/init.d/rsyslog restart > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +fi + + +## - Add a crontab to cleanup the quarantine folder +## - +echononl " Add a cronjob to cleanup the quarantine folder" +if ! grep -i -E "find\s+${QUARANTINE_DIR}/spam\s+-type\s+f\s+" /var/spool/cron/crontabs/root > /dev/null 2>&1; then + installation_failed=false + crontab -l > /tmp/tmp_crontab 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + + cat << EOF >> /tmp/tmp_crontab + +# - Remove old quarantined messages (>30 days). +# - +# - Spam +0 3 * * * find ${QUARANTINE_DIR}/spam -type f -name "spam-*" -mtime +30 -exec rm {} \; +# - Spammy +0 3 * * * find ${QUARANTINE_DIR}/spammy -type f -name "spammy-*" -mtime +30 -exec rm {} \; +# - Virus +0 3 * * * find ${QUARANTINE_DIR}/virus -type f -name "virus-*" -mtime +30 -exec rm {} \; +# - Banned files +0 3 * * * find ${QUARANTINE_DIR}/banned -type f -name "banned-*" -mtime +30 -exec rm {} \; +# - Bad headers +0 3 * * * find ${QUARANTINE_DIR}/bad-headers -type f -name "badh-*" -mtime +30 -exec rm {} \; +EOF + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + crontab /tmp/tmp_crontab > /dev/null 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + rm /tmp/tmp_crontab > /dev/null 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + if ! $installation_failed ; then + echo_ok + fi +else + echo_skipped +fi + + + +## - Install logrotate-script for amavis +## - +echononl " Install logrotate-script for amavis" +cat < /etc/logrotate.d/amavis +/var/log/amavis.log { + daily + start 0 + rotate 7 + missingok + compress + delaycompress + notifempty + create 644 amavis amavis + copytruncate +} +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + + +## - Set up /etc/postfix/master +## - +## - Forward emails to amavis using "Pre-Queue" Option smtpd_proxy_filter +## - +## - edit /etc/postfix/master.cf and add flags for "smtpd_proxy_filter" (to +## - forward to amavis service on localhost port 10024) and for "content_filter" +## - (to avoid rechecking by "Post-Queue" content_filter) to smtp service +## - +## - smtp inet n - - - - smtpd +## - -o smtpd_proxy_filter=127.0.0.1:10024 +## - -o content_filter= +## - +## - take care, that, in case NOT to reject, amavis fowards the mail to the +## - MTA (Postfix) for delivering. To avoid loops in checking, install a +## - (Postfix) smtpd service on a local Port (10025) without checking anymore +## - +## - to do this edit /etc/postfix/master.cf and add service: +## - +## - localhost:10025 inet n - - - - smtpd +## - -o content_filter= +## - -o smtpd_proxy_filter= +## - -o smtpd_authorized_xforward_hosts=127.0.0.0/8 +## - -o smtpd_client_restrictions= +## - -o smtpd_helo_restrictions= +## - -o smtpd_sender_restrictions= +## - -o smtpd_recipient_restrictions=permit_mynetworks,reject +## - -o smtpd_data_restrictions= +## - -o mynetworks=127.0.0.0/8,<$_ipv4_address/32> +## - -o receive_override_options=no_unknown_recipient_checks +## - +postfix_master_cf="/etc/postfix/master.cf" +_date=$(date +%Y-%m-%d-%H%M) +echo "" +echononl " Backup file \"${postfix_master_cf}\"" +cp -a $postfix_master_cf "${postfix_master_cf}.$_date" > /dev/null 2> $tmp_err_msg +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + +echononl " Create new file \"${postfix_master_cf}\"" +_found=false + +if grep -iq -E "^localhost:10025" "$postfix_master_cf" > /dev/null 2>&1 ; then + localhost_10025_present=true +else + localhost_10025_present=false +fi + +if grep -iq -E "^submission\s+" $postfix_master_cf > /dev/null 2>&1 ; then + submission_present=true +else + submission_present=false +fi + +if grep -iq -E "^smtps\s+" $postfix_master_cf > /dev/null 2>&1 ; then + smtps_present=true +else + smtps_present=false +fi + +if grep -iq -E "^amavisfeed\s+" $postfix_master_cf > /dev/null 2>&1 ; then + amavisfeed_present=true +else + amavisfeed_present=false +fi + +> $postfix_master_cf +while IFS='' read -r _line || [[ -n $_line ]] ; do + + if echo "$_line" | grep -i -E "^\s*smtp\s+inet\s+" > /dev/null 2>&1 ; then + _found=true + cat >> $postfix_master_cf << EOF +smtp inet n - y - - smtpd + -o smtpd_proxy_filter=127.0.0.1:10024 + -o content_filter= +EOF + if ! $submission_present && ! $smtps_present && ! $localhost_10025_present ; then + cat >> $postfix_master_cf << EOF +localhost:10025 inet n - y - - smtpd + -o content_filter= + -o smtpd_proxy_filter= + -o smtpd_authorized_xforward_hosts=127.0.0.0/8 + -o smtpd_client_restrictions= + -o smtpd_helo_restrictions= + -o smtpd_sender_restrictions= + -o smtpd_recipient_restrictions=permit_mynetworks,reject + -o smtpd_data_restrictions= + -o mynetworks=127.0.0.0/8 + -o receive_override_options=no_unknown_recipient_checks + #-o mynetworks=127.0.0.0/8,${IPV4}/32 +EOF + fi + + continue + fi + + + if $submission_present && echo "$_line" | grep -i -E "^^submission\s+" > /dev/null 2>&1 ; then + _found=true + cat >> $postfix_master_cf << EOF +submission inet n - y - 20 smtpd + -o content_filter=amavisfeed:[127.0.0.1]:10024 + -o smtpd_tls_security_level=encrypt + -o smtpd_sasl_auth_enable=yes + -o smtpd_client_restrictions=permit_sasl_authenticated,reject + #-o milter_macro_daemon_name=ORIGINATING +EOF + if ! $smtps_present ; then + if ! $localhost_10025_present ; then + cat >> $postfix_master_cf << EOF +localhost:10025 inet n - y - - smtpd + -o content_filter= + -o smtpd_proxy_filter= + -o smtpd_authorized_xforward_hosts=127.0.0.0/8 + -o smtpd_client_restrictions= + -o smtpd_helo_restrictions= + -o smtpd_sender_restrictions= + -o smtpd_recipient_restrictions=permit_mynetworks,reject + -o smtpd_data_restrictions= + -o mynetworks=127.0.0.0/8 + -o receive_override_options=no_unknown_recipient_checks + #-o mynetworks=127.0.0.0/8,${IPV4}/32 +EOF + fi + + if ! $amavisfeed_present ; then + cat >> $postfix_master_cf << EOF +amavisfeed unix - - n - 20 lmtp + -o smtp_data_done_timeout=1200 + -o smtp_send_xforward_command=yes + -o disable_dns_lookups=yes +EOF + fi + fi # if ! $smtps_present + + continue + + fi # if $submission_present && echo "$_line" | grep.. + + + if $smtps_present && echo "$_line" | grep -i -E "^smtps\s+" > /dev/null 2>&1 ; then + cat >> $postfix_master_cf << EOF +smtps inet n - y - - smtpd + -o content_filter=amavisfeed:[127.0.0.1]:10024 + -o smtpd_tls_wrappermode=yes + -o smtpd_sasl_auth_enable=yes + -o smtpd_client_restrictions=permit_sasl_authenticated,reject + # -o milter_macro_daemon_name=ORIGINATING +EOF + + if ! $localhost_10025_present ; then + cat >> $postfix_master_cf << EOF +localhost:10025 inet n - y - - smtpd + -o content_filter= + -o smtpd_proxy_filter= + -o smtpd_authorized_xforward_hosts=127.0.0.0/8 + -o smtpd_client_restrictions= + -o smtpd_helo_restrictions= + -o smtpd_sender_restrictions= + -o smtpd_recipient_restrictions=permit_mynetworks,reject + -o smtpd_data_restrictions= + -o mynetworks=127.0.0.0/8 + -o receive_override_options=no_unknown_recipient_checks + #-o mynetworks=127.0.0.0/8,${IPV4}/32 +EOF + fi + + if ! $amavisfeed_present ; then + cat >> $postfix_master_cf << EOF +amavisfeed unix - - n - 20 lmtp + -o smtp_data_done_timeout=1200 + -o smtp_send_xforward_command=yes + -o disable_dns_lookups=yes +EOF + fi + + continue + + fi # if $smtps_present + + + if $localhost_10025_present && echo "$_line" | grep -i -E "^localhost:10025" > /dev/null 2>&1 ; then + _found=true + cat >> $postfix_master_cf << EOF +localhost:10025 inet n - y - - smtpd + -o content_filter= + -o smtpd_proxy_filter= + -o smtpd_authorized_xforward_hosts=127.0.0.0/8 + -o smtpd_client_restrictions= + -o smtpd_helo_restrictions= + -o smtpd_sender_restrictions= + -o smtpd_recipient_restrictions=permit_mynetworks,reject + -o smtpd_data_restrictions= + -o mynetworks=127.0.0.0/8 + -o receive_override_options=no_unknown_recipient_checks + #-o mynetworks=127.0.0.0/8,${IPV4}/32 +EOF + continue + fi + + if $amavisfeed_present && echo "$_line" | grep -i -E "^amavisfeed\s+" > /dev/null 2>&1 ; then + _found=true + cat >> $postfix_master_cf << EOF +amavisfeed unix - - n - 20 lmtp + -o smtp_data_done_timeout=1200 + -o smtp_send_xforward_command=yes + -o disable_dns_lookups=yes +EOF + continue + fi + + # - [[:blank:]] means space and tab. This makes it similar to: [ \t] + # - [[:space;]] in addition to space and tab, includes newline, linefeed, formfeed, + # - and vertical tab. This makes it similar to: [ \t\n\r\f\v] + # - + #if [[ $_line =~ ^[[:space:]]+[^[:space:]]+ ]] && $_smtp_found ; then + # - + if [[ $_line =~ ^[[:blank:]]+[^[:space:]]+ ]] && $_found ; then + continue + fi + _found=false + + echo "$_line" >> $postfix_master_cf +done < "${postfix_master_cf}.$_date" + +echo_done +warn "Please check file \"$postfix_master_cf\" !" + + +# --- +# --- Restart Services +# --- + + +echo +echo -e "\033[37m\033[1mRestart Services..\033[m" +echo +echononl " Restart AmaViS" +if $systemd_exists ; then + systemctl restart amavis > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + /etc/init.d/amavis restart > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +fi +echononl " Restart Postfix" +if $systemd_exists ; then + systemctl restart postfix > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + /etc/init.d/postfix restart > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +fi + + +#fi # if $ommit ; then +# ------------------------------- + + + + +rm $tmp_err_msg +echo "" +exit 0 diff --git a/install_opendkim.sh b/install_opendkim.sh new file mode 100755 index 0000000..4ff57d7 --- /dev/null +++ b/install_opendkim.sh @@ -0,0 +1,610 @@ +#!/usr/bin/env bash + +clear +echo -e "\n \033[32mStart Installation of OpenDKIM..\033[m" + + + +# ------------- +# - Settings +# ------------- + +#_src_base_dir="$(realpath $(dirname $0))" +#conf_file="${_src_base_dir}/conf/install_opendkim.conf" + +log_file="$(mktemp)" + +_opendkim_packages="opendkim opendkim-tools" + +opendkim_base_dir="/etc/opendkim" +opendkim_key_dir="${opendkim_base_dir}/keys" +opendkim_conf_file="/etc/opendkim.conf" + +postfix_spool_dir="/var/spool/postfix" + +opendkim_socket_dir="${postfix_spool_dir}/opendkim" +opendkim_socket_file="${opendkim_socket_dir}/opendkim.sock" + +postfix_needs_restart=false +opendkim_needs_restart=false + +# ------------- +# --- Some functions +# ------------- +echononl(){ + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo -e -n "$*\\c" 1>&2 + else + echo -e -n "$*" 1>&2 + fi + rm /tmp/shprompt$$ +} + +fatal(){ + echo "" + echo -e "fatal error: $*" + echo "" + echo -e "\t\033[31m\033[1mInstalllation will be interrupted\033[m\033[m" + echo "" + exit 1 +} + +error(){ + echo "" + echo -e "\t[ \033[31m\033[1mFehler\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 "" +} + +echo_done() { + echo -e "\033[80G[ \033[32mdone\033[m ]" +} +echo_ok() { + echo -e "\033[80G[ \033[32mok\033[m ]" +} +echo_warning() { + echo -e "\033[80G[ \033[33m\033[1mwarn\033[m ]" +} +echo_failed(){ + echo -e "\033[80G[ \033[1;31mfailed\033[m ]" +} +echo_skipped() { + echo -e "\033[80G[ \033[37mskipped\033[m ]" +} + + +# ------------- +# - Some pre-installation tasks +# ------------- + +# - Is 'systemd' supported on this system +# - +if [ "X`which systemd`" = "X" ]; then + SYSTEMD_EXISTS=false +else + SYSTEMD_EXISTS=true +fi + + + +# ============= +# - Start Installation +# ============= + +echo "" + +# - Synchronise package index files with the repository +# - +echononl " Synchronise package index files with the repository.." +apt-get update > "$log_file" 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + + +# - Install OpenDKIM +# - +echononl " Install needed debian packages.." +opendkim_packages="" +packages_installed=false +for _pkg in $_opendkim_packages ; do + if aptitude search "$_pkg" | grep " $_pkg " | grep -e "^i" > /dev/null 2>&1 ; then + continue + else + opendkim_packages="$opendkim_packages $_pkg" + fi +done +if [[ -n "$opendkim_packages" ]]; then + DEBIAN_FRONTEND=noninteractive apt-get -y install $opendkim_packages > /dev/null 2> "$log_file" + packages_installed=true + opendkim_needs_restart=true + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + +# - Add user 'postfix' to group 'opendkim' +# - +echononl " Add user 'postfix' to group 'opendkim'.." +if grep opendkim /etc/group | grep -q postfix 2> /dev/null ; then + echo_skipped +else + adduser postfix opendkim > "$log_file" 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +fi + + +# - Save configuration file from distribution +# - +echononl " Save configuration file from distribution" +if $packages_installed ; then + cp -a $opendkim_conf_file $opendkim_conf_file.ORIG 2> "$log_file" + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + +# - Create OpenDKIM configuration +# - +echononl " Create OpenDKIM configuration" +if [[ -f "$opendkim_conf_file" ]] \ + && grep -i -q -E "^\s*Socket\s+local:$opendkim_socket_file" "$opendkim_conf_file" \ + && grep -i -q -E "^\s*SigningTable.*${opendkim_base_dir}/signing.table" "$opendkim_conf_file" \ + && grep -i -q -E "^\s*KeyTable.*${opendkim_base_dir}/key.table" "$opendkim_conf_file" ; then + echo_skipped + warn "OpenDKIM seems already be configured." +else + cat < $opendkim_conf_file 2> $log_file +# Datei $opendkim_conf_file + +# OpenDKIM agiert als Mail Filter (= Milter) in den +# Modi signer (s) und verifier (v) und verwendet eine +# Socket-Datei zur Kommunikation (alternativ: lokaler Port) +Mode sv +# Socket local:/var/run/opendkim/opendkim.sock +# Socket local:$opendkim_socket_file +# Socket inet:12345@localhost +Socket local:$opendkim_socket_file + +# OpenDKIM verwendet diesen Benutzer bzw. +# diese Gruppe +UserID opendkim:opendkim +UMask 002 +PidFile /var/run/opendkim/opendkim.pid + +# OpenDKIM bei Problemen neustarten, +# aber max. 10 mal pro Stunde +AutoRestart yes +AutoRestartRate 10/1h + +# Logging (wenn alles funktioniert eventuell reduzieren) +Syslog yes +SyslogSuccess yes +LogWhy yes + +# Verfahren, wie Header und Body durch +# OpenDKIM verarbeitet werden sollen. +Canonicalization relaxed/simple + +# interne Mails nicht mit OpenDKIM verarbeiten +ExternalIgnoreList refile:${opendkim_base_dir}/trusted +InternalHosts refile:${opendkim_base_dir}/trusted + +# welche Verschlüsselungs-Keys sollen für welche +# Domains verwendet werden +# (refile: für Dateien mit regulären Ausdrücke) +SigningTable refile:${opendkim_base_dir}/signing.table +KeyTable ${opendkim_base_dir}/key.table + +# diesen Signatur-Algorithmus verwenden +SignatureAlgorithm rsa-sha256 + +# Always oversign From (sign using actual From and a null From to prevent +# malicious signatures header fields (From and/or others) between the signer +# and the verifier. From is oversigned by default in the Debian pacakge +# because it is often the identity key used by reputation systems and thus +# somewhat security sensitive. +OversignHeaders From +EOF + opendkim_needs_restart=true + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +fi + + +# - Assign ownership to the opendkim user and restrict tthe +# - file permissions: +# - +echononl " Assign ownership and file permissions.." +chmod u=rw,go=r $opendkim_conf_file 2> $log_file +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + + +# - Create the directories to hold OpenDKIM’s data files, assign +# - ownership to the opendkim user, and restrict the file +# - permissions: +# - +echononl " Create directory '$opendkim_base_dir'" +if [[ -d "$opendkim_base_dir" ]] ; then + echo_skipped +else + opendkim_needs_restart=true + mkdir ${opendkim_base_dir} 2> $log_file + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +fi +echononl " Create directory '$opendkim_key_dir'" +if [[ -d "$opendkim_key_dir" ]] ; then + echo_skipped +else + opendkim_needs_restart=true + mkdir $opendkim_key_dir 2> $log_file + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +fi +echononl " Set ownership on directory '${opendkim_base_dir}' (recursive).." +chown -R opendkim:opendkim ${opendkim_base_dir} 2> $log_file +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi +echononl " Set file-permission on $opendkim_key_dir" +chmod go-rw $opendkim_key_dir 2> $log_file +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + + +# - Create empty files +# - ${opendkim_base_dir}/signing.table +# - ${opendkim_base_dir}/key.table +# - +echononl " Create empty file '${opendkim_base_dir}/signing.table'.." +if [[ -f "${opendkim_base_dir}/signing.table" ]] ; then + echo_skipped +else + touch ${opendkim_base_dir}/signing.table 2> $log_file + opendkim_needs_restart=true + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +fi +echononl " Create empty file '${opendkim_base_dir}/key.table'.." +if [[ -f "${opendkim_base_dir}/key.table" ]] ; then + echo_skipped +else + touch ${opendkim_base_dir}/key.table 2> $log_file + opendkim_needs_restart=true + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +fi + + +# - Create the trusted hosts file ${opendkim_base_dir}/trusted.hosts. +# - +echononl " Create trusted hosts file '${opendkim_base_dir}/trusted'.." +if [[ -f "${opendkim_base_dir}/trusted" ]] ; then + echo_skipped +else + cat < ${opendkim_base_dir}/trusted 2> $log_file +127.0.0.1 +::1 +localhost +$(hostname -f) +EOF + opendkim_needs_restart=true + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +fi + + +# - Create the OpenDKIM socket directory in Postfix’s work area +# - and make sure it has the correct ownership: +# - +echononl " Create the OpenDKIM socket directory in Postfix’s work area.." +if [[ -d "${postfix_spool_dir}/opendkim" ]] ; then + echo_skipped +else + mkdir ${postfix_spool_dir}/opendkim 2> $log_file + opendkim_needs_restart=true + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + echononl " Set ownership on directory '${postfix_spool_dir}/opendkim'.." + chown opendkim:postfix ${postfix_spool_dir}/opendkim 2> $log_file + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +fi + + +# - Edit /etc/default/opendkim +# - +# - Set: +# - SOCKET="local:${postfix_spool_dir}/opendkim/opendkim.sock" +# - +echononl " Set 'SOCKET' at file /etc/default/opendkim.." +if grep -q -E "^\s*SOCKET" /etc/default/opendkim 2>/dev/null ; then + if grep -q -E "^\s*SOCKET.*local:$opendkim_socket_file" /etc/default/opendkim 2>/dev/null ; then + echo_skipped + else + perl -i -n -p -e "s#^\s*SOCKET=.*#SOCKET=\"local:$opendkim_socket_file\"#" /etc/default/opendkim 2> $log_file + opendkim_needs_restart=true + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + fi +else + cat <>/etc/default/opendkim 2> $log_file +SOCKET="local:$opendkim_socket_file" +EOF + opendkim_needs_restart=true + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +fi + + +# - Edit /etc/postfix/main.cf and add a section to activate +# - processing of e-mail through the OpenDKIM daemon: +# - +backup_date="$(date +%Y-%m-%d-%H%M)" +echononl " Backup existing postfix configuration (main.cf).." +cp -a /etc/postfix/main.cf /etc/postfix/main.cf.$backup_date 2> $log_file +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl " Activate processing of e-mail through the OpenDKIM daemon.." +if grep -q -E "milter_default_action\s*=\s*accept" /etc/postfix/main.cf ; then + echo_skipped + warn "Postfix (main.cf) seems already be configured for milters" + echononl " Delete previosly saved Postfix configuration.." + rm /etc/postfix/main.cf.$backup_date 2> $log_file + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + cat <> /etc/postfix/main.cf 2> $log_file + +# ======= Milter configuration ======= + +# OpenDKIM + +milter_default_action = accept + +# Postfix ≥ 2.6 milter_protocol = 6, Postfix ≤ 2.5 milter_protocol = 2 +milter_protocol = 6 + +# Note: +# We will sign AFTER sending through AmaVIS, just befor sending out. So +# set 'smtpd_milters =' to an emty string here and add to localhost:10025 +# section in master.cf: 'smtpd_milters=local:/opendkim/opendkim.sock' +# +# If you want sign mails before sending through AmaVIS, set +# 'smtpd_milters = local:/opendkim/opendkim.sock' here and add to +# localhost:10025 section in master.cf: 'smtpd_milters=' +# +#smtpd_milters = local:/opendkim/opendkim.sock +smtpd_milters = +non_smtpd_milters = local:/opendkim/opendkim.sock +EOF + postfix_needs_restart=true + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +fi + + +# - Prevent Postfix from setting the DKIM Header twice (one befor +# - and one after processing amavis +# - +# - To disable milter processing after amavis, add to your master.cf in +# - the after-amavis section: +# - 127.0.0.1:10025 inet n - - - - smtpd +# - [...] +# - -o smtpd_milters= +# - +# - If you want to run the milter after amavis, set in main.cf +# - smtpd_milters= +# - to an empty string and add the smtpd_milters configuration to master.cf +# - (after-section amavis) instead: +# - -o smtpd_milters=local:/opendkim/opendkim.sock +# - +echononl " Backup file '/etc/postfix/master.cf'.." +cp -a /etc/postfix/master.cf /etc/postfix/master.cf.$backup_date 2> $log_file +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi +echononl " Adjust /etc/postfix/master.cf. Set DKIM after sending throuh AmaVIS.." +_found=false +_changed=false +tmp_master_file="/tmp/postfix_master.cf" +> $tmp_master_file +while IFS='' read -r _line || [[ -n $_line ]] ; do + + if $_found && ! echo "$_line" | grep -i -q -E "^\s*-o" 2> /dev/null ; then + echo " -o smtpd_milters=local:/opendkim/opendkim.sock" >> "$tmp_master_file" + _changed=true + _found=false + fi + + if $_found && echo "$_line" | grep -i -q -E "^\s*-o\s+smtpd_milters=\s*" ; then + _found=false + fi + + if echo "$_line" | grep -i -q -E "^\s*(127.0.0.1|localhost):10025\s+inet\s+" 2> /dev/null ; then + _found=true + fi + + echo "$_line" >> "$tmp_master_file" + +done < "/etc/postfix/master.cf" +if $_changed ; then + cp $tmp_master_file /etc/postfix/master.cf 2> $log_file + postfix_needs_restart=true + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped + warn "Postfix (master.cf) seems already be configured." + echononl " Delete previosly saved file '/etc/postfix/master.cf'.." + rm /etc/postfix/master.cf.$backup_date 2> $log_file + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +fi +rm -f $tmp_master_file + +echo "" + +# - Restart OpenDKIM +# - +echononl " Restart OpenDKIM.." +if $opendkim_needs_restart ; then + if $SYSTEMD_EXISTS ; then + systemctl restart opendkim > $log_file 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + else + /etc/init.d/opendkim restart > $log_file 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + fi +else + echo_skipped +fi + + +# - Restart Postfix so it starts using OpenDKIM when processing mail: +# - +echononl " Restart Postfix.." +if $postfix_needs_restart ; then + if $SYSTEMD_EXISTS ; then + systemctl restart postfix > $log_file 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + else + /etc/init.d/postfix restart > $log_file 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + fi +else + echo_skipped +fi + +echo "" +rm -f "$log_file" +exit 0 diff --git a/install_postfix_advanced.sh b/install_postfix_advanced.sh new file mode 100755 index 0000000..ef32944 --- /dev/null +++ b/install_postfix_advanced.sh @@ -0,0 +1,1484 @@ +#!/usr/bin/env bash + + +working_dir="$(dirname $(realpath $0))" +conf_file="${working_dir}/conf//install_postfix_advanced.conf" + +_TLS_CERT_DIR=/etc/postfix/ssl +_TLS_CERT_FILE="${_TLS_CERT_DIR}/mailserver.crt" +_TLS_KEY_FILE="${_TLS_CERT_DIR}/mailserver.key" + +_TLS_CA_FILE=/etc/ssl/certs/ca-certificates.crt + + +tmp_err_msg=$(mktemp) +backup_date="$(date +%Y-%m-%d-%H%M)" + +# ------------- +# --- Some functions +# ------------- +clean_up() { + + # Perform program exit housekeeping + rm -f $tmp_err_msg + exit $1 +} + +echononl(){ + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo -e -n "$*\\c" 1>&2 + else + echo -e -n "$*" 1>&2 + fi + rm /tmp/shprompt$$ +} + +fatal(){ + echo "" + echo -e "fatal error: $*" + echo "" + echo -e "\t\033[31m\033[1mInstalllation will be interrupted\033[m\033[m" + echo "" + clean_up 1 +} + +error(){ + echo "" + echo -e "\t[ \033[31m\033[1mFehler\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 "" +} + +echo_done() { + echo -e "\033[80G[ \033[32mdone\033[m ]" +} +echo_ok() { + echo -e "\033[80G[ \033[32mok\033[m ]" +} +echo_warning() { + echo -e "\033[80G[ \033[33m\033[1mwarn\033[m ]" +} +echo_failed(){ + echo -e "\033[80G[ \033[1;31mfailed\033[m ]" +} +echo_skipped() { + echo -e "\033[80G[ \033[33m\033[1mskipped\033[m ]" +} + + +trap clean_up SIGHUP SIGINT SIGTERM + + +# - Is this a systemd system? +# - +if [[ "X`which systemd`" = "X" ]]; then + systemd_exists=false +else + systemd_exists=true +fi + +echo "" + +# - Default Values +# - +#_IS_RELAY_HOST=false + +# - Read Configuration File if exists +# - +if [[ -f "$conf_file" ]]; then + source $conf_file +fi + +clear +echo -e "\033[21G\033[32mInstallation script for Postfix basic mailsystem \033[m" +echo + +HOSTNAME= +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Insert hostname" +echo "" +if [[ -n "$_HOSTNAME" ]]; then + echononl "hostname [${_HOSTNAME}]: " + read HOSTNAME + if [[ "X${HOSTNAME}" = "X" ]]; then + HOSTNAME=$_HOSTNAME + fi +else + while [[ "X${HOSTNAME}" = "X" ]]; do + echononl "hostname: " + read HOSTNAME + if [[ "X${HOSTNAME}" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mHostname is reqired\033[m\n" + fi + done +fi + +IPV4= +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Insert IPv4 address" +echo "" +if [[ -n "$_IPV4" ]]; then + echononl "IPv4 address [${_IPV4}]: " + read IPV4 + if [[ "X${IPV4}" = "X" ]]; then + IPV4=$_IPV4 + fi +else + while [[ "X${IPV4}" = "X" ]]; do + echononl "IPv4 address: " + read IPV4 + if [[ "X${IPV4}" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mIPv4 address is reqired\033[m\n" + fi + done +fi +IPV6= +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Insert IPv6 address" +echo "Type:" +echo -e "\t\033[33mNone\033[m if IPv6 is not suppoerted" +echo "" +if [[ -n "$_IPV6" ]]; then + [[ "X$_IPV6" = "Xdisabled" ]] && _IPV6=None + echononl "IPv6 address [${_IPV6}]: " + read IPV6 + if [[ "X${IPV6}" = "X" ]]; then + IPV6=$_IPV6 + fi +else + while [[ "X${IPV6}" = "X" ]]; do + echononl "IPv6 address: " + read IPV6 + if [[ "X${IPV6}" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mIPv4 address is reqired\033[m\n" + fi + done +fi +if [ "X$IPV6" = "Xnone" -o "X$IPV6" = "XNone" ]; then + IPV6=disabled +fi + + +IS_RELAY_HOST= +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "How will this Mailserver be used?" +echo "" +if [[ -n "$_IS_RELAY_HOST" ]]; then + if $_IS_RELAY_HOST ; then + echo "[1] Complete Mailserver (with mailboxes)" + echo -e "\033[37m\033[1m[2] Mailrelay Host\033[m" + else + echo -e "\033[37m\033[1m[1] complete Mailserver (with mailboxes)\033[m" + echo "[2] Mailrelay Host" + fi + echo "" + echononl "Choose a number or press for highlighted value: " +else + echo "[1] Complete Mailserver (with mailboxes)" + echo "[2] Mailrelay Host" + echo "" + echononl "Choose a Number: " +fi +while [[ "$IS_RELAY_HOST" != "true" && "$IS_RELAY_HOST" != "false" ]];do + read OPTION + case $OPTION in + 1) IS_RELAY_HOST=false + ;; + 2) IS_RELAY_HOST=true + ;; + '') if [[ -n "$_IS_RELAY_HOST" ]] ; then + IS_RELAY_HOST=$_IS_RELAY_HOST + else + echo "" + echo -e "\tWrong entry! [ 1 = Complete Mailserver ; 2 = Mailrelay Host]" + echo "" + echononl "Reentry: " + fi + ;; + *) IS_RELAY_HOST= + echo "" + if [[ -n "$_IS_RELAY_HOST" ]]; then + echo -e "\tWrong entry! [ 1 = Complete Mailserver ; 2 = Mailrelay Host] or type " + else + echo -e "\tWrong entry! [ 1 = Complete Mailserver ; 2 = Mailrelay Host]" + fi + echo "" + echononl "Reentry: " + ;; + esac +done + +SASL_AUTH_ENABLED="no" +if $IS_RELAY_HOST ; then + + SASL_AUTH_ENABLED="" + echo "" + echo -e "\033[32m--\033[m" + echo "" + echo "Should this mail relay server support Cyrus SASL authentication?" + echo "" + + while [[ "$SASL_AUTH_ENABLED" != "yes" && "$SASL_AUTH_ENABLED" != "no" ]];do + + if [[ -n "$_SASL_AUTH_ENABLED" ]]; then + echononl "Support Cyrus SASL authentication [${_SASL_AUTH_ENABLED}]: " + read SASL_AUTH_ENABLED + SASL_AUTH_ENABLED=${SASL_AUTH_ENABLED,,} + [[ -z "$SASL_AUTH_ENABLED" ]] && SASL_AUTH_ENABLED="$_SASL_AUTH_ENABLED" + else + echononl "Support Cyrus SASL authentication [yes/no]: " + read SASL_AUTH_ENABLED + SASL_AUTH_ENABLED=${SASL_AUTH_ENABLED,,} + fi + + if [[ "$SASL_AUTH_ENABLED" != "yes" && "$SASL_AUTH_ENABLED" != "no" ]] ; then + _SASL_AUTH_ENABLED="" + echo -e "\n\t\033[33m\033[1mWrong entry!\033[m\n Type 'yes' or 'no'" + fi + + done + +fi + + +ADMIN_EMAIL= +echo "" +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Insert e-mail address where messages to local root should be forwarded" +echo "" +echo "" +if [[ -n "$_ADMIN_EMAIL" ]]; then + echononl "Admin e-mail address [$_ADMIN_EMAIL]: " + read ADMIN_EMAIL + if [[ "X${ADMIN_EMAIL}" = "X" ]]; then + ADMIN_EMAIL=$_ADMIN_EMAIL + fi +else + while [[ "X${ADMIN_EMAIL}" = "X" ]]; do + echononl "Admin e-mail address: " + read ADMIN_EMAIL + if [[ "X${ADMIN_EMAIL}" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mAdmin e-mail address is reqired\033[m\n" + fi + done +fi + + +echo "" +echo "" +echo -e "\033[21G\033[32mStart installation/configuration with the following parameters\033[m" +echo "" +echo -e "\tHostname..........................: $HOSTNAME" +echo -e "\tIPv4 address......................: $IPV4" +echo -e "\tIPv6 address......................: $IPV6" +echo -e "\tAdmin e-mail......................: $ADMIN_EMAIL" +echo "" +if $IS_RELAY_HOST ; then + echo -e "\tConfigure as relay host?..........: \033[33m\033[1m$IS_RELAY_HOST\033[m" + echo -e "\tConfigure as complete mailserver..: false" + echo "" + echo -e "\tSupport Cyrus SASL authentication.: $SASL_AUTH_ENABLED" +else + echo -e "\tConfigure as relay host?..........: $IS_RELAY_HOST" + echo -e "\tConfigure as complete mailserver..: \033[33m\033[1mtrue\033[m" +fi +echo "" +echononl "einverstanden (yes/no): " +read OK +OK=${OK,,} +while [ "X$OK" != "Xyes" -a "X$OK" != "Xno" ]; do + echononl "Wrong entry! [yes/no]: " + read OK + OK=${OK,,} +done +[ $OK = "yes" ] || fatal Repeat with other settings.. + +echo "" +echo "" + + +_failed=false +echononl " Save Configuration" +cat << EOF > $conf_file +# --- +# - Parameter Settins Postfix Relay System +# --- + +_HOSTNAME=$HOSTNAME +_IPV4=$IPV4 +_IPV6=$IPV6 +_ADMIN_EMAIL=$ADMIN_EMAIL +_IS_RELAY_HOST=$IS_RELAY_HOST +EOF +if [[ $? -ne 0 ]]; then + _failed=true +fi +if $IS_RELAY_HOST ; then + cat << EOF >> $conf_file +_SASL_AUTH_ENABLED=$SASL_AUTH_ENABLED +EOF +if [[ $? -ne 0 ]]; then + _failed=true +fi +if $_failed ; then + echo_failed +else + echo_ok +fi + +[[ "$IPV6" = "disabled" ]] && IPV6="" + + +# - Deinstall debian exim4 packages +# - +echononl " Deinstall debian exim4 packages" +_installed_exim_packages=`dpkg -l | grep exim4 | grep -e "^i" | awk '{print$2}'` +for _pkg in $_installed_exim_packages ; do + installed_exim_packages="$installed_exim_packages $_pkg" +done +if [[ -n "$installed_exim_packages" ]] ; then + + if `dpkg -l | grep bsd-mailx | grep -e "^i" > /dev/null 2>&1` ; then + installed_exim_packages="$installed_exim_packages bsd-mailx" + fi + + apt-get remove --purge -qq -y $installed_exim_packages > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + + + +# - Install Postfix from debian packages system +# - +echononl " Install Postfix from debian packages system" +_needed_packages="postfix postfix-pgsql postfix-mysql postfix-pcre libsasl2-modules bsd-mailx haveged" +if [[ "$SASL_AUTH_ENABLED" = "yes" ]]; then + _needed_packages="$_needed_packages sasl2-bin" +fi +for _pkg in $_needed_packages ; do + if `dpkg -l | grep $_pkg | grep -e "^i" > /dev/null 2>&1` ; then + continue + else + needed_packages="$needed_packages $_pkg" + fi +done +if [[ -n "$needed_packages" ]]; then + DEBIAN_FRONTEND=noninteractive apt-get -y install $needed_packages > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + + +## - Install Postgrey from debian packages system +## - +echononl " Install Postgrey from debian packages system" +_pkg="postgrey" +if aptitude search $_pkg | grep " $_pkg " | grep -e "^i" > /dev/null 2>&1 ; then + echo_skipped +else + DEBIAN_FRONTEND=noninteractive apt-get -y install $_pkg > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +fi + +echononl " Adjust /etc/default/postgrey" +perl -i -n -p -e "s#^(\s*)(POSTGREY_OPTS=.*)#\#\1\2\nPOSTGREY_OPTS=\"--inet=10023 --delay=149 --auto-whitelist-clients=3 --lookup-by-subnet\"#" \ + /etc/default/postgrey > $tmp_err_msg 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + +echononl " Create /etc/postgrey/whitelist_clients.local (additional whitelist entries)" +cat << EOF > /etc/postgrey/whitelist_clients.local +# For Office 365 - servers: +##/.*outbound.protection.outlook.com\$/ +/^mail-.*\.outbound\.protection\.outlook\.com\$/ +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +echononl " Restart postrey daemon" +if $systemd_exists ; then + systemctl restart postgrey > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + /etc/init.d/postgrey restart > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +fi + + +# - Backup existing postfix configuration file +# - +echononl " Backup existing postfix configuration file" +if [[ -f "/etc/postfix/main.cf" ]]; then + cp -a /etc/postfix/main.cf /etc/postfix/main.cf.$backup_date + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + + +# - Creeate new postfix configuration file +# - +echononl " Creeate new postfix configuration file" +cat < /etc/postfix/main.cf +# ============ Basic settings ============ + +# Debian specific: Specifying a file name will cause the first +# line of that file to be used as the name. The Debian default +# is /etc/mailname. +#myorigin = /etc/mailname +myorigin = /etc/mailname + +smtpd_banner = \$myhostname ESMTP \$mail_name (Debian/GNU) +biff = no + +# appending .domain is the MUA's job. +append_dot_mydomain = no + +# Uncomment the next line to generate "delayed mail" warnings +#delay_warning_time = 4h + +readme_directory = /usr/share/doc/postfix +html_directory = /usr/share/doc/postfix/html + +## - The Internet protocols Postfix will attempt to use when making +## - or accepting connections. +## - DEFAULT: ipv4 +EOF + +if [ -n "$IPV6" ]; then + cat <> /etc/postfix/main.cf +inet_protocols = ipv4, ipv6 + +#inet_interfaces = all +inet_interfaces = + 127.0.0.1 + $IPV4 + $IPV6 + +myhostname = $HOSTNAME + +mydestination = + $HOSTNAME + localhost + +## - The list of "trusted" SMTP clients that have more +## - privileges than "strangers" +## - +mynetworks = + 127.0.0.0/8 + [::ffff:127.0.0.0]/104 + [::1]/128 + ${IPV4}/32 + [${IPV6}]/128 + # a.mx.oopen.de + #83.223.86.91 + #[2a01:30:0:13:2f7:50ff:fed2:cef7]/128 + # b.mx.oopen.de + #83.223.86.97 + #[2a01:30:0:13:21f:92ff:fe00:538b] + # d.mx.oopen.de + #83.223.86.92/32 + #[2a01:30:0:13:254:9eff:fed5:e7fd]/128 + +smtp_bind_address = $IPV4 +smtp_bind_address6 = $IPV6 + +EOF +else + cat <> /etc/postfix/main.cf +inet_protocols = ipv4 + +#inet_interfaces = all +inet_interfaces = + 127.0.0.1 + $IPV4 + +myhostname = $HOSTNAME + +mydestination = + $HOSTNAME + localhost + +## - The list of "trusted" SMTP clients that have more +## - privileges than "strangers" +## - +mynetworks = + 127.0.0.0/8 + ${IPV4}/32 + +#smtp_bind_address = $IPV4 +#smtp_bind_address6 = $IPV6 + +EOF +fi + +cat <> /etc/postfix/main.cf + +## - The method to generate the default value for the mynetworks parameter. +## - +## - mynetworks_style = host" when Postfix should "trust" only the local machine +## - mynetworks_style = subnet (default value) "when Postfix should "trust" SMTP +## - clients in the same IP subnetworks as the local machine. +## - mynetworks_style = class" when Postfix should "trust" SMTP clients in the same +## - IP class A/B/C networks as the local machine. +## - +#mynetworks_style = host + + +## - The maximal size of any local(8) individual mailbox or maildir file, +## - or zero (no limit). In fact, this limits the size of any file that is +## - written to upon local delivery, including files written by external +## - commands that are executed by the local(8) delivery agent. +## - +mailbox_size_limit = 0 + +## - The maximal size in bytes of an individual virtual(8) mailbox or +## - maildir file, or zero (no limit). +## - +virtual_mailbox_limit = 0 + +## - The maximal size in bytes of a message, including envelope information. +## - +## - we user 50MB +## - +message_size_limit = 52480000 + +## - The system-wide recipient address extension delimiter +## - +recipient_delimiter = + + +## - The alias databases that are used for local(8) delivery. +## - +alias_maps = + hash:/etc/aliases + +## - The alias databases for local(8) delivery that are updated +## - with "newaliases" or with "sendmail -bi". +## - +alias_database = + hash:/etc/aliases + +## - Optional lookup tables with mappings from recipient address +## - to (message delivery transport, next-hop destination). +## - See transport(5) for details. +## - +transport_maps = + btree:/etc/postfix/transport + btree:/etc/postfix/relay_domains + +## - The maximal time a message is queued before it is sent back as +## - undeliverable. Defaults to 5d (5 days) +## - Specify 0 when mail delivery should be tried only once. +## - +maximal_queue_lifetime = 3d +bounce_queue_lifetime = \$maximal_queue_lifetime + +## - delay_warning_time (default: 0h) +## - +## - The time after which the sender receives a copy of the message +## - headers of mail that is still queued. To enable this feature, +## - specify a non-zero time value (an integral value plus an optional +## - one-letter suffix that specifies the time unit). +## - Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks). +## - The default time unit is h (hours). +delay_warning_time = 1d + +#header_checks = pcre:/etc/postfix/header_checks +prepend_delivered_header = + forward + file + + +## - proxy_read_maps +## - +## - The lookup tables that the proxymap(8) server is allowed to access for the read-only service. +## - +## - Specify zero or more "type:name" lookup tables, separated by whitespace or comma. Table +## - references that don't begin with proxy: are ignored. +## - +#proxy_read_maps = \$local_recipient_maps \$mydestination \$virtual_alias_maps \$virtual_alias_domains \$virtual_mailbox_maps \$virtual_mailbox_domains \$relay_recipient_maps \$relay_domains \$canonical_maps \$sender_canonical_maps \$recipient_canonical_maps \$relocated_maps \$transport_maps \$mynetworks \$sender_bcc_maps \$recipient_bcc_maps \$smtp_generic_maps \$lmtp_generic_maps \$smtpd_sender_login_maps + + +# ============ Relay parameters ============ + +relayhost = +relay_domains = + \$mydestination + btree:/etc/postfix/relay_domains + + +# ============ TLS parameters ============ + +## - supports DNSSEC +## - +## - !! Notice !! +## - In order to support DNSSEC and DANE your resolver MUST support +## - DNSSEC too. +## - +## - If your resolver does not support DNSSEC, install "unbound". +## - +smtp_host_lookup = dns +smtp_dns_support_level = dnssec + +## - Aktiviert TLS für den Mailempfang +## - +## - may: +## - Opportunistic TLS. Use TLS if this is supported by the remote +## - SMTP server, otherwise use plaintext +## - +## - This overrides the obsolete parameters smtpd_use_tls and +## - smtpd_enforce_tls. This parameter is ignored with +## - "smtpd_tls_wrappermode = yes". +#smtpd_use_tls=yes +smtpd_tls_security_level=may + +## - Aktiviert TLS für den Mailversand +## - +## - may: +## - Opportunistic TLS: announce STARTTLS support to SMTP clients, +## - but do not require that clients use TLS encryption. +# smtp_use_tls=yes +#smtp_tls_security_level=may +smtp_tls_security_level=dane + +## - 0 Disable logging of TLS activity. +## - 1 Log TLS handshake and certificate information. +## - 2 Log levels during TLS negotiation. +## - 3 Log hexadecimal and ASCII dump of TLS negotiation process. +## - 4 Also log hexadecimal and ASCII dump of complete transmission after STARTTLS. +## - +smtpd_tls_loglevel = 1 +smtp_tls_loglevel = 1 + +smtpd_tls_cert_file = $_TLS_CERT_FILE +smtpd_tls_key_file = $_TLS_KEY_FILE + +## - File with DH parameters that the Postfix SMTP server should use with EDH ciphers. +## - +## - Dont't forget to create it, e.g with openssl: +## - openssl dhparam -out /etc/postfix/ssl/dh_1024.pem -2 1024 +## - +#smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_1024.pem +## - also possible to use 2048 key with that parameter +## - +smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_2048.pem + +## - File with DH parameters that the Postfix SMTP server should use with EDH ciphers. +## - +## - Dont't forget to create it, e.g with openssl: +## - openssl dhparam -out /etc/postfix/ssl/dh_512.pem -2 512 +## - +smtpd_tls_dh512_param_file = /etc/postfix/ssl/dh_512.pem + + +## - File containing CA certificates of root CAs trusted to sign either remote SMTP +## - server certificates or intermediate CA certificates. These are loaded into +## - memory !! BEFORE !! the smtp(8) client enters the chroot jail. +## - +smtp_tls_CAfile = $_TLS_CA_FILE + +## - Directory with PEM format certificate authority certificates that the Postfix SMTP +## - client uses to verify a remote SMTP server certificate. Don't forget to create the +## - necessary "hash" links with, for example, " +## - $OPENSSL_HOME/bin/c_rehash /etc/postfix/certs". +## - +## - !! Note !! +## - To use this option in chroot mode, this directory (or a copy) must be inside +## - the chroot jail. +## - +## - Note that a chrooted daemon resolves all filenames relative to the Postfix +## - queue directory (/var/spool/postfix) +## - +#smtpd_tls_CApath = /etc/postfix/certs + + +# Disable SSLv2 SSLv3 - Postfix SMTP server +# +# List of TLS protocols that the Postfix SMTP server will exclude or +# include with opportunistic TLS encryption. +smtpd_tls_protocols = !SSLv2, !SSLv3 +# +# The SSL/TLS protocols accepted by the Postfix SMTP server +# with mandatory TLS encryption. +smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3 + + +# Disable SSLv2 SSLv3 - Postfix SMTP client +# +# List of TLS protocols that the Postfix SMTP client will exclude or +# include with opportunistic TLS encryption. +smtp_tls_protocols = !SSLv2, !SSLv3 +# +# List of SSL/TLS protocols that the Postfix SMTP client will use +# with mandatory TLS encryption +smtp_tls_mandatory_protocols = !SSLv2, !SSLv3 + + +## - Activate des "Ephemeral Elliptic Curve Diffie-Hellman" (EECDH) key exchange +## - openssl > 1.0 +## - +smtpd_tls_eecdh_grade = strong + +# standard list cryptographic algorithm +tls_preempt_cipherlist = yes + +# Disable ciphers which are less than 256-bit: +# +#smtpd_tls_mandatory_ciphers = high +# +# opportunistic +smtpd_tls_ciphers = high + + +# Exclude ciphers +#smtpd_tls_exclude_ciphers = +# RC4 +# aNULL +# SEED-SHA +# EXP +# MD5 +smtpd_tls_exclude_ciphers = + aNULL + eNULL + EXPORT + DES + RC4 + MD5 + PSK + aECDH + EDH-DSS-DES-CBC3-SHA + EDH-RSA-DES-CDC3-SHA + KRB5-DE5 + CBC3-SHA + + +smtpd_tls_session_cache_database = btree:\${data_directory}/smtpd_scache +smtp_tls_session_cache_database = btree:\${data_directory}/smtp_scache + +EOF +if $IS_RELAY_HOST ; then + cat <> /etc/postfix/main.cf + +#======= SASL Authentification ============ +smtpd_sasl_auth_enable = \$SASL_AUTH_ENABLED +smtpd_sasl_type = cyrus +smtpd_sasl_path = smtpd + +smtpd_sasl_security_options = noanonymous +smtpd_sasl_tls_security_options = \$smtpd_sasl_security_options +smtpd_sasl_authenticated_header = yes +broken_sasl_auth_clients = yes + + +## - Optional lookup table with the SASL login names that own +## - sender (MAIL FROM) addresses. +smtpd_sender_login_maps = + + +#======= Virtual mailboxes ============ + +## - Local Mailboxes +## - +virtual_mailbox_base = +virtual_uid_maps = +virtual_gid_maps = +EOF + +else + + cat <> /etc/postfix/main.cf + +#======= SASL Authentification ============ + +## - Enable SASL authentication in the Postfix SMTP server. By default, +## - the Postfix SMTP server does not use authentication. +## - +smtpd_sasl_auth_enable = no + +## - The SASL plug-in type that the Postfix SMTP server should use for authentication. +## - The available types are listed with the "postconf -a" command. +## - +## - Available values are at least: cyrus, dovecot +## - +smtpd_sasl_type = dovecot + + +## - Implementation-specific information that the Postfix SMTP server passes +## - through to the SASL plug-in implementation that is selected with smtpd_sasl_type. +## - Typically this specifies the name of a configuration file or rendezvous point. +## - +smtpd_sasl_path = private/dovecot-auth + +smtpd_sasl_security_options = noanonymous +smtpd_sasl_authenticated_header = yes +broken_sasl_auth_clients = yes + + +## - Optional lookup table with the SASL login names that own +## - sender (MAIL FROM) addresses. +smtpd_sender_login_maps = + + +#======= Virtual mailboxes ============ + +## - Local Mailboxes +## - +virtual_mailbox_base = /var/vmail +virtual_uid_maps = static:5000 +virtual_gid_maps = static:5000 +EOF + +fi + +cat <> /etc/postfix/main.cf + +## - virtual_transport +## - ================= +## - +## - using postfix +## - virtual_transport = virtual +## - +## - using dovecot lda +## - virtual_transport = dovecot +## - +## - using dovecot's lmtp service +## - virtual_transport = lmtp:unix:private/dovecot-lmtp +## - +virtual_transport = virtual + +virtual_mailbox_maps = + +virtual_mailbox_domains = + +## - Optional lookup tables that alias specific mail addresses or domains +## - to other local or remote address. The table format and lookups are +## - documented in virtual(5). For an overview of Postfix address +## - manipulations see the ADDRESS_REWRITING_README document. +## - +virtual_alias_maps = + ## - mailman + #hash:/var/lib/mailman/data/virtual-mailman + +## - Postfix is final destination for the specified list of virtual alias +## - domains, that is, domains for which all addresses are aliased to addresses +## - in other local or remote domains. The SMTP server validates recipient +## - addresses with \$virtual_alias_maps and rejects non-existent recipients. +## - See also the virtual alias domain class in the ADDRESS_CLASS_README file +## - +virtual_alias_domains = + + +#======= Restrictions ============ +smtpd_recipient_restrictions = +# only special accounts (postmaster, abuse and other rolr accounts) + check_recipient_access btree:/etc/postfix/access_recipient-rfc, +# White- / Blacklisting + check_sender_access btree:/etc/postfix/access_sender, + check_recipient_access btree:/etc/postfix/access_recipient, +# permit trusted network (mynetwork) + permit_mynetworks, +# permit our users + permit_sasl_authenticated, +# dont' accept misconfigured Mail + reject_non_fqdn_sender, + reject_non_fqdn_recipient, + reject_unknown_sender_domain, + reject_unknown_recipient_domain, + reject_unlisted_recipient, +# don't accept misconfigured recipients +# RBL check - !! comment out if postcreens postscreen_dnsbl_sites is in use + # Whitelist (configured on a.ns.oopen.de + # in /opt/tinydns/root/zonefiles/dnswl.oopen.de.zone ) + permit_dnswl_client dnswl.oopen.de, + # Blacklists + reject_rbl_client zen.spamhaus.org, + reject_rbl_client ix.dnsbl.manitu.net, + #reject_rbl_client bl.spamcop.net, + # March 1, 2013: NJABL is in the process of being shut down + #reject_rbl_client dnsbl.njabl.org, +# Policyd-Weight + #check_policy_service inet:127.0.0.1:12525, +# Greylisting check + warn_if_reject, + check_policy_service inet:127.0.0.1:10023, +# Reject the request unless one of the following is true: +# +# - Postfix is mail forwarder: the resolved RCPT TO domain matches \$relay_domains +# or a subdomain thereof, and contains no sender-specified routing (user@elsewhere@domain), +# +# +# - Postfix is the final destination: the resolved RCPT TO domain matches +# \$mydestination, \$inet_interfaces, \$proxy_interfaces, \$virtual_alias_domains, +# or \$virtual_mailbox_domains, and contains no sender-specified routing (user@elsewhere@domain). + reject_unverified_recipient, +# permit Backup MX + permit_mx_backup, +# forbid all other relaying + reject_unauth_destination, +# permit, if all restrictions so far passed + permit + + +## - Sinve version 2.11 +## - +smtpd_relay_restrictions = +# only special accounts (postmaster, abuse and other rolr accounts) + check_recipient_access btree:/etc/postfix/access_recipient-rfc, +# White- / Blacklisting + check_sender_access btree:/etc/postfix/access_sender, + check_recipient_access btree:/etc/postfix/access_recipient, +# permit trusted network (mynetwork) + permit_mynetworks, +# permit our users + permit_sasl_authenticated, +# dont' accept misconfigured Mail + reject_non_fqdn_sender, + reject_non_fqdn_recipient, + reject_unknown_sender_domain, + reject_unknown_recipient_domain, + reject_unlisted_recipient, +# don't accept misconfigured recipients +# RBL check - !! comment out if postcreens postscreen_dnsbl_sites is in use + # Whitelist (configured on a.ns.oopen.de + # in /opt/tinydns/root/zonefiles/dnswl.oopen.de.zone ) + permit_dnswl_client dnswl.oopen.de, + # Blacklists + reject_rbl_client zen.spamhaus.org, + reject_rbl_client ix.dnsbl.manitu.net, + #reject_rbl_client bl.spamcop.net, + # March 1, 2013: NJABL is in the process of being shut down + #reject_rbl_client dnsbl.njabl.org, +# Policyd-Weight + #check_policy_service inet:127.0.0.1:12525, +# Greylisting check + warn_if_reject, + check_policy_service inet:127.0.0.1:10023, +# Reject the request unless one of the following is true: +# +# - Postfix is mail forwarder: the resolved RCPT TO domain matches \$relay_domains +# or a subdomain thereof, and contains no sender-specified routing (user@elsewhere@domain), +# +# +# - Postfix is the final destination: the resolved RCPT TO domain matches +# \$mydestination, \$inet_interfaces, \$proxy_interfaces, \$virtual_alias_domains, +# or \$virtual_mailbox_domains, and contains no sender-specified routing (user@elsewhere@domain). + reject_unverified_recipient, +# permit Backup MX + permit_mx_backup, +# forbid all other relaying + reject_unauth_destination, +# permit, if all restrictions so far passed + permit + +EOF +echo_ok + + +## - /etc/mailname +## - +echononl " Set \"/etc/mailname\"" +echo $HOSTNAME > /etc/mailname +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +## - /etc/aliases +## - +echononl " Adjust \"/etc/aliases\"" +cat << EOF > /etc/aliases +# See man 5 aliases for format +mailer-daemon: postmaster +postmaster: root +nobody: root +hostmaster: root +usenet: root +news: root +webmaster: root +www: root +ftp: root +abuse: root +noc: root +security: root + +do-not-reply: /dev/null + +root: $ADMIN_EMAIL +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + + +## - create directory for certificates and copy certificates +## - and coresponding keys to /etc/postfix/ssl/ +## - +echononl " Create directory for certificates \"/etc/postfix/ssl\"" +if [[ -d "/etc/postfix/ssl" ]] ; then + echo_skipped +else + mkdir -p /etc/postfix/ssl + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +fi + + +## - generate DH parameters that the Postfix SMTP server should use +## - with EDH ciphers (length 512 and 1024 +## - +echononl " Generate DH key length=512 \"/etc/postfix/ssl/dh_512.pem\"" +if [ ! -f /etc/postfix/ssl/dh_512.pem ]; then + openssl dhparam -out /etc/postfix/ssl/dh_512.pem -2 512 > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi +echononl " Generate DH key length=1024 \"/etc/postfix/ssl/dh_1024.pem\"" +if [ ! -f /etc/postfix/ssl/dh_1024.pem ]; then + openssl dhparam -out /etc/postfix/ssl/dh_1024.pem -2 1024 > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi +echononl " Generate DH key length=2048 \"/etc/postfix/ssl/dh_2048.pem\"" +if [ ! -f /etc/postfix/ssl/dh_2048.pem ]; then + openssl dhparam -out /etc/postfix/ssl/dh_2048.pem -2 2048 > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi +echononl " Create Symlink \"$_TLS_CERT_FILE\"" +if [ ! -h "$_TLS_CERT_FILE" ]; then + ln -s /etc/ssl/certs/ssl-cert-snakeoil.pem $_TLS_CERT_FILE + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi +echononl " Create Symlink \"$_TLS_KEY_FILE\"" +if [ ! -h "$_TLS_KEY_FILE" ]; then + ln -s /etc/ssl/private/ssl-cert-snakeoil.key $_TLS_KEY_FILE + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + +## - rebuld alias database +## - +echononl " Rebuld alias database" +newaliases > /dev/null 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + + +## - create files +## - +echononl " Create file \"access_recipient-rfc\"" +cat < /etc/postfix/access_recipient-rfc +# if destination is ok, permit +/^postmaster\@/ permit_auth_destination +/^abuse\@/ permit_auth_destination +EOF +postmap btree:/etc/postfix/access_recipient-rfc +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + + +## - Notice: +## - The access_sender list can also be used as white list: +## - backup@b3-bornim.de OK +## - backup_file-ah@oopen.de OK +## - backup_file-spr@oopen.de OK +## - root_file_spr@oopen.de OK +## - backup_anw-urban@oopen.de OK +## - anonymous@bbb-server.b3-bornim.de OK +echononl " Create file \"access_sender\"" +cat < /etc/postfix/access_sender +# - bekannte Virus/Spam Absener blocken +# - +error@mailfrom.com REJECT +EOF +postmap btree:/etc/postfix/access_sender +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +echononl " Create file \"access_recipient\"" +echo > /etc/postfix/access_recipient +postmap btree:/etc/postfix/access_recipient +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +echononl " Create file \"transport\"" +echo > /etc/postfix/transport +postmap btree:/etc/postfix/transport +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +echononl " Create file \"relay_domains\"" +echo > /etc/postfix/relay_domains +postmap btree:/etc/postfix/relay_domains +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +if ! $_IS_RELAY_HOST ; then + ## - Create Directory '/var/vmail' for virtual mailboxes + ## - + echononl " Create directory '/var/vmail'" + if [[ ! -d "/var/vmail" ]]; then + mkdir /var/vmail > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi + else + echo_skipped + fi + + + ## - Create user (vmail) for virtual mailboxes + ## - + echononl " Create user 'vmail' for virtual mailboxes" + if id -u vmail > /dev/null 2>&1; then + echo_skipped + else + useradd -s /bin/false -d /var/vmail -M -u 5000 vmail > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi + fi + + ## - Change ownership 'vmail:vmail' for dir '/var/vmail' + ## - + echononl " Change ownership 'vmail:vmail' for dir '/var/vmail'" + chown vmail:vmail /var/vmail > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi + + + ## - Change permissions for dir '/var/vmail' + ## - + echononl " Change permissions for dir '/var/vmail'" + chmod 700 /var/vmail > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + if [[ "$SASL_AUTH_ENABLED" = "yes" ]]; then + + echononl " Create directory '/etc/postfix/sasl'.." + if [[ ! -d "/etc/postfix/sasl" ]] ; then + mkdir "/etc/postfix/sasl" > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi + else + echo_skipped + fi + + echononl " Create file '/etc/postfix/sasl/smtpd.conf'.." + cat < /etc/postfix/sasl/smtpd.conf +# - Take care only using provided login mechanisms. You can check this, by +# - running command +# - +# - saslpluginviewer -x AUXPROP_MECHS +# - +pwcheck_method: auxprop +auxprop_plugin: sasldb +mech_list: PLAIN LOGIN CRAM-MD5 DIGEST-MD5 NTLM +EOF + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi + fi +fi + + +## - /etc/postfix/master.cf +## - +## - Create Listener for user authenticated smtp connection port 587 (submission) +## - and port 465 (smtps) +## - +postfix_master_cf="/etc/postfix/master.cf" +echononl " Backup file \"${postfix_master_cf}\"" +cp -a $postfix_master_cf "${postfix_master_cf}.$backup_date" > /dev/null 2> $tmp_err_msg +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + +if grep -iq -E "^submission\s+" $postfix_master_cf > /dev/null 2>&1 ; then + submission_present=true +else + submission_present=false +fi + +if grep -iq -E "^smtps\s+" $postfix_master_cf > /dev/null 2>&1 ; then + smtps_present=true +else + smtps_present=false +fi + +_found=false +echononl " Create new file \"${postfix_master_cf}\"" +if [[ -f "${postfix_master_cf}.$backup_date" ]]; then + > $postfix_master_cf + while IFS='' read -r _line || [[ -n $_line ]] ; do + + if echo "$_line" | grep -i -E "^\s*smtp\s+inet\s+" > /dev/null 2>&1 ; then + _found=true + cat >> $postfix_master_cf << EOF +smtp inet n - y - - smtpd +EOF + if ! $IS_RELAY_HOST ; then + if ! $submission_present ; then + cat >> $postfix_master_cf << EOF +submission inet n - y - 20 smtpd + -o smtpd_tls_security_level=encrypt + -o smtpd_sasl_auth_enable=yes + -o smtpd_client_restrictions=permit_sasl_authenticated,reject + #-o milter_macro_daemon_name=ORIGINATING +EOF + fi + if ! $smtps_present ; then + cat >> $postfix_master_cf << EOF +smtps inet n - y - - smtpd + -o smtpd_tls_wrappermode=yes + -o smtpd_sasl_auth_enable=yes + -o smtpd_client_restrictions=permit_sasl_authenticated,reject + #-o milter_macro_daemon_name=ORIGINATING +EOF + fi + fi + continue + fi + + if $submission_present && echo "$_line" | grep -iq -E "^submission\s+" 2> /dev/null ; then + _found=true + if ! $IS_RELAY_HOST ; then + cat >> $postfix_master_cf << EOF +submission inet n - y - 20 smtpd + -o smtpd_tls_security_level=encrypt + -o smtpd_sasl_auth_enable=yes + -o smtpd_client_restrictions=permit_sasl_authenticated,reject +# -o milter_macro_daemon_name=ORIGINATING +EOF + fi + continue + fi + + if $smtps_present && echo "$_line" | grep -iq -E "^smtps\s+" 2> /dev/null ; then + _found=true + if ! $IS_RELAY_HOST ; then + cat >> $postfix_master_cf << EOF +smtps inet n - y - - smtpd + -o smtpd_tls_wrappermode=yes + -o smtpd_sasl_auth_enable=yes + -o smtpd_client_restrictions=permit_sasl_authenticated,reject +# -o milter_macro_daemon_name=ORIGINATING +EOF + fi + continue + fi + + # - [[:blank:]] means space and tab. This makes it similar to: [ \t] + # - [[:space;]] in addition to space and tab, includes newline, linefeed, formfeed, + # - and vertical tab. This makes it similar to: [ \t\n\r\f\v] + # - + #if [[ $_line =~ ^[[:space:]]+[^[:space:]]+ ]] && $_smtp_found ; then + # - + if [[ $_line =~ ^[[:blank:]]+[^[:space:]]+ ]] && $_found ; then + continue + fi + _found=false + + echo "$_line" >> $postfix_master_cf + + done < "${postfix_master_cf}.$backup_date" + + echo_done + warn "Please check file \"$postfix_master_cf\" !" +else + echo_failed + error "File \"${postfix_master_cf}.$backup_date\" not found!" +fi + + +## - restart postfix +## - +echononl " Restart postfix" +if $systemd_exists ; then + systemctl restart postfix > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + /etc/init.d/postfix restart > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +fi + + +## - Omitt logging into system.log +## - +echononl " Create \"/etc/rsyslog.d/postfix.conf\"" +cat << EOF >> /etc/rsyslog.d/postfix.conf + +# +# Logging for the mail system. Split it up so that +# it is easy to write scripts to parse these files. +# +mail.info -/var/log/mail.info +mail.warn -/var/log/mail.warn +mail.err /var/log/mail.err + +mail.* -/var/log/mail.log +& ~ +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +echononl " Restart rsyslog daemon" +if $systemd_exists ; then + systemctl restart rsyslog > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + /etc/init.d/rsyslog restart > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +fi + + +rm $tmp_err_msg +echo "" +clean_up 0 diff --git a/install_postfix_base.sh b/install_postfix_base.sh new file mode 100755 index 0000000..b1896af --- /dev/null +++ b/install_postfix_base.sh @@ -0,0 +1,999 @@ +#!/usr/bin/env bash + +_TLS_CERT_DIR=/etc/postfix/ssl +_TLS_CERT_FILE="${_TLS_CERT_DIR}/mailserver.crt" +_TLS_KEY_FILE="${_TLS_CERT_DIR}/mailserver.key" +# +_TLS_CA_FILE=/etc/ssl/certs/ca-certificates.crt +# +# +#_HOSTNAME=o15.oopen.de +#_IPV4=83.223.86.96 +#_EXT_IF_IP=83.223.86.96 +# +### - Leave empty, if no IPv6 should be supported +### - +#_IPV6=2a01:30:0:13:5054:ff:fe09:2318 +##_IPV6= +# +#_ADMIN_EMAIL=admin@oopen.de +# +#_SASL_AUTH=false +#_RELAY_HOST=b.mx.oopen.de +#_SASL_USER=anw-urb +#_SASL_PASS='OhPie2aethei' + + +# ------------- +# --- Some functions +# ------------- +echononl(){ + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo -e -n "$*\\c" 1>&2 + else + echo -e -n "$*" 1>&2 + fi + rm /tmp/shprompt$$ +} + +fatal(){ + echo "" + echo -e "fatal error: $*" + echo "" + echo -e "\t\033[31m\033[1mInstalllation will be interrupted\033[m\033[m" + echo "" + exit 1 +} + +error(){ + echo "" + echo -e "\t[ \033[31m\033[1mFehler\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 "" +} + +echo_done() { + echo -e "\033[80G[ \033[32mdone\033[m ]" +} +echo_ok() { + echo -e "\033[80G[ \033[32mok\033[m ]" +} +echo_warning() { + echo -e "\033[80G[ \033[33m\033[1mwarn\033[m ]" +} +echo_failed(){ + echo -e "\033[80G[ \033[1;31mfailed\033[m ]" +} +echo_skipped() { + echo -e "\033[80G[ \033[33m\033[1mskipped\033[m ]" +} + + +# - Is this a systemd system? +# - +if [[ "X`which systemd`" = "X" ]]; then + systemd_exists=false +else + systemd_exists=true +fi + +echo "" + +conf_dir=$(dirname $0)/conf +conf_file="${conf_dir}/install_postfix_base.conf" + +if [[ -f "$conf_file" ]]; then + source $conf_file +fi + +clear +echo -e "\033[21G\033[32mInstallation script for Postfix basic mailsystem \033[m" +echo + +HOSTNAME= +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Insert hostname" +echo "" +if [[ -n "$_HOSTNAME" ]]; then + echononl "hostname [${_HOSTNAME}]: " + read HOSTNAME + if [[ "X${HOSTNAME}" = "X" ]]; then + HOSTNAME=$_HOSTNAME + fi +else + while [[ "X${HOSTNAME}" = "X" ]]; do + echononl "hostname: " + read HOSTNAME + if [[ "X${HOSTNAME}" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mHostname is reqired\033[m\n" + fi + done +fi + +IPV4= +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Insert IPv4 address" +echo "" +if [[ -n "$_IPV4" ]]; then + echononl "IPv4 address [${_IPV4}]: " + read IPV4 + if [[ "X${IPV4}" = "X" ]]; then + IPV4=$_IPV4 + fi +else + while [[ "X${IPV4}" = "X" ]]; do + echononl "IPv4 address: " + read IPV4 + if [[ "X${IPV4}" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mIPv4 address is reqired\033[m\n" + fi + done +fi +IPV6= +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Insert IPv6 address" +echo "Type:" +echo -e "\t\033[33mNone\033[m if IPv6 is not suppoerted" +echo "" +if [[ -n "$_IPV6" ]]; then + [[ "X$_IPV6" = "Xdisabled" ]] && _IPV6=None + echononl "IPv6 address [${_IPV6}]: " + read IPV6 + if [[ "X${IPV6}" = "X" ]]; then + IPV6=$_IPV6 + fi +else + while [[ "X${IPV6}" = "X" ]]; do + echononl "IPv6 address: " + read IPV6 + if [[ "X${IPV6}" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mIPv4 address is reqired\033[m\n" + fi + done +fi +if [ "X$IPV6" = "Xnone" -o "X$IPV6" = "XNone" ]; then + IPV6=disabled +fi + +ADMIN_EMAIL= +echo "" +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Insert e-mail address where messages to local root should be forwarded" +echo "" +echo "" +if [[ -n "$_ADMIN_EMAIL" ]]; then + echononl "Admin e-mail address [$_ADMIN_EMAIL]: " + read ADMIN_EMAIL + if [[ "X${ADMIN_EMAIL}" = "X" ]]; then + ADMIN_EMAIL=$_ADMIN_EMAIL + fi +else + while [[ "X${ADMIN_EMAIL}" = "X" ]]; do + echononl "Admin e-mail address: " + read ADMIN_EMAIL + if [[ "X${ADMIN_EMAIL}" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mAdmin e-mail address is reqired\033[m\n" + fi + done +fi + +SASL_AUTH= +echo "" +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Should this System relay mails through another host using sasl auth?" +echo "" +if [[ -n "$_SASL_AUTH" ]]; then + if $_SASL_AUTH ; then + echononl "Relay mails using sasl auth? [yes]; " + read SASL_AUTH + if [[ "X${SASL_AUTH}" = "X" ]]; then + SASL_AUTH=true + else + SASL_AUTH=${SASL_AUTH,,} + if [ "X$SASL_AUTH" != "Xyes" -a "X$SASL_AUTH" != "Xno" ]; then + echononl "Wrong entry {yes/no]: " + fi + fi + else + echononl "Relay mails using sasl auth? [no]; " + read SASL_AUTH + if [[ "X${SASL_AUTH}" = "X" ]]; then + SASL_AUTH=false + else + SASL_AUTH=${SASL_AUTH,,} + if [ "X$SASL_AUTH" != "Xyes" -a "X$SASL_AUTH" != "Xno" ]; then + echononl "Wrong entry [yes/no]: " + fi + fi + fi +else + echononl "Relay mails using sasl auth? (yes/no); " + while [[ "X${SASL_AUTH}" = "X" ]] ; do + read SASL_AUTH + SASL_AUTH=${SASL_AUTH,,} + if [ "X$SASL_AUTH" != "Xyes" -a "X$SASL_AUTH" != "Xno" ]; then + SASL_AUTH= + echononl "Wrong entry [yes/no]: " + fi + done +fi +if [[ "$SASL_AUTH" = "yes" ]] || $SASL_AUTH ; then + SASL_AUTH=true + + SASL_USER= + echo "" + echo "Insert SASL user" + echo "" + if [[ -n "$_SASL_USER" ]];then + echononl "SASL user [$_SASL_USER]: " + read SASL_USER + if [[ "X${SASL_USER}" = "X" ]]; then + SASL_USER=$_SASL_USER + fi + else + while [[ "X${SASL_USER}" = "X" ]]; do + echononl "SASL user: " + read SASL_USER + if [[ "X${SASL_USER}" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mSASL user is reqired\033[m\n" + fi + done + fi + + SASL_PASS= + echo "" + echo "Insert SASL pasword" + echo "" + if [[ -n "$_SASL_PASS" ]];then + echononl "SASL password [$_SASL_PASS]: " + read SASL_PASS + if [[ "X${SASL_PASS}" = "X" ]]; then + SASL_PASS=$_SASL_PASS + fi + else + while [[ "X${SASL_PASS}" = "X" ]]; do + echononl "SASL password: " + read SASL_PASS + if [[ "X${SASL_PASS}" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mSASL password is reqired\033[m\n" + fi + done + fi + + RELAY_HOST= + echo "" + echo "Insert Relayhost" + echo "" + if [[ -n "$_RELAY_HOST" ]];then + echononl "Relayhost [$_RELAY_HOST]: " + read RELAY_HOST + if [[ "X${RELAY_HOST}" = "X" ]]; then + RELAY_HOST=$_RELAY_HOST + fi + else + while [[ "X${RELAY_HOST}" = "X" ]]; do + echononl "Relayhost: " + read RELAY_HOST + if [[ "X${RELAY_HOST}" = "X" ]]; then + echo -e "\n\t\033[33m\033[1mRelayhost is reqired\033[m\n" + fi + done + fi + + + +else + SASL_AUTH=false +fi + + +echo "" +echo "" +echo -e "\033[21G\033[32mStart installation/configuration with the following parameters\033[m" +echo "" +echo -e "\tHostname.................: $HOSTNAME" +echo -e "\tIPv4 address.............: $IPV4" +echo -e "\tIPv6 address.............: $IPV6" +echo -e "\tAdmin e-mail.............: $ADMIN_EMAIL" +echo "" +echo -e "\tRelay using sasl auth....: $SASL_AUTH" +if $SASL_AUTH ; then + echo -e "\t sasl user.............: $SASL_USER" + echo -e "\t sasl password.........: $SASL_PASS" + echo -e "\t Relayhost.............: $RELAY_HOST" +fi +echo "" +echononl "einverstanden (yes/no): " +read OK +OK=${OK,,} +while [ "X$OK" != "Xyes" -a "X$OK" != "Xno" ]; do + echononl "Wrong entry! [yes/no]: " + read OK + OK=${OK,,} +done +[ $OK = "yes" ] || fatal Repeat with other settings.. + +echo "" +echo "" + +echononl " Save Configuration" +cat << EOF > $conf_file +# --- +# - Parameter Settings Postfix Bases System +# - +# - - automated generated config file - +# --- + +_HOSTNAME=$HOSTNAME +_IPV4=$IPV4 +_IPV6=$IPV6 +_ADMIN_EMAIL=$ADMIN_EMAIL +_SASL_AUTH=$SASL_AUTH +_SASL_USER=$SASL_USER +_SASL_PASS=$SASL_PASS +_RELAY_HOST=$RELAY_HOST +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +[[ "$IPV6" = "disabled" ]] && IPV6="" + + +# - Deinstall debian exim4 packages +# - +echononl " Deinstall debian exim4 packages" +_installed_exim_packages=`dpkg -l | grep exim4 | grep -e "^i" | awk '{print$2}'` +for _pkg in $_installed_exim_packages ; do + installed_exim_packages="$installed_exim_packages $_pkg" +done +if [[ -n "$installed_exim_packages" ]] ; then + + if `dpkg -l | grep bsd-mailx | grep -e "^i" > /dev/null 2>&1` ; then + installed_exim_packages="$installed_exim_packages bsd-mailx" + fi + + apt-get remove --purge -qq -y $installed_exim_packages > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + + + +# - Install Postfix from debian packages system +# - +echononl " Install Postfix from debian packages system" +_needed_packages="postfix postfix-pcre libsasl2-modules bsd-mailx haveged" +for _pkg in $_needed_packages ; do + if `dpkg -l | grep $_pkg | grep -e "^i" > /dev/null 2>&1` ; then + continue + else + needed_packages="$needed_packages $_pkg" + fi +done +if [[ -n "$needed_packages" ]]; then + DEBIAN_FRONTEND=noninteractive apt-get -y install $needed_packages > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + + +# - Backup existing postfix configuration file +# - +echononl " Backup existing postfix configuration file" +if [[ -f "/etc/postfix/main.cf" ]]; then + cp -a /etc/postfix/main.cf /etc/postfix/main.cf.`date +%Y%m%d-%H%M` + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + + +# - Creeate new postfix configuration file +# - +echononl " Creeate new postfix configuration file" +cat < /etc/postfix/main.cf +# ============ Basic settings ============ + +# Debian specific: Specifying a file name will cause the first +# line of that file to be used as the name. The Debian default +# is /etc/mailname. +#myorigin = /etc/mailname +myorigin = /etc/mailname + +smtpd_banner = \$myhostname ESMTP \$mail_name (Debian/GNU) +biff = no + +# appending .domain is the MUA's job. +append_dot_mydomain = no + +# Uncomment the next line to generate "delayed mail" warnings +#delay_warning_time = 4h + +readme_directory = /usr/share/doc/postfix +html_directory = /usr/share/doc/postfix/html + +## - The Internet protocols Postfix will attempt to use when making +## - or accepting connections. +## - DEFAULT: ipv4 +EOF + +if [ -n "$IPV6" ]; then + cat <> /etc/postfix/main.cf +inet_protocols = ipv4, ipv6 + +#inet_interfaces = all + +inet_interfaces = 127.0.0.1 + $IPV4 + $IPV6 + +myhostname = $HOSTNAME + +mydestination = + $HOSTNAME + localhost + +## - The list of "trusted" SMTP clients that have more +## - privileges than "strangers" +## - +mynetworks = + 127.0.0.0/8 + [::ffff:127.0.0.0]/104 + [::1]/128 + ${IPV4}/32 + [${IPV6}]/128 + +#smtp_bind_address = $IPV4 +#smtp_bind_address6 = $IPV6 + +EOF +else + cat <> /etc/postfix/main.cf +inet_protocols = ipv4 + +#inet_interfaces = all +inet_interfaces = + 127.0.0.1 + $IPV4 + +myhostname = $HOSTNAME + +mydestination = + $HOSTNAME + localhost + +## - The list of "trusted" SMTP clients that have more +## - privileges than "strangers" +## - +mynetworks = + 127.0.0.0/8 + ${IPV4}/32 + +#smtp_bind_address = $IPV4 +#smtp_bind_address6 = $IPV6 + +EOF +fi + +cat <> /etc/postfix/main.cf + +## - The method to generate the default value for the mynetworks parameter. +## - +## - mynetworks_style = host" when Postfix should "trust" only the local machine +## - mynetworks_style = subnet (default value) "when Postfix should "trust" SMTP +## - clients in the same IP subnetworks as the local machine. +## - mynetworks_style = class" when Postfix should "trust" SMTP clients in the same +## - IP class A/B/C networks as the local machine. +## - +#mynetworks_style = host + + +## - The maximal size of any local(8) individual mailbox or maildir file, +## - or zero (no limit). In fact, this limits the size of any file that is +## - written to upon local delivery, including files written by external +## - commands that are executed by the local(8) delivery agent. +## - +mailbox_size_limit = 0 + +## - The maximal size in bytes of a message, including envelope information. +## - +## - we user 50MB +## - +message_size_limit = 52480000 + +## - The system-wide recipient address extension delimiter +## - +recipient_delimiter = + + +## - The alias databases that are used for local(8) delivery. +## - +alias_maps = + hash:/etc/aliases + +## - The alias databases for local(8) delivery that are updated +## - with "newaliases" or with "sendmail -bi". +## - +alias_database = + hash:/etc/aliases + + +## - The maximal time a message is queued before it is sent back as +## - undeliverable. Defaults to 5d (5 days) +## - Specify 0 when mail delivery should be tried only once. +## - +maximal_queue_lifetime = 3d +bounce_queue_lifetime = \$maximal_queue_lifetime + +## - delay_warning_time (default: 0h) +## - +## - The time after which the sender receives a copy of the message +## - headers of mail that is still queued. To enable this feature, +## - specify a non-zero time value (an integral value plus an optional +## - one-letter suffix that specifies the time unit). +## - Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks). +## - The default time unit is h (hours). +delay_warning_time = 1d + + +EOF + +if $SASL_AUTH ; then + cat <> /etc/postfix/main.cf + +# ============ Relay parameters ============ + +#relayhost = + + +# ============ SASL authentication ============ + +# Enable SASL authentication +smtp_sasl_auth_enable = yes + +# Forwarding to the ip-adress of host b.mx.oopen.de +relayhost = [${RELAY_HOST}] + +# File including login data +smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd + +# Force using a (TLS) security connection +# obsulete - use smtp_tls_security_level instead +#smtp_use_tls = yes +#smtp_tls_enforce_peername = no +smtp_tls_security_level = encrypt + +# Disallow methods that allow anonymous authentication. +smtp_sasl_security_options = noanonymous + + + +# ============ TLS parameters ============ + +## - Aktiviert TLS für den Mailempfang +## - +## - may: +## - Opportunistic TLS. Use TLS if this is supported by the remote +## - SMTP server, otherwise use plaintext +## - +## - This overrides the obsolete parameters smtpd_use_tls and +## - smtpd_enforce_tls. This parameter is ignored with +## - "smtpd_tls_wrappermode = yes". +#smtpd_use_tls=yes +smtp_tls_security_level=encrypt + +EOF + +else + cat <> /etc/postfix/main.cf + +# ============ Relay parameters ============ + +relayhost = + + +# ============ TLS parameters ============ + +## - Aktiviert TLS für den Mailempfang +## - +## - may: +## - Opportunistic TLS. Use TLS if this is supported by the remote +## - SMTP server, otherwise use plaintext +## - +## - This overrides the obsolete parameters smtpd_use_tls and +## - smtpd_enforce_tls. This parameter is ignored with +## - "smtpd_tls_wrappermode = yes". +#smtpd_use_tls=yes +smtp_tls_security_level=may + +EOF +fi + +cat <> /etc/postfix/main.cf +## - Aktiviert TLS für den Mailversand +## - +## - may: +## - Opportunistic TLS: announce STARTTLS support to SMTP clients, +## - but do not require that clients use TLS encryption. +# smtp_use_tls=yes +smtpd_tls_security_level=may + +## - 0 Disable logging of TLS activity. +## - 1 Log TLS handshake and certificate information. +## - 2 Log levels during TLS negotiation. +## - 3 Log hexadecimal and ASCII dump of TLS negotiation process. +## - 4 Also log hexadecimal and ASCII dump of complete transmission after STARTTLS. +## - +smtpd_tls_loglevel = 1 +smtp_tls_loglevel = 1 + +smtpd_tls_cert_file = $_TLS_CERT_FILE +smtpd_tls_key_file = $_TLS_KEY_FILE + +## - File with DH parameters that the Postfix SMTP server should use with EDH ciphers. +## - +## - Dont't forget to create it, e.g with openssl: +## - openssl dhparam -out /etc/postfix/ssl/dh_1024.pem -2 1024 +## - +#smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_1024.pem +## - also possible to use 2048 key with that parameter +## - +smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_2048.pem + +## - File with DH parameters that the Postfix SMTP server should use with EDH ciphers. +## - +## - Dont't forget to create it, e.g with openssl: +## - openssl dhparam -out /etc/postfix/ssl/dh_512.pem -2 512 +## - +smtpd_tls_dh512_param_file = /etc/postfix/ssl/dh_512.pem + + +## - File containing CA certificates of root CAs trusted to sign either remote SMTP +## - server certificates or intermediate CA certificates. These are loaded into +## - memory !! BEFORE !! the smtp(8) client enters the chroot jail. +## - +smtp_tls_CAfile = $_TLS_CA_FILE + +## - Directory with PEM format certificate authority certificates that the Postfix SMTP +## - client uses to verify a remote SMTP server certificate. Don't forget to create the +## - necessary "hash" links with, for example, " +## - $OPENSSL_HOME/bin/c_rehash /etc/postfix/certs". +## - +## - !! Note !! +## - To use this option in chroot mode, this directory (or a copy) must be inside +## - the chroot jail. +## - +## - Note that a chrooted daemon resolves all filenames relative to the Postfix +## - queue directory (/var/spool/postfix) +## - +#smtpd_tls_CApath = /etc/postfix/certs + + +# Disable SSLv2 SSLv3 - Postfix SMTP server +# +# List of TLS protocols that the Postfix SMTP server will exclude or +# include with opportunistic TLS encryption. +smtpd_tls_protocols = !SSLv2, !SSLv3 +# +# The SSL/TLS protocols accepted by the Postfix SMTP server +# with mandatory TLS encryption. +smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3 + + +# Disable SSLv2 SSLv3 - Postfix SMTP client +# +# List of TLS protocols that the Postfix SMTP client will exclude or +# include with opportunistic TLS encryption. +smtp_tls_protocols = !SSLv2, !SSLv3 +# +# List of SSL/TLS protocols that the Postfix SMTP client will use +# with mandatory TLS encryption +smtp_tls_mandatory_protocols = !SSLv2, !SSLv3 + + +## - Activate des "Ephemeral Elliptic Curve Diffie-Hellman" (EECDH) key exchange +## - openssl > 1.0 +## - +smtpd_tls_eecdh_grade = strong + +# standard list cryptographic algorithm +tls_preempt_cipherlist = yes + +# Disable ciphers which are less than 256-bit: +# +#smtpd_tls_mandatory_ciphers = high +# +# opportunistic +smtpd_tls_ciphers = high + + +# Exclude ciphers +#smtpd_tls_exclude_ciphers = +# RC4 +# aNULL +# SEED-SHA +# EXP +# MD5 +smtpd_tls_exclude_ciphers = + aNULL + eNULL + EXPORT + DES + RC4 + MD5 + PSK + aECDH + EDH-DSS-DES-CBC3-SHA + EDH-RSA-DES-CDC3-SHA + KRB5-DE5, CBC3-SHA + + +smtpd_tls_session_cache_database = btree:\${data_directory}/smtpd_scache +smtp_tls_session_cache_database = btree:\${data_directory}/smtp_scache + +EOF +echo_ok + +echononl " Configure SASL authentification" +if $SASL_AUTH ; then + + _failed=false + echo "[$RELAY_HOST] ${SASL_USER}@${RELAY_HOST}:$SASL_PASS" > /etc/postfix/sasl_passwd + if [[ "$?" != "0" ]]; then + error "Setting \"/etc/postfix/sasl_passwd\" failed! " + _failed=true + fi + chown root:root /etc/postfix/sasl_passwd + if [[ "$?" != "0" ]]; then + error "Setting ownership of \"/etc/postfix/sasl_passwd\" failed! " + _failed=true + fi + chmod 600 /etc/postfix/sasl_passwd + if [[ "$?" != "0" ]]; then + error "Setting permissions on \"/etc/postfix/sasl_passwd\" failed! " + _failed=true + fi + postmap /etc/postfix/sasl_passwd + chown root:root /etc/postfix/sasl_passwd.db + if [[ "$?" != "0" ]]; then + error "Creating \"/etc/postfix/sasl_passwd\" failed! " + _failed=true + fi + chown root:root /etc/postfix/sasl_passwd.db + if [[ "$?" != "0" ]]; then + error "Setting ownership of \"/etc/postfix/sasl_passwd.db\" failed! " + _failed=true + fi + if $_failed ; then + echo_failed + else + echo_ok + fi +else + echo_skipped +fi + +## - /etc/mailname +## - +echononl " Set \"/etc/mailname\"" +echo $HOSTNAME > /etc/mailname +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +## - /etc/aliases +## - +echononl " Adjust \"/etc/aliases\"" +cat << EOF > /etc/aliases +# See man 5 aliases for format +mailer-daemon: postmaster +postmaster: root +nobody: root +hostmaster: root +usenet: root +news: root +webmaster: root +www: root +ftp: root +abuse: root +noc: root +security: root + +do-not-reply: /dev/null + +root: $ADMIN_EMAIL +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + + +## - create directory for certificates and copy certificates +## - and coresponding keys to /etc/postfix/ssl/ +## - +echononl " Create directory for certificates \"/etc/postfix/ssl\"" +if [[ -d "/etc/postfix/ssl" ]] ; then + echo_skipped +else + mkdir -p /etc/postfix/ssl + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +fi + + +## - generate DH parameters that the Postfix SMTP server should use +## - with EDH ciphers (length 512 and 1024 +## - +echononl " Generate DH key length=512 \"/etc/postfix/ssl/dh_512.pem\"" +if [ ! -f /etc/postfix/ssl/dh_512.pem ]; then + openssl dhparam -out /etc/postfix/ssl/dh_512.pem -2 512 > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi +echononl " Generate DH key length=1024 \"/etc/postfix/ssl/dh_1024.pem\"" +if [ ! -f /etc/postfix/ssl/dh_1024.pem ]; then + openssl dhparam -out /etc/postfix/ssl/dh_1024.pem -2 1024 > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi +echononl " Generate DH key length=2048 \"/etc/postfix/ssl/dh_2048.pem\"" +if [ ! -f /etc/postfix/ssl/dh_2048.pem ]; then + openssl dhparam -out /etc/postfix/ssl/dh_2048.pem -2 2048 > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi +echononl " Create Symlink \"$_TLS_CERT_FILE\"" +if [ ! -h "$_TLS_CERT_FILE" ]; then + ln -s /etc/ssl/certs/ssl-cert-snakeoil.pem $_TLS_CERT_FILE + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi +echononl " Create Symlink \"$_TLS_KEY_FILE\"" +if [ ! -h "$_TLS_KEY_FILE" ]; then + ln -s /etc/ssl/private/ssl-cert-snakeoil.key $_TLS_KEY_FILE + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + +## - rebuld alias database +## - +echononl " Rebuld alias database" +newaliases > /dev/null 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +## - restart postfix +## - +echononl " Restart postfix" +if $systemd_exists ; then + systemctl restart postfix > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + /etc/init.d/postfix restart > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +fi + + +## - Omitt logging into system.log +## - +echononl " Create \"/etc/rsyslog.d/postfix.conf\"" +cat << EOF >> /etc/rsyslog.d/postfix.conf + +# +# Logging for the mail system. Split it up so that +# it is easy to write scripts to parse these files. +# +mail.info -/var/log/mail.info +mail.warn -/var/log/mail.warn +mail.err /var/log/mail.err + +mail.* -/var/log/mail.log +& ~ +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + +echononl " Restart rsyslog daemon" +if $systemd_exists ; then + systemctl restart rsyslog > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + /etc/init.d/rsyslog restart > /dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +fi + + +echo "" +exit diff --git a/install_postfixadmin.sh b/install_postfixadmin.sh new file mode 100755 index 0000000..f3b6135 --- /dev/null +++ b/install_postfixadmin.sh @@ -0,0 +1,2978 @@ +#!/usr/bin/env bash +clear +echo -e "\n\t\033[32mStart script for installation Postfix Admin and vacation script..\033[m" + +## =================================================================== +## - Install Postfixadmin +## =================================================================== + +## ----------------------------------------------------------------- +## ---------------------------------------------------------------- +## --- +## --- For configurations see file conf/install_postfixadmin.conf +## --- +## --- Dont make changes here! +## --- +## ----------------------------------------------------------------- +## ----------------------------------------------------------------- + +# ------------- +# - Settings +# ------------- + +_src_base_dir="$(realpath $(dirname $0))" +#_src_base_dir=/usr/local/src/postfixadmin +conf_file="${_src_base_dir}/conf/install_postfixadmin.conf" +curdir=`pwd` + +log_file="$(mktemp)" +backup_date="$(date +%Y-%m-%d-%H%M)" + +declare -A check_entry_main_cf_arr + +# ------------- +# - Functions +# ------------- + +echononl(){ + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo "$*\\c" 1>&2 + else + echo -e -n "$*" 1>&2 + fi + rm /tmp/shprompt$$ +} + +fatal(){ + echo "" + echo -e "\t[ \033[31m\033[1mFatal\033[m ]: $*" + echo "" + echo -e "\t\033[31m\033[1mInstalllation wird abgebrochen\033[m\033[m" + echo "" + exit 1 +} + +error(){ + echo "" + echo -e "\t[ \033[31m\033[1mFehler\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 "" +} +# - remove leading/trailling whitespaces +# - +trim() { + local var="$*" + var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters + var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters + echo -n "$var" +} + +echo_ok() { + echo -e "\033[75G[ \033[32mok\033[m ]" + ## echo -e " [ ok ]" +} +echo_failed(){ + echo -e "\033[75G[ \033[1;31mfailed\033[m ]" + ## echo -e " [ failed ]" +} +echo_skipped() { + echo -e "\033[75G[ \033[30m\033[1mskipped\033[m ]" +} + +detect_os_1 () { + + if $(which lsb_release > /dev/null 2>&1) ; then + + os_dist="$(lsb_release -i | awk '{print tolower($3)}')" + os_version="$(lsb_release -r | awk '{print tolower($2)}')" + os_codename="$(lsb_release -c | awk '{print tolower($2)}')" + + if [[ "$os_dist" = "debian" ]]; then + if $(echo "$os_version" | grep -q '\.') ; then + os_version=$(echo "$os_version" | cut --delimiter='.' -f1) + fi + fi + + elif [[ -e "/etc/os-release" ]]; then + + . /etc/os-release + + os_dist=$ID + os_version=${os_version_ID} + + fi + + # remove whitespace from os_dist and os_version + os_dist="${os_dist// /}" + os_version="${os_version// /}" + +} + + + +# - Is 'systemd' supported on this system +# - +if [ "X`which systemd`" = "X" ]; then + SYSTEMD_EXISTS=false +else + SYSTEMD_EXISTS=true +fi + +# - Set variable +# - os_dist +# - os_version +# - os_codename +# - +detect_os_1 + + +if [ "$POSTFIX_DB_TYPE" = "postgres" -o "$POSTFIX_DB_TYPE" = "postgresql" -o "$POSTFIX_DB_TYPE" = "pgsql" -o "$POSTFIX_DB_TYPE" = "psql" ];then + POSTFIX_DB_TYPE=pgsql +fi + +echo +echononl "\tInclude Configuration file.." +if [[ ! -f $conf_file ]]; then + echo_failed + fatal "Missing configuration file '$conf_file'" +else + source $conf_file + echo_ok +fi + + + +# - Default values +# - +DEFAULT_HTTP_USER="www-data" +DEFAULT_HTTP_GROUP="www-data" +DEFAULT_APACHE_LOG_DIR="/var/log/apache2" +DEFAULT_WEBSITE_BASEDIR="/var/www/${WEBSITE_NAME}" +DEFAULT_DEBIAN_APACHE_CERT_DIR="/etc/apache2" +DEFAULT_APACHE_CERT_DIR="/usr/local/apache2/conf" +DEFAULT_APACHE_SERVER_CERT="server-bundle.crt" +DEFAULT_APACHE_SERVER_KEY="server.key" +DEFAULT_DEBIAN_APACHE_VHOST_DIR="/etc/apache2/sites-available" +DEFAULT_APACHE_VHOST_DIR="/usr/local/apache2/conf/vhosts" +DEFAULT_POSTFIX_DB_HOST="localhost" +DEFAULT_POSTFIX_DB_NAME="postfix" +DEFAULT_POSTFIX_DB_USER="postfix" +DEFAULT_POSTFIX_DB_SOCKET_PG="/var/run/postgresql" +DEFAULT_DEBIAN_MYSQL_CREDENTIALS="/etc/mysql/debian.cnf" +DEFAULT_MYSQL_CREDENTIALS="/usr/local/mysql/sys-maint.cnf" + +DEFAULT_DOVEADM_PW="/usr/local/dovecot/bin/doveadm pw" +DEFAULT_DELETED_MAILBOX_DIR="/var/deleted-maildirs" +DEFAULT_DELETED_DOMAINS_DIR="/var/deleted-maildomains" + +DEFAULT_VACATION_USER="vacation" +DEFAULT_VACATION_GROUP="vacation" + + +[[ -n "$PF_ADMIN_VERSION" ]] || fatal "Version of Postfix Admin to install (PF_ADMIN_VERSION) not present!" +[[ -n "$WEBSITE_NAME" ]] || fatal "Website's name (WEBSITE_NAME) not present!" + +TLD=${WEBSITE_NAME##*.} +_tmp_string=${WEBSITE_NAME%.*} +MAIN_DOMAIN=${_tmp_string##*.} + +DOMAIN="${MAIN_DOMAIN}.$TLD" + +[[ -n "$WEBMASTER_EMAIL" ]] || WEBMASTER_EMAIL="admin@${MAIN_DOMAIN}.$TLD" + +[[ -n "$IPV4" ]] || fatal "IPv4 Address (IPV4) not present!" +[[ -n "$IPV6" ]] || fatal "IPv4 Address (IPV6) not present!" + +[[ -n "$APACHE_DEBIAN_INSTALLATION" ]] || APACHE_DEBIAN_INSTALLATION=false + +httpd_binary="`which httpd`" +if [ -z "$httpd_binary" ]; then + httpd_binary="$(ps -axu | grep httpd | grep -e "^root" | grep -v grep | awk '{print$11}')" + if [ -z "$httpd_binary" ]; then + if [ -x "/usr/local/apache2/bin/httpd" ]; then + httpd_binary="/usr/local/apache2/bin/httpd" + fi + fi +fi + +if [ -x "$httpd_binary" ];then + + # - Determin websever user + # - + HTTP_USER="`$httpd_binary -t -D DUMP_RUN_CFG | grep -i -e "^User" | awk '{print$2}' | cut -d\"=\" -f2 | tr -d '"'`" + HTTP_GROUP="`$httpd_binary -t -D DUMP_RUN_CFG | grep -i -e "^Group" | awk '{print$2}' | cut -d\"=\" -f2 | tr -d '"'`" + + [[ -n "$HTTP_USER" ]] || HTTP_USER=$DEFAULT_HTTP_USER + [[ -n "$HTTP_GROUP" ]] || HTTP_GROUP=$DEFAULT_HTTP_GROUP + + # - Is webserver running ? + # - + PID=$(ps aux | grep "$(realpath $httpd_binary)" | grep -e "^root" | grep -v grep | awk '{print$2}') + if [[ "X${PID}X" = "XX" ]] ;then + IS_HTTPD_RUNNING=false + else + IS_HTTPD_RUNNING=true + fi +fi + +[[ -n "$WEBMASTER_EMAIL" ]] || fatal "E-Mail (WEBMASTER_EMAIL) for webmaster not present!" +[[ -n "$WEBSITE_BASEDIR" ]] || WEBSITE_BASEDIR=$DEFAULT_WEBSITE_BASEDIR + + +if [[ -z "$APACHE_CERT_DIR" ]] ; then + if $APACHE_DEBIAN_INSTALLATION ; then + APACHE_CERT_DIR="$DEFAULT_DEBIAN_APACHE_CERT_DIR" + else + APACHE_CERT_DIR="$DEFAULT_APACHE_CERT_DIR" + fi +fi + +[[ -n "$APACHE_SERVER_CERT" ]] || APACHE_SERVER_CERT=$DEFAULT_APACHE_SERVER_CERT +[[ -n "$APACHE_SERVER_KEY" ]] || APACHE_SERVER_KEY=$DEFAULT_APACHE_SERVER_KEY + +[[ -n "$APACHE_LOG_DIR" ]] || APACHE_LOG_DIR=$DEFAULT_APACHE_LOG_DIR + +if [[ -z "$PHP_TYPE" ]]; then + PHP_TYPE="php_fpm" +else + [[ "$PHP_TYPE" = "php_fpm" ]] || [[ "$PHP_TYPE" = "fcgid" ]] || [[ "$PHP_TYPE" = "mod_php" ]] || fatal "Wrong type of PHP (PHP_TYPE) given!" +fi + + +if [[ -z "$APACHE_VHOST_DIR" ]] ; then + if $APACHE_DEBIAN_INSTALLATION ; then + APACHE_VHOST_DIR="$DEFAULT_DEBIAN_APACHE_VHOST_DIR" + else + APACHE_VHOST_DIR="$DEFAULT_APACHE_VHOST_DIR" + fi +fi + +[[ -n "$AUTOREPLY_HOSTNAME" ]] || AUTOREPLY_HOSTNAME=autoreply.${MAIN_DOMAIN}.$TLD + +[[ -n "$AUTOREPLY_HOSTNAME" ]] || AUTOREPLY_HOSTNAME=autoreply.${MAIN_DOMAIN}.$TLD + + +[[ -n "$POSTFIX_DB_TYPE" ]] || fatal "Database Type of Postfix Database (POSTFIX_DB_TYPE) not present!" +[[ -n "$POSTFIX_DB_HOST" ]] || POSTFIX_DB_HOST="$DEFAULT_POSTFIX_DB_HOST" +[[ -n "$POSTFIX_DB_NAME" ]] || POSTFIX_DB_NAME="$DEFAULT_POSTFIX_DB_NAME" +[[ -n "$POSTFIX_DB_USER" ]] || POSTFIX_DB_USER="$DEFAULT_POSTFIX_DB_USER" +[[ -n "$POSTFIX_DB_PASS" ]] || fatal "Password of Postfix Database (POSTFIX_DB_PASS) not given!" + +if [[ -n "$POSTFIX_DB_SOCKET" ]]; then + if [[ "$POSTFIX_DB_TYPE" = "mysql" ]]; then + fatal "MySQL Socket (POSTFIX_DB_SOCKET) is not supported by this script" + fi +else + POSTFIX_DB_SOCKET="$DEFAULT_POSTFIX_DB_SOCKET_PG" +fi + +[[ -n "$MYSQL_DEBIAN_INSTALLATION" ]] || MYSQL_DEBIAN_INSTALLATION=false + +if [[ "$POSTFIX_DB_TYPE" = "mysql" ]]; then + if $MYSQL_DEBIAN_INSTALLATION ; then + [[ -n "$MYSQL_CREDENTIALS" ]] || MYSQL_CREDENTIALS="$DEFAULT_DEBIAN_MYSQL_CREDENTIALS" + else + [[ -n "$MYSQL_CREDENTIALS" ]] || MYSQL_CREDENTIALS="$DEFAULT_MYSQL_CREDENTIALS" + fi +else + [[ "$POSTFIX_DB_TYPE" = "pgsql" ]] || fatal "Unknown Database Type '$POSTFIX_DB_TYPE' (POSTFIX_DB_TYPE)" +fi + +[[ -n "$ENCRYPTION_METHOD" ]] || fatal "Encryption method for Passwords (ENCRYPTION_METHOD) not set!" + +if [[ "$ENCRYPTION_METHOD" =~ dovecot ]]; then + [[ -n "$DOVEADM_PW" ]] || DOVEADM_PW=$DEFAULT_DOVEADM_PW +fi + +[[ -n "$DELETED_MAILBOX_DIR" ]] || DELETED_MAILBOX_DIR=$DEFAULT_DELETED_MAILBOX_DIR +[[ -n "$DELETED_DOMAINS_DIR" ]] || DELETED_DOMAINS_DIR=$DEFAULT_DELETED_DOMAINS_DIR + +# - Vacation +# - + +[[ -n "$VACATION_USER" ]] || VACATION_USER=$DEFAULT_VACATION_USER +[[ -n "$VACATION_GROUP" ]] || VACATION_GROUP=$DEFAULT_VACATION_GROUP + + +# - Determin PHP of all installed versions +# - +echononl "\tGet major numbers of all installed PHP versions" +php_major_versions=`find /usr/local/ -maxdepth 1 -mindepth 1 -type l -name "php-*" -print | cut -d "-" -f2 | sort` +if [[ -z "$php_major_versions" ]]; then + echo_failed + error "Getting major numbers of installed PHP versions failed! No installed PHP versiond found!" +else + echo_ok +fi + +# - Get the latest PHP version +# - +echononl "\tGet major number of latest installed PHP version" +php_latest_ver="" +if [[ -n "$php_major_versions" ]]; then + for _ver in $php_major_versions ; do + if [[ -z "$php_latest_ver" ]] ; then + php_latest_ver=$_ver + elif [[ "${_ver%.*}" -gt "${php_latest_ver%.*}" ]] ; then + php_latest_ver=$_ver + elif [[ "${_ver%.*}" -eq "${php_latest_ver%.*}" ]] ; then + [[ "${_ver#*.}" -gt "${php_latest_ver#*.}" ]] && php_latest_ver=$_ver + fi + done + echo_ok +else + echo_skipped + warn "Getting major number of latest installed PHP version failed! - No installed PHP versiond found!" +fi + + +echo "" +echo "" +echo -e "\033[1;32mSettings for installation of \033[1;37mPostfix Admin / Vacation\033[m" +echo "" +echo -e "\tPostfix Admin Version................: $PF_ADMIN_VERSION" +echo "" +echo -e "\tName of the Website..................: $WEBSITE_NAME" +echo "" +echo -e "\tIPv4 Address.........................: $IPV4" +echo -e "\tIPv6 Address.........................: $IPV6" +echo "" +echo -e "\tApache from Debian Package System....: $APACHE_DEBIAN_INSTALLATION" +echo -e "\tApache User..........................: $HTTP_USER" +echo -e "\tApache Group.........................: $HTTP_GROUP" +echo -e "\tApache VHOST Directory...............: $APACHE_VHOST_DIR" +echo -e "\tApache LOG Directory.................: $APACHE_LOG_DIR" +echo "" +echo -e "\tApache Cert directory................: $APACHE_CERT_DIR" +echo -e "\tWebsite Certificate..................: $APACHE_SERVER_CERT" +if [[ -n "$CERT_ChainFile" ]] ; then + echo -e "\tCertificate Chain File...............: $CERT_ChainFile" +fi +echo -e "\tWebsite Key..........................: $APACHE_SERVER_KEY" +echo "" +echo -e "\tWebmasters E-Mail Address............: $WEBMASTER_EMAIL" +echo -e "\tBase Directory of PFA Website........: $WEBSITE_BASEDIR" +echo "" +echo -e "\tType of PHP connection...............: $PHP_TYPE" +echo "" +echo -e "\tInstalled PHP versions...............: $php_major_versions" +echo -e "\tNewest PHP Version...................: $php_latest_ver" +echo "" +if [[ "$POSTFIX_DB_TYPE" = "mysql" ]]; then + echo -e "\tDatabase type of Postfix Database....: MySQL" + echo -e "\tMySQL from Debian Package System.....: $MYSQL_DEBIAN_INSTALLATION" +else + echo -e "\tDatabase type of Postfix Database....: PostgreSQL" +fi +echo -e "\tHost of Postfix Database.............: $POSTFIX_DB_HOST" +echo -e "\tName of Postfix Database.............: $POSTFIX_DB_NAME" +echo -e "\tUser of Postfix Database.............: $POSTFIX_DB_USER" +echo -e "\tPassword of Postfix Database.........: $POSTFIX_DB_PASS" +if [[ "$POSTFIX_DB_TYPE" = "mysql" ]]; then + echo -e "\tMySQL Credentials (root access)......: $MYSQL_CREDENTIALS" +fi +echo "" +echo -e "\tEncryption Method used for Passwords.: $ENCRYPTION_METHOD" +if [[ "$ENCRYPTION_METHOD" =~ dovecot ]]; then + echo -e "\t'doveadm' binary.....................: $DOVEADM_PW" +fi +echo "" +echo -e "\tDirectory for deleted mailboxes......: $DELETED_MAILBOX_DIR" + +echo -e "\tDirectory for deleted mail domains...: $DELETED_DOMAINS_DIR" +echo "" +echo -e "\tHostname for Vacation Messages.......: $AUTOREPLY_HOSTNAME" +echo -e "\tUser of vacation script..............: $VACATION_USER" +echo -e "\tGroup of vacation script.............: $VACATION_GROUP" +echo "" +echo -e "\tSystem supports systemd..............: $SYSTEMD_EXISTS" +echo "" +echo "" + +echo "" +echo -n "Type upper case 'YES' to continue executing with this parameters: " +read OK +if [[ "$OK" = "YES" ]] ; then + echo "" + echo "" + echo -e "\t\033[1;32mGoing to install Postfix Admin / Vacation \033[1;37m\033[m" +else + fatal "Abort by user request - Answer as not 'YES'" +fi + + + +_log_dir=${_src_base_dir}/log-postfixadmin-$_version + +# - Determine major/minor version +# - +MAJOR_VERSION="$(echo $PF_ADMIN_VERSION | cut -d '.' -f1)" +MINOR_VERSION="$(echo $PF_ADMIN_VERSION | cut -d '.' -f2)" + + + + +echo -e "\n\n\t\033[37m\033[1mPre-installion tasks ..\033[m\n" + +# - Datenbank etstellen: +# - +# - MySQL/PostgreSQL Datenbank erstellen +# - +# - +_failed=false +> $log_file + + +_actual_config_file="" +_actual_password_hash="" +_actual_pfa_dir="" +if [[ -d "${WEBSITE_BASEDIR}/htdocs" ]] ; then + _actual_pfa_dir="$(realpath "${WEBSITE_BASEDIR}/htdocs")" +fi +echononl "\tKeep passwordhasch from actual installation in mind.." +if [[ -n "$_actual_pfa_dir" && -d "$_actual_pfa_dir" ]] ; then + if [[ -f "${_actual_pfa_dir}/config.local.php" ]]; then + _actual_config_file="${_actual_pfa_dir}/config.local.php" + else + _actual_config_file="${_actual_pfa_dir}/config.inc.php" + fi +fi + + +if [[ -f "$_actual_config_file" ]]; then + _actual_password_hash="$(grep -E "^\s*\\\$CONF\['setup_password'\]" $_actual_config_file 2> /dev/null \ + | grep -v changeme \ + | awk -F '=' '{print$2}'\ + | awk -F ';' '{print$1}')" + + _actual_password_hash="${_actual_password_hash#"${_actual_password_hash%%[![:space:]]*}"}" + # - Remove trailing whitespace characters + _actual_password_hash="${_actual_password_hash%"${_actual_password_hash##*[![:space:]]}"}" + # - Remove leading single quote + _actual_password_hash="${_actual_password_hash#"${_actual_password_hash%%[!\']*}"}" + # - Remove trailing single quote + _actual_password_hash="${_actual_password_hash%"${_actual_password_hash##*[!\']}"}" + # - Remove leading double quote + _actual_password_hash="${_actual_password_hash#"${_actual_password_hash%%[!\"]*}"}" + # - Remove trailing double quote + _actual_password_hash="${_actual_password_hash%"${_actual_password_hash##*[!\"]}"}" + + echo_ok +else + echo_skipped +fi + + +if [[ "$POSTFIX_DB_TYPE" = "mysql" ]] ; then + if ! mysql $MYSQL_CREDENTIALS -N -s -e \ + "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '$POSTFIX_DB_NAME'" 2>> $log_file \ + | grep $POSTFIX_DB_NAME >> $log_file 2>&1 ; then + database_exists=false + else + database_exists=true + fi +elif [[ "$POSTFIX_DB_TYPE" = "pgsql" ]]; then + count=$(su - postgres -c "psql -q -A -t -l" | grep -c -e "^$POSTFIX_DB_NAME") + if [[ $count -eq 0 ]];then + database_exists=false + else + database_exists=true + fi +else + fatal "Cannot detect database type (value of POSTFIX_DB_TYPE is neither 'mysql' nor 'pgsql')" +fi + +if ! $database_exists ; then + echononl "\tCreate Postfix Database '$POSTFIX_DB_NAME'" + if [ "$POSTFIX_DB_TYPE" = "mysql" ]; then + echo -n " (MySQL).." + mysql $MYSQL_CREDENTIALS -N -s -e \ + "CREATE DATABASE IF NOT EXISTS $POSTFIX_DB_NAME CHARACTER SET utf8 COLLATE utf8_general_ci" >> $log_file 2>&1 + if [[ $? -ne 0 ]] ; then + _failed=true + fi + mysql $MYSQL_CREDENTIALS -N -s -e \ + "GRANT ALL ON $POSTFIX_DB_NAME.* TO '$POSTFIX_DB_USER'@'localhost' IDENTIFIED BY '$POSTFIX_DB_PASS'" >> $log_file 2>&1 + if [[ $? -ne 0 ]] ; then + _failed=true + fi + mysql $MYSQL_CREDENTIALS -N -s -e "FLUSH PRIVILEGES" >> $log_file 2>&1 + if [[ $? -ne 0 ]] ; then + _failed=true + fi + if $_failed; then + echo_failed + error "$(cat $log_file)" + else + echo_ok + fi + elif [ "$POSTFIX_DB_TYPE" = "pgsql" ]; then + echo -n " (PostgreSQL).." + echo "CREATE ROLE $POSTFIX_DB_USER WITH LOGIN NOCREATEDB NOCREATEROLE NOSUPERUSER ENCRYPTED PASSWORD '$POSTFIX_DB_PASS'" \ + | su - postgres -c "psql" >> $log_file 2>&1 + if [[ $? -ne 0 ]] ; then + _failed=true + fi + su - postgres -c "createdb -E utf8 -O $POSTFIX_DB_USER $POSTFIX_DB_NAME" >> $log_file 2>&1 + if [[ $? -ne 0 ]] ; then + _failed=true + fi + if $_failed; then + echo_failed + error "$(cat $log_file)" + else + echo_ok + fi + fi +else + echononl "\tBackup Postfix Database '$POSTFIX_DB_NAME'" + if [[ "$POSTFIX_DB_TYPE" = "mysql" ]]; then + echo -n " (MySQL).." + mysqldump $MYSQL_CREDENTIALS --opt $POSTFIX_DB_NAME >> ${WEBSITE_BASEDIR}/${POSTFIX_DB_NAME}.${backup_date}.sql 2> $log_file + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + elif [[ "$POSTFIX_DB_TYPE" = "pgsql" ]]; then + echo -n " (PostgreSQL).." + su - postgres -c "pg_dump $POSTFIX_DB_NAME" >> ${WEBSITE_BASEDIR}/${POSTFIX_DB_NAME}.${backup_date}.sql 2> $log_file + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + fi +fi + +echononl "\tInstall needed debian packages.." +needed_packages="" +_needed_packages=" + libdbi-perl + libmime-encwords-perl + libemail-valid-perl + libmail-sendmail-perl + liblog-log4perl-perl + libdbi-dev + libemail-sender-perl + cpanminus" +if [[ $os_version -lt 9 ]] ; then + _needed_packages="$_needed_packages libmail-sender-perl" +fi +if [[ "$POSTFIX_DB_TYPE" = "pgsql" ]] ; then + _needed_packages="$_needed_packages + libdbd-pgsql + libdbd-pg-perl + libdbi-perl + libdbi-dev" +else + _needed_packages="$_needed_packages + libdbd-mysql + libdbd-mysql-perl" +fi +for _pkg in $_needed_packages ; do + if aptitude search "$_pkg" | grep " $_pkg " | grep -e "^i" > /dev/null 2>&1 ; then + continue + else + needed_packages="$needed_packages $_pkg" + fi +done +if [[ -n "$needed_packages" ]]; then + DEBIAN_FRONTEND=noninteractive apt-get -y install $needed_packages > /dev/null 2> "$log_file" + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +echononl "\tInstall database related CPAN Modules" +_failed=false +> $log_file +_needed_cpan_modules=" + CPAN + DBI + Mail::Sender" +if [[ "$POSTFIX_DB_TYPE" = "pgsql" ]] ; then + _needed_cpan_modules="$_needed_cpan_modules + DBD::Pg" +else + _needed_cpan_modules="$_needed_cpan_modules + DBD::mysql" +fi +for _module in $_needed_cpan_modules ; do + cpanm -q --skip-installed $_module >> "$log_file" 2>&1 + if [[ "$?" -ne 0 ]] ; then + error "$(cat $tmp_err_msg)" + fi +done +if $_failed ; then + echo_failed + error "$(cat $log_file)" +else + echo_ok +fi + + + +echo -e "\n\n\t\033[37m\033[1mBase install Postfixadmin..\033[m\n" + + +# - Get postfixadmin sources if not yet downloaded +# - +echononl "\tDownload 'postfixadmin-${PF_ADMIN_VERSION}'.." +if [[ ! -f "${_src_base_dir}/postfixadmin-${PF_ADMIN_VERSION}.tar.gz" ]];then + wget -O ${_src_base_dir}/postfixadmin-${PF_ADMIN_VERSION}.tar.gz http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin-${PF_ADMIN_VERSION}/postfixadmin-${PF_ADMIN_VERSION}.tar.gz > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +echononl "\tBackup existing source directory 'postfixadmin-${PF_ADMIN_VERSION}'.." +if [[ -d "${_src_base_dir}/postfixadmin-${PF_ADMIN_VERSION}" ]]; then + mv ${_src_base_dir}/postfixadmin-${PF_ADMIN_VERSION} \ + ${_src_base_dir}/postfixadmin-${PF_ADMIN_VERSION}.${backup_date} + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +echononl "\tUnpack 'postfixadmin-${PF_ADMIN_VERSION}.." +gunzip < ${_src_base_dir}/postfixadmin-${PF_ADMIN_VERSION}.tar.gz | tar -C ${_src_base_dir} -xf - 2> $log_file +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tCreate '$WEBSITE_BASEDIR'.." +if [[ ! -d "$WEBSITE_BASEDIR" ]]; then + mkdir $WEBSITE_BASEDIR > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +echononl "\tBackup existing web-directory 'postfixadmin-${PF_ADMIN_VERSION}'.." +if [[ -d "${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION}" ]]; then + mv ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION} \ + ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION}.${backup_date} > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + + +echononl "\tCopy Postfix Admin Directory to web-directory" +cp -a ${_src_base_dir}/postfixadmin-${PF_ADMIN_VERSION} ${WEBSITE_BASEDIR}/ +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +_failed=false +echononl "\tSet Permissions on \n\t ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION}" +find ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION} -type f -print0 2> $log_file \ + | xargs -0 chmod 640 2>> $log_file +if [[ $? -ne 0 ]] ; then + _failed=true +fi + +find ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION} -type f -print0 2>> $log_file \ + | xargs -0 chown root:$HTTP_GROUP 2>> $log_file +if [[ $? -ne 0 ]] ; then + _failed=true +fi + +find ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION} -type d -print0 2>> $log_file \ + | xargs -0 chown root:$HTTP_GROUP 2>> $log_file +if [[ $? -ne 0 ]] ; then + _failed=true +fi + +if [[ ! -d "${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION}/templates_c" ]]; then + mkdir ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION}/templates_c + if [[ $? -ne 0 ]] ; then + _failed=true + fi +fi +chown -R ${HTTP_USER}:$HTTP_GROUP ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION}/templates_c >> $log_file 2>&1 +if [[ $? -ne 0 ]] ; then + _failed=true +fi + +if $_failed; then + echo_failed + error "$(cat $log_file)" +else + echo_ok +fi + + +echononl "\tRemove existing symlink '${WEBSITE_BASEDIR}/htdocs'" +if [[ -h "${WEBSITE_BASEDIR}/htdocs" ]]; then + rm ${WEBSITE_BASEDIR}/htdocs + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi +echononl "\tCreate Symlink for DocumentRoot Directory 'htdocs'.." +if [[ ! -h "${WEBSITE_BASEDIR}/htdocs" ]]; then + ln -s postfixadmin-${PF_ADMIN_VERSION} ${WEBSITE_BASEDIR}/htdocs > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + + + +if [[ "$PHP_TYPE" = "fcgid" ]] ; then + echo -e "\n\n\t\033[37m\033[1mConfiguration for FastCGI PHP Connections (mod_fcgid)..\033[m\n" +elif [[ "$PHP_TYPE" = "php_fpm" ]] ; then + echo -e "\n\n\t\033[37m\033[1mConfiguration for PHP-FPM Connection ..\033[m\n" +elif [[ "$PHP_TYPE" = "mod_php" ]] ; then + echo -e "\n\n\t\033[37m\033[1mConfiguration for PHP Connection using Apache's mod_php..\033[m\n" +else + fatal "Wrong PHP Type '$PHP_TYPE' (PHP_TYPE)!" +fi + +echononl "\tCreate Log Directory '$APACHE_LOG_DIR'.." +if [[ ! -d "$APACHE_LOG_DIR" ]]; then + mkdir $APACHE_LOG_DIR > $log_file 2>&1 + if [[ "$?" = "0" ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +if [[ "$PHP_TYPE" = "fcgid" ]] ; then + + _dirs="${WEBSITE_BASEDIR}/sessions ${WEBSITE_BASEDIR}/tmp ${WEBSITE_BASEDIR}/logs" + for _dir in $_dirs ; do + echononl "\tCreate Directory '$_dir'" + if [[ ! -d "$_dir" ]]; then + mkdir $_dir > $log_file 2>&1 + if [[ "$?" = "0" ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + else + echo_skipped + fi + + echononl "\tSet Permissons on '$_dir'.." + chown ${HTTP_USER}:${HTTP_GROUP} $_dir > $log_file 2>&1 + if [[ "$?" = "0" ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + done + + echononl "\tCreate directory '${WEBSITE_BASEDIR}/conf'.." + if [[ ! -d "${WEBSITE_BASEDIR}/conf" ]]; then + mkdir ${WEBSITE_BASEDIR}/conf > $log_file 2>&1 + if [[ "$?" = "0" ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + else + echo_skipped + fi + + echononl "\tSet Permissions on '${WEBSITE_BASEDIR}/conf'.." + _failed=false + chown root:$HTTP_USER ${WEBSITE_BASEDIR}/conf > $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + chmod 750 ${WEBSITE_BASEDIR}/conf > $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + if ! $_failed ; then + echo_ok + fi + + for _version in $php_major_versions ; do + + echononl "\tPlace file '${WEBSITE_BASEDIR}/conf/php.ini-$_version'" + cp /usr/local/php-${_version}/etc/php.ini ${WEBSITE_BASEDIR}/conf/php.ini-$_version > $log_file 2>&1 + if [[ "$?" = "0" ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + + echononl "\tSet Permissions on '${WEBSITE_BASEDIR}/conf'.." + _failed=false + chown root:$HTTP_USER ${WEBSITE_BASEDIR}/conf/php.ini-$_version > $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + chmod 640 ${WEBSITE_BASEDIR}/conf/php.ini-$_version > $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + if ! $_failed ; then + echo_ok + fi + + echononl "\tCreate file '${WEBSITE_BASEDIR}/conf/fcgid-$_version'.." + cat < ${WEBSITE_BASEDIR}/conf/fcgid-$_version 2> $log_file +#!/bin/sh +export PHPRC="${WEBSITE_BASEDIR}/conf/" +export TMPDIR="${WEBSITE_BASEDIR}/tmp" +# PHP child process management (PHP_FCGI_CHILDREN) should +# always be disabled with mod_fcgid, which will only route one +# request at a time to application processes it has spawned; +# thus, any child processes created by PHP will not be used +# effectively. (Additionally, the PHP child processes may not +# be terminated properly.) By default, and with the environment +# variable setting PHP_FCGI_CHILDREN=0, PHP child process +# management is disabled. +PHP_FCGI_CHILDREN=0 +export PHP_FCGI_CHILDREN + +exec /usr/local/php-${_version}/bin/php-cgi +EOF + if [[ "$?" = "0" ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + + echononl "\tSet Permissions on '${WEBSITE_BASEDIR}/conf/fcgid-$_version'.." + _failed=false + chown root:$HTTP_USER ${WEBSITE_BASEDIR}/conf/fcgid-$_version > $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + chmod 750 ${WEBSITE_BASEDIR}/conf/fcgid-$_version > $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + if ! $_failed ; then + echo_ok + fi + done + + # - Create Symlinks in fcgid's config directory + # - + if [[ "$_version" = "$php_latest_ver" ]]; then + echononl "\tCreate symlink '${WEBSITE_BASEDIR}/conf/php.ini'.." + if [[ ! -h "${WEBSITE_BASEDIR}/conf/php.ini" ]]; then + ln -s php.ini-$_version ${WEBSITE_BASEDIR}/conf/php.ini > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + else + echo_skipped + fi + + echononl "\tCreate symlink '${WEBSITE_BASEDIR}/conf/fcgid'.." + if [[ ! -h "${WEBSITE_BASEDIR}/conf/fcgid" ]]; then + ln -s fcgid-$_version ${WEBSITE_BASEDIR}/conf/fcgid > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + else + echo_skipped + fi + + fi + + echononl "\tCreate file '${WEBSITE_BASEDIR}/conf/changes.php.ini.txt'.." + cat << EOF > ${WEBSITE_BASEDIR}/conf/changes.php.ini.txt +error_log = "${WEBSITE_BASEDIR}/logs/php_errors.log" +sys_temp_dir = "${WEBSITE_BASEDIR}/tmp" +upload_tmp_dir = "${WEBSITE_BASEDIR}/tmp" +session.save_path = "${WEBSITE_BASEDIR}/sessions" +soap.wsdl_cache_dir = "${WEBSITE_BASEDIR}/tmp" +EOF + if [[ "$?" = "0" ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + + echononl "\tCreate file '${WEBSITE_BASEDIR}/logs/php_errors.log'.." + + if [[ ! -f "${WEBSITE_BASEDIR}/logs/php_errors.log" ]]; then + touch ${WEBSITE_BASEDIR}/logs/php_errors.log > $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + chown ${HTTP_USER}:${HTTP_GROUP} ${WEBSITE_BASEDIR}/logs/php_errors.log > $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + if ! $_failed ; then + echo_ok + fi + else + echo_skipped + fi + + _php_ini_file="${WEBSITE_BASEDIR}/conf/php.ini-*" + + echononl "\tAdjust files '${WEBSITE_BASEDIR}/conf/php.ini-*'.." + _failed=false + _key=error_log + _val="${WEBSITE_BASEDIR}/logs/php_errors.log" + if grep -e "^\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + #sed -i "0,/^\([ \t]*${_key}[ \t]*=.*\)/ s##;\1\n${_key} = \"${_val}\"#" $_php_ini_file + perl -i -n -p -e "s#^(\s*${_key}\s*=.*)#;\1\n${_key} = ${_val}#" $_php_ini_file > $log_file 2>&1 + elif grep -e "^\s*;\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + sed -i "0,/^\([ \t]*;[ \t]*${_key}[ \t]*=.*\)/ s##\1\n${_key} = \"${_val}\"\n#" $_php_ini_file > $log_file 2>&1 + fi + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + + _key="sys_temp_dir" + _val="${WEBSITE_BASEDIR}/tmp" + if grep -e "^\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + #sed -i "0,/^\([ \t]*${_key}[ \t]*=.*\)/ s##;\1\n${_key} = \"${_val}\"#" $_php_ini_file + perl -i -n -p -e "s#^(\s*${_key}\s*=.*)#;\1\n${_key} = ${_val}#" $_php_ini_file > $log_file 2>&1 + elif grep -e "^\s*;\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + sed -i "0,/^\([ \t]*;[ \t]*${_key}[ \t]*=.*\)/ s##\1\n${_key} = \"${_val}\"\n#" $_php_ini_file > $log_file 2>&1 + fi + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + + _key="upload_tmp_dir" + _val="${WEBSITE_BASEDIR}/tmp" + if grep -e "^\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + #sed -i "0,/^\([ \t]*${_key}[ \t]*=.*\)/ s##;\1\n${_key} = \"${_val}\"#" $_php_ini_file + perl -i -n -p -e "s#^(\s*${_key}\s*=.*)#;\1\n${_key} = ${_val}#" $_php_ini_file > $log_file 2>&1 + elif grep -e "^\s*;\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + sed -i "0,/^\([ \t]*;[ \t]*${_key}[ \t]*=.*\)/ s##\1\n${_key} = \"${_val}\"\n#" $_php_ini_file > $log_file 2>&1 + fi + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + + _key="session.save_path" + _val="${WEBSITE_BASEDIR}/sessions" + if grep -e "^\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + #sed -i "0,/^\([ \t]*${_key}[ \t]*=.*\)/ s##;\1\n${_key} = \"${_val}\"#" $_php_ini_file + perl -i -n -p -e "s#^(\s*${_key}\s*=.*)#;\1\n${_key} = ${_val}#" $_php_ini_file > $log_file 2>&1 + elif grep -e "^\s*;\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + sed -i "0,/^\([ \t]*;[ \t]*${_key}[ \t]*=.*\)/ s##\1\n${_key} = \"${_val}\"\n#" $_php_ini_file > $log_file 2>&1 + fi + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + + _key="soap.wsdl_cache_dir" + _val="${WEBSITE_BASEDIR}/tmp" + if grep -e "^\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + #sed -i "0,/^\([ \t]*${_key}[ \t]*=.*\)/ s##;\1\n${_key} = \"${_val}\"#" $_php_ini_file + perl -i -n -p -e "s#^(\s*${_key}\s*=.*)#;\1\n${_key} = ${_val}#" $_php_ini_file > $log_file 2>&1 + elif grep -e "^\s*;\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + sed -i "0,/^\([ \t]*;[ \t]*${_key}[ \t]*=.*\)/ s##\1\n${_key} = \"${_val}\"\n#" $_php_ini_file > $log_file 2>&1 + fi + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + + if ! $_failed ; then + echo_ok + fi + +fi + + +echo -e "\n\n\t\033[37m\033[1mConfigure Apache Webservice\033[m\n" + + +SSLCertificateChainFile="" +# - Create SSCertificateChainFile rule for apache vhost entry +# - +echononl "\tCreate SSCertificateChainFile rule for apache vhost entry" +if [ -n "$CERT_ChainFile" ];then + SSLCertificateChainFile="SSLCertificateChainFile ${APACHE_CERT_DIR}/$CERT_ChainFile" + echo_ok +else + echo_skipped +fi + + +echo "" + + +# - Save existing vhost file +# - +echononl "\tSave existing vhost file.." +if [ -f ${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf ];then + if [[ -f "${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf" ]]; then + mv ${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf ${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf.`date +%Y%m%d-%H%M` > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + else + echo_skipped + fi +else + echo_skipped +fi + +echononl "\tCreate VHost Configuration '${WEBSITE_NAME}.conf'.." +_failed=false +cat < ${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf 2>> $log_file +# -- $WEBSITE_NAME -- # + + + + ServerAdmin $WEBMASTER_EMAIL + + ServerName $WEBSITE_NAME + + RewriteEngine on + RewriteCond %{HTTPS} !=on + RewriteRule (.*) https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L] + + CustomLog ${APACHE_LOG_DIR}/${WEBSITE_NAME}-access.log combined + ErrorLog ${APACHE_LOG_DIR}/${WEBSITE_NAME}-error.log + + + + + + + ServerAdmin $WEBMASTER_EMAIL + + ServerName $WEBSITE_NAME + +EOF +if [[ $? -ne 0 ]]; then + failed=true +fi + +if [[ "$PHP_TYPE" = "mod_php" ]] ; then + cat <> ${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf 2>> $log_file + ## - its allowed to overwrite by .htaccess + ## - + php_value error_reporting "E_ALL & ~E_NOTICE" + + ## - Overwriting by .htaccess NOT allowd + ## - + php_admin_value upload_tmp_dir "${WEBSITE_BASEDIR}/tmp/" + php_admin_flag log_errors on + php_admin_value error_log "${WEBSITE_BASEDIR}/logs/php_error.log" + + DocumentRoot "${WEBSITE_BASEDIR}/htdocs/" +EOF + if [[ $? -ne 0 ]]; then + failed=true + fi +elif [[ "$PHP_TYPE" = "fcgid" ]]; then + cat <> ${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf 2>> $log_file + DocumentRoot "${WEBSITE_BASEDIR}/htdocs/" + + Require all granted + FCGIWrapper ${WEBSITE_BASEDIR}/conf/fcgid .php + + SetHandler fcgid-script + + Options +ExecCGI + +EOF + if [[ $? -ne 0 ]]; then + failed=true + fi +elif [[ "$PHP_TYPE" = "php_fpm" ]]; then + cat <> ${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf 2>> $log_file + DocumentRoot "${WEBSITE_BASEDIR}/htdocs/" + + + SetHandler "proxy:unix:/tmp/php-${php_latest_ver}-fpm.www.sock|fcgi://127.0.0.1" + + + + DirectoryIndex index.php index.html + +EOF + if [[ $? -ne 0 ]]; then + failed=true + fi +fi +cat <> ${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf 2>> $log_file + + SSLEngine on + + # - HTTP Strict Transport Security (HSTS) + # - + # - HSTS tells a browser that the website should only be accessed through + # - a secure connection. The HSTS header will be remembered by a standard + # compliant browser for max-age seconds. + # - + # - Remember this settings for 1 year + # - + Header always set Strict-Transport-Security "max-age=31536000" + + SSLCertificateFile ${APACHE_CERT_DIR}/$APACHE_SERVER_CERT + SSLCertificateKeyFile ${APACHE_CERT_DIR}/$APACHE_SERVER_KEY + $SSLCertificateChainFile + + CustomLog ${APACHE_LOG_DIR}/${WEBSITE_NAME}-access.log combined + ErrorLog ${APACHE_LOG_DIR}/${WEBSITE_NAME}-error.log + + + + +# --- +# --- IPv6 +# --- + + + + ServerAdmin $WEBMASTER_EMAIL + + ServerName $WEBSITE_NAME + + RewriteEngine on + RewriteCond %{HTTPS} !=on + RewriteRule (.*) https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L] + + CustomLog ${APACHE_LOG_DIR}/${WEBSITE_NAME}-access.log combined + ErrorLog ${APACHE_LOG_DIR}/${WEBSITE_NAME}-error.log + + + + + + + ServerAdmin $WEBMASTER_EMAIL + + ServerName $WEBSITE_NAME + +EOF +if [[ $? -ne 0 ]]; then + _failed=true +fi + +if [[ "$PHP_TYPE" = "mod_php" ]]; then + + cat <> ${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf 2>> $log_file + ## - its allowed to overwrite by .htaccess + ## - + php_value error_reporting "E_ALL & ~E_NOTICE" + + ## - Overwriting by .htaccess NOT allowd + ## - + php_admin_value upload_tmp_dir "${WEBSITE_BASEDIR}/tmp/" + php_admin_flag log_errors on + php_admin_value error_log "${WEBSITE_BASEDIR}/logs/php_error.log" + + DocumentRoot "${WEBSITE_BASEDIR}/htdocs/" +EOF + if [[ $? -ne 0 ]]; then + _failed=true + fi +elif [[ "$PHP_TYPE" = "fcgid" ]]; then + cat <> ${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf 2>> $log_file + DocumentRoot "${WEBSITE_BASEDIR}/htdocs/" + + Require all granted + FCGIWrapper ${WEBSITE_BASEDIR}/conf/fcgid .php + + SetHandler fcgid-script + + Options +ExecCGI + +EOF + if [[ $? -ne 0 ]]; then + _failed=true + fi +elif [[ "$PHP_TYPE" = "php_fpm" ]]; then + cat <> ${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf 2>> $log_file + DocumentRoot "${WEBSITE_BASEDIR}/htdocs/" + + + SetHandler "proxy:unix:/tmp/php-${php_latest_ver}-fpm.www.sock|fcgi://127.0.0.1" + + + + DirectoryIndex index.php index.html + +EOF + if [[ $? -ne 0 ]]; then + failed=true + fi +fi +cat <> ${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf 2>> $log_file + + SSLEngine on + + # - HTTP Strict Transport Security (HSTS) + # - + # - HSTS tells a browser that the website should only be accessed through + # - a secure connection. The HSTS header will be remembered by a standard + # compliant browser for max-age seconds. + # - + # - Remember this settings for 1 year + # - + Header always set Strict-Transport-Security "max-age=31536000" + + SSLCertificateFile ${APACHE_CERT_DIR}/$APACHE_SERVER_CERT + SSLCertificateKeyFile ${APACHE_CERT_DIR}/$APACHE_SERVER_KEY + $SSLCertificateChainFile + + CustomLog ${APACHE_LOG_DIR}/${WEBSITE_NAME}-access.log combined + ErrorLog ${APACHE_LOG_DIR}/${WEBSITE_NAME}-error.log + + +EOF +if [[ $? -ne 0 ]]; then + _failed=true +fi +if $_failed ; then + echo_failed + error "$(cat $log_file)" +else + echo_ok +fi + +if $APACHE_DEBIAN_INSTALLATION ; then + ## - add to /etc/apache2/ports.conf + ## - + ## - NameVirtualHost 46.4.73.217:80 + ## - NameVirtualHost [2a01:4f8:140:34c1::4]:80 + ## - Listen 46.4.73.217:80 + ## - Listen [2a01:4f8:140:34c1::4]:80 + ## - + ## - .. + ## - NameVirtualHost 46.4.73.217:443 + ## - NameVirtualHost [2a01:4f8:140:34c1::4]:443 + ## - Listen 46.4.73.217:443 + ## - Listen [2a01:4f8:140:34c1::4]:443 + ## - + ## - .. + #vim /etc/apache2/ports.conf + + + ## - enable site webmail.warenform.de + ## - + echononl "\tEnable ${WEBSITE_NAME}.conf" + a2ensite ${WEBSITE_NAME}.conf > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +fi + +echononl "\tCreate 'robots.txt'.." +cat < ${WEBSITE_BASEDIR}/htdocs/robots.txt 2> $log_file +User-agent: * +Disallow: / +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tRestart Apache Webservice.." +if $APACHE_DEBIAN_INSTALLATION ; then + /etc/init.d/apache2 reload > $log_file 2>&1 +else + /etc/init.d/apache2 restart > $log_file 2>&1 +fi +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + + +echo -e "\n\n\t\033[37m\033[1mInstall Vacation\033[m\n" + + +echononl "\tCreate system group '$VACATION_GROUP'" +if ! grep -q "$VACATION_GROUP" /etc/group /etc/group > /dev/null 2>&1 ; then + addgroup --system --gid 65501 $VACATION_GROUP > "$log_file" 2>&1 + if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat $log_file)" + else + echo_ok + fi +else + echo_skipped +fi + +echononl "\tCreate system user '$VACATION_USER'" +if ! grep -q "$VACATION_USER" /etc/passwd > /dev/null 2>&1 ; then + adduser --system --home /var/spool/vacation --no-create-home --uid 65501 --gid 65501 --shell /usr/sbin/nologin $VACATION_USER > "$log_file" 2>&1 + + if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat $log_file)" + else + echo_ok + fi +else + echo_skipped +fi + +echononl "\tCreate directory '/var/spool/vacation'" +if [[ ! -d "/var/spool/vacation" ]]; then + mkdir /var/spool/vacation > "$log_file" 2>&1 + if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat $log_file)" + else + echo_ok + fi +else + echo_skipped +fi + +echononl "\tSet Permissions on directoy '/var/spool/vacation'" +chown -R ${VACATION_USER}:$VACATION_GROUP /var/spool/vacation > "$log_file" 2>&1 +if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat $log_file)" +else + echo_ok +fi + +echononl "\tBackup existing script 'vacation.pl'" +if [[ -f "/var/spool/vacation/vacation.pl" ]] ; then + mv /var/spool/vacation/vacation.pl /var/spool/vacation/vacation.pl.${backup_date} > "$log_file" 2>&1 + if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat $log_file)" + else + echo_ok + fi +else + echo_skipped +fi + + +echononl "\tCopy vacation script to '/var/spool/vacation/vacation.pl'" +_vacacion_script="$(find ${_src_base_dir}/postfixadmin-${PF_ADMIN_VERSION} -type f -name vacation.pl -print 2>/dev/null)" +if [[ -z "$(trim "$_vatacion_script")" ]] ; then + cp -a ${_vacacion_script} /var/spool/vacation/ > "$log_file" 2>&1 + if [[ $? -eq 0 ]];then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + error "Vacation script not found!" +fi + + +# - Encoding does not work as exspected. +# - +# - NOTE: +# - this IS NOT a fix, but a workaround +# - +echononl "\tWorkaround, because encoding does not work as exspected." +perl -i -n -p -e "s/(\s*\'ctype\'\s* =>\s*)\'text\/plain.*$/\1\'text\/plain; charset=iso-8859-1\',/" \ + /var/spool/vacation/vacation.pl > "$log_file" 2>&1 +if [[ $? -eq 0 ]];then + echo_ok + info "This IS NOT a fix, but a workaround." +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tSet Permission on vacation script" +_failed=false +chown ${VACATION_USER}:$VACATION_GROUP /var/spool/vacation/vacation.pl > "$log_file" 2>&1 +if [[ $? -ne 0 ]]; then + _failed=true +fi +chmod 700 /var/spool/vacation/vacation.pl > "$log_file" 2>&1 +if [[ $? -ne 0 ]]; then + _failed=true +fi +if $_failed ;then + echo_failed + error "$(cat $log_file)" +else + echo_ok +fi + +# - Script vacation.pl tries to reads setting from +# - +# - /etc/mail/postfixadmin/vacation.conf +# - /etc/postfixadmin/vacation.conf +# - +# - Instead of changing this script, we put the needed entries +# - to file /etc/postfixadmin/vacation.conf: +# - +echononl "\tCreate directory '/etc/postfixadmin' " +if [[ ! -d "/etc/postfixadmin" ]]; then + mkdir /etc/postfixadmin > "$log_file" 2>&1 + if [[ $? -eq 0 ]];then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +echononl "\tBackup existing file '/etc/postfixadmin/vacation.conf'" +if [[ -f "/etc/postfixadmin/vacation.conf" ]]; then + mv /etc/postfixadmin/vacation.conf /etc/postfixadmin/vacation.conf.${backup_date} > "$log_file" 2>&1 + if [[ $? -eq 0 ]];then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +# - Create configuration file '/etc/postfixadmin/vacation.conf' +# - +echononl "\tCreate configuration file '/etc/postfixadmin/vacation.conf'" +if [[ "$POSTFIX_DB_TYPE" = "pgsql" ]]; then + _db_type="Pg" +else + _db_type="mysql" +fi + +cat < /etc/postfixadmin/vacation.conf 2> "$log_file" +\$db_type = '$_db_type'; +\$db_username = '${POSTFIX_DB_USER}'; +\$db_password = '${POSTFIX_DB_PASS}'; +\$db_name = '${POSTFIX_DB_NAME}'; +\$vacation_domain = '${AUTOREPLY_HOSTNAME}'; +\$syslog = 0; +\$log_to_file = 1; +\$logfile = '/var/log/vacation.log'; +\$log_level = 1; +\$interval = 60*60*24; +EOF +if [[ $? -eq 0 ]];then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + + +echononl "\tCreate logfile /var/log/vacation.log" +touch /var/log/vacation.log > "$log_file" 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi +echononl "\tSet permissions on /var/log/vacation.log" +chown ${VACATION_USER}:$VACATION_GROUP /var/log/vacation.log > "$log_file" 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi +echononl "\tConfigure logrotation for '/var/log/vacation.log'" +cat < /etc/logrotate.d/vacation 2> "$log_file" +/var/log/vacation.log { + daily + start 0 + rotate 7 + missingok + compress + delaycompress + notifempty + create 640 vacation vacation + copytruncate +} +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + + +# - Create an entry in /etc/hosts for the (non-existant domain) +# - $AUTOREPLY_HOSTNAME +# - +# - add: +# - +# - 127.0.0.1 $AUTOREPLY_HOSTNAME +# - +echononl "\tCreate entry in /etc/hosts for '$AUTOREPLY_HOSTNAME'" +if ! grep -q "$AUTOREPLY_HOSTNAME" /etc/hosts > $log_file 2>&1 ; then + perl -i -n -p -e"s#(^\s*127.0.0.1\s+localhost.*)#\1\n\n127.0.0.1 ${AUTOREPLY_HOSTNAME}#" /etc/hosts > $log_file 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +# - Define the transport type in the Postfix master file +# - /etc/postfix/master.cf +# - +# - vacation unix - n n - - pipe +# - flags=Rq user=vacation argv=/var/spool/vacation/vacation.pl -f ${sender} -- ${recipient} +# - +echononl "\tDefine transport for vacation in /etc/postfix/master.cf" +if ! grep -q -E "^\s*vacation\s+unix" /etc/postfix/master.cf > $log_file 2>&1 ; then + cat <> /etc/postfix/master.cf + +vacation unix - n n - - pipe + flags=Rq user=vacation argv=/var/spool/vacation/vacation.pl -f \${sender} -- \${recipient} +EOF + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +# - Setup the transport maps file /etc/postfix/transport +# - +# - add line: +# - +# - $AUTOREPLY_HOSTNAME vacation: +# - +echononl "\tSetup the transport maps for vacation domain in '/etc/postfix/transport'" +if ! grep -q -E "^\s*$AUTOREPLY_HOSTNAME\s+vacation:" /etc/postfix/transport > $log_file 2>&1 ; then + _failed=false + echo "$AUTOREPLY_HOSTNAME vacation:" >> /etc/postfix/transport 2> $log_file + if [[ $? -ne 0 ]] ; then + _failed=true + fi + postmap btree:/etc/postfix/transport > $log_file 2>&1 + if [[ $? -ne 0 ]] ; then + _failed=true + fi + if [[ $? -ne 0 ]]; then + _failed=true + fi + if $_failed ;then + echo_failed + error "$(cat $log_file)" + else + echo_ok + fi +else + echo_skipped +fi + +check_entry_main_cf_arr["transport_maps"]="btree:/etc/postfix/transport" +# - Add 'btree:/etc/postfix/transport' ton parameter transport_maps in /etc/postfix/main.cf +# - +# - take care the entry for transport_maps in /etc/postfix/main.cf +# - contains "btree:/etc/postfix/transport" +# - +echononl "\tAdd 'btree:/etc/postfix/transport' to parameter transport_maps" +if ! grep -q "btree:/etc/postfix/transport" /etc/postfix/main.cf > $log_file 2>&1 ; then + perl -i -n -p -e "s#(^transport_maps\s+=.*)#\1\n btree:/etc/postfix/transport#" /etc/postfix/main.cf > $log_file 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +echononl "\tReload/Restart postfix" +if $SYSTEMD_EXISTS ; then + systemctl reload postfix > $log_file 2>&1 +else + /etc/init.d/postfix reload > $log_file 2>&1 +fi +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + + +echo -e "\n\n\t\033[37m\033[1mConfigure Postfix Admin\033[m\n" + +if [[ $MAJOR_VERSION -eq 3 &&$MINOR_VERSION -gt 0 ]]; then + pfa_conf_file="${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION}/config.local.php" + cp -a "${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION}/config.inc.php" "$pfa_conf_file" +else + pfa_conf_file="${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION}/config.inc.php" + cp -a "$pfa_conf_file" "${pfa_conf_file}.ORIG" +fi + + + +# - Use 'Re: $SUBJECT' as the default subject template for vacation +# - in postfixadmin +# - +echononl "\tUse 'Re: \$SUBJECT' as default subject of autorespons messages" +perl -i -n -p -e "s#(^\s*\\\$PALANG\['pUsersVacation_subject_text'\].*$)#\#\1\n\\\$PALANG['pUsersVacation_subject_text'] = 'Re: \\\$SUBJECT';#" ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION}/languages/*.lang > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tAdjust file 'languages/de.lang'" +perl -i -n -p -e "s#^(\s*\\\$PALANG\['reply_every_mail'\]\s+=.*)#\1\n\\\$PALANG['reply_once_per_day'] = 'Einmal pro Tag antworten';#" \ + ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION}/languages/de.lang >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$PALANG\['reply_every_mail'\]\s+=.*)#\1\n\\\$PALANG['reply_once_per_day'] = 'Reply once per day';#" \ + ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION}/languages/en.lang >> $log_file 2>&1 || _failed=true +if $_failed ; then + echo_failed + error "$(cat $log_file)" +else + echo_ok +fi + + +## - Adjust Postfix Admin's Configuration - Part 1 +## - +## - configure postfixadmin +## - +## - edit file config.inc.php +## - +## - set: +## - +## - $CONF['default_language'] = 'de'; +## - $CONF['database_type'] = '$POSTFIX_DB_TYPE'; +## - $CONF['database_host'] = 'localhost'; +## - $CONF['database_user'] = '$POSTFIX_DB_USER'; +## - $CONF['database_password'] = '$POSTFIX_DB_PASS'; +## - $CONF['database_name'] = '$POSTFIX_DB_NAME'; +## - $CONF['database_prefix'] = ''; +## - $CONF['admin_email'] = '$WEBMASTER_EMAIL'; +## - $CONF['encrypt'] = '$ENCRYPTION_METHOD'; +## - $CONF['dovecotpw'] = "$DOVEADM_PW"; +## - +echo "" +echononl "\tAdjust Postfix Admin's Configuration - Part 1" +_failed=false +> $log_file +perl -i -n -p -e "s#^(\s*\\\$CONF\['default_language'\]\s*=.*)#//!\1\n\\\$CONF['default_language'] = 'de';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['database_type'\]\s*=.*)#//!\1\n\\\$CONF['database_type'] = '$POSTFIX_DB_TYPE';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['database_host'\]\s*=.*)#//!\1\n\\\$CONF['database_host'] = 'localhost';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['database_user'\]\s*=.*)#//!\1\n\\\$CONF['database_user'] = '$POSTFIX_DB_USER';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['database_password'\]\s*=.*)#//!\1\n\\\$CONF['database_password'] = '$POSTFIX_DB_PASS';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['database_name'\]\s*=.*)#//!\1\n\\\$CONF['database_name'] = '$POSTFIX_DB_NAME';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['database_prefix'\]\s*=.*)#//!\1\n\\\$CONF['database_prefix'] = '';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['admin_email'\]\s*=.*)#//!\1\n\\\$CONF['admin_email'] = '$WEBMASTER_EMAIL';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['encrypt'\]\s*=.*)#//!\1\n\\\$CONF['encrypt'] = '$ENCRYPTION_METHOD';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['dovecotpw'\]\s*=.*)#//!\1\n\\\$CONF['dovecotpw'] = '$DOVEADM_PW';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +if $_failed ; then + echo_failed + error "$(cat $log_file)" +else + echo_ok +fi + + +## - Adjust Postfix Admin's Configuration - Part 2 +## - +## - $CONF['default_aliases'] = array ( +## - 'abuse' => 'postmaster@$DOMAIN', +## - 'postmaster' => 'postmaster@$DOMAIN', +## - ); +## - $CONF['domain_path'] = 'YES'; +## - $CONF['domain_in_mailbox'] = 'NO'; +## - $CONF['aliases'] = '100'; +## - $CONF['mailboxes'] = '100'; +## - $CONF['maxquota'] = '0'; +## - $CONF['domain_quota_default'] = '0'; +## - $CONF['quota'] = 'YES'; +## - $CONF['domain_quota'] = 'Yes'; +## - $CONF['quota_multiplier'] = '1048576'; +## - +echononl "\tAdjust Postfix Admin's Configuration - Part 2" +_failed=false +> $log_file +perl -i -n -p -e "s#^(\s*\\\$CONF\['default_aliases'\]\s*=.*)#//\n//! 'default_aliases' will be overridden - see end of configfile\n//\n\1#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true + +cat <> $pfa_conf_file 2> $log_file + +// Default Aliases +// The default aliases that need to be created for all domains. +// You can specify the target address in two ways: +// a) a full mail address +// b) only a localpart ('postmaster' => 'admin') - the alias target will point to the same domain +// +\$CONF['default_aliases'] = array ( + 'abuse' => 'postmaster@$DOMAIN', + 'postmaster' => 'postmaster@$DOMAIN' +); +EOF + +perl -i -n -p -e "s#^(\s*\\\$CONF\['domain_path'\]\s*=.*)#//!\1\n\\\$CONF['domain_path'] = 'YES';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['domain_in_mailbox'\]\s*=.*)#//!\1\n\\\$CONF['domain_in_mailbox'] = 'NO';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['aliases'\]\s*=.*)#//!\1\n\\\$CONF['aliases'] = '100';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['mailboxes'\]\s*=.*)#//!\1\n\\\$CONF['mailboxes'] = '100';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['maxquota'\]\s*=.*)#//!\1\n\\\$CONF['maxquota'] = '0';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['domain_quota_default'\]\s*=.*)#//!\1\n\\\$CONF['domain_quota_default'] = '0';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['quota'\]\s*=.*)#//!\1\n\\\$CONF['quota'] = 'YES';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['domain_quota'\]\s*=.*)#//!\1\n\\\$CONF['domain_quota'] = 'YES';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['quota_multiplier'\]\s*=.*)#//!\1\n\\\$CONF['quota_multiplier'] = '1048576';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +if $_failed ; then + echo_failed + error "$(cat $log_file)" +else + echo_ok +fi + + +## - Adjust Postfix Admin's Configuration - Part 3 +## - +## - $CONF['transport_options'] = array ( +## - 'lmtp:unix:private/dovecot-lmtp', // for virtual accounts +## - 'local', // for system accounts +## - 'relay' // for backup mx +## - ); +## - $CONF['transport_default'] = 'lmtp:unix:private/dovecot-lmtp'; +## - $CONF['vacation'] = 'YES'; +## - $CONF['vacation_domain'] = '$AUTOREPLY_HOSTNAME'; +## - +echononl "\tAdjust Postfix Admin's Configuration - Part 3" +_failed=false +> $log_file +perl -i -n -p -e "s#^(\s*\\\$CONF\['transport_options'\]\s*=.*)#//\n//! \"transport_options\" will be overridden - see end of configfile\n//\n\1#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['transport_default'\]\s*=.*)#//\n//! \"transport_default\" will be overridden - see end of configfile\n//\n\1#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true + +cat <> $pfa_conf_file 2> $log_file + +// Transport options +// If you want to define additional transport options put them in array below. +// +\$CONF['transport_options'] = array ( + 'lmtp:unix:private/dovecot-lmtp', // for virtual accounts + 'local', // for system accounts + 'relay' // for backup mx +); +// Transport default +// You should define default transport. It must be in array above. +\$CONF['transport_default'] = 'lmtp:unix:private/dovecot-lmtp'; +EOF + +perl -i -n -p -e "s#^(\s*\\\$CONF\['vacation'\]\s*=.*)#//!\1\n\\\$CONF['vacation'] = 'YES';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['vacation_domain'\]\s*=.*)#//!\1\n\\\$CONF['vacation_domain'] = '$AUTOREPLY_HOSTNAME';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +if $_failed ; then + echo_failed + error "$(cat $log_file)" +else + echo_ok +fi + + +## - Adjust Postfix Admin's Configuration - Part 4 +## - +## - $CONF['vacation_choice_of_reply'] = array ( +## - 0 => 'reply_once', // Sends only Once the message during Out of Office +## - 1 => 'reply_every_mail', // Reply on every email +## - 60*60*24 => 'reply_once_per_day', // Reply if last autoreply was at least one day ago +## - 60*60*24*7 => 'reply_once_per_week' // Reply if last autoreply was at least a week ago +## - ); +## - +echononl "\tAdjust Postfix Admin's Configuration - Part 4" +_failed=false +> $log_file +perl -i -n -p -e "s#^(\s*\\\$CONF\['vacation_choice_of_reply'\]\s*=.*)#//\n//! 'vacation_choice_of_reply' will be overridden - see end of configfile\n//\n\1#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true + +cat <> $pfa_conf_file 2> $log_file + +// ReplyType options +// If you want to define additional reply options put them in array below. +// The array has the format seconds between replies => $PALANG text +// Special values for seconds are: +// 0 => only reply to the first mail while on vacation +// 1 => reply on every mail +// 60*60*24*7 => Reply if last autoreply was at least a week ago +// +//! ckubu added: +// - 60*60*24 => 'reply_once_per_day', +// ADD also "languages/de.lang": +// +// $PALANG['reply_once_per_day'] = 'Einmal pro Tag antworten'; +// +\$CONF['vacation_choice_of_reply'] = array ( + 0 => 'reply_once', // Sends only Once the message during Out of Office + 1 => 'reply_every_mail', // Reply on every email + 60*60*24 => 'reply_once_per_day', // Reply if last autoreply was at least one day ago + 60*60*24*7 => 'reply_once_per_week' // Reply if last autoreply was at least a week ago +); +EOF + +perl -i -n -p -e "s#^(\s*\\\$CONF\['welcome_text'\]\s*=.*)#//\n//! 'welcome_text' will be overridden - see end of configfile\n//\n\1#" \ + $pfa_conf_file >> $log_file 2>&1 +if $_failed ; then + echo_failed + error "$(cat $log_file)" +else + echo_ok +fi + + +## - $CONF['welcome_text'] = <<> $pfa_conf_file 2> $log_file + +// Welcome Message +// This message is send to every newly created mailbox. +// Change the text between EOM. +\$CONF['welcome_text'] = << $log_file +perl -i -n -p -e "s#^(\s*\\\$CONF\['alias_control_admin'\]\s+=.*)#//!\1\n\\\$CONF['alias_control_admin'] = 'YES';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['alias_control'\]\s*=.*)#//!\1\n\\\$CONF['alias_control'] = 'YES';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['special_alias_control'\]\s*=.*)#//!\1\n\\\$CONF['special_alias_control'] = 'NO';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['backup'\]\s*=.*)#//!\1\n\\\$CONF['backup'] = 'YES';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['fetchmail'\]\s*=.*)#//!\1\n\\\$CONF['fetchmail'] = 'NO';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['user_footer_link'\]\s+=.*)#//!\1\n\\\$CONF['user_footer_link'] = 'https://${WEBSITE_NAME}/main.php';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['footer_text'\]\s+=.*)#//!\1\n\\\$CONF['footer_text'] = 'Main Menu';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['footer_link'\]\s+=.*)#//!\1\n\\\$CONF['footer_link'] = 'http://${WEBSITE_NAME}/main.php';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['emailcheck_resolve_domain'\]\s*=.*)#//!\1\n\\\$CONF['emailcheck_resolve_domain'] = 'NO';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['show_status'\]\s*=.*)#//!\1\n\\\$CONF['show_status'] = 'YES';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['show_status_key'\]\s*=.*)#//!\1\n\\\$CONF['show_status_key'] = 'YES';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['show_undeliverable'\]\s*=.*)#//!\1\n\\\$CONF['show_undeliverable'] = 'NO';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['show_popimap'\]\s*=.*)#//!\1\n\\\$CONF['show_popimap'] = 'NO';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['used_quotas'\]\s*=.*)#//!\1\n\\\$CONF['used_quotas'] = 'YES';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*\\\$CONF\['new_quota_table'\]\s*=.*)#//!\1\n\\\$CONF['new_quota_table'] = 'YES';#" \ + $pfa_conf_file >> $log_file 2>&1 || _failed=true +if $_failed ; then + echo_failed + error "$(cat $log_file)" +else + echo_ok +fi + + +# - After finished, you must alos change the value of $CONF['configured'] +# - to 'true' +# - +# - $CONF['configured'] = true; +echononl "\tSet '\$CONF['configured'] = true'" +perl -i -n -p -e "s#^(\s*\\\$CONF\['configured'\]\s*=.*)#//!\1\n\\\$CONF['configured'] = true;#" \ + $pfa_conf_file > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed +fi + + +# - Take passwordhash from previosly installation +# - +echononl "\tTake passwordhash from previosly installation.." +if [[ -n "$_actual_password_hash" ]] ; then + perl -i -n -p -e "s#^(\s*\\\$CONF\['setup_password'\]\s*=.*)#//!\1\n\\\$CONF['setup_password'] = '$_actual_password_hash';#" \ + $pfa_conf_file >> $log_file 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + +echo "" + + +# - AFTER DELETION MAILBOX +# - +# - activate script for moving a mailbox from the mailboxdirectory +# - and save it to the backupb directory /var/deleted-maildirs +# - +echo -e "\n\t\033[32mMailbox post-deletion script\033[m" +echononl "\tCreate folder '${DELETED_MAILBOX_DIR}" +if [[ ! -d "${DELETED_MAILBOX_DIR}" ]] ; then + mkdir $DELETED_MAILBOX_DIR > $log_file 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +echononl "\tChange permissions on '${DELETED_MAILBOX_DIR}" +_failed=false +chown vmail:vmail $DELETED_MAILBOX_DIR > $log_file 2>&1 || _failed=true +chmod 700 $DELETED_MAILBOX_DIR >> $log_file 2>&1 || _failed=true +if $_failed ; then + echo_failed + error "$(cat $log_file)" +else + echo_ok +fi + +echononl "\tBackup existing post-deletion script" +if [[ -f "/usr/local/bin/postfixadmin-mailbox-postdeletion.sh" ]]; then + mv /usr/local/bin/postfixadmin-mailbox-postdeletion.sh \ + /usr/local/bin/postfixadmin-mailbox-postdeletion.sh.${backup_date} > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +echononl "\tCopy 'postfixadmin-mailbox-postdeletion.sh' to /usr/local/bin/" +cp -a ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION}/ADDITIONS/postfixadmin-mailbox-postdeletion.sh \ + /usr/local/bin/ > $log_file 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tSet Permissions on 'postfixadmin-mailbox-postdeletion.sh'" +chmod 755 /usr/local/bin/postfixadmin-mailbox-postdeletion.sh > $log_file 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +# - Change the posdeletion scripts to your needs: +# - +# - set: +# - basedir=/var/vmail +# - trashbase=$DELETED_MAILBOX_DIR +# - +# - trashdir="${trashbase}/$2/`date +%F_$H-%M`_${subdir}" +# - +echononl "\tAdjust 'postfixadmin-mailbox-postdeletion.sh'" +_failed=false +> $log_file 2>&1 +perl -i -n -p -e "s#^(\s*)(basedir=.*)#\#\1\2\n\1basedir=/var/vmail#" \ + /usr/local/bin/postfixadmin-mailbox-postdeletion.sh >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*)(trashbase=.*)#\#\1\2\n\1trashbase=${DELETED_MAILBOX_DIR}#" \ + /usr/local/bin/postfixadmin-mailbox-postdeletion.sh >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*)(trashdir=.*)#\#\1\2\n\1trashdir=\"\\\${trashbase}/\\\$2/\`date +%F_%H-%M\`_\\\${subdir}\"#" \ + /usr/local/bin/postfixadmin-mailbox-postdeletion.sh >> $log_file 2>&1 || _failed=true +if $_failed ; then + echo_failed + error "$(cat $log_file)" +else + echo_ok +fi + + +# - Edit ${WEBSITE_BASEDIR}/htdocs/config.inc.php +# - +# - in section add line +# - $CONF['mailbox_postdeletion_script']='sudo -u vmail /usr/local/bin/postfixadmin-mailbox-postdeletion.sh'; +# - +echononl "\tAdjust 'config.inc.php' to make script available" +perl -i -n -p -e "s#^(\s*[/*]?\s*\\\$CONF\['mailbox_postdeletion_script'\]\s*=.*)#//!\1\n\\\$CONF['mailbox_postdeletion_script'] = 'sudo -u vmail /usr/local/bin/postfixadmin-mailbox-postdeletion.sh';#" \ + $pfa_conf_file > $log_file 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed +fi + +## - !! Notice: +## - Have a look at ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION}/config.inc.php +## - and see if changes affected +## - + + +# - You need also an entry in /etc/sudores +# - +# - ues visudo-command to add: +# - www-data ALL=(vmail) NOPASSWD: /usr/local/bin/postfixadmin-mailbox-postdeletion.sh +# - +_failed=false +echononl "\tCreate needed entry in '/etc/sudores'" +if ! grep -q -E "${HTTP_USER}.*NOPASSWD:\s*/usr/local/bin/postfixadmin-mailbox-postdeletion.sh" /etc/sudoers ; then + touch /etc/sudoers.tmp >> $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + fi + cat /etc/sudoers > /tmp/sudoers.new 2>> $log_file + if [[ $? -ne 0 ]]; then + _failed=true + fi + echo "" >> /tmp/sudoers.new + echo "${HTTP_USER} ALL=(vmail) NOPASSWD: /usr/local/bin/postfixadmin-mailbox-postdeletion.sh" >> /tmp/sudoers.new 2>> $log_file + if [[ $? -ne 0 ]]; then + _failed=true + fi + visudo -c -f /tmp/sudoers.new >> $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + else + cp /tmp/sudoers.new /etc/sudoers >> $log_file 2>&1 + if [ $? -ne 0 ]; then + _failed=true + fi + fi + rm /etc/sudoers.tmp >> $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + fi + rm -f /tmp/sudoers.new + if $_failed ; then + echo_failed + error "$(cat $log_file)" + else + echo_ok + fi +else + echo_skipped +fi + + +# - AFTER DELETION MAILDOMIAN +# - +# - activate script for moving a mailbox from the mailboxdirectory +# - and save it to the backupb directory $DELETED_DOMAINS_DIR +# - +echo -e "\n\t\033[32mMaildomain post-deletion script\033[m" +echononl "\tCreate folder '${DELETED_DOMAINS_DIR}" +if [[ ! -d "${DELETED_DOMAINS_DIR}" ]] ; then + mkdir $DELETED_DOMAINS_DIR > $log_file 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +echononl "\tChange permissions on '${DELETED_DOMAINS_DIR}" +_failed=false +chown vmail:vmail $DELETED_DOMAINS_DIR > $log_file 2>&1 || _failed=true +chmod 700 $DELETED_DOMAINS_DIR >> $log_file 2>&1 || _failed=true +if $_failed ; then + echo_failed + error "$(cat $log_file)" +else + echo_ok +fi + +echononl "\tBackup existing post-deletion script" +if [[ -f "/usr/local/bin/postfixadmin-domain-postdeletion.sh" ]]; then + mv /usr/local/bin/postfixadmin-domain-postdeletion.sh \ + /usr/local/bin/postfixadmin-domain-postdeletion.sh.${backup_date} > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + +echononl "\tCopy 'postfixadmin-domain-postdeletion.sh' to /usr/local/bin/" +cp -a ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION}/ADDITIONS/postfixadmin-domain-postdeletion.sh \ + /usr/local/bin/ > $log_file 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + + +echononl "\tSet Permissions on 'postfixadmin-domain-postdeletion.sh'" +chmod 755 /usr/local/bin/postfixadmin-domain-postdeletion.sh > $log_file 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + + +# - Change the posdeletion scripts to your needs: +# - +# - set: +# - basedir=/var/vmail +# - trashbase=$DELETED_DOMAINS_DIR +# - +# - trashdir="${trashbase}/`date +%F_%H-%M`_$1" +# - +echononl "\tAdjust 'postfixadmin-domain-postdeletion.sh'" +_failed=false +> $log_file 2>&1 +perl -i -n -p -e "s#^(\s*)(basedir=.*)#\#\1\2\n\1basedir=/var/vmail#" \ + /usr/local/bin/postfixadmin-domain-postdeletion.sh >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*)(trashbase=.*)#\#\1\2\n\1trashbase=${DELETED_DOMAINS_DIR}#" \ + /usr/local/bin/postfixadmin-domain-postdeletion.sh >> $log_file 2>&1 || _failed=true +perl -i -n -p -e "s#^(\s*)(trashdir=.*)#\#\1\2\n\1trashdir=\"\\\${trashbase}/\`date +%F_%H-%M\`_\\\$1\"#" \ + /usr/local/bin/postfixadmin-domain-postdeletion.sh >> $log_file 2>&1 || _failed=true +if $_failed ; then + echo_failed + error "$(cat $log_file)" +else + echo_ok +fi + +# - edit ${WEBSITE_BASEDIR}/htdocs/config.inc.php +# - +# - in section add line +# - $CONF['domain_postdeletion_script']='sudo -u vmail /usr/local/bin/postfixadmin-domain-postdeletion.sh'; +# - +echononl "\tAdjust 'config.inc.php' to make script available" +perl -i -n -p -e "s#^(\s*[/*]?\s*\\\$CONF\['domain_postdeletion_script'\]\s*=.*)#//!\1\n\\\$CONF['domain_postdeletion_script'] = 'sudo -u vmail /usr/local/bin/postfixadmin-domain-postdeletion.sh';#" \ + $pfa_conf_file >> $log_file 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed +fi + +## - !! Notice: +## - Have a look at ${WEBSITE_BASEDIR}/postfixadmin-${PF_ADMIN_VERSION}/config.inc.php +## - and see if changes affected +## - + + +# - You need also an entry in /etc/sudores +# - +# - ues visudo-command to add: +# - www-data ALL=(vmail) NOPASSWD: /usr/local/bin/postfixadmin-domain-postdeletion.sh +# - +_failed=false +echononl "\tCreate needed entry in '/etc/sudores'" +if ! grep -q -E "${HTTP_USER}.*NOPASSWD:\s*/usr/local/bin/postfixadmin-domain-postdeletion.sh" /etc/sudoers ; then + touch /etc/sudoers.tmp >> $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + fi + cat /etc/sudoers > /tmp/sudoers.new 2>> $log_file + if [[ $? -ne 0 ]]; then + _failed=true + fi + echo "" >> /tmp/sudoers.new + echo "${HTTP_USER} ALL=(vmail) NOPASSWD: /usr/local/bin/postfixadmin-domain-postdeletion.sh" >> /tmp/sudoers.new 2>> $log_file + if [[ $? -ne 0 ]]; then + _failed=true + fi + visudo -c -f /tmp/sudoers.new >> $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + else + cp /tmp/sudoers.new /etc/sudoers >> $log_file 2>&1 + if [ $? -ne 0 ]; then + _failed=true + fi + fi + rm /etc/sudoers.tmp >> $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + fi + rm -f /tmp/sudoers.new + if $_failed ; then + echo_failed + error "$(cat $log_file)" + else + echo_ok + fi +else + echo_skipped +fi + + +## - Using Postfixadmin, all changes (create/delete maildomains, mailboxes, +## - aliases, etc..) will result in concerning entries in the tables of the +## - specified database. +## - +## - Now you have to setup Postfix to recognize all these entries. To do so, +## - you must specify database requests (in different files) and load them +## - into Postfix configuration. In particular that are the following files: +## - +## - pgsql_relay-domain-maps.cf +## - pgsql_sender_login_maps.cf +## - pgsql_transport_maps.cf +## - pgsql_virtual_alias_domain_catchall_maps.cf +## - pgsql_virtual_alias_domain_mailbox_maps.cf +## - pgsql_virtual_alias_domain_maps.cf +## - pgsql_virtual_alias_maps.cf +## - pgsql_virtual_domains_maps.cf +## - pgsql_virtual_mailbox_limit_maps.cf +## - pgsql_virtual_mailbox_maps.cf +## - +echo -e "\n\t\033[32mSetup Postfix\033[m" + +echononl "\tCreate file '/etc/postfix/${POSTFIX_DB_TYPE}_relay-domain-maps.cf'" +if [ "$POSTFIX_DB_TYPE" = "pgsql" ]; then + + cat < /etc/postfix/${POSTFIX_DB_TYPE}_relay-domain-maps.cf 2> $log_file +hosts = $POSTFIX_DB_SOCKET +user = $POSTFIX_DB_USER +password = $POSTFIX_DB_PASS +dbname = $POSTFIX_DB_NAME +query = SELECT domain FROM domain WHERE domain = '%s' AND backupmx = true +EOF + +elif [ "$POSTFIX_DB_TYPE" = "mysql" ];then + + cat < /etc/postfix/${POSTFIX_DB_TYPE}_relay-domain-maps.cf 2> $log_file +hosts = $POSTFIX_DB_HOST +user = $POSTFIX_DB_USER +password = $POSTFIX_DB_PASS +dbname = $POSTFIX_DB_NAME +query = SELECT domain FROM domain WHERE domain = "%s" AND backupmx = 1 +EOF + +else + echo "[ FATAL ]: Unknown database type $POSTFIX_DB_TYPE" +fi +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +check_entry_main_cf_arr["relay_domains"]="proxy:$POSTFIX_DB_TYPE:/etc/postfix/${POSTFIX_DB_TYPE}_relay-domain-maps.cf" +# - /etc/postfix/main.cf +# - +# - add to relay_domains: +# - proxy:$POSTFIX_DB_TYPE:/etc/postfix/${POSTFIX_DB_TYPE}_relay-domain-maps.cf +# - +echononl "\tUpdate '/etc/postfix/main.cf'" +if ! grep -q "proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_relay-domain-maps.cf" /etc/postfix/main.cf > /dev/null 2>&1 ; then + perl -i -n -p -e "s#\s*(relay_domains\s*=.*$)#\1\n proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_relay-domain-maps.cf#" \ + /etc/postfix/main.cf > $log_file 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + +echononl "\tCreate file '/etc/postfix/${POSTFIX_DB_TYPE}_sender_login_maps.cf'" +if [ "$POSTFIX_DB_TYPE" = "pgsql" ]; then + + cat < /etc/postfix/${POSTFIX_DB_TYPE}_sender_login_maps.cf 2> $log_file +hosts = $POSTFIX_DB_SOCKET +user = $POSTFIX_DB_USER +password = $POSTFIX_DB_PASS +dbname = $POSTFIX_DB_NAME +query = SELECT username AS allowedUser FROM mailbox WHERE username='%s' AND active = true UNION SELECT goto FROM alias WHERE address='%s' AND active = true +EOF + +elif [ "$POSTFIX_DB_TYPE" = "mysql" ];then + + cat < /etc/postfix/${POSTFIX_DB_TYPE}_sender_login_maps.cf 2> $log_file +hosts = $POSTFIX_DB_HOST +user = $POSTFIX_DB_USER +password = $POSTFIX_DB_PASS +dbname = $POSTFIX_DB_NAME +query = SELECT username AS allowedUser FROM mailbox WHERE username="%s" AND active = 1 UNION SELECT goto FROM alias WHERE address="%s" AND active = 1 +EOF + +else + echo "[ FATAL ]: Unknown database type $POSTFIX_DB_TYPE" +fi +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +check_entry_main_cf_arr["smtpd_sender_login_maps"]="proxy:$POSTFIX_DB_TYPE:/etc/postfix/${POSTFIX_DB_TYPE}_sender_login_maps.cf" +# - /etc/postfix/main.cf +# - +# - add to smtpd_sender_login_maps: +# - proxy:$POSTFIX_DB_TYPE:/etc/postfix/${POSTFIX_DB_TYPE}_sender_login_maps.cf +# - +echononl "\tUpdate '/etc/postfix/main.cf'" +if ! grep -q "proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_sender_login_maps.cf" /etc/postfix/main.cf > /dev/null 2>&1 ; then + perl -i -n -p -e "s#\s*(smtpd_sender_login_maps\s*=.*$)#\1\n proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_sender_login_maps.cf#" \ + /etc/postfix/main.cf > $log_file 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + + +echononl "\tCreate file '/etc/postfix/${POSTFIX_DB_TYPE}_transport_maps.cf'" +if [ "$POSTFIX_DB_TYPE" = "pgsql" ]; then + + cat < /etc/postfix/${POSTFIX_DB_TYPE}_transport_maps.cf +hosts = $POSTFIX_DB_SOCKET +user = $POSTFIX_DB_USER +password = $POSTFIX_DB_PASS +dbname = $POSTFIX_DB_NAME +## - +#table = domain +#select_field = transport +#where_field = domain +query = SELECT transport FROM domain WHERE domain ='%s'; +EOF + +elif [ "$POSTFIX_DB_TYPE" = "mysql" ];then + cat < /etc/postfix/${POSTFIX_DB_TYPE}_transport_maps.cf +hosts = $POSTFIX_DB_HOST +user = $POSTFIX_DB_USER +password = $POSTFIX_DB_PASS +dbname = $POSTFIX_DB_NAME +## - +#table = domain +#select_field = transport +#where_field = domain +query = SELECT transport FROM domain WHERE domain ='%s'; +EOF + +else + echo "[ FATAL ]: Unknown database type $POSTFIX_DB_TYPE" +fi +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + + +check_entry_main_cf_arr["transport_maps"]="proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_transport_maps.cf" +# - /etc/postfix/main.cf +# - +# - add to transport_maps: +# - proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_transport_maps.cf +# - +echononl "\tUpdate '/etc/postfix/main.cf'" +if ! grep -q "proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_transport_maps.cf" /etc/postfix/main.cf > /dev/null 2>&1 ; then + perl -i -n -p -e "s#\s*(transport_maps\s*=.*$)#\1\n proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_transport_maps.cf#" \ + /etc/postfix/main.cf > $log_file 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + + +echononl "\tCreate file '/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_maps.cf'" +if [ "$POSTFIX_DB_TYPE" = "pgsql" ]; then + + cat < /etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_maps.cf +hosts = $POSTFIX_DB_SOCKET +user = $POSTFIX_DB_USER +password = $POSTFIX_DB_PASS +dbname = $POSTFIX_DB_NAME +query = SELECT goto FROM alias WHERE address='%s' AND active = true +EOF + +elif [ "$POSTFIX_DB_TYPE" = "mysql" ];then + + cat < /etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_maps.cf +hosts = $POSTFIX_DB_HOST +user = $POSTFIX_DB_USER +password = $POSTFIX_DB_PASS +dbname = $POSTFIX_DB_NAME +query = SELECT goto FROM alias WHERE address='%s' AND active = '1' +EOF + +else + echo "[ FATAL ]: Unknown database type $POSTFIX_DB_TYPE" +fi +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tCreate file '/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_domain_maps.cf'" +if [ "$POSTFIX_DB_TYPE" = "pgsql" ]; then + + cat < /etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_domain_maps.cf +hosts = $POSTFIX_DB_SOCKET +user = $POSTFIX_DB_USER +password = $POSTFIX_DB_PASS +dbname = $POSTFIX_DB_NAME +query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = '%u' || '@' || alias_domain.target_domain AND alias.active = true AND alias_domain.active = true +EOF + +elif [ "$POSTFIX_DB_TYPE" = "mysql" ];then + + cat < /etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_domain_maps.cf +hosts = $POSTFIX_DB_HOST +user = $POSTFIX_DB_USER +password = $POSTFIX_DB_PASS +dbname = $POSTFIX_DB_NAME +query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('%u', '@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1' +EOF + +else + echo "[ FATAL ]: Unknown database type $POSTFIX_DB_TYPE" +fi +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tCreate file '/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_domain_catchall_maps.cf'" +if [ "$POSTFIX_DB_TYPE" = "pgsql" ]; then + cat < /etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_domain_catchall_maps.cf +hosts = $POSTFIX_DB_SOCKET +user = $POSTFIX_DB_USER +password = $POSTFIX_DB_PASS +dbname = $POSTFIX_DB_NAME +query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = '@' || alias_domain.target_domain AND alias.active = true AND alias_domain.active = true +EOF + +elif [ "$POSTFIX_DB_TYPE" = "mysql" ];then + + cat < /etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_domain_catchall_maps.cf +hosts = $POSTFIX_DB_HOST +user = $POSTFIX_DB_USER +password = $POSTFIX_DB_PASS +dbname = $POSTFIX_DB_NAME +query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1' +EOF + +else + echo "[ FATAL ]: Unknown database type $POSTFIX_DB_TYPE" +fi +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + + +check_entry_main_cf_arr["virtual_alias_maps"]="proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_maps.cf,proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_domain_maps.cf,proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_domain_catchall_maps.cf" +# - Edit /etc/postfix/main.cf +# - +# - add to virtual_alias_maps: +# - proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_maps.cf, +# - proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_domain_maps.cf, +# - proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_domain_catchall_maps.cf +# - ## - mailman +# - #hash:/var/lib/mailman/data/virtual-mailman +# - +echononl "\tUpdate '/etc/postfix/main.cf'" +if ! grep -q "proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_maps.cf" /etc/postfix/main.cf > /dev/null 2>&1 ; then + perl -i -n -p -e "s#\s*(virtual_alias_maps\s*=.*$)#\1\n proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_maps.cf\n proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_domain_maps.cf\n proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_domain_catchall_maps.cf#" \ + /etc/postfix/main.cf > $log_file 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + + +echononl "\tCreate file '/etc/postfix/${POSTFIX_DB_TYPE}_virtual_mailbox_maps.cf'" +if [ "$POSTFIX_DB_TYPE" = "pgsql" ]; then + + cat < /etc/postfix/${POSTFIX_DB_TYPE}_virtual_mailbox_maps.cf +hosts = $POSTFIX_DB_SOCKET +user = $POSTFIX_DB_USER +password = $POSTFIX_DB_PASS +dbname = $POSTFIX_DB_NAME +query = SELECT maildir FROM mailbox WHERE username='%s' AND active = true +EOF + +elif [ "$POSTFIX_DB_TYPE" = "mysql" ];then + + cat < /etc/postfix/${POSTFIX_DB_TYPE}_virtual_mailbox_maps.cf +hosts = $POSTFIX_DB_HOST +user = $POSTFIX_DB_USER +password = $POSTFIX_DB_PASS +dbname = $POSTFIX_DB_NAME +query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1' +EOF + +else + echo "[ FATAL ]: Unknown database type $POSTFIX_DB_TYPE" +fi +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tCreate file '/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_domain_mailbox_maps.cf'" +if [ "$POSTFIX_DB_TYPE" = "pgsql" ]; then + + cat < /etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_domain_mailbox_maps.cf +hosts = $POSTFIX_DB_SOCKET +user = $POSTFIX_DB_USER +password = $POSTFIX_DB_PASS +dbname = $POSTFIX_DB_NAME +query = SELECT maildir FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' and mailbox.username = '%u' || '@' || alias_domain.target_domain AND mailbox.active = true AND alias_domain.active = true +EOF + +elif [ "$POSTFIX_DB_TYPE" = "mysql" ];then + + cat < /etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_domain_mailbox_maps.cf +hosts = $POSTFIX_DB_HOST +user = $POSTFIX_DB_USER +password = $POSTFIX_DB_PASS +dbname = $POSTFIX_DB_NAME +query = SELECT maildir FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' and mailbox.username = CONCAT('%u', '@', alias_domain.target_domain) AND mailbox.active = 1 AND alias_domain.active='1' +EOF + +else + echo "[ FATAL ]: Unknown database type $POSTFIX_DB_TYPE" +fi +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +check_entry_main_cf_arr["virtual_mailbox_maps"]="proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_mailbox_maps.cf,proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_domain_mailbox_maps.cf" +# - Edit /etc/postfix/main.cf +# - +# - add to virtual_mailbox_maps: +# - proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_mailbox_maps.cf, +# - proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_domain_mailbox_maps.cf +# - +echononl "\tUpdate '/etc/postfix/main.cf'" +if ! grep -q "proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_mailbox_maps.cf" /etc/postfix/main.cf > /dev/null 2>&1 ; then + perl -i -n -p -e "s#\s*(virtual_mailbox_maps\s*=.*$)#\1\n proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_mailbox_maps.cf\n proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_domain_mailbox_maps.cf#" \ + /etc/postfix/main.cf > $log_file 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + + +echononl "\tCreate file '/etc/postfix/${POSTFIX_DB_TYPE}_virtual_domains_maps.cf'" +if [ "$POSTFIX_DB_TYPE" = "pgsql" ]; then + + cat < /etc/postfix/${POSTFIX_DB_TYPE}_virtual_domains_maps.cf +hosts = $POSTFIX_DB_SOCKET +user = $POSTFIX_DB_USER +password = $POSTFIX_DB_PASS +dbname = $POSTFIX_DB_NAME +query = SELECT domain FROM domain WHERE domain = '%s' AND active = true +EOF + +elif [ "$POSTFIX_DB_TYPE" = "mysql" ];then + + cat < /etc/postfix/${POSTFIX_DB_TYPE}_virtual_domains_maps.cf +hosts = $POSTFIX_DB_HOST +user = $POSTFIX_DB_USER +password = $POSTFIX_DB_PASS +dbname = $POSTFIX_DB_NAME +query = SELECT domain FROM domain WHERE domain='%s' AND active = '1' +EOF + +else + echo "[ FATAL ]: Unknown database type $POSTFIX_DB_TYPE" +fi +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +check_entry_main_cf_arr["virtual_mailbox_domains"]="proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_domains_maps.cf" +# - Edit /etc/postfix/main.cf +# - +# - Add to virtual_mailbox_domains: +# - proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_domains_maps.cf +# - +echononl "\tUpdate '/etc/postfix/main.cf'" +if ! grep -q "proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_domains_maps.cf" /etc/postfix/main.cf > /dev/null 2>&1 ; then + perl -i -n -p -e "s#\s*(virtual_mailbox_domains\s*=.*$)#\1\n proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_domains_maps.cf#" \ + /etc/postfix/main.cf > $log_file 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + +# - address-extension with delimeter "-" +# - +echononl "\tCreate file '/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_address_rewriting.cf'" +if [ "$POSTFIX_DB_TYPE" = "pgsql" ]; then + + cat < /etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_address_rewriting.cf +## - this address rewriting acts as address extension +## - with delimeter "-" +## - +hosts = $POSTFIX_DB_SOCKET +user = $POSTFIX_DB_USER +password = $POSTFIX_DB_PASS +dbname = $POSTFIX_DB_NAME +query = SELECT username FROM mailbox WHERE domain = '%d' AND '%u' LIKE local_part || '-%%' AND active = true ORDER BY username DESC LIMIT 1; +EOF + +elif [ "$POSTFIX_DB_TYPE" = "mysql" ];then + cat < /etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_address_rewriting.cf +hosts = $POSTFIX_DB_HOST +user = $POSTFIX_DB_USER +password = $POSTFIX_DB_PASS +dbname = $POSTFIX_DB_NAME +query = SELECT username FROM mailbox WHERE domain = '%d' AND '%u' LIKE CONCAT(local_part, '-%%') AND active = '1' ORDER BY username DESC LIMIT 1; +EOF + + +else + echo "[ FATAL ]: Unknown database type $POSTFIX_DB_TYPE" +fi +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +check_entry_main_cf_arr["virtual_alias_maps"]="${check_entry_main_cf_arr['virtual_alias_maps']},proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_address_rewriting.cf" +# - Edit /etc/postfix/main.cf +# - +# - NOTICE!! +# - add this entry to virtual_alias_maps AT THE END, BUT BEFOR CATCH-ALL MAPS +# - if exists +# - +# - might look like this: +# - virtual_alias_maps = +# - proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_maps.cf, +# - proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_domain_maps.cf, +# - proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_address_rewriting.cf, +# - proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_domain_catchall_maps.cf +# - ## - mailman +# - #hash:/var/lib/mailman/data/virtual-mailman +# - +echononl "\tUpdate '/etc/postfix/main.cf'" +if ! grep -q "proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_address_rewriting.cf" /etc/postfix/main.cf > /dev/null 2>&1 ; then + perl -i -n -p -e "s#(\s*proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_domain_catchall_maps.cf.*$)# proxy:${POSTFIX_DB_TYPE}:/etc/postfix/${POSTFIX_DB_TYPE}_virtual_alias_address_rewriting.cf\n\1#" \ + /etc/postfix/main.cf > $log_file 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + +echo -e "\n\n\t\033[37m\033[1mSome final checks\033[m\n" + +# - Check, if previously created entries in /etc/postfix/main.cf are really present +# - +echononl "\tCheck /etc/postfix/main.cf" +first_err=true +_found_err=false +for _key in ${!check_entry_main_cf_arr[@]} ; do + IFS=',' read -a _val_arr <<< "${check_entry_main_cf_arr[$_key]}" + for _val in ${_val_arr[@]} ; do + if ! grep "$_val" /etc/postfix/main.cf > /dev/null 2>&1 ; then + if $first_err ; then + echo_failed + first_err=false + fi + _found_err=true + error "No Entry '${_val}' found for parameter '${_key}' in /etc/postfix/main.cf" + fi + done +done +if ! $_found_err ; then + echo_ok +fi + + +echo "" +echononl "\tReload/Restart postfix" +if $SYSTEMD_EXISTS ; then + systemctl reload postfix > $log_file 2>&1 +else + /etc/init.d/postfix reload > $log_file 2>&1 +fi +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echo "" +info "Browse to \033[1mhttp://${WEBSITE_NAME}/setup.php\033[m to create a 'setup password'\n$(cat < /etc/postfix/pgsql_virtual_mailbox_limit_maps.cf +hosts = /var/run/postgresql +user = postfix +password = FKt4z55FxMZp +dbname = postfix +query = SELECT quota FROM mailbox WHERE username='%s' AND active = true +EOF + +## - add configuration parameter virtual_mailbox_limit_maps +## - in Postfix /etc/postfix/main.cf +## - +## - add: +## - virtual_mailbox_limit_maps = proxy:pgsql:/etc/postfix/pgsql_virtual_mailbox_limit_maps.cf +## - +vim /etc/postfix/main.cf +## - !!!!!!!!!! diff --git a/install_roundcube.sh b/install_roundcube.sh new file mode 100755 index 0000000..61baff8 --- /dev/null +++ b/install_roundcube.sh @@ -0,0 +1,3030 @@ +#!/usr/bin/env bash + +clear +echo -e "\n\t\033[32mStart script for installation Roundcube Webmailer..\033[m" + +## ----------------------------------------------------------------- +## ---------------------------------------------------------------- +## --- +## --- For configurations see file conf/install_upgrade_roundcube.conf +## --- +## --- Dont make changes here! +## --- +## ----------------------------------------------------------------- +## ----------------------------------------------------------------- + + +# ------------- +# - Settings +# ------------- + +_src_base_dir="$(realpath $(dirname $0))" +#_src_base_dir=/usr/local/src/postfixadmin +conf_file="${_src_base_dir}/conf/install_upgrade_roundcube.conf" +curdir=`pwd` + +log_file="$(mktemp)" +tmp_dir="$(mktemp -d)" +backup_date="$(date +%Y-%m-%d-%H%M)" + + +# ------------- +# - Functions +# ------------- + +clean_up() { + + # Perform program exit housekeeping + rm -f "$log_file" + rm -rf "$tmp_dir" + exit $1 +} + +echononl(){ + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo "$*\\c" 1>&2 + else + echo -e -n "$*" 1>&2 + fi + rm /tmp/shprompt$$ +} + +fatal(){ + echo "" + echo -e "\t[ \033[31m\033[1mFatal\033[m ]: $*" + echo "" + echo -e "\t\033[31m\033[1mInstalllation wird abgebrochen\033[m" + echo "" + clean_up 1 +} + +error(){ + echo "" + echo -e "\t[ \033[31m\033[1mFehler\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 "" +} + + +echo_ok() { + echo -e "\033[75G[ \033[32mok\033[m ]" +} +echo_failed(){ + echo -e "\033[75G[ \033[1;31mfailed\033[m ]" +} +echo_skipped() { + echo -e "\033[75G[ \033[30m\033[1mskipped\033[m ]" +} + +trap clean_up SIGHUP SIGINT SIGTERM + + +if [ "$DB_TYPE" = "postgres" -o "$DB_TYPE" = "postgresql" -o "$DB_TYPE" = "pgsql" -o "$DB_TYPE" = "psql" ];then + DB_TYPE=pgsql +fi + +echo +echononl "\tInclude Configuration file.." +if [[ ! -f $conf_file ]]; then + echo_failed + fatal "Missing configuration file '$conf_file'" +else + source $conf_file + echo_ok +fi + +echo -e "\033[32m--\033[m" +echo "" +echo "Version of the Roundcube Webmailer to install" +echo "" +echo "" +ROUNDCUBE_VERSION= +while [ "X$ROUNDCUBE_VERSION" = "X" ] +do + echononl "Roundcube Version: " + read ROUNDCUBE_VERSION + if [ "X$ROUNDCUBE_VERSION" = "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 "" + + +# - Default values +# - +DEFAULT_SPAM_FOLDER_NAME="Spam" +DEFAULT_HTTP_USER="www-data" +DEFAULT_HTTP_GROUP="www-data" +DEFAULT_APACHE_LOG_DIR="/var/log/apache2" +DEFAULT_WEBSITE_BASEDIR="/var/www/${WEBSITE_NAME}" +DEFAULT_ROUNDCUBE_TMPDIR="${DEFAULT_WEBSITE_BASEDIR}/temp" +DEFAULT_DEBIAN_APACHE_CERT_DIR="/etc/apache2" +DEFAULT_APACHE_CERT_DIR="/usr/local/apache2/conf" +DEFAULT_APACHE_SERVER_CERT="server-bundle.crt" +DEFAULT_APACHE_SERVER_KEY="server.key" +DEFAULT_DEBIAN_APACHE_VHOST_DIR="/etc/apache2/sites-available" +DEFAULT_APACHE_VHOST_DIR="/usr/local/apache2/conf/vhosts" +DEFAULT_DB_HOST="localhost" +DEFAULT_DB_NAME="roundcubemail" +DEFAULT_DB_USER="roundcube" +DEFAULT_DEBIAN_MYSQL_CREDENTIALS="/etc/mysql/debian.cnf" +DEFAULT_MYSQL_CREDENTIALS="/usr/local/mysql/sys-maint.cnf" + +[[ -n "$ROUNDCUBE_VERSION" ]] || fatal "Roundcube Version (ROUNDCUBE_VERSION) not present!" +[[ -n "$WEBSITE_NAME" ]] || fatal "Website's name (WEBSITE_NAME) not present!" + +TLD=${WEBSITE_NAME##*.} +_tmp_string=${WEBSITE_NAME%.*} +MAIN_DOMAIN=${_tmp_string##*.} + +[[ -n "$WEBMASTER_EMAIL" ]] || WEBMASTER_EMAIL="admin@${MAIN_DOMAIN}.$TLD" + +[[ -n "$ROUNDCUBE_TMPDIR" ]] || ROUNDCUBE_TMPDIR="$DEFAULT_ROUNDCUBE_TMPDIR" + +[[ -n "$IPV4" ]] || fatal "IPv4 Address (IPV4) not present!" +[[ -n "$IPV6" ]] || fatal "IPv4 Address (IPV6) not present!" + +[[ -n "$APACHE_DEBIAN_INSTALLATION" ]] || APACHE_DEBIAN_INSTALLATION=false + +httpd_binary="`which httpd`" +if [ -z "$httpd_binary" ]; then + httpd_binary="$(ps -axu | grep httpd | grep -e "^root" | grep -v grep | awk '{print$11}')" + if [ -z "$httpd_binary" ]; then + if [ -x "/usr/local/apache2/bin/httpd" ]; then + httpd_binary="/usr/local/apache2/bin/httpd" + fi + fi +fi + +if [ -x "$httpd_binary" ];then + + # - Determin websever user + # - + HTTP_USER="`$httpd_binary -t -D DUMP_RUN_CFG | grep -i -e "^User" | awk '{print$2}' | cut -d\"=\" -f2 | tr -d '"'`" + HTTP_GROUP="`$httpd_binary -t -D DUMP_RUN_CFG | grep -i -e "^Group" | awk '{print$2}' | cut -d\"=\" -f2 | tr -d '"'`" + + [[ -n "$HTTP_USER" ]] || HTTP_USER=$DEFAULT_HTTP_USER + [[ -n "$HTTP_GROUP" ]] || HTTP_GROUP=$DEFAULT_HTTP_GROUP + + # - Is webserver running ? + # - + PID=$(ps aux | grep "$(realpath $httpd_binary)" | grep -e "^root" | grep -v grep | awk '{print$2}') + if [[ "X${PID}X" = "XX" ]] ;then + IS_HTTPD_RUNNING=false + else + IS_HTTPD_RUNNING=true + fi +fi + +[[ -n "$WEBMASTER_EMAIL" ]] || fatal "E-Mail (WEBMASTER_EMAIL) for webmaster not present!" +[[ -n "$WEBSITE_BASEDIR" ]] || WEBSITE_BASEDIR=$DEFAULT_WEBSITE_BASEDIR + +if [[ -z "$APACHE_CERT_DIR" ]] ; then + if $APACHE_DEBIAN_INSTALLATION ; then + APACHE_CERT_DIR="$DEFAULT_DEBIAN_APACHE_CERT_DIR" + else + APACHE_CERT_DIR="$DEFAULT_APACHE_CERT_DIR" + fi +fi + +[[ -n "$APACHE_SERVER_CERT" ]] || APACHE_SERVER_CERT=$DEFAULT_APACHE_SERVER_CERT +[[ -n "$APACHE_SERVER_KEY" ]] || APACHE_SERVER_KEY=$DEFAULT_APACHE_SERVER_KEY + +[[ -n "$APACHE_LOG_DIR" ]] || APACHE_LOG_DIR=$DEFAULT_APACHE_LOG_DIR + +if [[ -z "$PHP_TYPE" ]]; then + PHP_TYPE="php_fpm" +else + [[ "$PHP_TYPE" = "php_fpm" ]] || [[ "$PHP_TYPE" = "fcgid" ]] || [[ "$PHP_TYPE" = "mod_php" ]] || fatal "Wrong type of PHP (PHP_TYPE) given!" +fi + + +if [[ -z "$APACHE_VHOST_DIR" ]] ; then + if $APACHE_DEBIAN_INSTALLATION ; then + APACHE_VHOST_DIR="$DEFAULT_DEBIAN_APACHE_VHOST_DIR" + else + APACHE_VHOST_DIR="$DEFAULT_APACHE_VHOST_DIR" + fi +fi + +[[ -n "$AUTOREPLY_HOSTNAME" ]] || AUTOREPLY_HOSTNAME=autoreply.${MAIN_DOMAIN}.$TLD + + +[[ -n "$DB_TYPE" ]] || fatal "Database Type of Roundcube Database (DB_TYPE) not present!" +[[ -n "$DB_HOST" ]] || DB_HOST="$DEFAULT_DB_HOST" +[[ -n "$DB_NAME" ]] || DB_NAME="$DEFAULT_DB_NAME" +[[ -n "$DB_USER" ]] || DB_USER="$DEFAULT_DB_USER" +[[ -n "$DB_PASS" ]] || fatal "Password of Roundcube Database (DB_PASS) not given!" + +[[ -n "$MYSQL_DEBIAN_INSTALLATION" ]] || MYSQL_DEBIAN_INSTALLATION=false + +if [[ "$DB_TYPE" = "mysql" ]]; then + if $MYSQL_DEBIAN_INSTALLATION ; then + [[ -n "$MYSQL_CREDENTIALS" ]] || MYSQL_CREDENTIALS="$DEFAULT_DEBIAN_MYSQL_CREDENTIALS" + else + [[ -n "$MYSQL_CREDENTIALS" ]] || MYSQL_CREDENTIALS="$DEFAULT_MYSQL_CREDENTIALS" + fi +else + [[ "$DB_TYPE" = "pgsql" ]] || fatal "Unknown Database Type '$DB_TYPE' (DB_TYPE)" +fi + +[[ -n "$SPAM_FOLDER_NAME" ]] || SPAM_FOLDER_NAME=$DEFAULT_SPAM_FOLDER_NAME + +[[ -n "$SUPPORT_URL" ]] || SUPPORT_URL="http://www.${MAIN_DOMAIN}.$TLD" + +SKIN_LOGO_PRESENT=false +if [[ -f "${WEBSITE_BASEDIR}/htdocs/${SKIN_LOGO}" ]]; then + SKIN_LOGO_PRESENT=true + SKIN_LOGO_DIR="$(echo "${SKIN_LOGO%/*}")" + SKIN_LOGO_FILE="$(echo "${SKIN_LOGO##*/}")" + if [[ "$(echo "${SKIN_LOGO%/*}")" = "$SKIN_LOGO" ]] ; then + cp -a "${WEBSITE_BASEDIR}/htdocs/${SKIN_LOGO}" "${tmp_dir}/" + else + cp -a "${WEBSITE_BASEDIR}/htdocs/${SKIN_LOGO_DIR}" "${tmp_dir}/" + fi +fi + +# --- +# - Plugins +# -- + +# - Pligin acl +# - +[[ -n "$INCLUDE_ACL_PLUGIN" ]] || INCLUDE_ACL_PLUGIN=false + + +# - Plugin passord +# - +[[ -n "$PW_CONFIRM_CURRENT" ]] || PW_CONFIRM_CURRENT=true +[[ -n "$PW_MIN_LENGTH" ]] || PW_MIN_LENGTH=10 +[[ -n "$PW_REQUIRE_NONALPHA" ]] || PW_REQUIRE_NONALPHA=true +[[ -n "$PW_PASSWD_ALGO" ]] || PW_PASSWD_ALGO="dovecot" +#[[ -n "$PW_PASSWD_ALGO_PREFIX" ]] || PW_PASSWD_ALGO_PREFIX="{CRAM-MD5}" + +[[ -n "$POSTFIX_DB_TYPE" ]] || fatal "Plugin password: Database Type for Password Database (POSTFIX_DB_TYPE) not given!" +if [[ "$POSTFIX_DB_TYPE" != "pgsql" ]] && [[ "$POSTFIX_DB_TYPE" != "mysql" ]]; then + fatal "Unknown Database Type '$POSTFIX_DB_TYPE' for Password Database (POSTFIX_DB_TYPE)" +fi +[[ -n "$POSTFIX_DB_HOST" ]] || POSTFIX_DB_HOST="localhost" +[[ -n "$POSTFIX_DB_NAME" ]] || POSTFIX_DB_NAME="postfix" +[[ -n "$POSTFIX_DB_USER" ]] || POSTFIX_DB_USER="postfix" +[[ -n "$POSTFIX_DB_PASSWD" ]] || fatal "Plugin password: Password for Password Database (POSTFIX_DB_PASSWD) not given!" +[[ -n "$PW_DB_UPDATE_STRING" ]] || fatal "Plugin password: No SQL query for changing password present!" +[[ -n "$PW_DOVEADM_PW" ]] || PW_DOVEADM_PW='/usr/local/dovecot/bin/doveadm pw' +[[ -n "$PW_DOVECOT_PW_METHOD" ]] || PW_DOVECOT_PW_METHOD='CRAM-MD5' + +# - Plugin vacation +# - +[[ -n "$VAC_GUI_FORWARDER" ]] || VAC_GUI_FORWARDER=false + + +# - Determin PHP of all installed versions +# - +echononl "\tGet major version of all installed PHP versions" +php_major_versions=`find /usr/local/ -maxdepth 1 -mindepth 1 -type l -name "php-*" -print | cut -d "-" -f2 | sort` +if [[ -z "$php_major_versions" ]]; then + echo_failed + error "Getting major version of installed PHP versions failed! No installed PHP versiond found!" +else + echo_ok +fi + +# - Get the latest PHP version +# - +echononl "\tGet major version of latest installed PHP version" +php_latest_ver="" +if [[ -n "$php_major_versions" ]]; then + for _ver in $php_major_versions ; do + if [[ -z "$php_latest_ver" ]] ; then + php_latest_ver=$_ver + elif [[ "${_ver%.*}" -gt "${php_latest_ver%.*}" ]] ; then + php_latest_ver=$_ver + elif [[ "${_ver%.*}" -eq "${php_latest_ver%.*}" ]] ; then + [[ "${_ver#*.}" -gt "${php_latest_ver#*.}" ]] && php_latest_ver=$_ver + fi + done + echo_ok +else + echo_skipped + warn "Getting major version of latest installed PHP version failed! - No installed PHP versiond found!" +fi + +echo "" +echo "" +echo -e "\033[1;32mSettings for installation of \033[1;37mRoundcube Webmail\033[m" +echo "" +echo -e "\tRoundcube Version....................: $ROUNDCUBE_VERSION" +echo "" +echo -e "\tName of the Website..................: $WEBSITE_NAME" +echo "" +echo -e "\tIPv4 Address.........................: $IPV4" +echo -e "\tIPv6 Address.........................: $IPV6" +echo "" +echo -e "\tApache from Debian Package System....: $APACHE_DEBIAN_INSTALLATION" +echo -e "\tApache User..........................: $HTTP_USER" +echo -e "\tApache Group.........................: $HTTP_GROUP" +echo -e "\tApache VHOST Directory...............: $APACHE_VHOST_DIR" +echo -e "\tApache LOG Directory.................: $APACHE_LOG_DIR" +echo "" +echo -e "\tApache Cert directory................: $APACHE_CERT_DIR" +echo -e "\tWebsite Certificate..................: $APACHE_SERVER_CERT" +if [[ -n "$CERT_ChainFile" ]] ; then + echo -e "\tCertificate Chain File...............: $CERT_ChainFile" +fi +echo -e "\tWebsite Key..........................: $APACHE_SERVER_KEY" +echo "" +echo -e "\tWebmasters E-Mail Address............: $WEBMASTER_EMAIL" +echo -e "\tBase Directory of Roundcube Website..: $WEBSITE_BASEDIR" +echo "" +echo -e "\tRoundcube TEMP Directory.............: $ROUNDCUBE_TMPDIR" +echo -e "\tRoundcube LOG Directory..............: ${WEBSITE_BASEDIR}/logs" +echo -e "\tType of PHP connection...............: $PHP_TYPE" +echo "" +echo -e "\tInstalled PHP versions...............: $php_major_versions" +echo -e "\tNewest PHP Version...................: $php_latest_ver" +echo "" +if [[ "$DB_TYPE" = "mysql" ]]; then + echo -e "\tDatabase type of Roundcube Database..: MySQL" + echo -e "\tMySQL from Debian Package System.....: $MYSQL_DEBIAN_INSTALLATION" +else + echo -e "\tDatabase type of Roundcube Database..: PostgreSQL" +fi +echo -e "\tHost of Roundcube Database...........: $DB_HOST" +echo -e "\tName of Roundcube Database...........: $DB_NAME" +echo -e "\tUser of Roundcube Database...........: $DB_USER" +echo -e "\tPassword of Roundcube Database.......: $DB_PASS" +if [[ "$DB_TYPE" = "mysql" ]]; then + echo -e "\tMySQL Credentials (root access)......: $MYSQL_CREDENTIALS" +fi +echo "" +echo -e "\tHostname for Vacation Messages.......: $AUTOREPLY_HOSTNAME" +echo "" +echo -e "\tName of Junk Folder..................: $SPAM_FOLDER_NAME" +echo "" +echo "" +echo -e "\tInclude 'acl' plugin?..................: $INCLUDE_ACL_PLUGIN" + +echo "" +echo -n "Type upper case 'YES' to continue executing with this parameters: " +read OK +if [[ "$OK" = "YES" ]] ; then + echo "" + echo "" + echo -e "\t\033[1;32mGoing to install Roundcube Webmailer \033[1;37m$network \033[m" + echo "" +else + fatal "Abort by user request - Answer as not 'YES'" +fi + + + +_log_dir=${_src_base_dir}/log-roundcube-$_version + + +## ---------------------------- +## - Begin Installation + +# - REQUIREMENTS +# - ============ +# - +# - * An IMAP, HTTP and SMTP server +# - * .htaccess support allowing overrides for DirectoryIndex +# - * PHP Version 5.4 or greater including: +# - - PCRE, DOM, JSON, Session, Sockets, OpenSSL, Mbstring (required) +# - - PHP PDO with driver for either MySQL, PostgreSQL, SQL Server, Oracle or SQLite (required) +# - - Iconv, Zip, Fileinfo, Intl, Exif (recommended) +# - - LDAP for LDAP addressbook support (optional) +# - * PEAR and PEAR packages distributed with Roundcube or external: +# - - Mail_Mime 1.10.0 or newer +# - - Net_SMTP 1.7.1 or newer +# - - Net_Socket 1.0.12 or newer +# - - Net_IDNA2 0.1.1 or newer +# - - Auth_SASL 1.0.6 or newer +# - - Net_Sieve 1.3.2 or newer (for managesieve plugin) +# - - Crypt_GPG 1.6.0 or newer (for enigma plugin) +# - - Endroid/QrCode 1.6.0 or newer (https://github.com/endroid/QrCode) +# - * php.ini options (see .htaccess file): +# - - error_reporting E_ALL & ~E_NOTICE & ~E_STRICT +# - - memory_limit > 16MB (increase as suitable to support large attachments) +# - - file_uploads enabled (for attachment upload features) +# - - session.auto_start disabled +# - - suhosin.session.encrypt disabled +# - - mbstring.func_overload disabled +# - * A MySQL, PostgreSQL, MS SQL Server (2005 or newer), Oracle database +# - or SQLite support in PHP - with permission to create tables +# - * Composer installed either locally or globally (https://getcomposer.org) + + +needed_php_pear_modules=" + MDB2 + Mail_Mime + Mail_mimeDecode + Net_SMTP + Net_IDNA2 + Auth_SASL" + +if [[ "$DB_TYPE" = "pgsql" ]]; then + needed_php_pear_modules="$needed_php_pear_modules MDB2_Driver_pgsql" +else + needed_php_pear_modules="$needed_php_pear_modules MDB2_Driver_mysql MDB2_Driver_mysqli" +fi + +## - install php PEAR packages +## - +## - !! Take care to do this for all php installations (PHP 5.5/5.6/..) +## - +for _version in $php_major_versions ; do + + echo -e "\n\n\t\033[37m\033[1mInstall modules for PHP Version ${_version}..\033[m\n" + + for _module in $needed_php_pear_modules ; do + echononl "\tInstall Module '$_module'.." + if ! /usr/local/php-${_version}/bin/pear list | grep -q "$_module" 2> /dev/null ; then + /usr/local/php-${_version}/bin/pear install $_module > $log_file 2>&1 + if [[ "$?" = "0" ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + if [[ "$_module" = "Net_IDNA2" ]]; then + echononl "\tInstall (beta) Net_IDNA2-0.1.1 .." + /usr/local/php-${_version}/bin/pear install channel://pear.php.net/Net_IDNA2-0.1.1 > $log_file 2>&1 + if [ "$?" = "0" ]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + fi + fi + else + echo_skipped + fi + done +done + + +echo -e "\n\n\t\033[37m\033[1mInstall (global) composer..\033[m\n" + +echononl "\tDownload composer from 'getcomposer.org'.." +php -r "copy('https://getcomposer.org/installer', '${_src_base_dir}/composer-setup.php');" > $log_file 2>&1 +if [[ "$?" = "0" ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tInstall composer to /usr/local/bin" +php ${_src_base_dir}/composer-setup.php --install-dir=/usr/local/bin --filename=composer > $log_file 2>&1 +if [[ "$?" = "0" ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + + +echo -e "\n\n\t\033[37m\033[1mCreate some Backups..\033[m\n" + + +echononl "\tBackup existing source directory 'roundcubemail-${ROUNDCUBE_VERSION}'.." +if [[ -d "${_src_base_dir}/roundcubemail-${ROUNDCUBE_VERSION}" ]] ;then + mv ${_src_base_dir}/roundcubemail-${ROUNDCUBE_VERSION} \ + ${_src_base_dir}/roundcubemail-${ROUNDCUBE_VERSION}.$backup_date > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +echononl "\tBackup existing web-directory 'roundcubemail-${ROUNDCUBE_VERSION}'.." +if [[ -d "${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}" ]]; then + mv ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION} \ + ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}.$backup_date > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + +echo -e "\n\n\t\033[37m\033[1mBase install Roundcube Webmail..\033[m\n" + +# - install roundcube +# - +echononl "\tDownload 'roundcubemail-${ROUNDCUBE_VERSION}'.." +if [[ ! -f "$_src_base_dir/roundcubemail-${ROUNDCUBE_VERSION}.tar.gz" ]]; then + wget -O ${_src_base_dir}/roundcubemail-${ROUNDCUBE_VERSION}.tar.gz https://github.com/roundcube/roundcubemail/releases/download/${ROUNDCUBE_VERSION}/roundcubemail-${ROUNDCUBE_VERSION}.tar.gz > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +echononl "\tUnpack 'roundcubemail-${ROUNDCUBE_VERSION}'.." +gunzip < ${_src_base_dir}/roundcubemail-${ROUNDCUBE_VERSION}.tar.gz | tar -C ${_src_base_dir} -xf - 2> $log_file +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tCreate '$WEBSITE_BASEDIR'.." +if [[ ! -d "$WEBSITE_BASEDIR" ]]; then + mkdir $WEBSITE_BASEDIR > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +echononl "\tCopy Roundcube to web-directory" +cp -a ${_src_base_dir}/roundcubemail-${ROUNDCUBE_VERSION} $WEBSITE_BASEDIR/ > $log_file 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tChange owner/group for Roundcube Webdirectory.." +chown -R ${HTTP_USER}:$HTTP_GROUP $WEBSITE_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION} > $log_file 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + + +echononl "\tChange into Roundcube Webdirectory.." +cd "${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}" > $log_file 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tRename the composer.json-dist file into composer.json" +cp -a "composer.json-dist" "composer.json" > $log_file 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tInstall composer to ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}" +php ${_src_base_dir}/composer-setup.php --install-dir=${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION} > $log_file 2>&1 +if [[ "$?" = "0" ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tRemove the installer" +php -r "unlink('${_src_base_dir}/composer-setup.php');" > $log_file 2>&1 +if [[ "$?" = "0" ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + + +echononl "\tInstall PHP dependencies.." +#/usr/local/php-${php_latest_ver}/bin/php /usr/local/bin/composer install --no-dev +su www-data -c"cd ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION} + /usr/local/php-${php_latest_ver}/bin/php /usr/local/bin/composer install --no-dev" -s /bin/bash \ + > $log_file 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tInstall Javascript dependencies.." +${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/bin/install-jsdeps.sh > $log_file 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + + +# - Install a cronjob for cleaning up database +# - +echononl "\tInstall a cronjob for cleaning up database" +crontab -l > /tmp/tmp_crontab +if ! grep -q -E "${WEBSITE_BASEDIR}/htdocs/bin/cleandb.sh" /tmp/tmp_crontab 2> /dev/null ; then + echo "" >> /tmp/tmp_crontab + echo "# - Keep roundcube database slick and clean" >> /tmp/tmp_crontab + echo "# -" >> /tmp/tmp_crontab + echo "37 3 * * * ${WEBSITE_BASEDIR}/htdocs/bin/cleandb.sh" >> /tmp/tmp_crontab + crontab /tmp/tmp_crontab > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + +echononl "\tSet Permissions 'root:root' on \n\t ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}" +chown -R root:root $WEBSITE_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION} > $log_file 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tRemove existing symlink '${WEBSITE_BASEDIR}/htdocs'" +if [[ -h "${WEBSITE_BASEDIR}/htdocs" ]]; then + rm ${WEBSITE_BASEDIR}/htdocs + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi +echononl "\tCreate Symlink for DocumentRoot Directory 'htdocs'.." +if [[ ! -h "${WEBSITE_BASEDIR}/htdocs" ]]; then + ln -s roundcubemail-${ROUNDCUBE_VERSION} ${WEBSITE_BASEDIR}/htdocs > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +if $SKIN_LOGO_PRESENT ; then + _failed=false + echononl "\tRestore logo '$SKIN_LOGO_FILE'" + if [[ "$(echo "${SKIN_LOGO%/*}")" = "$SKIN_LOGO" ]] ; then + cp -a "${tmp_dir}/${SKIN_LOGO}" "${WEBSITE_BASEDIR}/htdocs/" >> $log_file 2>&1 + else + if [[ ! -d "${WEBSITE_BASEDIR}/htdocs/${SKIN_LOGO_DIR}" ]]; then + cp -a "${tmp_dir}/${SKIN_LOGO_DIR}" "${WEBSITE_BASEDIR}/htdocs/" >> $log_file 2>&1 + else + cp -a "$(realpath "${tmp_dir}/${SKIN_LOGO_DIR}/${SKIN_LOGO_FILE}")" \ + "${WEBSITE_BASEDIR}/htdocs/${SKIN_LOGO_DIR}/${SKIN_LOGO_FILE}" >> $log_file 2>&1 + fi + + fi + if [[ $? -ne 0 ]]; then + echo_failed + error $(cat $log_file) + else + echo_ok + fi +fi + +echononl "\tCreate Roundcube LOG directory '${WEBSITE_BASEDIR}/logs'" +if [[ ! -d "${WEBSITE_BASEDIR}/logs" ]]; then + mkdir ${WEBSITE_BASEDIR}/logs > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +echononl "\tSet Permissions on Roundcube LOG directory '${WEBSITE_BASEDIR}/logs'.." +chown -R ${HTTP_USER}:$HTTP_GROUP ${WEBSITE_BASEDIR}/logs > $log_file 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tCreate Roundcube TMP directory (ROUNDCUBE_TMPDIR)" +if [[ ! -d "$ROUNDCUBE_TMPDIR" ]]; then + mkdir $ROUNDCUBE_TMPDIR > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +echononl "\tSet Permissions on Roundcube TMP directory '${ROUNDCUBE_TMPDIR}'.." +chown -R ${HTTP_USER}:$HTTP_GROUP $ROUNDCUBE_TMPDIR > $log_file 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + + +if [[ "$PHP_TYPE" = "fcgid" ]] ; then + echo -e "\n\n\t\033[37m\033[1mConfiguration for FastCGI PHP Connections (mod_fcgid)..\033[m\n" +elif [[ "$PHP_TYPE" = "php_fpm" ]] ; then + echo -e "\n\n\t\033[37m\033[1mConfiguration for PHP-FPM Connection ..\033[m\n" +elif [[ "$PHP_TYPE" = "mod_php" ]] ; then + echo -e "\n\n\t\033[37m\033[1mConfiguration for PHP Connection using Apache's mod_php..\033[m\n" +else + fatal "Wrong PHP Type '$PHP_TYPE' (PHP_TYPE)!" +fi + +echononl "\tCreate Log Directory '$APACHE_LOG_DIR'.." +if [[ ! -d "$APACHE_LOG_DIR" ]]; then + mkdir $APACHE_LOG_DIR > $log_file 2>&1 + if [[ "$?" = "0" ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + +if [[ "$PHP_TYPE" = "fcgid" ]] ; then + + _dirs="${WEBSITE_BASEDIR}/sessions ${WEBSITE_BASEDIR}/tmp ${WEBSITE_BASEDIR}/logs" + for _dir in $_dirs ; do + echononl "\tCreate Directory '$_dir'" + if [[ ! -d "$_dir" ]]; then + mkdir $_dir > $log_file 2>&1 + if [[ "$?" = "0" ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + else + echo_skipped + fi + + echononl "\tSet Permissons on '$_dir'.." + chown ${HTTP_USER}:${HTTP_GROUP} $_dir > $log_file 2>&1 + if [[ "$?" = "0" ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + done + + echononl "\tCreate directory '${WEBSITE_BASEDIR}/conf'.." + if [[ ! -d "${WEBSITE_BASEDIR}/conf" ]]; then + mkdir ${WEBSITE_BASEDIR}/conf > $log_file 2>&1 + if [[ "$?" = "0" ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + else + echo_skipped + fi + + echononl "\tSet Permissions on '${WEBSITE_BASEDIR}/conf'.." + _failed=false + chown root:$HTTP_USER ${WEBSITE_BASEDIR}/conf > $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + chmod 750 ${WEBSITE_BASEDIR}/conf > $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + if ! $_failed ; then + echo_ok + fi + + for _version in $php_major_versions ; do + + echononl "\tPlace file '${WEBSITE_BASEDIR}/conf/php.ini-$_version'" + cp /usr/local/php-${_version}/etc/php.ini ${WEBSITE_BASEDIR}/conf/php.ini-$_version > $log_file 2>&1 + if [[ "$?" = "0" ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + + echononl "\tSet Permissions on '${WEBSITE_BASEDIR}/conf'.." + _failed=false + chown root:$HTTP_USER ${WEBSITE_BASEDIR}/conf/php.ini-$_version > $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + chmod 640 ${WEBSITE_BASEDIR}/conf/php.ini-$_version > $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + if ! $_failed ; then + echo_ok + fi + + echononl "\tCreate file '${WEBSITE_BASEDIR}/conf/fcgid-$_version'.." + cat < ${WEBSITE_BASEDIR}/conf/fcgid-$_version 2> $log_file +#!/bin/sh +export PHPRC="${WEBSITE_BASEDIR}/conf/" +export TMPDIR="${WEBSITE_BASEDIR}/tmp" +# PHP child process management (PHP_FCGI_CHILDREN) should +# always be disabled with mod_fcgid, which will only route one +# request at a time to application processes it has spawned; +# thus, any child processes created by PHP will not be used +# effectively. (Additionally, the PHP child processes may not +# be terminated properly.) By default, and with the environment +# variable setting PHP_FCGI_CHILDREN=0, PHP child process +# management is disabled. +PHP_FCGI_CHILDREN=0 +export PHP_FCGI_CHILDREN + +exec /usr/local/php-${_version}/bin/php-cgi +EOF + if [[ "$?" = "0" ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + + echononl "\tSet Permissions on '${WEBSITE_BASEDIR}/conf/fcgid-$_version'.." + _failed=false + chown root:$HTTP_USER ${WEBSITE_BASEDIR}/conf/fcgid-$_version > $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + chmod 750 ${WEBSITE_BASEDIR}/conf/fcgid-$_version > $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + if ! $_failed ; then + echo_ok + fi + done + + # - Create Symlinks in fcgid's config directory + # - + if [[ "$_version" = "$php_latest_ver" ]]; then + echononl "\tCreate symlink '${WEBSITE_BASEDIR}/conf/php.ini'.." + if [[ ! -h "${WEBSITE_BASEDIR}/conf/php.ini" ]]; then + ln -s php.ini-$_version ${WEBSITE_BASEDIR}/conf/php.ini > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + else + echo_skipped + fi + + echononl "\tCreate symlink '${WEBSITE_BASEDIR}/conf/fcgid'.." + if [[ ! -h "${WEBSITE_BASEDIR}/conf/fcgid" ]]; then + ln -s fcgid-$_version ${WEBSITE_BASEDIR}/conf/fcgid > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + else + echo_skipped + fi + + fi + + echononl "\tCreate file '${WEBSITE_BASEDIR}/conf/changes.php.ini.txt'.." + cat << EOF > ${WEBSITE_BASEDIR}/conf/changes.php.ini.txt +error_log = "${WEBSITE_BASEDIR}/logs/php_errors.log" +sys_temp_dir = "${WEBSITE_BASEDIR}/tmp" +upload_tmp_dir = "${WEBSITE_BASEDIR}/tmp" +session.save_path = "${WEBSITE_BASEDIR}/sessions" +soap.wsdl_cache_dir = "${WEBSITE_BASEDIR}/tmp" +EOF + if [[ "$?" = "0" ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + + echononl "\tCreate file '${WEBSITE_BASEDIR}/logs/php_errors.log'.." + + if [[ ! -f "${WEBSITE_BASEDIR}/logs/php_errors.log" ]]; then + touch ${WEBSITE_BASEDIR}/logs/php_errors.log > $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + chown ${HTTP_USER}:${HTTP_GROUP} ${WEBSITE_BASEDIR}/logs/php_errors.log > $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + if ! $_failed ; then + echo_ok + fi + else + echo_skipped + fi + + _php_ini_file="${WEBSITE_BASEDIR}/conf/php.ini-*" + + echononl "\tAdjust files '${WEBSITE_BASEDIR}/conf/php.ini-*'.." + _failed=false + _key=error_log + _val="${WEBSITE_BASEDIR}/logs/php_errors.log" + if grep -e "^\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + #sed -i "0,/^\([ \t]*${_key}[ \t]*=.*\)/ s##;\1\n${_key} = \"${_val}\"#" $_php_ini_file + perl -i -n -p -e "s#^(\s*${_key}\s*=.*)#;\1\n${_key} = ${_val}#" $_php_ini_file > $log_file 2>&1 + elif grep -e "^\s*;\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + sed -i "0,/^\([ \t]*;[ \t]*${_key}[ \t]*=.*\)/ s##\1\n${_key} = \"${_val}\"\n#" $_php_ini_file > $log_file 2>&1 + fi + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + + _key="sys_temp_dir" + _val="${WEBSITE_BASEDIR}/tmp" + if grep -e "^\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + #sed -i "0,/^\([ \t]*${_key}[ \t]*=.*\)/ s##;\1\n${_key} = \"${_val}\"#" $_php_ini_file + perl -i -n -p -e "s#^(\s*${_key}\s*=.*)#;\1\n${_key} = ${_val}#" $_php_ini_file > $log_file 2>&1 + elif grep -e "^\s*;\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + sed -i "0,/^\([ \t]*;[ \t]*${_key}[ \t]*=.*\)/ s##\1\n${_key} = \"${_val}\"\n#" $_php_ini_file > $log_file 2>&1 + fi + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + + _key="upload_tmp_dir" + _val="${WEBSITE_BASEDIR}/tmp" + if grep -e "^\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + #sed -i "0,/^\([ \t]*${_key}[ \t]*=.*\)/ s##;\1\n${_key} = \"${_val}\"#" $_php_ini_file + perl -i -n -p -e "s#^(\s*${_key}\s*=.*)#;\1\n${_key} = ${_val}#" $_php_ini_file > $log_file 2>&1 + elif grep -e "^\s*;\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + sed -i "0,/^\([ \t]*;[ \t]*${_key}[ \t]*=.*\)/ s##\1\n${_key} = \"${_val}\"\n#" $_php_ini_file > $log_file 2>&1 + fi + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + + _key="session.save_path" + _val="${WEBSITE_BASEDIR}/sessions" + if grep -e "^\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + #sed -i "0,/^\([ \t]*${_key}[ \t]*=.*\)/ s##;\1\n${_key} = \"${_val}\"#" $_php_ini_file + perl -i -n -p -e "s#^(\s*${_key}\s*=.*)#;\1\n${_key} = ${_val}#" $_php_ini_file > $log_file 2>&1 + elif grep -e "^\s*;\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + sed -i "0,/^\([ \t]*;[ \t]*${_key}[ \t]*=.*\)/ s##\1\n${_key} = \"${_val}\"\n#" $_php_ini_file > $log_file 2>&1 + fi + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + + _key="soap.wsdl_cache_dir" + _val="${WEBSITE_BASEDIR}/tmp" + if grep -e "^\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + #sed -i "0,/^\([ \t]*${_key}[ \t]*=.*\)/ s##;\1\n${_key} = \"${_val}\"#" $_php_ini_file + perl -i -n -p -e "s#^(\s*${_key}\s*=.*)#;\1\n${_key} = ${_val}#" $_php_ini_file > $log_file 2>&1 + elif grep -e "^\s*;\s*${_key}\s*=" $_php_ini_file > /dev/null 2>&1 ; then + sed -i "0,/^\([ \t]*;[ \t]*${_key}[ \t]*=.*\)/ s##\1\n${_key} = \"${_val}\"\n#" $_php_ini_file > $log_file 2>&1 + fi + if [[ $? -ne 0 ]]; then + _failed=true + error "$(cat $log_file)" + fi + + if ! $_failed ; then + echo_ok + fi + +fi + + +echo -e "\n\n\t\033[37m\033[1mConfigure Apache Webservice\033[m\n" + + +SSLCertificateChainFile="" +# - Create SSCertificateChainFile rule for apache vhost entry +# - +echononl "\tCreate SSCertificateChainFile rule for apache vhost entry" +if [ -n "$CERT_ChainFile" ];then + SSLCertificateChainFile="SSLCertificateChainFile ${APACHE_CERT_DIR}/$CERT_ChainFile" + echo_ok +else + echo_skipped +fi + + +echo "" + +# - Save existing vhost file +# - +echononl "\tSave existing vhost file.." +if [ -f ${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf ];then + if [[ -f "${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf" ]]; then + mv ${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf ${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf.$backup_date > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + else + echo_skipped + fi +else + echo_skipped +fi + +echononl "\tCreate VHost Configuration '${WEBSITE_NAME}.conf'.." +_failed=false +cat < ${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf 2>> $log_file +# -- $WEBSITE_NAME -- # + + + + ServerAdmin $WEBMASTER_EMAIL + + ServerName $WEBSITE_NAME + + RewriteEngine on + RewriteCond %{HTTPS} !=on + RewriteRule (.*) https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L] + + CustomLog ${APACHE_LOG_DIR}/${WEBSITE_NAME}-access.log combined + ErrorLog ${APACHE_LOG_DIR}/${WEBSITE_NAME}-error.log + + + + + + + ServerAdmin $WEBMASTER_EMAIL + + ServerName $WEBSITE_NAME + +EOF +if [[ $? -ne 0 ]]; then + failed=true +fi + +if [[ "$PHP_TYPE" = "mod_php" ]] ; then + cat <> ${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf 2>> $log_file + ## - its allowed to overwrite by .htaccess + ## - + php_value error_reporting "E_ALL & ~E_NOTICE" + + ## - Overwriting by .htaccess NOT allowd + ## - + php_admin_value upload_tmp_dir "${WEBSITE_BASEDIR}/tmp/" + php_admin_flag log_errors on + php_admin_value error_log "${WEBSITE_BASEDIR}/logs/php_error.log" + php_admin_value session.save_path "${WEBSITE_BASEDIR}/sessions" + + DocumentRoot "${WEBSITE_BASEDIR}/htdocs/" +EOF + if [[ $? -ne 0 ]]; then + failed=true + fi +elif [[ "$PHP_TYPE" = "fcgid" ]]; then + cat <> ${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf 2>> $log_file + DocumentRoot "${WEBSITE_BASEDIR}/htdocs/" + + Require all granted + FCGIWrapper ${WEBSITE_BASEDIR}/conf/fcgid .php + + SetHandler fcgid-script + + Options +ExecCGI + +EOF + if [[ $? -ne 0 ]]; then + failed=true + fi +elif [[ "$PHP_TYPE" = "php_fpm" ]]; then + cat <> ${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf 2>> $log_file + DocumentRoot "${WEBSITE_BASEDIR}/htdocs/" + + + SetHandler "proxy:unix:/tmp/php-${php_latest_ver}-fpm.www.sock|fcgi://127.0.0.1" + + + + DirectoryIndex index.php index.html + +EOF + if [[ $? -ne 0 ]]; then + failed=true + fi +fi +cat <> ${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf 2>> $log_file + + SSLEngine on + + # - HTTP Strict Transport Security (HSTS) + # - + # - HSTS tells a browser that the website should only be accessed through + # - a secure connection. The HSTS header will be remembered by a standard + # compliant browser for max-age seconds. + # - + # - Remember this settings for 1 year + # - + Header always set Strict-Transport-Security "max-age=31536000" + + SSLCertificateFile ${APACHE_CERT_DIR}/$APACHE_SERVER_CERT + SSLCertificateKeyFile ${APACHE_CERT_DIR}/$APACHE_SERVER_KEY + $SSLCertificateChainFile + + CustomLog ${APACHE_LOG_DIR}/${WEBSITE_NAME}-access.log combined + ErrorLog ${APACHE_LOG_DIR}/${WEBSITE_NAME}-error.log + + + + +# --- +# --- IPv6 +# --- + + + + ServerAdmin $WEBMASTER_EMAIL + + ServerName $WEBSITE_NAME + + RewriteEngine on + RewriteCond %{HTTPS} !=on + RewriteRule (.*) https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L] + + CustomLog ${APACHE_LOG_DIR}/${WEBSITE_NAME}-access.log combined + ErrorLog ${APACHE_LOG_DIR}/${WEBSITE_NAME}-error.log + + + + + + + ServerAdmin $WEBMASTER_EMAIL + + ServerName $WEBSITE_NAME + +EOF +if [[ $? -ne 0 ]]; then + _failed=true +fi + +if [[ "$PHP_TYPE" = "mod_php" ]]; then + + cat <> ${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf 2>> $log_file + ## - its allowed to overwrite by .htaccess + ## - + php_value error_reporting "E_ALL & ~E_NOTICE" + + ## - Overwriting by .htaccess NOT allowd + ## - + php_admin_value upload_tmp_dir "${WEBSITE_BASEDIR}/tmp/" + php_admin_flag log_errors on + php_admin_value error_log "${WEBSITE_BASEDIR}/logs/php_error.log" + php_admin_value session.save_path "${WEBSITE_BASEDIR}/sessions" + + DocumentRoot "${WEBSITE_BASEDIR}/htdocs/" +EOF + if [[ $? -ne 0 ]]; then + _failed=true + fi +elif [[ "$PHP_TYPE" = "fcgid" ]]; then + cat <> ${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf 2>> $log_file + DocumentRoot "${WEBSITE_BASEDIR}/htdocs/" + + Require all granted + FCGIWrapper ${WEBSITE_BASEDIR}/conf/fcgid .php + + SetHandler fcgid-script + + Options +ExecCGI + +EOF + if [[ $? -ne 0 ]]; then + _failed=true + fi +elif [[ "$PHP_TYPE" = "php_fpm" ]]; then + cat <> ${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf 2>> $log_file + DocumentRoot "${WEBSITE_BASEDIR}/htdocs/" + + + SetHandler "proxy:unix:/tmp/php-${php_latest_ver}-fpm.www.sock|fcgi://127.0.0.1" + + + + DirectoryIndex index.php index.html + +EOF + if [[ $? -ne 0 ]]; then + failed=true + fi +fi +cat <> ${APACHE_VHOST_DIR}/${WEBSITE_NAME}.conf 2>> $log_file + + SSLEngine on + + # - HTTP Strict Transport Security (HSTS) + # - + # - HSTS tells a browser that the website should only be accessed through + # - a secure connection. The HSTS header will be remembered by a standard + # compliant browser for max-age seconds. + # - + # - Remember this settings for 1 year + # - + Header always set Strict-Transport-Security "max-age=31536000" + + SSLCertificateFile ${APACHE_CERT_DIR}/$APACHE_SERVER_CERT + SSLCertificateKeyFile ${APACHE_CERT_DIR}/$APACHE_SERVER_KEY + $SSLCertificateChainFile + + CustomLog ${APACHE_LOG_DIR}/${WEBSITE_NAME}-access.log combined + ErrorLog ${APACHE_LOG_DIR}/${WEBSITE_NAME}-error.log + + +EOF +if [[ $? -ne 0 ]]; then + _failed=true +fi +if $_failed ; then + echo_failed + error "$(cat $log_file)" +else + echo_ok +fi + +if $APACHE_DEBIAN_INSTALLATION ; then + ## - add to /etc/apache2/ports.conf + ## - + ## - NameVirtualHost 46.4.73.217:80 + ## - NameVirtualHost [2a01:4f8:140:34c1::4]:80 + ## - Listen 46.4.73.217:80 + ## - Listen [2a01:4f8:140:34c1::4]:80 + ## - + ## - .. + ## - NameVirtualHost 46.4.73.217:443 + ## - NameVirtualHost [2a01:4f8:140:34c1::4]:443 + ## - Listen 46.4.73.217:443 + ## - Listen [2a01:4f8:140:34c1::4]:443 + ## - + ## - .. + #vim /etc/apache2/ports.conf + + + ## - enable site webmail.warenform.de + ## - + echononl "\tEnable ${WEBSITE_NAME}.conf" + a2ensite ${WEBSITE_NAME}.conf > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +fi + +echononl "\tCreate 'robots.txt'.." +cat < ${WEBSITE_BASEDIR}/htdocs/robots.txt 2> $log_file +User-agent: * +Disallow: / +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tRestart Apache Webservice.." +if $APACHE_DEBIAN_INSTALLATION ; then + /etc/init.d/apache2 reload > $log_file 2>&1 +else + /etc/init.d/apache2 restart > $log_file 2>&1 +fi +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +# - Install a cronjob for cleaning up tmp-directory +# - +if [[ "$PHP_TYPE" = "fcgid" ]] ; then + echononl "\tCreate cronjob for cleaning up tmp-directory.." + crontab -l > /tmp/tmp_crontab + if ! grep -q -E "find\s+${WEBSITE_BASEDIR}/tmp\s*-type\s*f" /tmp/tmp_crontab 2> /dev/null ; then + echo "" >> /tmp/tmp_crontab + echo "# - Cleanup tmp directory of the Rounfcube Webmailer" >> /tmp/tmp_crontab + echo "# -" >> /tmp/tmp_crontab + echo "23 3 * * * find $WEBSITE_BASEDIR/tmp -type f -mtime +1 -exec rm -f {} \;" >> /tmp/tmp_crontab + crontab /tmp/tmp_crontab + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + else + echo_skipped + fi + rm /tmp/tmp_crontab +fi + + +# - Logrotate logfiles from webmailer, locatet at $WEBSITE_BASEDIR/logs +# - +echononl "\tCreate logrotate entry.." +if [[ "$PHP_TYPE" = "fcgid" ]] ; then + cat < /etc/logrotate.d/roundcube 2> $log_file +$WEBSITE_BASEDIR/logs/errors +$WEBSITE_BASEDIR/logs/sql +$WEBSITE_BASEDIR/logs/sendmail +$WEBSITE_BASEDIR/logs/*.log { + daily + start 0 + rotate 7 + missingok + notifempty + compress + delaycompress + create 640 www-data www-data + copytruncate +} +EOF + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +elif [[ "$APACHE_LOG_DIR" =~ ${WEBSITE_BASEDIR} ]] ; then + cat < /etc/logrotate.d/roundcube 2> $log_file +$APACHE_LOG_DIR/*.log { + daily + start 0 + rotate 7 + missingok + notifempty + compress + delaycompress + create 640 www-data www-data + copytruncate +} +EOF + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + +echo -e "\n\n\t\033[37m\033[1mSetup Database '$DB_TYPE'..\033[m\n" + +# - Datenbank etstellen: +# - +# - MySQL/PostgreSQL Datenbank erstellen +# - +# - + +if [[ "$DB_TYPE" = "mysql" ]]; then + if ! mysql $MYSQL_CREDENTIALS -N -s -e \ + "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '$DB_NAME'" 2>> $log_file \ + | grep $DB_NAME >> $log_file 2>&1 ; then + database_exists=false + else + database_exists=true + fi +elif [[ "$DB_TYPE" = "pgsql" ]]; then + count=$(su - postgres -c "psql -q -A -t -l" | grep -c -e "^$DB_NAME") + if [[ $count -eq 0 ]];then + database_exists=false + else + database_exists=true + fi +else + fatal "Cannot detect database type (value of DB_TYPE is neither 'mysql' nor 'pgsql')" +fi + +_failed=false +echononl "\tCreate Database '$DB_NAME'" +if ! $database_exists ; then + if [[ "$DB_TYPE" = "mysql" ]]; then + echo -n " (MySQL).." + mysql -u$_mysql_rootuser -p$_mysql_rootpass -N -s -e \ + "CREATE DATABASE IF NOT EXISTS $DB_NAME CHARACTER SET utf8 COLLATE utf8_general_ci" + if [[ $? -ne 0 ]]; then + _failed=true + fi + mysql -u$_mysql_rootuser -p$_mysql_rootpass -N -s -e \ + "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS'" + if [[ $? -ne 0 ]]; then + _failed=true + fi + mysql -u$_mysql_rootuser -p$_mysql_rootpass -N -s -e "FLUSH PRIVILEGES" + if [[ $? -ne 0 ]]; then + _failed=true + fi + if ! $_failed ; then + echo_ok + else + echo_failed + fi + elif [[ "$DB_TYPE" = "pgsql" ]]; then + echo -n " (PostgreSQL).." + echo "CREATE ROLE $DB_USER WITH LOGIN NOCREATEDB NOCREATEROLE NOSUPERUSER ENCRYPTED PASSWORD '$DB_PASS'" \ + | su - postgres -c "psql" > /dev/null + if [[ $? -ne 0 ]]; then + _failed=true + fi + su - postgres -c "createdb -E utf8 -O $DB_USER $DB_NAME" + if [[ $? -ne 0 ]]; then + _failed=true + fi + if ! $_failed ; then + echo_ok + else + echo_failed + fi + fi +else + echo_skipped +fi + +echononl "\tBackup existing Database '$DB_NAME'" +if $database_exists ; then + if [[ "$DB_TYPE" = "mysql" ]]; then + echo -n " (MySQL).." + mysqldump -u$_mysql_rootuser -p$_mysql_rootpass --opt $DB_NAME > ${WEBSITE_BASEDIR}/${DB_NAME}.$backup_date 2> $log_file + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + elif [[ "$DB_TYPE" = "pgsql" ]]; then + echo -n " (PostgreSQL).." + su - postgres -c "pg_dump -c $DB_NAME" > ${WEBSITE_BASEDIR}/${DB_NAME}.$backup_date.sql 2> $log_file + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + fi +else + echo_skipped +fi + + +info "Now browse to the intaller site and continue installation.\n$(cat <>$WEBSITE_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/config.inc.php 2> $log_file + +// ================================== +// Added after basic installation +// ================================== + +// This key is used for encrypting purposes, like storing of imap password +// in the session. For historical reasons it's called DES_key, but it's used +// with any configured cipher_method (see below). +\$config['des_key'] = '$_des_key'; + +// ---------------------------------- +// SYSTEM +// ---------------------------------- + +// THIS OPTION WILL ALLOW THE INSTALLER TO RUN AND CAN EXPOSE SENSITIVE CONFIG DATA. +// ONLY ENABLE IT IF YOU'RE REALLY SURE WHAT YOU'RE DOING! +\$config['enable_installer'] = false; + +// Allow browser-autocompletion on login form. +// 0 - disabled, 1 - username and host only, 2 - username, host, password +\$config['login_autocomplete'] = 1; + + +// ---------------------------------- +// USER PREFERENCES +// ---------------------------------- + +// Clear Trash on logout +\$config['logout_purge'] = true; + +// 'Delete always' +// This setting reflects if mail should be always deleted +// when moving to Trash fails. This is necessary in some setups +// when user is over quota and Trash is included in the quota. +\$config['delete_always'] = true; + +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echo -e "\n\n\t\033[37m\033[1mEnable Spellcheccking..\033[m\n" + +echononl "\tInstall needed debian packages.." +needed_packages_spell="" +_needed_packages_spell=" + aspell-en + aspell-de + aspell-da + aspell-es + aspell-fr + aspell-it" +for _pkg in $_needed_packages_spell ; do + if aptitude search "$_pkg" | grep " $_pkg " | grep -e "^i" > /dev/null 2>&1 ; then + continue + else + needed_packages_spell="$needed_packages_spell $_pkg" + fi +done +if [[ -n "$needed_packages_spell" ]]; then + DEBIAN_FRONTEND=noninteractive apt-get -y install $needed_packages_spell > /dev/null 2> "$log_file" + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +echononl "\tAdjust Roundcube Configuration for specclchecking" +cat <>$WEBSITE_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/config.inc.php 2> $log_file + +// ---------------------------------- +// USER INTERFACE +// ---------------------------------- + +// Make use of the built-in spell checker. It is based on GoogieSpell. +// Since Google only accepts connections over https your PHP installatation +// requires to be compiled with Open SSL support +\$config['enable_spellcheck'] = true; + +// Enables spellchecker exceptions dictionary. +// Setting it to 'shared' will make the dictionary shared by all users. +\$config['spellcheck_dictionary'] = false; + +// Set the spell checking engine. Possible values: +// - 'googie' - the default +// - 'pspell' - requires the PHP Pspell module and aspell installed +// - 'enchant' - requires the PHP Enchant module +// - 'atd' - install your own After the Deadline server or check with the people at http://www.afterthedeadline.com before using their API +// Since Google shut down their public spell checking service, you need to +// connect to a Nox Spell Server when using 'googie' here. Therefore specify the 'spellcheck_uri' +\$config['spellcheck_engine'] = 'pspell'; + +// For locally installed Nox Spell Server or After the Deadline services, +// please specify the URI to call it. +// Get Nox Spell Server from http://orangoo.com/labs/?page_id=72 or +// the After the Deadline package from http://www.afterthedeadline.com. +// Leave empty to use the public API of service.afterthedeadline.com +\$config['spellcheck_uri'] = ''; + +// These languages can be selected for spell checking. +// Configure as a PHP style hash array: array('en'=>'English', 'de'=>'Deutsch'); +// Leave empty for default set of available language. +// +// Take care tha dictionaries for aspell ar installed ! +// for debian: +// apt-get install aspell-en aspell-de aspell-da aspell-es aspell-fr aspell-it +\$config['spellcheck_languages'] = array( + 'en' => 'English', + 'de' => 'Deutsch', + 'da' => 'Dansk', + 'fr' => 'Français', + 'it' => 'Italiano', + 'es' => 'Español', +); +// Makes that words with all letters capitalized will be ignored (e.g. GOOGLE) +\$config['spellcheck_ignore_caps'] = true; + +// Makes that words with numbers will be ignored (e.g. g00gle) +\$config['spellcheck_ignore_nums'] = true; + +// Makes that words with symbols will be ignored (e.g. g@@gle) +\$config['spellcheck_ignore_syms'] = true; + +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + + + +echo -e "\n\n\t\033[37m\033[1mAdd/Configure Plugins..\033[m" +declare -a add_plugin_arr + + +# - acl +# - +if $INCLUDE_ACL_PLUGIN ; then + _plugin="acl" + add_plugin_arr+=("$_plugin") + echo -e "\n\t\033[32mPlugin '$_plugin'\033[m" + echononl "\tCopy default config file to 'config.inc.php'.." + cp -a ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php.dist \ + ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php > $log_file 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + + echononl "\tActivate advanced mode.." + _key="acl_advanced_mode" + _val="true" + perl -i -n -p -e "s#(^\s*\\\$config\['$_key'\].*)#//\!\1\n\\\$config['$_key'] = $_val;#" \ + ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php > $log_file 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + + echo -e "\tNothing more to do here. Plugin '$_plugin' will be added to array plugins later.." + +fi + + +# - archive +# - +_plugin="archive" +add_plugin_arr+=("$_plugin") +echo -e "\n\t\033[32mPlugin '$_plugin'\033[m" +echo -e "\tNothing to do here. Plugin '$_plugin' will be added to array plugins later.." + + +# - contextmenu +# - +_plugin="contextmenu" +add_plugin_arr+=("$_plugin") +echo -e "\n\t\033[32mPlugin '$_plugin'\033[m" +echononl "\tDownload Pluging '$_plugin'.." +wget -O ${WEBSITE_BASEDIR}/Roundcube-Plugin-Context-Menu-master.zip \ + https://github.com/JohnDoh/Roundcube-Plugin-Context-Menu/archive/master.zip > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tUnpack archiv into Plugin Folder" +unzip -d ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/ \ + ${WEBSITE_BASEDIR}/Roundcube-Plugin-Context-Menu-master.zip > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi +echononl "\tCeate Symlink '$_pligin' in plugin folder.." +ln -s Roundcube-Plugin-Context-Menu-master \ + ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin} > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echo -e "\tNothing more to do here. Plugin '$_plugin' will be added to array plugins later.." + + +# - jqueryui +# - +_plugin="jqueryui" +add_plugin_arr+=("$_plugin") +echo -e "\n\t\033[32mPlugin '$_plugin'\033[m" +echononl "\tCopy default config file to 'config.inc.php'.." +cp -a ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php.dist \ + ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echo -e "\tNothing more to do here. Plugin '$_plugin' will be added to array plugins later.." + + +# - login_lang +# - +_plugin="login_lang" +add_plugin_arr+=("$_plugin") +echo -e "\n\t\033[32mPlugin '$_plugin'\033[m" +echononl "\tDownload Pluging '$_plugin' (roundcube-login-language-master)" +wget -O ${WEBSITE_BASEDIR}/roundcube-login-language-master.zip \ + https://github.com/hassansin/roundcube-login-language/archive/master.zip > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tUnpack archiv into Plugin Folder" +unzip -d ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/ \ + ${WEBSITE_BASEDIR}/roundcube-login-language-master.zip > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tCeate Symlink '$_pligin' in plugin folder.." +ln -s roundcube-login-language-master \ + ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin} > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tCopy default config file to 'config.inc.php'.." +cp -a ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php.dist \ + ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tChange default language to 'de_DE'" +_key="language_dropdown_selected" +_val="'de_DE'" +perl -i -n -p -e "s#(^\s*\\\$config\['$_key'\].*)#//\!\1\n\\\$config['$_key'] = $_val;#" \ + ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echo -e "\tNothing more to do here. Plugin '$_plugin' will be added to array plugins later.." + + +# - managesieve +# - +_plugin="managesieve" +add_plugin_arr+=("$_plugin") +echo -e "\n\t\033[32mPlugin '$_plugin'\033[m" +echononl "\tCopy default config file to 'config.inc.php'.." +cp -a ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php.dist \ + ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +_key=managesieve_port +_val="4190" +echononl "\tChange '$_key' to $_val" +perl -i -n -p -e "s#(^\s*\\\$config\['$_key'\].*)#//\!\1\n\\\$config['$_key'] = $_val;#" \ + ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +_key=managesieve_default +_val="'/usr/local/dovecot/etc/dovecot/sieve/move-spam.sieve'" +echononl "\tChange '$_key' to $_val" +perl -i -n -p -e "s#(^\s*\\\$config\['$_key'\].*)#//\!\1\n\\\$config['$_key'] = $_val;#" \ + ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +_key="managesieve_disabled_extensions" +_val="array('vacation')" +echononl "\tChange '$_key' to $_val" +perl -i -n -p -e "s#(^\s*\\\$config\['$_key'\].*)#//\!\1\n\\\$config['$_key'] = $_val;#" \ + ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echo -e "\tNothing more to do here. Plugin '$_plugin' will be added to array plugins later.." + + +# - markasjunk2 +# - +_plugin="markasjunk2" +add_plugin_arr+=("$_plugin") +echo -e "\n\t\033[32mPlugin '$_plugin'\033[m" +echononl "\tDownload Pluging '$_plugin'.." +wget -O ${WEBSITE_BASEDIR}/Roundcube-Plugin-Mark-as-Junk-2-master.zip \ + https://github.com/JohnDoh/Roundcube-Plugin-Mark-as-Junk-2/archive/master.zip > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tUnpack archiv into Plugin Folder" +unzip -d ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/ \ + ${WEBSITE_BASEDIR}/Roundcube-Plugin-Mark-as-Junk-2-master > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi +echononl "\tCeate Symlink '$_pligin' in plugin folder.." +ln -s Roundcube-Plugin-Mark-as-Junk-2-master \ + ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin} > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echo -e "\tNothing more to do here. Plugin '$_plugin' will be added to array plugins later.." + + +# - password +# - +_plugin="password" +add_plugin_arr+=("$_plugin") +echo -e "\n\t\033[32mPlugin '$_plugin'\033[m" +echononl "\tCopy default config file to 'config.inc.php'.." +cp -a ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php.dist \ + ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +_key="password_driver" +_val="'sql'" +echononl "\tChange '$_key' to $_val" +perl -i -n -p -e "s#(^\s*\\\$config\['$_key'\].*)#//\!\1\n\\\$config['$_key'] = $_val;#" \ + ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +_key="password_confirm_current" +_val="$PW_CONFIRM_CURRENT" +echononl "\tChange '$_key' to $_val" +perl -i -n -p -e "s#(^\s*\\\$config\['$_key'\].*)#//\!\1\n\\\$config['$_key'] = $_val;#" \ + ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +_key="password_minimum_length" +_val="$PW_MIN_LENGTH" +echononl "\tChange '$_key' to $_val" +perl -i -n -p -e "s#(^\s*\\\$config\['$_key'\].*)#//\!\1\n\\\$config['$_key'] = $_val;#" \ + ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +_key="password_require_nonalpha" +_val="$PW_REQUIRE_NONALPHA" +echononl "\tChange '$_key' to $_val" +perl -i -n -p -e "s#(^\s*\\\$config\['$_key'\].*)#//\!\1\n\\\$config['$_key'] = $_val;#" \ + ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +_key="password_algorithm" +_val="'$PW_PASSWD_ALGO'" +echononl "\tChange '$_key' to $_val" +perl -i -n -p -e "s#(^\s*\\\$config\['$_key'\].*)#//\!\1\n\\\$config['$_key'] = $_val;#" \ + ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +_key="password_algorithm_prefix" +_val="'$PW_PASSWD_ALGO_PREFIX'" +echononl "\tChange '$_key' to $_val" +perl -i -n -p -e "s#(^\s*\\\$config\['$_key'\].*)#//\!\1\n\\\$config['$_key'] = $_val;#" \ + ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +_key="password_dovecotpw" +_val="'$PW_DOVEADM_PW'" +echononl "\tChange '$_key' to $_val" +perl -i -n -p -e "s#(^\s*\\\$config\['$_key'\].*)#//\!\1\n\\\$config['$_key'] = $_val;#" \ + ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +_key="password_dovecotpw_method" +_val="'$PW_DOVECOT_PW_METHOD'" +echononl "\tChange '$_key' to $_val" +perl -i -n -p -e "s#(^\s*\\\$config\['$_key'\].*)#//\!\1\n\\\$config['$_key'] = $_val;#" \ + ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +_key="password_db_dsn" +_val="'${POSTFIX_DB_TYPE}://${POSTFIX_DB_USER}:${POSTFIX_DB_PASSWD}\@${POSTFIX_DB_HOST}/${POSTFIX_DB_NAME}'" +echononl "\tChange '$_key' to $_val" +perl -i -n -p -e "s#(^\s*\\\$config\['$_key'\].*)#//\!\1\n\\\$config['$_key'] = $_val;#" \ + ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +_key="password_query" +_val="'$PW_DB_UPDATE_STRING'" +echononl "\tChange '$_key' to $_val" +perl -i -n -p -e "s#(^\s*\\\$config\['$_key'\].*)#//\!\1\n\\\$config['$_key'] = $_val;#" \ + ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echo -e "\tNothing more to do here. Plugin '$_plugin' will be added to array plugins later.." + + +# - vacation +# - +_plugin="vacation" +add_plugin_arr+=("$_plugin") + +_config_file="${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php" +_backup_file="${_config_file}.$backup_date" + +echo -e "\n\t\033[32mPlugin '$_plugin'\033[m" +echononl "\tDownload Pluging '$_plugin'.." +wget -O ${WEBSITE_BASEDIR}/rc-vacation-master.zip \ + https://github.com/bhuisgen/rc-vacation/archive/master.zip > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tUnpack archiv into Plugin Folder" +unzip -d ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/ \ + ${WEBSITE_BASEDIR}/rc-vacation-master.zip > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tCeate Symlink '$_pligin' in plugin folder.." +ln -s rc-vacation-master \ + ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin} > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tCopy default config file to 'config.inc.php'.." +cp -a ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/plugins/${_plugin}/config.inc.php.dist \ + $_config_file > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +_key="vacation_gui_vacationdate" +_val="TRUE" +echononl "\tChange '$_key' to $_val" +perl -i -n -p -e "s#(^\s*\\\$(rcmail_)?config\['$_key'\].*)#//\!\1\n\\\$config['$_key'] = $_val;#" \ + $_config_file > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +_key="vacation_subject_default" +_val="'Re: \\\$SUBJECT'" +echononl "\tChange '$_key' to $_val" +perl -i -n -p -e "s#(^\s*\\\$(rcmail_)?config\['$_key'\].*)#//\!\1\n\\\$config['$_key'] = $_val;#" \ + $_config_file > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +_key="vacation_gui_vacationforwarder" +_val="$VAC_GUI_FORWARDER" +echononl "\tchange '$_key' to $_val" +perl -i -n -p -e "s#(^\s*\\\$(rcmail_)?config\['$_key'\].*)#//\!\1\n\\\$config['$_key'] = $_val;#" \ + $_config_file > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +_key="vacation_dateformat" +_val="'Y-m-d'" +echononl "\tChange '$_key' to $_val" +perl -i -n -p -e "s#(^\s*\\\$(rcmail_)?config\['$_key'\].*)#//\!\1\n\\\$config['$_key'] = $_val;#" \ + $_config_file > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +_key="vacation_jquery_calendar" +_val="TRUE" +echononl "\tChange '$_key' to $_val" +perl -i -n -p -e "s#(^\s*\\\$(rcmail_)?config\['$_key'\].*)#//\!\1\n\\\$config['$_key'] = $_val;#" \ + $_config_file > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +_key="vacation_jquery_dateformat" +_val="'yy-m-d'" +echononl "\tChange '$_key' to $_val" +perl -i -n -p -e "s#(^\s*\\\$(rcmail_)?config\['$_key'\].*)#//\!\1\n\\\$config['$_key'] = $_val;#" \ + $_config_file > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +_key="vacation_forwarder_multiple" +_val="'FALSE'" +echononl "\tChange '$_key' to $_val" +perl -i -n -p -e "s#(^\s*\\\$(rcmail_)?config\['$_key'\].*)#//\!\1\n\\\$config['$_key'] = $_val;#" \ + $_config_file > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +_key="vacation_forwarder_separator" +_val="','" +echononl "\tChange '$_key' to $_val" +perl -i -n -p -e "s#(^\s*\\\$(rcmail_)?config\['$_key'\].*)#//\!\1\n\\\$config['$_key'] = $_val;#" \ + $_config_file > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +_key="vacation_driver" +_val="'sql'" +echononl "\tChange '$_key' to $_val" +perl -i -n -p -e "s#(^\s*\\\$(rcmail_)?config\['$_key'\].*)#//\!\1\n\\\$config['$_key'] = $_val;#" \ + $_config_file > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + + +_key="vacation_sql_dsn" +_val="'${POSTFIX_DB_TYPE}://${POSTFIX_DB_USER}:${POSTFIX_DB_PASSWD}@${POSTFIX_DB_HOST}/${POSTFIX_DB_NAME}'" +echononl "\tChange '$_key' to $_val" + +failed=false +mv $_config_file $_backup_file > $log_file 2>&1 +if [[ $? -ne 0 ]]; then + _failed=true +fi +_found=false +_found_comment=false +while IFS='' read -r _line || [[ -n $_line ]] ; do + if echo "$_line" | grep -i -E "^\s*\\\$(rcmail_)?config\['$_key'\]\s*=\s*'[^']*'\s*;" > /dev/null 2>&1 ; then + echo '//!'"$_line" >> $_config_file + echo "\$config['$_key'] = $_val;" >> $_config_file + continue + elif echo "$_line" | grep -i -E "^\s*\\\$(rcmail_)?config\['$_key'\]" > /dev/null 2>&1 ; then + _found=true + echo "/*" >> $_config_file + echo "$_line" >> $_config_file + continue + fi + + if $_found && echo "$_line" | grep -i -E "^\s*/\*.*" > /dev/null 2>&1 ; then + _found_comment=true + fi + + if $_found_comment ; then + echo "$_line" >> $_config_file + if echo "$_line" | grep -i -E "\*/\s*$" > /dev/null 2>&1 ; then + echo "/*" >> $_config_file + _found_comment=false + fi + continue + fi + + if $_found && echo "$_line" | grep -i -E "^\s*[^(//|/\*)]+'.+';$" > /dev/null 2>&1 ; then + echo "$_line" >> $_config_file + echo "*/" >> $_config_file + echo "\$config['$_key'] = $_val;" >> $_config_file + _found=false + continue + fi + + echo "$_line" >> $_config_file + +done < "$_backup_file" +if [[ $? -ne 0 ]]; then + _failed=true +fi +if $_failed ; then + echo_failed +else + echo_ok +fi + + +failed=false +mv $_config_file $_backup_file > $log_file 2>&1 +if [[ $? -ne 0 ]]; then + _failed=true +fi +_key="vacation_sql_read" +echononl "\tChange '$_key'.." +_found=false +_found_comment=false +while IFS='' read -r _line || [[ -n $_line ]] ; do + if echo "$_line" | grep -i -E "^\s*\\\$(rcmail_)?config\['$_key'\]\s*=\s*array\s*\([^\)]*\)\s*;" > /dev/null 2>&1 ; then + echo '//!'"$_line" >> $_config_file + echo "\$config['$_key'] = array($;" >> $_config_file + continue + elif echo "$_line" | grep -i -E "^\s*\\\$(rcmail_)?config\['$_key'\]" > /dev/null 2>&1 ; then + _found=true + echo "/*" >> $_config_file + echo "$_line" >> $_config_file + continue + fi + + if $_found && echo "$_line" | grep -i -E "^\s*/\*.*" > /dev/null 2>&1 ; then + _found_comment=true + fi + + if $_found_comment ; then + echo "$_line" >> $_config_file + if echo "$_line" | grep -i -E "\*/\s*$" > /dev/null 2>&1 ; then + echo "/*" >> $_config_file + _found_comment=false + fi + continue + fi + + if $_found && echo "$_line" | grep -i -E "^\s*[^(//|/\*)]+\)\s*;$" > /dev/null 2>&1 ; then + echo "$_line" >> $_config_file + echo "*/" >> $_config_file + echo "\$config['${_key}'] = array(" >> $_config_file + + if [[ "$POSTFIX_DB_TYPE" = "pgsql" ]]; then + cat <> $_config_file 2>> $log_file + "SELECT + subject AS vacation_subject, + body AS vacation_message, + date(activefrom) AS vacation_start, + date(activeuntil) AS vacation_end, + CASE WHEN vacation.active = TRUE THEN true ELSE false END AS vacation_enable, + udf_forwarders_out(%username,'${AUTOREPLY_HOSTNAME}',',') AS vacation_forwarder + FROM vacation,alias + WHERE email=%username AND address=%username AND vacation.domain=%email_domain;" +EOF + else + cat <> $_config_file 2>> $log_file + "SELECT subject AS vacation_subject, body AS vacation_message," . + "UNIX_TIMESTAMP(activefrom) AS vacation_start," . + "UNIX_TIMESTAMP(activeuntil) AS vacation_end," . + "vacation.active AS vacation_enable," . + "FORWARDERS_OUT(%username,'${AUTOREPLY_HOSTNAME}',',') AS vacation_forwarder " . + "FROM vacation,alias " . + "WHERE email=%username AND address=%username AND vacation.domain=%email_domain;" +EOF + fi + echo ");" >> $_config_file + _found=false + continue + fi + + echo "$_line" >> $_config_file +done < "$_backup_file" +if [[ $? -ne 0 ]]; then + _failed=true +fi +if $_failed ; then + echo_failed +else + echo_ok +fi + +failed=false +mv $_config_file $_backup_file > $log_file 2>&1 +if [[ $? -ne 0 ]]; then + _failed=true +fi +_key="vacation_sql_write" +echononl "\tChange '$_key'.." +_found=false +_found_comment=false +while IFS='' read -r _line || [[ -n $_line ]] ; do + if echo "$_line" | grep -i -E "^\s*\\\$(rcmail_)?config\['$_key'\]\s*=\s*array\s*\([^\)]*\)\s*;" > /dev/null 2>&1 ; then + echo '//!'"$_line" >> $_config_file + echo "\$config['$_key'] = array($;" >> $_config_file + continue + elif echo "$_line" | grep -i -E "^\s*\\\$(rcmail_)?config\['$_key'\]" > /dev/null 2>&1 ; then + _found=true + echo "/*" >> $_config_file + echo "$_line" >> $_config_file + continue + fi + + if $_found && echo "$_line" | grep -i -E "^\s*/\*.*" > /dev/null 2>&1 ; then + _found_comment=true + fi + + if $_found_comment ; then + echo "$_line" >> $_config_file + if echo "$_line" | grep -i -E "\*/\s*$" > /dev/null 2>&1 ; then + echo "/*" >> $_config_file + _found_comment=false + fi + continue + fi + + if $_found && echo "$_line" | grep -i -E "^\s*[^(//|/\*)]+\)\s*;$" > /dev/null 2>&1 ; then + echo "$_line" >> $_config_file + echo "*/" >> $_config_file + echo "\$config['${_key}'] = array(" >> $_config_file + + if [[ "$POSTFIX_DB_TYPE" = "pgsql" ]]; then + if $VAC_GUI_FORWARDER ; then + + # - Database: PostgreSQL + # - Allow vacation forwarder: false + # - + cat <> $_config_file 2>> $log_file + + // Clean up vacation + "DELETE FROM vacation WHERE email=%email AND domain=%email_domain;", + + // Cleanup notifications + "DELETE from vacation_notification WHERE on_vacation=%email;", + + // Save entries to table vacation + "INSERT INTO vacation (email,domain,subject,body,activefrom,activeuntil,interval_time,created,active) " . + "VALUES (%email,%email_domain,%vacation_subject,%vacation_message," . + "to_timestamp(%vacation_start - extract(timezone from current_timestamp))," . + "to_timestamp(%vacation_end + 86399 - extract(timezone from current_timestamp))," . + "86400,NOW(),udf_set_active(%vacation_enable));", + + // Update table alias + "UPDATE alias SET goto = udf_forwarders_in(udf_forwarders_out(%email,'${AUTOREPLY_HOSTNAME}',',')," . + "%email,'${AUTOREPLY_HOSTNAME}',',',udf_set_active(%vacation_enable))" . + ", modified = NOW() " . + " WHERE address = %email" +EOF + else + + # - Database: PostgreSQL + # - Allow vacation forwarder: true + # - + cat <> $_config_file 2>> $log_file + + // Clean up vacation + "DELETE FROM vacation WHERE email=%email AND domain=%email_domain;", + + // Cleanup notifications + "DELETE from vacation_notification WHERE on_vacation=%email;", + + // Save entries to table vacation + "INSERT INTO vacation (email,domain,subject,body,activefrom,activeuntil,interval_time,created,active) " . + "VALUES (%email,%email_domain,%vacation_subject,%vacation_message," . + "to_timestamp(%vacation_start - extract(timezone from current_timestamp))," . + "to_timestamp(%vacation_end + 86399 - extract(timezone from current_timestamp))," . + "86400,NOW(),udf_set_active(%vacation_enable));", + + // Update table alias + "UPDATE alias SET goto = udf_forwarders_in(%vacation_forwarder," . + "%email,'${AUTOREPLY_HOSTNAME}',',',udf_set_active(%vacation_enable))" . + ", modified = NOW() " . + " WHERE address = %email" +EOF + fi + else + if $VAC_GUI_FORWARDER ; then + + # - Database: MySQL + # - Allow vacation forwarder: FALSE + # - + cat <> $_config_file 2>> $log_file + + // Clean up vacation + "DELETE FROM vacation WHERE email=%email AND domain=%email_domain;", + + // Cleanup notifications + "DELETE from vacation_notification WHERE on_vacation=%email;", + + // Save entries to table vacation + "INSERT INTO vacation (email,domain,subject,body,activefrom,activeuntil,interval_time,created,active) " . + "VALUES (%email,%email_domain,%vacation_subject,%vacation_message," . + "CONCAT(DATE(FROM_UNIXTIME(%vacation_start)), ' 00:00:00')," . + "CONCAT(DATE(FROM_UNIXTIME(%vacation_end)), ' 23:59:59')," . + "86400,NOW(),%vacation_enable);", + + // Update table alias + "UPDATE alias SET goto = FORWARDERS_IN(FORWARDERS_OUT(%email,'${AUTOREPLY_HOSTNAME}',',')," . + "%email,'${AUTOREPLY_HOSTNAME}',',',%vacation_enable)" . + ", modified = NOW() " . + " WHERE address = %email" +EOF + else + + # - Database: MySQL + # - Allow vacation forwarder: TRUE + # - + cat <> $_config_file 2>> $log_file + + // Clean up vacation + "DELETE FROM vacation WHERE email=%email AND domain=%email_domain;", + + // Cleanup notifications + "DELETE from vacation_notification WHERE on_vacation=%email;", + + // Save entries to table vacation + "INSERT INTO vacation (email,domain,subject,body,activefrom,activeuntil,interval_time,created,active) " . + "VALUES (%email,%email_domain,%vacation_subject,%vacation_message," . + "CONCAT(DATE(FROM_UNIXTIME(%vacation_start)), ' 00:00:00')," . + "CONCAT(DATE(FROM_UNIXTIME(%vacation_end)), ' 23:59:59')," . + "86400,NOW(),%vacation_enable);", + + // Update table alias + "UPDATE alias SET goto = FORWARDERS_IN(%vacation_forwarder," . + "%email,'${AUTOREPLY_HOSTNAME}',',',%vacation_enable)" . + ", modified = NOW() " . + " WHERE address = %email" +EOF + fi + fi + echo ");" >> $_config_file + _found=false + continue + fi + + echo "$_line" >> $_config_file +done < "$_backup_file" +if [[ $? -ne 0 ]]; then + _failed=true +fi +if $_failed ; then + echo_failed +else + echo_ok +fi + +if [[ "$POSTFIX_DB_TYPE" = 'pgsql' ]] ; then + echononl "\tCreate postfix language plpgsql" + _pgpsql_exists=$(su - postgres -c "psql -t -c \"SELECT EXISTS ( SELECT 1 FROM pg_language WHERE lanname = 'plpgsql');\"") + if [[ "$_pgpsql_exists" =~ t ]]; then + echo_skipped + else + su - postgres -c "psql -t -c \"CREATE LANGUAGE plpgsql;\"" > $log_file 2>&1 + if [[ $? -ne 0 ]] ; then + echo_failed + erro $(cat $log_file) + else + echo_ok + fi + fi + + + # - Create postfix trigger function udf_forwarders_out + # - + _trigger_function="udf_forwarders_out" + echononl "\tCreate postfix trigger function $_trigger_function" + if [[ -n "$(su - postgres -c"psql postfix -t -c \"\\df $_trigger_function\"" | awk '{print$3}')" ]]; then + echo_skipped + else + + _psql_trigger_file="$(mktemp)" + echo "" > $log_file + echo "cat < \$_psql_trigger_file" >> $log_file + echo ".." >> $log_file + echo "EOF" >> $log_file + cat < $_psql_trigger_file 2>> $log_file +CREATE FUNCTION udf_forwarders_out(email_str text, vacation_domain text, list_seperator character) RETURNS text + LANGUAGE plpgsql + AS \$\$ + DECLARE + forward_str text; + local_email_part TEXT; + domain_email_part TEXT; + BEGIN + + -- get list of forwarders + -- + SELECT goto INTO forward_str FROM alias WHERE address=email_str; + + -- entferne mailbox emailadresse + -- + forward_str = replace(forward_str, email_str, '' ); + + -- entferne vacation adresse + -- + local_email_part = substring(email_str, 1, position('@' in email_str) - 1); + domain_email_part = substring(email_str, position('@' in email_str) + 1 ); + forward_str = replace(forward_str, local_email_part || '#' || domain_email_part || '@' || vacation_domain, ''); + + -- enferne doppelte seperatorzeichen + -- + WHILE position( list_seperator || list_seperator in forward_str ) > 0 LOOP + forward_str = replace(forward_str, list_seperator || list_seperator , ''); + END LOOP; + + -- entferne erstes zeichen wenn es das seperatorzeichen ist + -- + IF substring(forward_str,1,1) = list_seperator THEN + forward_str = substring(forward_str from 2); + END IF; + + + -- entferne letztes zeichen wenn es das seperatorzeichen ist + -- + IF substring(forward_str from char_length(forward_str)) = list_seperator THEN + forward_str = substring(forward_str, 1, char_length(forward_str) - 1); + END IF; + + + -- forward_str = substring(forward_str from char_length(forward_str)); + + RETURN forward_str; + END; + \$\$; +EOF + if [[ $? -ne 0 ]]; then + _failed=true + fi + + _pgppass_back_file="~/.pgpass.$backup_date" + _pgpass_was_present=false + if [[ -f "~/.pgpass" ]]; then + _pgpass_was_present=true + echo "" >> $log_file + echo "mv \"~/.pgpass\" \"$_pgppass_back_file\"" >> $log_file + mv "~/.pgpass" "$_pgppass_back_file" >> $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + fi + fi + + echo "" >> $log_file + echo "echo \"${POSTFIX_DB_HOST}:5432:${POSTFIX_DB_NAME}:${POSTFIX_DB_USER}:${POSTFIX_DB_PASSWD}\" > ~/.pgpass" >> $log_file 2>> $log_file + echo "${POSTFIX_DB_HOST}:5432:${POSTFIX_DB_NAME}:${POSTFIX_DB_USER}:${POSTFIX_DB_PASSWD}" > ~/.pgpass + if [[ $? -ne 0 ]]; then + _failed=true + fi + + echo "" >> $log_file + echo "psql -w -U $POSTFIX_DB_USER $POSTFIX_DB_NAME < $_psql_trigger_file" >> $log_file + psql -w -U $POSTFIX_DB_USER $POSTFIX_DB_NAME < $_psql_trigger_file >> $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + fi + + echo "" >> $log_file + echo "rm $_psql_trigger_file" >> $log_file + rm $_psql_trigger_file >> $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + fi + + if $_pgpass_was_present ; then + echo "" >> $log_file + echo "mv \"$_pgppass_back_file\" \"~/.pgpass\"" >> $log_file + mv \"$_pgppass_back_file\" \"~/.pgpass\" >> $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + fi + fi + + if $_failed ; then + echo_failed + erro $(cat $log_file) + else + echo_ok + fi + fi + + + # - Create postfix trigger function udf_set_active + # - + _trigger_function="udf_set_active" + echononl "\tCreate postfix trigger function $_trigger_function" + if [[ -n "$(su - postgres -c"psql postfix -t -c \"\\df $_trigger_function\"" | awk '{print$3}')" ]]; then + echo_skipped + else + + _psql_trigger_file="$(mktemp)" + echo "" > $log_file + echo "cat < \$_psql_trigger_file" >> $log_file + echo ".." >> $log_file + echo "EOF" >> $log_file + cat < $_psql_trigger_file 2>> $log_file +CREATE FUNCTION udf_set_active(vacation_enable text) RETURNS boolean + LANGUAGE plpgsql + AS \$\$ + DECLARE + return_val boolean; + BEGIN + + return_val = 't'; + + IF vacation_enable = '' THEN + return_val = 'f'; + END IF; + + IF vacation_enable = '0' THEN + return_val = 'f'; + END IF; + + IF lower(vacation_enable) = 'false' THEN + return_val = 'f'; + END IF; + + RETURN return_val; + END; + \$\$; +EOF + if [[ $? -ne 0 ]]; then + _failed=true + fi + + _pgppass_back_file="~/.pgpass.$backup_date" + _pgpass_was_present=false + if [[ -f "~/.pgpass" ]]; then + _pgpass_was_present=true + echo "" >> $log_file + echo "mv \"~/.pgpass\" \"$_pgppass_back_file\"" >> $log_file + mv "~/.pgpass" "$_pgppass_back_file" >> $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + fi + fi + + echo "" >> $log_file + echo "echo \"${POSTFIX_DB_HOST}:5432:${POSTFIX_DB_NAME}:${POSTFIX_DB_USER}:${POSTFIX_DB_PASSWD}\" > ~/.pgpass" >> $log_file 2>> $log_file + echo "${POSTFIX_DB_HOST}:5432:${POSTFIX_DB_NAME}:${POSTFIX_DB_USER}:${POSTFIX_DB_PASSWD}" > ~/.pgpass + if [[ $? -ne 0 ]]; then + _failed=true + fi + + echo "" >> $log_file + echo "psql -w -U $POSTFIX_DB_USER $POSTFIX_DB_NAME < $_psql_trigger_file" >> $log_file + psql -w -U $POSTFIX_DB_USER $POSTFIX_DB_NAME < $_psql_trigger_file >> $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + fi + + echo "" >> $log_file + echo "rm $_psql_trigger_file" >> $log_file + rm $_psql_trigger_file >> $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + fi + + if $_pgpass_was_present ; then + echo "" >> $log_file + echo "mv \"$_pgppass_back_file\" \"~/.pgpass\"" >> $log_file + mv \"$_pgppass_back_file\" \"~/.pgpass\" >> $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + fi + fi + + if $_failed ; then + echo_failed + erro $(cat $log_file) + else + echo_ok + fi + fi + + + # - Create postfix trigger function udf_forwarders_in + # - + _trigger_function="udf_forwarders_in" + echononl "\tCreate postfix trigger function $_trigger_function" + if [[ -n "$(su - postgres -c"psql postfix -t -c \"\\df $_trigger_function\"" | awk '{print$3}')" ]]; then + echo_skipped + else + + _psql_trigger_file="$(mktemp)" + echo "" > $log_file + echo "cat < \$_psql_trigger_file" >> $log_file + echo ".." >> $log_file + echo "EOF" >> $log_file + cat < $_psql_trigger_file 2>> $log_file +CREATE FUNCTION udf_forwarders_in(forewarders_str text, email_str text, vacation_domain text, list_seperator character, vacation_enable boolean) RETURNS text + LANGUAGE plpgsql + AS \$\$ + DECLARE + return_str text; + local_email_part TEXT; + domain_email_part TEXT; + BEGIN + + return_str = email_str; + + IF vacation_enable THEN + local_email_part = substring(email_str, 1, position('@' in email_str) - 1); + domain_email_part = substring(email_str, position('@' in email_str) + 1 ); + return_str = return_str || list_seperator || local_email_part || '#' || domain_email_part || '@' || vacation_domain; + END IF; + + IF char_length(forewarders_str) > 7 THEN + return_str = return_str || list_seperator || forewarders_str; + END IF; + + RETURN return_str; + END; + \$\$; +EOF + if [[ $? -ne 0 ]]; then + _failed=true + fi + + _pgppass_back_file="~/.pgpass.$backup_date" + _pgpass_was_present=false + if [[ -f "~/.pgpass" ]]; then + _pgpass_was_present=true + echo "" >> $log_file + echo "mv \"~/.pgpass\" \"$_pgppass_back_file\"" >> $log_file + mv "~/.pgpass" "$_pgppass_back_file" >> $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + fi + fi + + echo "" >> $log_file + echo "echo \"${POSTFIX_DB_HOST}:5432:${POSTFIX_DB_NAME}:${POSTFIX_DB_USER}:${POSTFIX_DB_PASSWD}\" > ~/.pgpass" >> $log_file 2>> $log_file + echo "${POSTFIX_DB_HOST}:5432:${POSTFIX_DB_NAME}:${POSTFIX_DB_USER}:${POSTFIX_DB_PASSWD}" > ~/.pgpass + if [[ $? -ne 0 ]]; then + _failed=true + fi + + echo "" >> $log_file + echo "psql -w -U $POSTFIX_DB_USER $POSTFIX_DB_NAME < $_psql_trigger_file" >> $log_file + psql -w -U $POSTFIX_DB_USER $POSTFIX_DB_NAME < $_psql_trigger_file >> $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + fi + + echo "" >> $log_file + echo "rm $_psql_trigger_file" >> $log_file + rm $_psql_trigger_file >> $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + fi + + if $_pgpass_was_present ; then + echo "" >> $log_file + echo "mv \"$_pgppass_back_file\" \"~/.pgpass\"" >> $log_file + mv \"$_pgppass_back_file\" \"~/.pgpass\" >> $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + fi + fi + + if $_failed ; then + echo_failed + erro $(cat $log_file) + else + echo_ok + fi + fi +else + + echononl "\tCreate function 'FORWARDERS_OUT'" + echo_skipped + echononl "\tCreate function 'FORWARDERS_IN'" + echo_skipped + + warn "Create fubctions 'FORWARDERS_OUT' and 'FORWARDERS_IN' not yet implemented" + +fi + +echo -e "\tNothing more to do here. Plugin '$_plugin' will be added to array plugins later.." + + +# - zipdownload +# - +_plugin="zipdownload" +add_plugin_arr+=("$_plugin") +echo -e "\n\t\033[32mPlugin '$_plugin'\033[m" +echo -e "\tNothing more to do here. Plugin '$_plugin' will be added to array plugins later.." + + +echo -e "\n\n\t\033[37m\033[1mActivate Plugins..\033[m" + +echo "" +echononl "\tSet a comment bevor existing parameter '$config['plugins']'.." +perl -i -n -p -e "s#(^\s*\\\$config\['plugins'\].*)#//\n// !! Note: This parameter will be overwritten at the end of this file !!\n//\n\1#" $WEBSITE_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/config.inc.php > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tSet parameter 'config['plugins']' to make plugin's available.." +if [[ ${#add_plugin_arr[@]} -gt 0 ]] ; then + cat <>$WEBSITE_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/config.inc.php 2> $log_file + + +// ---------------------------------- +// PLUGINS +// ---------------------------------- + +// List of active plugins (in plugins/ directory) +\$config['plugins'] = array( +EOF + for _plugin in ${add_plugin_arr[@]} ; do + echo " '$_plugin'," >> $WEBSITE_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/config.inc.php + done + echo ");" >> $WEBSITE_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/config.inc.php + echo "" >> $WEBSITE_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/config/config.inc.php + + echo_ok +else + echo_skipped +fi + + +echo -e "\n\n\t\033[37m\033[1mPost installation tasks\033[m" +echo "" + +echononl "\tIndex build-in addressbook" +${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/bin/indexcontacts.sh > $log_file 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echo "" +echononl "\tRemove installer Folder.." +rm -r $WEBSITE_BASEDIR/roundcubemail-${ROUNDCUBE_VERSION}/installer > $log_file 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echo "" +clean_up 0 + diff --git a/install_update_dovecot.sh b/install_update_dovecot.sh new file mode 100755 index 0000000..12f90c9 --- /dev/null +++ b/install_update_dovecot.sh @@ -0,0 +1,3223 @@ +#!/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)" + +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 ]" + + +# ------------- +# - Functions an Variable +# ------------- + +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 + exit 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 "" +} + +# - 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 + +_log_dir=${_src_base_dir}/log-dovecot-$_version + + + +# ------------- +# - 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" +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_address" + echo -e "\t AUTH Listener PORT.........: $xmpp_listener_port" +fi +echo "" + +if ! $_update ;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 + +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" + + + +# ------------- +# - 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}'" + 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" + fatal "Cannot Backup (move) directory '${_src_base_dir}/dovecot-${_version}'" + fi +else + echo -e "$rc_skipped" +fi + +mkdir -p $_log_dir + + +## ----------------- +## --- Download + +cd ${_src_base_dir} + +echo "" +echo "Download sources.." + +## - Downloud Dovecot 2.2.x +## - +echononl "\tDownload dovecot-${_version}.tar.gz" +#if [ ! -f "${_src_base_dir}/tarballs/dovecot-${_version}.tar.gz" ]; then +if [ ! -f "${_src_base_dir}/dovecot-${_version}.tar.gz" ]; then + wget http://www.dovecot.org/releases/2.2/dovecot-${_version}.tar.gz > /dev/null 2>&1 + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Download failed" + fi +else + echo -e "$rc_skipped" +fi + + +## - Download Pigeonhole for Dovecot v2.2 +## - +echononl "\tDownload ${_pigeonhole}.tar.gz.." +#if [ ! -f "${_src_base_dir}/tarballs/${_pigeonhole}.tar.gz" ]; then +if [ ! -f "${_src_base_dir}/${_pigeonhole}.tar.gz" ]; then + wget http://pigeonhole.dovecot.org/releases/2.2/${_pigeonhole}.tar.gz > /dev/null 2>&1 + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Download failed" + 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 + + + ## ----------------- + ## - Create Users/groups needed for dovecot + + echo "" + echo "Create required users/groups.." + 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 "\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 + +fi + + +## ----------------- +## --- Install Base System + +echo "" +echo "Installing Base System.." + +cd ${_src_base_dir} +echononl "\tUnpack dovecot-${_version}.tar.gz.." +#tar -xzf tarballs/dovecot-${_version}.tar.gz > /dev/null +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} + +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 + +echononl "\tCompile Dovecot Sources.." +make > ${_log_dir}/dovecot-${_version}-make.log 2>&1 || exit 1 +if [ "$?" = 0 ]; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal Compiling dovecot failed +fi +echononl "\tInstall Dovecot into Folder /usr/local/dovecot-${_version}" +make install > ${_log_dir}/dovecot-${_version}-install.log 2>&1 || exit 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 ${_pigeonhole}.tar.gz.." +#gunzip < tarballs/${_pigeonhole}.tar.gz | tar -xf - +gunzip < ${_pigeonhole}.tar.gz | tar -xf - +if [ "$?" = 0 ]; then + echo -e "$rc_done" +else + echo -e "$rc_failed" + fatal Extracting ${_pigeonhole}.tar.gz failed +fi +cd ${_pigeonhole} + + +echononl "\tConfigure Pigeonhole ManageSieve.." +./configure \ + --prefix=/usr/local/dovecot-${_version} \ + --with-dovecot=/usr/local/dovecot-${_version}/lib/dovecot > ${_log_dir}/${_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}/${_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}/${_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 "Configure Dovecot.." + +## - 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/ +## - shutdown_clients = no +## - +## - dict { +## - expire = $db_driver:/usr/local/dovecot/etc/dovecot/sql-dict.conf.ext +## - } +## - +echononl "\tAdjust file dovecot.conf.." +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 +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/#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 +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 + + +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 + + count=`su - postgres -c "psql -q -A -t -l" | grep -c -e "^$dbname"` + 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}.." + cat << EOF | psql -U$dbuser $dbname > /dev/null 2>&1 + +create table 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" + fatal Creating table expires failed + fi + + echononl "\tCreate function merge_expires() / trigger mergeexpires.." + 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" + fatal "Creating function merge_expires() / trigger mergeexpires failed" + 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" > /dev/null 2>&1 + + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Creating database $dbname failed" + 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'" > /dev/null 2>&1 + + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Creating database user $dbuser failed" + fi + + echononl "\tFlushing database privileges.." + mysql -u$MYSQL_ROOT_USER -p$MYSQL_ROOT_PW -N -s -e "FLUSH PRIVILEGES" > /dev/null 2>&1 + + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Flushing database privileges failed" + fi + + fi + + + ## - Create table expires in database ${dbname} + ## - + echononl "\tCreate table expires in database ${dbname}.." + cat << EOF | mysql -u$dbuser -p$dbpassword $dbname > /dev/null 2>&1 + +create table 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" + fatal Creating table expires failed + fi + fi +fi + + +if [ "$db_driver" = "pgsql" ]; 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 +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 + + +## - edit /usr/local/dovecot/etc/dovecot/conf.d/10-master.conf +## - +## - default_process_limit = 200 +## - default_client_limit = 2000 +## - +## - 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. 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_address +## - 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_address\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 = 200#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 = 2000#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 + + +## - edit /usr/local/dovecot/etc/dovecot/conf.d/10-ssl.conf +## - +## - ssl_cert = <$server_cert +## - ssl_key = <$server_key +## - +## - ssl_dh_parameters_length = 2048 +## - +## - ssl_protocols = !SSLv2 !SSLv3 +## - +## - 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#^([ ]*)(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 +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 +perl -i -n -p -e "s#^([ ]*)\#?(ssl_protocols\ ?=.*)#\1\#\# \2\nssl_protocols = !SSLv2 !SSLv3#g" \ + /usr/local/dovecot-${_version}/etc/dovecot/conf.d/10-ssl.conf || _failed=true + +perl -i -n -p -e "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#g" \ + /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 +## - +## - first_valid_gid = 5000 +## - last_valid_gid = 5000 +## - +## - auth_socket_path = /var/run/dovecot/auth-userdb +## - mail_plugins = quota expire +## - +_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#^([ ]*)\#?\ ?(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 +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 + + +## - 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 "found!" + 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.ORIG +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 + + +#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" +if [ "$spam_folder" != "Junk" ]; then + perl -i.ORIG -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 +else + perl -i.ORIG -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 +fi +perl -i -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 +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 +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 + +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 = no#g" \ + /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" + fatal "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 = 10 +## - 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 = 10#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 +## - +## - autocreate = $spam_folder +## - autocreate2 = Sent +## - autocreate3 = Trash +## - autocreate4 = Drafts + +## - autosubscribe = $spam_folder +## - autosubscribe2 = Sent +## - autosubscribe3 = Trash +## - autosubscribe4 = Drafts +## - +## - expire_dict = proxy::expire +## - +## - expire = Trash +## - expire2 = Trash.* +## - expire3 = $spam_folder +## - +_failed=false +echononl "\tAdjusting file 90-plugin.conf" +perl -i.ORIG -n -p -e "s#^([ ]*)(\#?\ ?setting_name\ +=.*)#\1\2\n\n\1autocreate = $spam_folder\n\1autocreate2 = Sent\n\1autocreate3 = Trash\n\1autocreate4 = Drafts\n\n\1autosubscribe = $spam_folder\n\1autosubscribe2 = Sent\n\1autosubscribe3 = Trash\n\1autosubscribe4 = Drafts\n\n\1expire_dict = proxy::expire\n\n\1expire = Trash\n\1expire2 = Trash.*\n\1expire3 = $spam_folder\n#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 + + +## - 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"]; +# 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" + fatal "Creating global sieve script failed" +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)" +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 + + _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 + + + ## - Make dovecot start at boot time + ## - + 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_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_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 1d; /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 + +fi + +echo +echo -e "Change (from lda) to lmtp-service" + +## ----------------- +## --- 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 + + +if $_new ; then + + ## - /etc/postfix/main.cf + ## - + ## - comment in: + ## - #virtual_transport = dovecot + ## - + ## - change: + ## - smtpd_sasl_auth_enable = yes + ## - smtpd_sasl_type = dovecot + ## - smtpd_sasl_path = private/dovecot-auth + ## - virtual_transport = lmtp:unix:private/dovecot-lmtp + _failed=false + echononl "\tAdjust /etc/postfix/main.cf" + perl -i -n -p -e "s#^(\s*)(smtpd_sasl_auth_enable\ *=.*)#smtpd_sasl_auth_enable = yes#" \ + /etc/postfix/main.cf || _failed=true + #perl -i -n -p -e "s#^(\s*)(smtpd_sasl_type\ *=.*)#\1\#\2\n\1smtpd_sasl_type = dovecot#" \ + 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\ *=.*)#\1\#\2\n\1smtpd_sasl_path = private/dovecot-auth#" \ + # /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\ *=.*)#\1\#\2\n\1virtual_transport = lmtp:unix:private/dovecot-lmtp#" \ + # /etc/postfix/main.cf || _failed=true + perl -i -n -p -e "s#^(\s*)(virtual_transport\ *=.*)#virtual_transport = lmtp:unix:private/dovecot-lmtp#" \ + /etc/postfix/main.cf || _failed=true + perl -i-n -p -e "s#^(\s*)(dovecot_destination_recipient_limit.*)#\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 + +fi + + +## ----------------- +## --- Configure quota support for dovecot + +echo +echo -e "Configure quota support for dovecot" + + +## - 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 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" + fatal "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 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" + fatal "Creating table quota2 in database \"$dbname\" failed" + fi + fi + +fi + +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 +} + +# 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 "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 +} + +# 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 "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 + + +## - 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 = dovecot +## - unix_listener quota-warning { +## - user = vmail +## - } +## - } +## - +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 = dovecot + unix_listener quota-warning { + user = vmail + } +} +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 +#!/bin/sh + +# 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 +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" +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 +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 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" + fatal "Creating table user_shares failed" + fi + + echononl "\tCreate table anyone_shares" + cat << EOF | psql -U$dbuser $dbname > /dev/null 2>&1 +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.'; +EOF + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "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 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" + fatal "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 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" + fatal "Creating table anyone_shares failed" + fi + fi +fi + + +if [ "$db_driver" = "pgsql" ]; then + + ## - adjust/renew file /usr/local/dovecot/etc/dovecot/sql-dict.conf.ext + ## - + echononl "\tRenew file 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 +} + +# 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 + } +} + + +# 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 [ "$?" = 0 ]; 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 + ## - + echononl "\tRenew file 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 +} + +# 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 + } +} + + +# 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 [ "$?" = 0 ]; 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 +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 +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 + +_restart="" +echo +echo -e -n "Restart services (dovecot/postfix)? [y/n]: " +read _restart +if [ "y" = "$_restart" -o "Y" = "$_restart" -o "Yes" = "$_restart" -o "yes" = "$_restart" ];then + echononl "\tRestart dovecot.." + if $systemd_support ; then + systemctl start dovecot + else + /etc/init.d/dovecot restart > /dev/null 2>&1 + fi + if [ "$?" = 0 ]; then + echo -e "$rc_done" + else + echo -e "$rc_failed" + fatal "Restarting dovecot 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 + + +echo " + +Notice: +If you want to support more than 128 simultanously connections (the default), +you have to increase \"/proc/sys/fs/inotify/max_user_instances\". + +If you are running dovecot on a VServer Guest System, you have to do that on the +VServer Root System: + + # echo \"fs.inotify.max_user_instances = 1024\" >> /etc/sysctl.conf + # sysctl -p + +" +echo "" + +rm -f "$log_file" +exit diff --git a/upgrade_roundcube.sh b/upgrade_roundcube.sh new file mode 100755 index 0000000..3565588 --- /dev/null +++ b/upgrade_roundcube.sh @@ -0,0 +1,572 @@ +#!/usr/bin/env bash + +clear +echo -e "\n \033[32mStart script for upgrading Roundcube Webmailer..\033[m" + +## ----------------------------------------------------------------- +## ---------------------------------------------------------------- +## --- +## --- For configurations see file conf/install_upgrade_roundcube.conf +## --- +## --- Dont make changes here! +## --- +## ----------------------------------------------------------------- +## ----------------------------------------------------------------- + + +# ------------- +# - Settings +# ------------- + +_src_base_dir="$(realpath $(dirname $0))" +conf_file="${_src_base_dir}/conf/install_upgrade_roundcube.conf" +curdir=`pwd` + +log_file="$(mktemp)" +tmp_dir="$(mktemp -d)" +backup_date="$(date +%Y-%m-%d-%H%M)" + +crontab_backup_file="/root/crontab-root.${backup_date}" + + +# ------------- +# - Functions +# ------------- + +clean_up() { + + # Perform program exit housekeeping + rm -f "$log_file" + rm -rf "$tmp_dir" + exit $1 +} + +echononl(){ + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo "$*\\c" 1>&2 + else + echo -e -n "$*" 1>&2 + fi + rm /tmp/shprompt$$ +} + +fatal(){ + echo "" + echo -e "\t[ \033[31m\033[1mFatal\033[m ]: $*" + echo "" + echo -e "\t\033[31m\033[1mInstalllation wird abgebrochen\033[m" + echo "" + clean_up 1 +} + +error(){ + echo "" + echo -e "\t[ \033[31m\033[1mFehler\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 "" +} + + +echo_ok() { + echo -e "\033[85G[ \033[32mok\033[m ]" +} +echo_failed(){ + echo -e "\033[85G[ \033[1;31mfailed\033[m ]" +} +echo_skipped() { + echo -e "\033[85G[ \033[30m\033[1mskipped\033[m ]" +} +echo_not_yet_implemented(){ + echo -e "\033[85G[ \033[30m\033[1mnot yet implemented\033[m ]" +} + +trap clean_up SIGHUP SIGINT SIGTERM + + +# - Support systemd ? +# - +if [[ "X$(which systemd)" = "X" ]]; then + SYSTEMD_EXISTS=false +else + SYSTEMD_EXISTS=true +fi + + + +DEFAULT_DB_HOST="localhost" +DEFAULT_DB_NAME="roundcubemail" +DEFAULT_DB_USER="roundcube" + +echo +echononl " Include Configuration file.." +if [[ ! -f $conf_file ]]; then + echo_failed + fatal "Missing configuration file '$conf_file'" +else + source $conf_file + echo_ok +fi + +[[ -n "$WEBSITE_NAME" ]] || fatal "Website's name (WEBSITE_NAME) not present!" + +DEFAULT_WEBSITE_BASEDIR="/var/www/${WEBSITE_NAME}" + +[[ -n "$WEBSITE_BASEDIR" ]] || WEBSITE_BASEDIR=$DEFAULT_WEBSITE_BASEDIR +CUR_INSTALL_DIR="$(realpath "${WEBSITE_BASEDIR}/htdocs")" + +if [[ ! -d "$CUR_INSTALL_DIR" ]] ; then + fatal "No current installation of roundcube found!" +fi + +[[ -n "$DB_TYPE" ]] || fatal "Database Type of Roundcube Database (DB_TYPE) not present!" +[[ -n "$DB_HOST" ]] || DB_HOST="$DEFAULT_DB_HOST" +[[ -n "$DB_NAME" ]] || DB_NAME="$DEFAULT_DB_NAME" +[[ -n "$DB_USER" ]] || DB_USER="$DEFAULT_DB_USER" + +[[ -n "$MYSQL_DEBIAN_INSTALLATION" ]] || MYSQL_DEBIAN_INSTALLATION=false + + +if [ "$DB_TYPE" = "postgres" -o "$DB_TYPE" = "postgresql" -o "$DB_TYPE" = "pgsql" -o "$DB_TYPE" = "psql" ];then + DB_TYPE="pgsql" +fi + + +if [[ "$DB_TYPE" = "mysql" ]]; then + if $MYSQL_DEBIAN_INSTALLATION ; then + [[ -n "$MYSQL_CREDENTIALS" ]] || MYSQL_CREDENTIALS="$DEFAULT_DEBIAN_MYSQL_CREDENTIALS" + else + [[ -n "$MYSQL_CREDENTIALS" ]] || MYSQL_CREDENTIALS="$DEFAULT_MYSQL_CREDENTIALS" + fi +else + [[ "$DB_TYPE" = "pgsql" ]] || fatal "Unknown Database Type '$DB_TYPE' (DB_TYPE)" +fi + + +echo -e "\033[32m--\033[m" +echo "" +echo "Version of the Roundcube Webmailer to install" +echo "" +echo "" +ROUNDCUBE_VERSION= +while [ "X$ROUNDCUBE_VERSION" = "X" ] +do + echononl "Roundcube Version: " + read ROUNDCUBE_VERSION + if [ "X$ROUNDCUBE_VERSION" = "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 "" +NEW_INSTALL_DIR="${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}" + +if [[ "$NEW_INSTALL_DIR" = "$CUR_INSTALL_DIR" ]] ; then + fatal "Version '${ROUNDCUBE_VERSION}' is already installed" +fi + + +echo "" +echo "" +echo -e "\033[1;32mSettings for installation of \033[1;37mRoundcube Webmail\033[m" +echo "" +echo -e "\tRoundcube Version....................: $ROUNDCUBE_VERSION" +echo "" +echo -e "\tName of the Website..................: $WEBSITE_NAME" +echo "" +if [[ "$DB_TYPE" = "mysql" ]]; then + echo -e "\tDatabase type of Roundcube Database..: MySQL" + echo -e "\tMySQL from Debian Package System.....: $MYSQL_DEBIAN_INSTALLATION" +else + echo -e "\tDatabase type of Roundcube Database..: PostgreSQL" +fi +echo -e "\tHost of Roundcube Database...........: $DB_HOST" +echo -e "\tName of Roundcube Database...........: $DB_NAME" +echo -e "\tUser of Roundcube Database...........: $DB_USER" +echo -e "\tPassword of Roundcube Database.......: $DB_PASS" +if [[ "$DB_TYPE" = "mysql" ]]; then + echo -e "\tMySQL Credentials (root access)......: $MYSQL_CREDENTIALS" +fi +echo "" +echo -e "\tCrontab backup file..................: $crontab_backup_file" + +echo "" +echo -n "Type upper case 'YES' to continue executing with this parameters: " +read OK +if [[ "$OK" = "YES" ]] ; then + echo "" + echo "" + echo -e " \033[1;32mGoing to upgrade Roundcube Webmailer \033[1;37m$network \033[m" + echo "" +else + fatal "Abort by user request - Answer as not 'YES'" +fi + +if [[ "$DB_TYPE" = "mysql" ]]; then + if ! mysql $MYSQL_CREDENTIALS -N -s -e \ + "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '$DB_NAME'" 2>> $log_file \ + | grep $DB_NAME >> $log_file 2>&1 ; then + fatal "MySQL Database '$DB_NAME' does not exit. (See Parameter 'DB_NAME')" + fi +elif [[ "$DB_TYPE" = "pgsql" ]]; then + count=$(su - postgres -c "psql -q -A -t -l" | grep -c -e "^$DB_NAME") + if [[ $count -eq 0 ]];then + fatal "PostgreSQL Database '$DB_NAME' does not exit. (See Parameter 'DB_NAME')" + fi +else + fatal "Cannot detect database type (value of DB_TYPE is neither 'mysql' nor 'pgsql')" +fi + + +echo -e "\n\n \033[37m\033[1mCreate some Backups..\033[m\n" + +echononl " Backup existing Database '$DB_NAME'" +if [[ "$DB_TYPE" = "mysql" ]]; then + echo -n " (MySQL).." + mysqldump -u$_mysql_rootuser -p$_mysql_rootpass --opt $DB_NAME > ${WEBSITE_BASEDIR}/${DB_NAME}.$backup_date 2> $log_file + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +elif [[ "$DB_TYPE" = "pgsql" ]]; then + echo -n " (PostgreSQL).." + su - postgres -c "pg_dump -c $DB_NAME" > ${WEBSITE_BASEDIR}/${DB_NAME}.$backup_date.sql 2> $log_file + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +fi + + +echononl " Backup existing web-directory .." +if [[ -d "$CUR_INSTALL_DIR" ]]; then + mv "$CUR_INSTALL_DIR" "${CUR_INSTALL_DIR}.$backup_date" > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + fatal "$(cat $log_file)" + fi +else + fatal "No current installation of roundcube found!" +fi + + +echo -e "\n\n \033[37m\033[1mDownloud/Unpack source archive..\033[m\n" + +echononl " Download 'roundcubemail-${ROUNDCUBE_VERSION}'.." +if [[ ! -f "$_src_base_dir/roundcubemail-${ROUNDCUBE_VERSION}.tar.gz" ]]; then + wget -O ${_src_base_dir}/roundcubemail-${ROUNDCUBE_VERSION}.tar.gz https://github.com/roundcube/roundcubemail/releases/download/${ROUNDCUBE_VERSION}/roundcubemail-${ROUNDCUBE_VERSION}.tar.gz > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +echononl " Remove existing source directory" +if [[ -d "${_src_base_dir}/roundcubemail-${ROUNDCUBE_VERSION}" ]]; then + rm -rf "${_src_base_dir}/roundcubemail-${ROUNDCUBE_VERSION}" > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + +echononl " Unpack roundcube source archive.." +gunzip < ${_src_base_dir}/roundcubemail-${ROUNDCUBE_VERSION}.tar.gz | tar -C ${_src_base_dir} -xf - > $log_file 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + fatal "$(cat $log_file)" +fi + +echo -e "\n\n \033[37m\033[1mSome pre-installation tasks..\033[m\n" + + +## - Disable crontab for user root +## - +echononl " Backup crontab" +echo "" >> ${logdir}/main.log +echo "crontab -u root -l > $crontab_backup_file" >> ${logdir}/main.log +crontab -u root -l >> $crontab_backup_file 2>> ${logdir}/main.log +if [[ "$?" = "0" ]]; then + echo_ok +else + echo_failed +fi + +echononl " Disable crontab for user root" +echo "" >> ${logdir}/main.log +echo "crontab -r -u root" >> ${logdir}/main.log +crontab -r -u root >> ${logdir}/main.log 2>&1 +if [[ "$?" = "0" ]]; then + echo_ok +else + echo_failed +fi + + +echononl " Stop Apache Webserver.." +if $SYSTEMD_EXISTS ; then + systemctl stop apache2 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + fatal "$(cat $log_file)" + fi +else + /etc/init.d/apache2 stop + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + fatal "$(cat $log_file)" + fi +fi + + + +# - Determin PHP of all installed versions +# - +echononl "\tGet major version of all installed PHP versions" +php_major_versions="$(find /usr/local/ -maxdepth 1 -mindepth 1 -type l -name "php-*" -print | cut -d "-" -f2 | sort)" +if [[ -z "$php_major_versions" ]]; then + echo_failed + error "Getting version numbers of installed PHP versions failed! No installed PHP versiond found!" +else + echo_ok +fi + +# - Stop all PHP FPM engines +# - +if [[ -n "$php_major_versions" ]]; then + for _ver in $php_major_versions ; do + echononl " Stop PHP FPM engine v${_ver}.." + if [[ -f "/etc/init.d/php-${_ver}-fpm" ]]; then + /etc/init.d/php-${_ver}-fpm stop > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + elif [[ -f "/etc/systemd/system/php-${_ver}-fpm.service" ]] ; then + systemctl stop php-${_ver}-fpm > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + else + echo_skipped + fi + done +fi + +echo -e "\n\n \033[37m\033[1mUgrade Roundcube Webmail..\033[m\n" + +echononl " Copy current web-directory into a the new one.." +cp -a "${CUR_INSTALL_DIR}.$backup_date" "${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}" > $log_file 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + fatal "$(cat $log_file)" +fi + + +echononl " Set actual timestamp to the new web-directory" +touch -t "$(date +%Y%m%d%H%M.%S)" "${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}" > $log_file 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + fatal "$(cat $log_file)" +fi + + +echononl " Change into new roundcube source directory" +cd "${_src_base_dir}/roundcubemail-${ROUNDCUBE_VERSION}" > $log_file 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + fatal "$(cat $log_file)" +fi + +echononl " Create log-directory for update log file" +if [[ ! -d "${_src_base_dir}/log" ]]; then + mkdir "${_src_base_dir}/log" > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + fatal "$(cat $log_file)" + fi +else + echo_skipped +fi + +echo "" +echo " Update the the roundcube web-directory to version '${ROUNDCUBE_VERSION}'" +echononl " See: ${_src_base_dir}/log/update_roundcube-${ROUNDCUBE_VERSION}.${backup_date}.log" +echo "y" | ${_src_base_dir}/roundcubemail-${ROUNDCUBE_VERSION}/bin/installto.sh "${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}" > ${_src_base_dir}/log/update_roundcube-${ROUNDCUBE_VERSION}.${backup_date}.log 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed +fi +echo "" + +echononl " Change into new roundcube web directory" +cd "${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}" > $log_file 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + fatal "$(cat $log_file)" +fi + +echononl " Update dependencies by running 'php composer.phar update --no-dev'" +php composer.phar update --no-dev > ${_src_base_dir}/log/update_roundcube-${ROUNDCUBE_VERSION}-dependencies.${backup_date}.log 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat ${_src_base_dir}/log/update_roundcube-${ROUNDCUBE_VERSION}-dependencies.${backup_date}.log)" +fi + +echononl " Index build-in addressbook" +${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/bin/indexcontacts.sh > $log_file 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +_failed=false +echononl " Symlink DocumentRoot to the new installation directory.." +if [[ -h "${WEBSITE_BASEDIR}/htdocs" ]]; then + rm "${WEBSITE_BASEDIR}/htdocs" > $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + fi +elif [[ -f "${WEBSITE_BASEDIR}/htdocs" ]]; then + mv "${WEBSITE_BASEDIR}/htdocs" "${WEBSITE_BASEDIR}/htdocs/.$backup_date" > $log_file 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + fi +fi + +ln -s "roundcubemail-${ROUNDCUBE_VERSION}" "${WEBSITE_BASEDIR}/htdocs" >> $log_file 2>&1 +if [[ $? -ne 0 ]]; then + _failed=true +fi +if $_failed ; then + echo_failed + error "$(cat $log_file)" +else + echo_ok +fi + + +echo -e "\n\n \033[37m\033[1mSome post-installation tasks..\033[m\n" + +# - Start all PHP FPM engines +# - +if [[ -n "$php_major_versions" ]]; then + for _ver in $php_major_versions ; do + echononl " Start PHP FPM engine v${_ver}.." + if [[ -f "/etc/init.d/php-${_ver}-fpm" ]]; then + /etc/init.d/php-${_ver}-fpm start > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + elif [[ -f "/etc/systemd/system/php-${_ver}-fpm.service" ]] ; then + systemctl start php-${_ver}-fpm > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + else + echo_skipped + fi + done +fi + +# - Start Apache Webserver +# - +echononl " Start Apache Webserver.." +if $SYSTEMD_EXISTS ; then + systemctl start apache2 > $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + fatal "$(cat $log_file)" + fi +else + /etc/init.d/apache2 start> $log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + fatal "$(cat $log_file)" + fi +fi + + +echononl " Renstall previously saved crontab from '$crontab_backup_file'.." +crontab $crontab_backup_file > $log_file 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echononl " Delete previously saved crontab file '$crontab_backup_file'.." +rm "$crontab_backup_file" > $log_file 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + + +echo "" +clean_up 0 +