From 5b853a26cbdd7a573b8c5f6798e4eff183a5b69d Mon Sep 17 00:00:00 2001 From: Christoph Date: Wed, 7 Jan 2026 00:14:36 +0100 Subject: [PATCH] Backup old (Post-Queue setting) installation scripts. --- BAK/install_amavis.sh.Pre-Queue.00 | 5297 +++++++++++++++++++++++++ BAK/install_opendkim.sh.Pre-Queue.00 | 684 ++++ BAK/install_opendmarc.sh.Pre-Queue.00 | 936 +++++ 3 files changed, 6917 insertions(+) create mode 100755 BAK/install_amavis.sh.Pre-Queue.00 create mode 100755 BAK/install_opendkim.sh.Pre-Queue.00 create mode 100755 BAK/install_opendmarc.sh.Pre-Queue.00 diff --git a/BAK/install_amavis.sh.Pre-Queue.00 b/BAK/install_amavis.sh.Pre-Queue.00 new file mode 100755 index 0000000..348bc9d --- /dev/null +++ b/BAK/install_amavis.sh.Pre-Queue.00 @@ -0,0 +1,5297 @@ +#!/usr/bin/env bash + + +script_dir="$(realpath $(dirname $0))" +script_name="$(basename "$0")" +conf_file="${script_dir}/conf/install_amavis.conf" + +backup_date="$(date +%Y-%m-%d-%H%M)" +crontab_backup_file="${script_dir}/crontab-root-${backup_date}.install_amavis.lst" + + + +# ------------- +# --- 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 "" + if [[ -f "$crontab_backup_file" ]]; then + echononl " Reenable previously saved crontab from '$crontab_backup_file'.." + crontab $crontab_backup_file > $tmp_err_msg 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + fi + 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 ]" +} + +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=${VERSION_ID} + + fi + + # remove whitespace from os_dist and os_version + os_dist="${os_dist// /}" + os_version="${os_version// /}" + +} + + +# ------------- +# --- Some default settings +# ------------- + +DEFAULT_SASL_AUTH_ENABLED="no" + +DEFAULT_QUARANTINE_DIR="/var/QUARANTINE" +DEFAULT_QUARANTINE_ADMIN='postmaster\@$mydomain' +DEFAULT_DB_IN_USE=false + +DEFAULT_INSTALL_CLAMAV_UNOFFICIAL_SIGS=true + +DEFAULT_MALWARE_PATROL_IN_USE=false +DEFAULT_MALWERE_PATROL_FREE=false +DEFAULT_MP_RECEIPT_NUMBER=106015125438 + +DEFAULT_SECURITE_INFO_IN_USE=true +DEFAULT_SI_AUTHORISATION_SIGNATURE_WF=76ed7ca6670dbee497e1a0397a7e178c4caa25888bc26d7327d1eab0195342a4cfa522dcf10382623d57dbc2a79bd37627b9a52def4d4bfe617d26e35405ce3b + +#DEFAULT_SI_AUTHORISATION_SIGNATURE_OOPEN=b0b7e94d3fcc8f3b1f128edd5830392361868cf0174723a9924ac25bf8b1b588cb974b50234e1bc1d9839dfe0ca6e1627733d90daf1399347b1046d20c2e3a89 +DEFAULT_SI_AUTHORISATION_SIGNATURE_OOPEN=abb4ec6b194639f3d123154f1b971843a3b8751d8c1bcdc7d07ed6db26621b11bca0e23d2a42b60aef3f7b7803a1466a964d90c7b1e82d67c7680c8f46b59a4e + +# SecuriteInfo signatur databases +# +SI_SIGNATUR_DATABASES=" + securiteinfo.hdb + securiteinfo.ign2 + javascript.ndb + spam_marketing.ndb + securiteinfohtml.hdb + securiteinfoascii.hdb + securiteinfoandroid.hdb + securiteinfoold.hdb + securiteinfopdf.hdb + securiteinfo0hour.hdb + securiteinfo.mdb + securiteinfo.yara + securiteinfo.pdb + securiteinfo.wdb +" + +# - This parameter will be not asked, so setting it here +# - +QUARANTINE_ADMIN=$DEFAULT_QUARANTINE_ADMIN + + +# - Is this a systemd system? +# - +systemd_exists=false +systemd=$(which systemd) +systemctl=$(which systemctl) + +if [[ -n "$systemd" ]] || [[ -n "$systemctl" ]] ; then + systemd_exists=true +fi + +# - Set variable +# - os_dist +# - os_version +# - os_codename +# - +detect_os_1 + +echo "" + +if [[ -f "$conf_file" ]]; then + source $conf_file +fi + + + +# ------------- +# --- Set default values for some non existent variables (i.e. no configuration file is present) +# ------------- + +if [[ -z "$_HOSTNAME" ]] ; then + _HOSTNAME="$(hostname -f)" + _HOSTNAME_SHORT="$(hostname)" + [[ "$_HOSTNAME" = "$_HOSTNAME_SHORT" ]] && _HOSTNAME="" +fi + +[[ -z "$_SASL_AUTH_ENABLED" ]] && _SASL_AUTH_ENABLED="$DEFAULT_SASL_AUTH_ENABLED" + + +[[ -z "$_QUARANTINE_DIR" ]] && _QUARANTINE_DIR="$DEFAULT_QUARANTINE_DIR" + +[[ -z "$_DB_IN_USE" ]] && _DB_IN_USE=$DEFAULT_DB_IN_USE + +[[ -z "$_INSTALL_CLAMAV_UNOFFICIAL_SIGS" ]] && _INSTALL_CLAMAV_UNOFFICIAL_SIGS=$DEFAULT_INSTALL_CLAMAV_UNOFFICIAL_SIGS + +[[ -z "$_MALWARE_PATROL_IN_USE" ]] && _MALWARE_PATROL_IN_USE=$DEFAULT_MALWARE_PATROL_IN_USE +[[ -z "$_MALWERE_PATROL_FREE" ]] && _MALWERE_PATROL_FREE=$DEFAULT_MALWERE_PATROL_FREE + +[[ -z "$_SECURITE_INFO_IN_USE" ]] && _SECURITE_INFO_IN_USE=$DEFAULT_SECURITE_INFO_IN_USE + + +_needed_packages_clamav="clamav \ + clamav-base \ + clamav-daemon \ + clamav-docs \ + clamav-freshclam \ + libgmp-dev \ + libgmp10" +if [[ "${os_dist,,}" = "debian" ]] && [[ "$os_version" -eq 10 ]] ; then + _needed_packages_clamav="$_needed_packages_clamav \ + libclamunrar7" +elif [[ "${os_dist,,}" = "debian" ]] && [[ "$os_version" -eq 11 ]] ; then + _needed_packages_clamav="$_needed_packages_clamav \ + libclamunrar9" +elif [[ "${os_dist,,}" = "debian" ]] && [[ "$os_version" -eq 12 ]] ; then + _needed_packages_clamav="$_needed_packages_clamav \ + libclamunrar11" +else + _needed_packages_clamav="$_needed_packages_clamav \ + libclamunrar13" +fi + +_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 \ + rar \ + unrar \ + unrar-free \ + unzip \ + zip " + +if [[ "${os_dist,,}" = "debian" ]] && [[ "$os_version" -lt 10 ]] ; then + _needed_decoders_amavis="$_needed_decoders_amavis \ + ripole \ + zoo" +fi + + +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 + + + +# ------------- +# --- Some further default values depending on Hostname +# ------------- + +# - Set default values for ipv4- and ipv6-address +# - +if [[ -z $_IPV4 ]] && [[ -n "$_HOSTNAME" ]] && [[ -x "$(which dig)" ]]; then + _IPV4="$(dig +short "$_HOSTNAME" A)" +fi +if [[ -z $_IPV6 ]] && [[ -n "$_HOSTNAME" ]] && [[ -x "$(which dig)" ]]; then + _IPV6="$(dig +short "$_HOSTNAME" AAAA)" +fi + +# - Set defaul value for securite signature +# - +if [[ -z "$_SI_AUTHORISATION_SIGNATURE" ]]; then + [[ "$HOSTNAME" =~ warenform.de$ ]] && _SI_AUTHORISATION_SIGNATURE=$DEFAULT_SI_AUTHORISATION_SIGNATURE_WF + + # - For all this take O.OPEN's Signature + # - + [[ "$HOSTNAME" =~ oopen.de$ ]] && _SI_AUTHORISATION_SIGNATURE=$DEFAULT_SI_AUTHORISATION_SIGNATURE_OOPEN + [[ "$HOSTNAME" =~ cadus.org$ ]] && _SI_AUTHORISATION_SIGNATURE=$DEFAULT_SI_AUTHORISATION_SIGNATURE_OOPEN + [[ "$HOSTNAME" =~ so36.net$ ]] && _SI_AUTHORISATION_SIGNATURE=$DEFAULT_SI_AUTHORISATION_SIGNATURE_OOPEN + [[ "$HOSTNAME" =~ interventionistische-linke.org$ ]] && _SI_AUTHORISATION_SIGNATURE=$DEFAULT_SI_AUTHORISATION_SIGNATURE_OOPEN + +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 + +SASL_AUTH_ENABLED= +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Should this mail 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 + + + +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 "Use 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 + + +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 + + # - Set default Value for Malware Patrol serial number (if non free account in use) + # - + if ! $MALWERE_PATROL_FREE ; then + [[ -z "$_MP_RECEIPT_NUMBER" ]] && _MP_RECEIPT_NUMBER="$DEFAULT_MP_RECEIPT_NUMBER" + 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 + +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 lookups for local 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" + _DB_TYPE="None" +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 "" +echo -e "\tSASL AUTH support......................: $SASL_AUTH_ENABLED" +echo "" +echo -e "\tQuarantine Directory ..................: $QUARANTINE_DIR" +echo "" +echo -e "\tInstall ClamAv Unoffical Sigs .........: $INSTALL_CLAMAV_UNOFFICIAL_SIGS" +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........................: $DB_IN_USE" +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 +# --- +# - Parametersettings for installscript $script_name +# --- + +_HOSTNAME=$HOSTNAME +_IPV4=$IPV4 +_IPV6=$IPV6 + +_SASL_AUTH_ENABLED=$SASL_AUTH_ENABLED + +_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 +EOF +if $MALWARE_PATROL_IN_USE ; then + cat << EOF >> $conf_file +_MALWERE_PATROL_FREE=$MALWERE_PATROL_FREE +_MP_RECEIPT_NUMBER=$MP_RECEIPT_NUMBER +EOF +else + cat << EOF >> $conf_file +_MALWERE_PATROL_FREE= +_MP_RECEIPT_NUMBER= +EOF +fi +if $SECURITE_INFO_IN_USE ; then + cat << EOF >> $conf_file +_SECURITE_INFO_IN_USE=$SECURITE_INFO_IN_USE +_SI_AUTHORISATION_SIGNATURE=$SI_AUTHORISATION_SIGNATURE + +EOF +else + cat << EOF >> $conf_file +_SECURITE_INFO_IN_USE=$SECURITE_INFO_IN_USE +_SI_AUTHORISATION_SIGNATURE= + +EOF +fi +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 + +# - Synchronise package index files with the repository +# - +echononl " Synchronise package index files with the repository.." +apt-get update > "$tmp_err_msg" 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + +# - 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 \ + libnet-patricia-perl \ + 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)" + + echononl "\tcontinue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + + fi +else + echo_skipped +fi + +echononl " Install database related CPAN Modules" +installation_failed=false +_needed_cpan_modules="CPAN + DBI + DBD::mysql + DBD::Pg" + +if [[ "${os_dist,,}" = "debian" ]] && [[ "$os_version" -lt 12 ]] ; then + 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) + + command was: + cpanm -q --skip-installed $_module" + + echononl "\tcontinue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + + fi + done + if ! $installation_failed ; then + echo_ok + fi +else + echo_skipped + info "Needed Perl modules are: + + DBI + DBD::mysql + DBD::Pg + + All of them are installed via debian package system: + + libdbi-perl + libdbd-mysql-perl + libdbd-pg-perl" + +fi + +## - Temporarily disable crontab for user root +## - + +echononl " Backup crontab" +crontab -u root -l > $crontab_backup_file 2> $tmp_err_msg +if [[ "$?" = "0" ]]; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + +echononl " Disable crontab for user root" +echo "crontab -r -u root" > $tmp_err_msg +crontab -r -u root > $tmp_err_msg 2>&1 +if [[ "$?" = "0" ]]; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + + +echo +echo -e "\033[37m\033[1mInstall AMaViS..\033[m" +echo + + +## - 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 \ + sa-compile \ + razor \ + pyzor \ + libio-socket-ssl-perl \ + libdbi-perl \ + libmail-dkim-perl \ + libmail-spf-perl \ + libgeo-ipfree-perl \ + libnet-ident-perl \ + libio-string-perl \ + libimage-info-perl \ + libnet-cidr-lite-perl \ + libgeo-ip-perl \ + geoip-bin \ + libgeoip-dev \ + geoip-database \ + re2c \ + ftp \ + ncftp \ + less" + +if [[ "$os_version" -lt 10 ]] ; then + _needed_packages_spamassassin="$_needed_packages_spamassassin \ + libio-zlib-perl" +fi +if [[ "$os_version" -gt 11 ]] ; then + _needed_packages_spamassassin="$_needed_packages_spamassassin \ + spamd" +fi + +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 /root/sample-spam.txt +Subject: Test spam mail (GTUBE) +Message-ID: +Date: Wed, 23 Jul 2003 23:30:00 +0200 +From: Sender +To: Recipient +Precedence: junk +MIME-Version: 1.0 +Content-Type: text/plain; charset=us-ascii +Content-Transfer-Encoding: 7bit + +This is the GTUBE, the + Generic + Test for + Unsolicited + Bulk + Email + +If your spam filter supports it, the GTUBE provides a test by which you +can verify that the filter is installed correctly and is detecting incoming +spam. You can send yourself a test mail containing the following string of +characters (in upper case and with no white spaces and line breaks): + +XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X + +You should send this test mail from an account outside of your network +EOF +if [[ $? -ne 0 ]] ; then + echo_failed + error "$(cat $tmp_err_msg)" +else + 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" + +## - 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."${backup_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)" + + echononl " Try to create \"razor-agent.conf\" in (user root) once again.." + + razor-admin -create > $tmp_err_msg 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + + echononl "\tcontinue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + + fi + +fi + +## - 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."${backup_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.${backup_date}" ]] ; then + echononl " Delete previous created backup \"${_home_amavais}/.razor.${backup_date}\"" + rm -r "${_home_amavais}/.razor.${backup_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.${backup_date}" ]] ; then + echononl " Delete previous created backup \"/root/.razor.${backup_date}\"" + rm -r "/root/.razor.${backup_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 [[ -f "$crontab_backup_file" ]]; then + if ! grep -i -E "/usr/bin/razor-admin\s+-discover" "$crontab_backup_file" > /dev/null 2>&1; then + cat << EOF >> $crontab_backup_file + +# - Update razor2 +# - +33 0 * * * su amavis -lc '/usr/bin/razor-admin -discover' +EOF + if [[ "$?" -ne 0 ]] ; then + echo_failed + else + echo_ok + fi + else + echo_skipped + fi +elif [[ -f "/var/spool/cron/crontabs/root" ]] ; then + + 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 +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." + +services=("clamav-freshclam" "clamav-daemon" "adcc") +for svc in "${services[@]}"; do + echononl " Stop Service '${svc}.." + if systemctl is-active --quiet "$svc"; then + systemctl stop "$svc" > /dev/null 2> $tmp_err_msg + if [[ $? -ne 0 ]] ; then + echo_failed + + error "$(cat $tmp_err_msg)" + else + echo_ok + fi + else + echo_skipped + fi +done + + + +#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 +_archiv=dcc.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 archive \"$_archiv\"" +wget --no-check-certificate -O ${_dcc_src_dir}/$_archiv https://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)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + +fi + +echononl " 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 [[ -f "$crontab_backup_file" ]]; then + + if ! grep -i -E "/var/dcc/libexec/cron-dccd" "$crontab_backup_file" > /dev/null 2>&1; then + cat << EOF >> $crontab_backup_file + +# - Cleaning up dcc (Distributed Checksum Clearinghouses) +# - +13 1 * * * /var/dcc/libexec/cron-dccd + +EOF + if [[ "$?" -ne 0 ]] ; then + echo_failed + else + echo_ok + fi + else + echo_skipped + fi + +elif [[ -f "/var/spool/cron/crontabs/root" ]] ; then + + 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 +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 +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 +else + echononl " Backup $_config_file" + cp -a "$_config_file" "${_config_file}.${backup_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 +# +########################################################################### + +# A 'contact address' users should contact for more info. (replaces +# _CONTACTADDRESS_ in the report template) +# report_contact youremailaddress@domain.tld + +# 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 + + +# Whether to decode non- UTF-8 and non-ASCII textual parts and recode +# them to UTF-8 before the text is given over to rules processing. +# +# normalize_charset 1 + +# Textual body scan limit (default: 50000) +# +# Amount of data per email text/* mimepart, that will be run through body +# rules. This enables safer and faster scanning of large messages, +# perhaps having very large textual attachments. There should be no need +# to change this well tested default. +# +# body_part_scan_size 50000 + +# Textual rawbody data scan limit (default: 500000) +# +# Amount of data per email text/* mimepart, that will be run through +# rawbody rules. +# +# rawbody_part_scan_size 500000 + + +# 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}.${backup_date}" ]]; then + if diff "${_config_file}" "${_config_file}.${backup_date}" > /dev/null 2>&1 ; then + info "${_config_file} has not changed.\n\t Removing previos created backup.." + rm "${_config_file}.${backup_date}" + fi +fi + + +# - Adjust /etc/spamassassin/v310.pre +# - +_config_file=/etc/spamassassin/v310.pre +_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}.${backup_date}" 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi + _backup_file="${_config_file}.${backup_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 +_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}.${backup_date}" 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + _backup_file=${_config_file}.${backup_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 +_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}.${backup_date}" 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi + _backup_file="${_config_file}.${backup_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 cleaning up bayes" +if [[ -f "$crontab_backup_file" ]]; then + + if ! grep -i -E "/usr/bin/sa-learn\s+--sync" "$crontab_backup_file" > /dev/null 2>&1; then + cat << EOF >> $crontab_backup_file + +# - 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 + echo_failed + else + echo_ok + fi + else + echo_skipped + fi + +elif [[ -f "/var/spool/cron/crontabs/root" ]] ; then + + 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 +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 --reallyallowplugins --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 [[ -f "$crontab_backup_file" ]]; then + + if ! grep -i -E "/root/bin/sa-update.sh" "$crontab_backup_file" > /dev/null 2>&1; then + cat << EOF >> $crontab_backup_file + +# - Update spamassassin rules +# - +36 1 * * * /root/bin/sa-update.sh + +EOF + if [[ "$?" -ne 0 ]] ; then + echo_failed + else + echo_ok + fi + else + echo_skipped + fi + +elif [[ -f "/var/spool/cron/crontabs/root" ]] ; then + + 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 +# - +36 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 +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 [[ -f "$crontab_backup_file" ]]; then + + if ! grep -i -E "/root/bin/sa-compile.sh" "$crontab_backup_file" > /dev/null 2>&1; then + cat << EOF >> $crontab_backup_file + +# - Compiling rules (SpamAssassin) +# - +56 1 * * * /root/bin/sa-compile.sh + +EOF + if [[ "$?" -ne 0 ]] ; then + echo_failed + else + echo_ok + fi + else + echo_skipped + fi + +elif [[ -f "/var/spool/cron/crontabs/root" ]] ; then + + 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) +# - +56 1 * * * /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 +fi + +echononl " Restart spamassassin" +if [[ "${os_dist,,}" = "debian" ]] && [[ "$os_version" -lt 12 ]] ; then + _service="spamassassin" +else + _service="spamd" +fi +if $systemd_exists ; then + systemctl restart ${_service} > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + fi +else + if [[ -f "/etc/init.d/${_service}" ]]; then + /etc/init.d/${_service} restart > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + fi + else + echo_skipped + warn "Please restart spamassassin manually.." + 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 > $tmp_err_msg 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + + fi + +else + echo_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)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" +fi + + +echononl " 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)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + fi +else + /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)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + fi +fi + +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)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + fi +else + /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)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + fi +fi + +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)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" +fi + +echononl " Add SecuriteInfo signatur databases to freshclam.conf" +if $SECURITE_INFO_IN_USE ; then + + if [[ -f "/etc/clamav/freshclam.conf" ]] ; then + + _done=false + for signatur_database in $SI_SIGNATUR_DATABASES ; do + + if ! $(grep -q -E "DatabaseCustomURL\s+https://www.securiteinfo.com.*${signatur_database}" "/etc/clamav/freshclam.conf" 2>/dev/null) ; then + + echo "DatabaseCustomURL https://www.securiteinfo.com/get/signatures/${SI_AUTHORISATION_SIGNATURE}/${signatur_database}" >> /etc/clamav/freshclam.conf + + _done=true + + fi + + done + + if $_done ; then + echo_ok + else + echo_skipped + fi + + else + + echo_failed + error "Cannot find freshclam configuration file '/etc/clamav/freshclam.conf'!" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + + fi # if [[ -f "/etc/clamav/freshclam.conf" ]] ; then + +else + echo_skipped +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)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + fi +else + /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)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + fi +fi + +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)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + fi +else + /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)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + fi +fi + + +## - Add cronjob for updating clamav (and freshclam) packages +## - +## - +echononl " Add a cronjob for updating clamav (and freshclam) packages" +if [[ -f "$crontab_backup_file" ]]; then + + if ! grep -i -E "/usr/bin/apt-get\s+.*clamav-daemon" "$crontab_backup_file" > /dev/null 2>&1; then + cat << EOF >> $crontab_backup_file + +# - 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 clamav clamav-base clamav-docs clamav-daemon clamav-freshclam > /dev/null + +EOF + if [[ "$?" -ne 0 ]] ; then + echo_failed + else + echo_ok + fi + else + echo_skipped + fi + +elif [[ -f "/var/spool/cron/crontabs/root" ]] ; then + + 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 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 +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)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + fi + fi + + 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) + + command was: + cpanm -q --skip-installed $_module" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + fi + + + echononl " 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)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + fi + + echononl " 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)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + fi + + + echononl " Check if working directory for 'urlhaus' will be created if not exists.." + _clamav_script="/usr/local/sbin/clamav-unofficial-sigs.sh" + if ! $(grep -q -E "^\s*xshok_mkdir_ownership\s+\"\\\$work_dir_urlhaus\"" "${_clamav_script}" 2> /dev/null) ; then + + if $(grep -q -E "^\s*xshok_mkdir_ownership\s+\"\\\$work_dir\"" "${_clamav_script}" 2> /dev/null) ; then + + perl -i -n -p \ + -e "s#(\s*xshok_mkdir_ownership\s+)(\"\\\$work_dir\")#\1\2\n\1\"\\\$work_dir_urlhaus\"#" \ + "${_clamav_script}" > $tmp_err_msg 2>&1 + + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + fi + + else + echo_skipped + fi + else + echo_skipped + fi + + echononl " Backup directory '/etc/clamav-unofficial-sigs' .." + if [[ -d "/etc/clamav-unofficial-sigs" ]]; then + mv "/etc/clamav-unofficial-sigs" "/etc/clamav-unofficial-sigs.BAK.${backup_date}" > $tmp_err_msg 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + fi + else + echo_skipped + 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)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + fi + fi + 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)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + fi + + echononl " Copy readme file 'INSTALL' into '/etc/clamav-unofficial-sigs/'.." + if [[ -f "/tmp/clamav-unofficial-sigs/INSTALL" ]]; then + cp -a /tmp/clamav-unofficial-sigs/INSTALL /etc/clamav-unofficial-sigs/INSTALL > $tmp_err_msg 2>&1 + + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + fi + + elif [[ -f "/tmp/clamav-unofficial-sigs/INSTALL.md" ]]; then + cp -a /tmp/clamav-unofficial-sigs/INSTALL.md /etc/clamav-unofficial-sigs/INSTALL.md > $tmp_err_msg 2>&1 + + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + fi + + else + echo_skipped + fi + + + + if [[ "${os_dist,,}" = "debian" ]] ; then + + ## - For Debian Jessie (Debian 8) // Stretch (Debian 9) // Buster (Debian 10) // Bullseye (Debian 11) + ## - + _failed=false + echononl " At directory /etc/clamav-unofficial-sigs copy os.debian${os_version}.conf to os.conf" + if [[ ! -f /etc/clamav-unofficial-sigs/os/os.debian${os_version}.conf ]] ; then + _tmp_version=$(expr $os_version - 1) + if [[ -f "/etc/clamav-unofficial-sigs/os/os.debian${_tmp_version}.systemd.conf" ]] ; then + cp "/etc/clamav-unofficial-sigs/os/os.debian${_tmp_version}.systemd.conf" \ + "/etc/clamav-unofficial-sigs/os.conf" > $tmp_err_msg 2>&1 + if [[ $? -ne 0 ]]; then + echo "Error copying /etc/clamav-unofficial-sigs/os.debian${os_version}.systemd.conf" >> $tmp_err_msg + _failed=true + fi + else + if [[ -f "/etc/clamav-unofficial-sigs/os/os.debian.conf" ]] ; then + cp "/etc/clamav-unofficial-sigs/os/os.debian.conf" \ + "/etc/clamav-unofficial-sigs/os.conf" > $tmp_err_msg 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + fi + else + _failed=true + fi + fi + else + cp "/etc/clamav-unofficial-sigs/os/os.debian${os_version}.conf" \ + "/etc/clamav-unofficial-sigs/os.conf" > $tmp_err_msg 2>&1 + if [[ $? -ne 0 ]]; then + _failed=true + fi + fi + if ! $_failed ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + fi + + ## - 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 + + if [[ "${os_dist,,}" = "debian" ]] && [[ "$os_version" -ge 10 ]]; then + perl -i -n -p -e "s#^([ ]*\ *)(clamd_pid=.*)#\#\#\1\2\nclamd_pid=\"/run/clamav/clamd.pid\"#" \ + /etc/clamav-unofficial-sigs/os.conf > $tmp_err_msg 2>&1 + else + 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 + fi + 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 + if [[ "${os_dist,,}" = "debian" ]] && [[ "$os_version" -ge 10 ]]; then + perl -i -n -p -e "s#^([ ]*\#?\ *)(clamd_socket=.*)#\#\#\1\2\nclamd_socket=\"/run/clamav/clamd.ctl\"#" \ + /etc/clamav-unofficial-sigs/os.conf > $tmp_err_msg 2>&1 + else + 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 + fi + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + fi + if ! $installation_failed ; then + echo_ok + fi + + else + + error "Cannot create file 'os.conf' (No Linux Distribution detected) + See file /etc/clamav-unofficial-sigs/INSTALL to create it manually" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + + fi # if [[ "${os_dist,,}" = "debian" ]] + + 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") + +# - SecuriteInfo +# - +# - SecuriteInfo signatures are now directly integrated into ClamAV's Freshclam. +# - +# - We therefore disable them here. +# - +securiteinfo_enabled="no" +EOF + + + 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 + + else + cat << EOF >> /etc/clamav-unofficial-sigs/user.conf 2> $tmp_err_msg + +# - MalwarePatrol +# - +# - Not in use +# - +malwarepatrol_enabled="no" +EOF + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + + fi #if $MALWARE_PATROL_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 + else + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + + fi + + + echononl " Copy Systemd Configurations to /etc/systemd/system" + cp /tmp/clamav-unofficial-sigs/systemd/* /etc/systemd/system/ > $tmp_err_msg 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + fi + + echononl " Adjust /etc/systemd/system/clamav-unofficial-sigs.service" + perl -i -n -p -e "s#^([ ]*\ *)(ExecStart=.*)#\#\#\1\2\nExecStart=/usr/local/sbin/clamav-unofficial-sigs.sh#" \ + /etc/systemd/system/clamav-unofficial-sigs.service > $tmp_err_msg 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + fi + + + echononl " 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) + + command was: + /usr/local/sbin/clamav-unofficial-sigs.sh --install-cron" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + echo "" + echo "" + 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) + + command was: + /usr/local/sbin/clamav-unofficial-sigs.sh --install-logrotate" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + echo "" + echo "" + 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) + + command was: + /usr/local/sbin/clamav-unofficial-sigs.sh --install-man" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + echo "" + echo "" + fi + + echononl " Whitelist signature 'MBL_27966083'.." + echo "MBL_27966083" >> /var/lib/clamav/my_whitelist.ign2 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error " +$(cat $tmp_err_msg) + + command was: + echo "MBL_27966083" >> /var/lib/clamav/my_whitelist.ign2" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + echo "" + echo "" + 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) + + command was: + /usr/local/sbin/clamav-unofficial-sigs.sh" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + echo "" + echo "" + 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)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + echo "" + echo "" + 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" + + #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)" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + + fi +else + echo_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) + + command was: + cpanm -q --skip-installed $_module" + + echononl "continue anyway [yes/no]: " + read OK + OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')" + while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do + echononl "Wrong entry! - repeat [yes/nno]: " + read OK + done + [[ $OK = "yes" ]] || fatal "Abbruch durch User" + fi + +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 + +echononl " Create file '/etc/postfix/sender_whitelist'" +if [[ ! -f "/etc/postfix/sender_whitelist" ]]; then + cat << EOF > /etc/postfix/sender_whitelist 2> '$tmp_err_msg' +# - Example '/etc/postfix/sender_whitelist' +# - +# - Used by Amavis Configuration 'whitelist_sender_maps' / '%whitelist_sender' +# - +# - #full email address +# - some.trustworthy@doma.in 1 +# - +# - #full local part +# - some.trustworthy@ 1 +# - +# - #full email domain +# - in.domain.we.trust 1 +# - +# - #accepting sub domains +# - .we.trust 1 +# - +EOF + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + echo_skipped +fi + +echononl " Create file '/etc/postfix/spam_lovers'" +if [[ ! -f "/etc/postfix/spam_lovers" ]]; then + cat << EOF > /etc/postfix/spam_lovers 2> '$tmp_err_msg' +# - Example '/etc/postfix/spam_lovers' +# - +# - # Adresses +# - adress@domain1.com 1 +# - [..] +# - +# - # All addresses of a domain +# - domain2.com 1 +# - [..] +# - +# - # All adresses of a domain except a single user +# - adress_1@domain3.com 0 +# - domain3.com 1 +# - +# - Wichtig: letzte Zeile mit Newline abschließen! +EOF + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + echo_skipped +fi + +echononl " Create file '/etc/postfix/virus_lovers'" +if [[ ! -f "/etc/postfix/virus_lovers" ]]; then + cat << EOF > /etc/postfix/virus_lovers 2> '$tmp_err_msg' +# - Example '/etc/postfix/virus_lovers' +# - +# - # Adresses +# - adress@domain1.com 1 +# - [..] +# - +# - # All addresses of a domain +# - domain2.com 1 +# - [..] +# - +# - # All adresses of a domain except a single user +# - adress_1@domain3.com 0 +# - domain3.com 1 +# - +# - Wichtig: letzte Zeile mit Newline abschließen! +EOF + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +else + echo_skipped +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 +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}).${backup_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) +# +# 10029: used for whitelisting senders from spam checks BUT NOT from virus check +# +# 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]; +#\$inet_socket_port = [10024, 10029]; +#\$inet_socket_port = [10024, 10026, 10029]; + +# 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, +#}; + + +# Bypass spam checking for whitelisted senders +# +#\$interface_policy{'10029'} = 'VIRUSONLY'; +#\$policy_bank{'VIRUSONLY'} = { # mail from the pickup daemon +# bypass_spam_checks_maps => ['@whitelist_sender_maps'], # don't spam-check this mail +# bypass_banned_checks_maps => ['@whitelist_sender_maps'], # don't banned-check this mail +# bypass_header_checks_maps => ['@whitelist_sender_maps'], # don't header-check this mail +#}; + + +## - 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 +## - + + +## - %whitelist_sender = ( +## - # Full E-Mail Adresses +## - adress1@domain1.com => '1', +## - [..] +## - # Full local Part +##- adresse2@ +## - # All addresses of a domain +## - domain2.com => '1', +## - [..] +## - # Accept Sub Domains +## - .domain3.com => '1', +## - ); +## - +## - But we will use the read_hash function to read in a list +## - of senders from the external file '/etc/postfix/sender_whitelist' +## - +## - Example '/etc/postfix/sender_whitelist' +## - +## - some.trustworthy@doma.in #full email address +## - some.trustworthy@ #full local part +## - in.domain.we.trust #full email domain +## - .we.trust #accepting sub domains +## - +## - +read_hash(\%whitelist_sender, '/etc/postfix/sender_whitelist'); + +## - Global whitelisting of senders. +## - +## - Don't know if this works !! +## - +@whitelist_sender_maps = (\%whitelist_sender); + + + +# ---------------------------------------------------------- +# Basis-Quarantäneverzeichnis +# ---------------------------------------------------------- + +\$QUARANTINEDIR = '${QUARANTINE_DIR}'; + +# Keine automatisch erzeugten Unterverzeichnisse wie a/, b/, c/, f/, g/ +\$quarantine_subdir_levels = 0; + +\$sa_spam_subject_tag = undef; # Kein Prefix wie "***SPAM***" o.ä. +\$sa_spam_modifies_subj = 0; # Betreff NICHT verändern + +# Viren: /var/QUARANTINE/virus/virus-.gz +\$virus_quarantine_method = 'local:virus/virus-%m.gz'; + +# Spam (Kill-Spam): /var/QUARANTINE/spam/spam-.gz +\$spam_quarantine_method = 'local:spam/spam-%m.gz'; + +# Banned: /var/QUARANTINE/banned/banned- +\$banned_files_quarantine_method = 'local:banned/banned-%m'; + +# Bad headers: /var/QUARANTINE/bad-headers/badh- +\$bad_header_quarantine_method = 'local:bad-headers/badh-%m'; + + +# ---------------------------------------------------------- +# Einbinden der Spam- und Virus-Lovers Dateien +# ---------------------------------------------------------- + +@bypass_spam_checks_maps = ( + read_hash('/etc/postfix/spam_lovers'), +); + +@bypass_virus_checks_maps = ( + read_hash('/etc/postfix/virus_lovers'), +); + + +# ---------------------------------------------------------- +# Spam-Schwellwerte +# ---------------------------------------------------------- + +\$sa_tag_level_deflt = 1.9; # ab hier Info-Header +\$sa_tag2_level_deflt = 5.1; # ab hier X-Spam-Flag: YES +\$sa_kill_level_deflt = 9.51; # high-spam - final destiny (DISCARD) +\$sa_dsn_cutoff_level = 20.1; # ab hier keine DSN mehr +\$sa_quarantine_cutoff_level = 30.1; # oberhalb keine Quarantäne mehr + + +# ---------------------------------------------------------- +# Domain-/Adress-spezifische Einstellungen extern einlesen +# ---------------------------------------------------------- + +my \$policy_banks_file = '/etc/amavis/policy_banks.conf'; +if (-r \$policy_banks_file) { + do \$policy_banks_file + or die "Fehler beim Einlesen von \$policy_banks_file: \$@"; +} + + +# ---------------------------------------------------------- +# spammy (zwischen Tag2 und Kill-Level) +# zusätzlich in /spammy/, Mail wird zugestellt +# ---------------------------------------------------------- + +# spammy in /var/QUARANTINE/spammy/ +\$quarantine_method_by_ccat{+CC_SPAMMY} + = 'local:spammy/spammy-%m.gz'; +\$final_destiny_by_ccat{+CC_SPAMMY} = D_PASS; + + +# ---------------------------------------------------------- +# Final Destinies +# ---------------------------------------------------------- + +# High-Spam (>=9.51) +\$final_spam_destiny = D_DISCARD; + +# Viren +\$final_virus_destiny = D_DISCARD; + +# Banned (z.B. .exe) +\$final_banned_destiny = D_BOUNCE; + +# Schlechte Header +\$final_bad_header_destiny = D_PASS; + + +# ---------------------------------------------------------- +# Admin E-Mails / Warnungen direct von AMaViS (nicht DSN- oder Bounce-Mails) +# ---------------------------------------------------------- + +# Bemerkung: +# *nochmal*: das hat nichts mit den eigentlichen DSN-/Bounce-Mails zu tun. + +\$virus_admin = undef; +\$spam_admin = undef; + +\$warnvirusrecip = 0; +\$warnbannedrecip = 0; +\$warnbannedsender = 0; +\$warnbadhrecip = 0; +\$warn_offsite = 0; + + + +# Bypass spam checking for trusted networks using mynetworks +# +# list of trusted IPs: +# +# - $HOSTNAME ($IPV4 [${IPV6}]) +# - b.mx.oopen.de (83.223.86.97 [2a01:30:0:13:21f:92ff:fe00:538b]) +# +#@mynetworks = qw( 127.0.0.0/8 [::1] $IPV4 [${IPV6}] 83.223.86.97 [2a01:30:0:13:21f:92ff:fe00:538b] ); + +#\$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 = 0; # load DKIM signing code, keys defined by dkim_key + +## - DKIM Signing (if \$enable_dkim_signing = 1) by AMaVIS +## - +#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' } } ); + +## - Laut RFC 4871 können auch die +## - +## - Received: from-Zeilen +## - +## - zur Signierung der e-Mail mit herangezogen werden. +## - +## - Dies hat jedoch den Nachteil, dass bei einer Veränderung der Received: from-Zeilen +## - im Nachhinein, wie es z.B. bei der Einlieferung durch Postfix via smtpd_proxy_filter +## - (Pre-Queue) bei AMaViS der Fall sein könnte, die DKIM-Sigantur sprichwörtlich „ +## - kaputt“ geht. +## - +## - Dies kann durch hinzufügen von nachfolgender Konfigurationszeile in die +## - datei /etc/amavisd.conf +## - +## - \$signed_header_fields{'received'} = 0; # turn off signing of Received +## - +## - verhindert werden, indem die Received: from-Zeilen nicht mehr mit in die +## - Berechnung der DKIM-Signatur mit einfließen. +## - +\$signed_header_fields{'received'} = 0; # turn off signing of Received + + + +#------------ 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}).${backup_date}" ]]; then + if diff "${_config_file}" "/etc/amavis/$(basename ${_config_file}).${backup_date}" > /dev/null 2>&1 ; then + info "${_config_file} has not changed.\n\t Removing previos created backup.." + rm "/etc/amavis/$(basename ${_config_file}).${backup_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 + + +## - Create File containing policy settings +## - +_config_policy_banks_file=/etc/amavis/policy_banks.conf +echononl " Create File \"${_config_policy_banks_file}\"" +if [[ -f "${_config_policy_banks_file}" ]]; then + echo_skipped +else + cat <<'EOF' > ${_config_policy_banks_file} +# /etc/amavis/policy_banks.conf +# +# --------------------------------------------- +# Domain- und adressspezifische Amavis-Settings +# --------------------------------------------- +# +# +# Wichtig: KEIN "use strict;" hier, das ist schon in 50-user aktiv. +# Diese Datei wird via "do" aus /etc/amavis/conf.d/50-user eingelesen. +# +# +# Tag2-Level (Schwelle für X-Spam-Flag: YES) abhängig von Empfänger/Domain +# ======================================================================== +# +# +# Read from file using @spam_tag2_level_maps +# ------------------------------------------ +# +# default: @spam_tag2_level_maps = ($sa_tag2_level_deflt); +# +# Example file '/etc/postfix/tag2_level_maps.dat' +# +# # Specific address first +# info@123comics.net 2.1 +# ckubu@oopen.de 2.2 +# ... +# +# # All recipients of the domains @oopen.de / @k8h.de +# oopen.de 3.1 +# k8h.de 4.5 +# +# # default +# . 5.1 +# +# +# Read file into the variable @spam_tag2_level_maps +# +# @spam_tag2_level_maps = ( read_hash('/etc/postfix/tag2_level_maps.dat') ); +# +# +# Set the variable $sa_tag2_level_deflt directly. +# ----------------------------------------------- +# +# Example: +# +# @spam_tag2_level_maps = ( +# { +# # Spezifische Adresse zuerst +# 'info@123comics.net' => 3.1, +# 'info@berliner-register.de' => 3.1, +# +# # Domains (alle Empfänger @oopen.de / @123comics.net) +# '.oopen.de' => 3.1, +# '.123comics.net' => 4.1, +# 'regishut.de' => 2.5, +# }, +# +# # Fallback: Standard-Tag2-Level aus 50-user +# $sa_tag2_level_deflt, +# ); + + +#------------ Do not modify anything below this line ------------- +1; # ensure a defined return +EOF + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +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 +& stop +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 check if AMaViS is running. +## - +echononl " Add a cronjobs to to check if AMaViS is running .." +if [[ -f "/root/bin/monitoring/check_amavis.pl" ]]; then + if [[ -f "$crontab_backup_file" ]]; then + if ! $(grep -q -E "*\s+/root/bin/monitoring/check_amavis.pl\s+" "$crontab_backup_file" 2>/dev/null) ; then + cat << EOF >> $crontab_backup_file + +# - Check if Amavis is running. Restart service if needed.. +# - +*/5 * * * * /root/bin/monitoring/check_amavis.pl -f postmaster -t do-not-reply -s 127.0.0.1 -p 10024 +EOF + if [[ $? -eq 0 ]]; then + echo_done + else + echo_failed + fi + else + echo_skipped + fi + elif [[ -f "/var/spool/cron/crontabs/root" ]] ; then + + installed=false + installation_failed=false + + crontab -l > /tmp/tmp_crontab 2> $tmp_err_msg + if [[ $? -ne 0 ]] ; then + installation_failed=true + fi + + if ! $(grep -q -E "*\s+/root/bin/monitoring/check_amavis.pl\s+" "/tmp/tmp_crontab" 2>/dev/null) ; then + + cat << EOF >> /tmp/tmp_crontab + +# - Check if Amavis is running. Restart service if needed.. +# - +*/5 * * * * /root/bin/monitoring/check_amavis.pl -f postmaster -t do-not-reply -s 127.0.0.1 -p 10024 +EOF + if [[ $? -ne 0 ]] ; then + installation_failed=true + fi + + crontab /tmp/tmp_crontab > /dev/null 2>> $tmp_err_msg + if [[ $? -ne 0 ]] ; then + installation_failed=true + fi + + rm /tmp/tmp_crontab > /dev/null 2>> $tmp_err_msg + if [[ $? -ne 0 ]] ; then + installation_failed=true + fi + + if ! $installation_failed ; then + echo_ok + else + echo_failed + fi + + else + echo_skipped + rm /tmp/tmp_crontab > /dev/null 2>> $tmp_err_msg + if [[ $? -ne 0 ]] ; then + installation_failed=true + fi + if $installation_failed ; then + error "$(cat $tmp_err_msg)" + fi + fi + else + echo_skipped + fi +else + echo_skipped +fi + +## - Add a crontab to cleanup the quarantine folder +## - +echononl " Add a cronjobs to cleanup the quarantine folder" +if [[ -f "$crontab_backup_file" ]]; then + + installed=false + installation_failed=false + if ! grep -i -E "for\s+_file\s+in\s+\\\$\(grep\s+-l\s+\"To:\s+do-not-reply\"" $crontab_backup_file > /dev/null 2>&1; then + + installed=true + cat << EOF >> $crontab_backup_file + +# - Remove quarantined messages generated by check_amavis.pl +# - +2 * * * * for _file in \$(grep -l "To: do-not-reply" /var/QUARANTINE/virus/* 2> /dev/null) ; do rm \$_file ; done +EOF + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + fi + fi + + if ! grep -i -E "find\s+${QUARANTINE_DIR}/spam\s+-type\s+f\s+" "$crontab_backup_file" > /dev/null 2>&1; then + + installed=true + cat << EOF >> $crontab_backup_file + +# - 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 + fi + fi + + if ! $installation_failed ; then + if $installed ; then + echo_ok + else + echo_skipped + fi + else + echo_failed + fi + +elif [[ -f "/var/spool/cron/crontabs/root" ]] ; then + + installed=false + installation_failed=false + if ! grep -i -E "for\s+_file\s+in\s+\\\$\(grep\s+-l\s+\"To:\s+do-not-reply\"" /var/spool/cron/crontabs/root > /dev/null 2>&1; then + + installed=true + + 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 quarantined messages generated by check_amavis.pl +# - +2 * * * * for _file in \$(grep -l "To: do-not-reply" /var/QUARANTINE/virus/* 2> /dev/null) ; do rm \$_file ; done +EOF + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + fi + + if ! grep -i -E "find\s+${QUARANTINE_DIR}/spam\s+-type\s+f\s+" /var/spool/cron/crontabs/root > /dev/null 2>&1; then + + installed=true + + if [[ ! -f "/tmp/tmp_crontab" ]]; then + crontab -l > /tmp/tmp_crontab 2> $tmp_err_msg + if [[ "$?" -ne 0 ]] ; then + installation_failed=true + error "$(cat $tmp_err_msg)" + fi + 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 + fi + + if $installed ; then + 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 + else + echo_failed + fi + else + echo_skipped + fi +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,[::1]/128 +## - -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,[::1]/128,<$_ipv4_address/32> +## - -o receive_override_options=no_unknown_recipient_checks +## - +postfix_master_cf="/etc/postfix/master.cf" +echo "" +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 + +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 +if grep -iq -E "^[0-9]{2,5}\s+inet.*smtpd" $postfix_master_cf > /dev/null 2>&1 ; then + listen_on_additional_smtp_port=true + additional_smtp_port="$(grep -E "^[0-9]{2,5}\s+inet.*smtpd" /etc/postfix/master.cf | grep -o -E "^[0-9]{2,5}")" +else + listen_on_additional_smtp_port=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= + -o smtpd_milters= + -o non_smtpd_milters= +EOF + if [[ "$SASL_AUTH_ENABLED" = "no" ]] ; then + cat >> $postfix_master_cf << EOF + -o smtpd_sasl_auth_enable=no +EOF + fi + + 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,[::1]/128 + -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,[::1]/128 + -o receive_override_options=no_unknown_recipient_checks +EOF + if [[-n "$(which opendmarc)" ]] ; then + cat >> $postfix_master_cf << EOF + -o smtpd_milters=local:/opendmarc/opendmarc.sock +EOF + fi + cat >> $postfix_master_cf << EOF + #-o mynetworks=127.0.0.0/8,[::1]/128,${IPV4}/32 +EOF + fi + + continue + fi + + if ${listen_on_additional_smtp_port} \ + && echo "$_line" | grep -i -E "^\s*${additional_smtp_port}\s+inet" > /dev/null 2>&1 ; then + _found=true + cat >> $postfix_master_cf << EOF +${additional_smtp_port} inet n - y - - smtpd + -o smtpd_proxy_filter=127.0.0.1:10024 + -o content_filter= +EOF + if [[ "$SASL_AUTH_ENABLED" = "no" ]] ; then + cat >> $postfix_master_cf << EOF + -o smtpd_sasl_auth_enable=no +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 +EOF + if [[ -n "$(which opendkim)" ]] ; then + cat >> $postfix_master_cf << EOF + -o smtpd_milters=local:/opendkim/opendkim.sock +EOF + fi + cat >> $postfix_master_cf << EOF + #-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,[::1]/128 + -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,[::1]/128 + -o receive_override_options=no_unknown_recipient_checks +EOF + if [[ -n "$(which opendmarc)" ]] ; then + cat >> $postfix_master_cf << EOF + -o smtpd_milters=local:/opendmarc/opendmarc.sock +EOF + fi + cat >> $postfix_master_cf << EOF + #-o mynetworks=127.0.0.0/8,[::1]/128,${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 + _found=true + 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 +EOF + if [[ -n "$(which opendkim)" ]] ; then + cat >> $postfix_master_cf << EOF + -o smtpd_milters=local:/opendkim/opendkim.sock +EOF + fi + cat >> $postfix_master_cf << EOF + #-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,[::1]/128 + -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,[::1]/128 + -o receive_override_options=no_unknown_recipient_checks +EOF + if [[ -n "$(which opendmarc)" ]] ; then + cat >> $postfix_master_cf << EOF + -o smtpd_milters=local:/opendmarc/opendmarc.sock +EOF + fi + cat >> $postfix_master_cf << EOF + #-o mynetworks=127.0.0.0/8,[::1]/128,${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,[::1]/128 + -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,[::1]/128 + -o receive_override_options=no_unknown_recipient_checks +EOF + if [[ -n "$(which opendmarc)" ]] ; then + cat >> $postfix_master_cf << EOF + -o smtpd_milters=local:/opendmarc/opendmarc.sock +EOF + fi + cat >> $postfix_master_cf << EOF + #-o mynetworks=127.0.0.0/8,[::1]/128,${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}.$backup_date" + +echo_done +warn "Please check file \"$postfix_master_cf\" !" + + +echononl " Reenable previously saved crontab from '$crontab_backup_file'.." +crontab $crontab_backup_file > $tmp_err_msg 2>&1 +if [[ $? -eq 0 ]]; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + + + +# --- +# --- 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 + +if ${listen_on_additional_smtp_port}; then + + echo "" + warn "Please do not forget to allow incomming traffic on port \033[1m${additional_smtp_port}\033[m. + Check your firewall settings.." +fi + + +#fi # if $ommit ; then +# ------------------------------- + + + + +rm $tmp_err_msg +echo "" +exit 0 diff --git a/BAK/install_opendkim.sh.Pre-Queue.00 b/BAK/install_opendkim.sh.Pre-Queue.00 new file mode 100755 index 0000000..b1e2adf --- /dev/null +++ b/BAK/install_opendkim.sh.Pre-Queue.00 @@ -0,0 +1,684 @@ +#!/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)" + +backup_date="$(date +%Y-%m-%d-%H%M)" + +_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 +# - +SYSTEMD_EXISTS=false +systemd=$(which systemd) +systemctl=$(which systemctl) + +if [[ -n "$systemd" ]] || [[ -n "$systemctl" ]] ; then + 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 + +echononl " Backup existing file '${opendkim_conf_file}'.." +if [[ -f "${opendkim_conf_file}" ]] ; then + mv "${opendkim_conf_file}" "${opendkim_conf_file}.${backup_date}" + 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 + +# Sets the "authserv-id" to use when generating the Authentication-Results: +# header field after verifying a message. The default is to use the name of +# the MTA processing the message. If the string "HOSTNAME" is provided, the +# name of the host running the filter (as returned by the gethostname(3) +# function) will be used. +AuthservID "DKIM check $(hostname -f)" + +# 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 + +# Add an "Authentication-Results:" header field even to unsigned messages +# from domains with no "signs all" policy. The reported DKIM result will be +# "none" in such cases. Normally unsigned mail from non-strict domains does +# not cause the results header field to be added. +AlwaysAddARHeader yes + +# Causes opendkim to fork and exits immediately, leaving the service running +# in the background. The default is "true". +Background yes + +# Sets the DNS timeout in seconds. A value of 0 causes an infinite wait. The +# default is 5. Ignored if not using an asynchronous resolver package. See +# also the NOTES section below. +DNSTimeout 5 +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 = + +# Was sind non_smtpd_milters? +# +# non_smtpd_milters gilt für alle Postfix-Prozesse, die Mails verarbeiten, aber NICHT +# der smtpd-Daemon sind. +# +# Das betrifft z. B.: +# +# cleanup Header/Content-Bereinigung +# qmgr Queue-Manager +# lmtp / smtp Auslieferung nach extern +# local lokale Zustellung +# +# Das sind z. B.: +# +# - interne Bounces (MAILER-DAEMON) +# +# - Cron-Mails vom Server +# +# - Weiterleitungen, die Postfix selbst generiert +# +# - Mails, die über sendmail CLI gesendet werden +# +# - Mails, die Amavis über LMTP zurückgibt +# +# - etc. +# +# +# DKIM soll auch die ausgehenden Mails signieren, die nicht über smtpd daemon versendet werden. +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 + if ! echo "$_line" | grep -i -q -E "^\s*-o\s+smtpd_milters=\s*local:/opendkim/opendkim.sock\s*$" ; then + echo " -o smtpd_milters=local:/opendkim/opendkim.sock" >> "$tmp_master_file" + _changed=true + continue + fi + fi + + if echo "$_line" | grep -i -q -E "^\s*(submission|smtps)\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 + info "Postfix (master.cf) was not changed - seems already be configured right." + 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/BAK/install_opendmarc.sh.Pre-Queue.00 b/BAK/install_opendmarc.sh.Pre-Queue.00 new file mode 100755 index 0000000..c33c530 --- /dev/null +++ b/BAK/install_opendmarc.sh.Pre-Queue.00 @@ -0,0 +1,936 @@ +#!/usr/bin/env bash + +clear +echo -e "\n \033[32mStart Installation of OpenDMARC..\033[m" + +overwrite_config_files=true + + +# ------------- +# - Settings +# ------------- + +#_src_base_dir="$(realpath $(dirname $0))" +#conf_file="${_src_base_dir}/conf/install_opendmarc.conf" + +_opendmarc_packages="opendmarc" + +opendmarc_base_dir="/etc/opendmarc" +opendmarc_conf_file="/etc/opendmarc.conf" + +postfix_spool_dir="/var/spool/postfix" + +opendmarc_socket_dir="${postfix_spool_dir}/opendmarc" +opendmarc_socket_file="${opendmarc_socket_dir}/opendmarc.sock" + +config_file_name_value_parameters=" + AuthservID|$(hostname -f) + TrustedAuthservIDs|$(hostname -f) + PidFile|/run/opendmarc/opendmarc.pid + RejectFailures|true + Syslog|true + SyslogFacility|mail + IgnoreHosts|${opendmarc_base_dir}/ignore.hosts + IgnoreMailFrom|${opendmarc_base_dir}/ignore.mailfrom + IgnoreAuthenticatedClients|true + RequiredHeaders|false + UMask|002 + FailureReports|false + AutoRestart|true + HistoryFile|/run/opendmarc/opendmarc.dat + SPFIgnoreResults|false + SPFSelfValidate|true + Socket|${opendmarc_socket_file} +" +declare -a config_file_name_value_parameter_arr=() +for _conf in $config_file_name_value_parameters ; do + config_file_name_value_parameter_arr+=("$_conf") +done + +postfix_needs_restart=false +opendmarc_needs_restart=false + +backup_date="$(date +%Y-%m-%d-%H%M)" +log_file="$(mktemp)" + +# ------------- +# --- 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 +# - +SYSTEMD_EXISTS=false +systemd=$(which systemd) +systemctl=$(which systemctl) + +if [[ -n "$systemd" ]] || [[ -n "$systemctl" ]] ; then + 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 opendmarc +# - +echononl " Install needed debian packages.." +opendmarc_packages="" +packages_installed=false +for _pkg in $_opendmarc_packages ; do + if aptitude search "$_pkg" | grep " $_pkg " | grep -e "^i" > /dev/null 2>&1 ; then + continue + else + opendmarc_packages="$opendmarc_packages $_pkg" + fi +done +if [[ -n "$opendmarc_packages" ]]; then + DEBIAN_FRONTEND=noninteractive apt-get -y install $opendmarc_packages > /dev/null 2> "$log_file" + packages_installed=true + opendmarc_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 'opendmarc' +# - +echononl " Add user 'postfix' to group 'opendmarc'.." +if grep -E "^opendmarc" /etc/group | grep -q postfix 2> /dev/null ; then + echo_skipped +else + usermod -a -G opendmarc postfix > "$log_file" 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +fi + + +# - Add 'IgnoreHosts' with default value to the original opendmarc.conf file +# +echononl " Add 'IgnoreHosts' with default value to the opendmarc.conf file.." +if ! $(grep -q -E "^IgnoreHosts\s+" ${opendmarc_conf_file} 2> /dev/null) ; then + cat << EOF >> ${opendmarc_conf_file} + +## Specifies the path to a file that contains a list of hostnames, IP addresses, +## and/or CIDR expressions identifying hosts whose SMTP connections are to be +## ignored by the filter. If not specified, defaults to "127.0.0.1" only. +# +IgnoreHosts 127.0.0.1 + +# Optional - auch nach Absender-Domain ignorieren: +IgnoreMailFrom ${opendmarc_base_dir}/ignore.mailfrom +EOF + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + +# - Add 'IgnoreAuthenticatedClients' with default value to the original opendmarc.conf file +# +_param="IgnoreAuthenticatedClients" +echononl " Add '${_param}' with default value to the opendmarc.conf file.." +if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then + cat << EOF >> ${opendmarc_conf_file} + +## If set, causes mail from authenticated clients (i.e., those that used +## SMTP AUTH) to be ignored by the filter. The default is "false". +# +IgnoreAuthenticatedClients false +EOF + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + +# - Add 'TrustedAuthservIDs' with default value to the original opendmarc.conf file +# +_param="TrustedAuthservIDs" +echononl " Add '${_param}' with default value to the opendmarc.conf file.." +if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then + cat << EOF >> ${opendmarc_conf_file} + +# Provides a list of authserv-ids that are to be used to identify Authentication-Results +# header fields whose contents are to be assumed as valid input for the DMARC assessment. +# To provide a list, separate values by commas. If the string "HOSTNAME" is provided, +# the name of the host running the filter (as returned by the gethostname(3) function) +# will be used. Matching against this list is case-insensitive. The default is to use the +# value of AuthservID. +# +TrustedAuthservIDs OpenDMARC +EOF + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + +# - Add 'RequiredHeaders' with default value to the original opendmarc.conf file +# +_param="IgnoreAuthenticatedClients" +echononl " Add '${_param}' with default value to the opendmarc.conf file.." +if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then + cat << EOF >> ${opendmarc_conf_file} + +## If set, causes mail from authenticated clients (i.e., those that used +## SMTP AUTH) to be ignored by the filter. The default is "false". +# +IgnoreAuthenticatedClients false +EOF + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + +# - Add 'RequiredHeaders' with default value to the original opendmarc.conf file +# +_param="RequiredHeaders" +echononl " Add '${_param}' with default value to the opendmarc.conf file.." +if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then + cat << EOF >> ${opendmarc_conf_file} + +## If set, the filter will ensure the header of the message conforms to the basic +## header field count restrictions laid out in RFC5322, Section 3.6. Messages +## failing this test are rejected without further processing. A From: field from +## which no domain name could be extracted will also be rejected. +# +RequiredHeaders false +EOF + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + +# - Add 'AutoRestart' with default value to the original opendmarc.conf file +# +_param="AutoRestart" +echononl " Add '${_param}' with default value to the opendmarc.conf file.." +if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then + cat << EOF >> ${opendmarc_conf_file} + +## Automatically re-start on failures. Use with caution; if the filter fails +## instantly after it starts, this can cause a tight fork(2) loop. +# +AutoRestart false +EOF + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + +# - Add 'HistoryFile' with default value to the original opendmarc.conf file +# +_param="HistoryFile" +echononl " Add '${_param}' with default value to the opendmarc.conf file.." +if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then + cat << EOF >> ${opendmarc_conf_file} + +## If set, specifies the location of a text file to which records are written +## that can be used to generate DMARC aggregate reports. Records are batches of +## rows containing information about a single received message, and include all +## relevant information needed to generate a DMARC aggregate report. It is +## expected that this will not be used in its raw form, but rather periodically +## imported into a relational database from which the aggregate reports can be +## extracted using opendmarc-importstats(8). +# +HistoryFile /run/opendmarc/opendmarc.dat +EOF + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + +# - Add 'SPFIgnoreResults' with default value to the original opendmarc.conf file +# +_param="SPFIgnoreResults" +echononl " Add '${_param}' with default value to the opendmarc.conf file.." +if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then + cat << EOF >> ${opendmarc_conf_file} + +## Causes the filter to ignore any SPF results in the header of the message. This +## is useful if you want the filter to perform SPF checks itself, or because you +## don't trust the arriving header. The default is "false". +# +SPFIgnoreResults false +EOF + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + +# - Add 'SPFSelfValidate' with default value to the original opendmarc.conf file +# +_param="SPFSelfValidate" +echononl " Add '${_param}' with default value to the opendmarc.conf file.." +if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then + cat << EOF >> ${opendmarc_conf_file} + +## Causes the filter to perform a fallback SPF check itself when it can find no +## SPF results in the message header. If SPFIgnoreResults is also set, it never +## looks for SPF results in headers and always performs the SPF check itself when +## this is set. The default is "false". +# +SPFSelfValidate false +EOF + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + + +# - Save configuration file from distribution +# - +echononl " Save configuration file from distribution" +if [[ -f "${opendmarc_conf_file}.ORIG" ]] ; then + echo_skipped +else + cp -a $opendmarc_conf_file $opendmarc_conf_file.ORIG 2> "$log_file" + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +fi + +for _val in "${config_file_name_value_parameter_arr[@]}" ; do + IFS='|' read -a _val_arr <<< "${_val}" + + echononl " $opendmarc_conf_file: ${_val_arr[0]} -> ${_val_arr[1]}.." + if $(grep -E -q "^\s*${_val_arr[0]}\s+${_val_arr[1]}\s*$" $opendmarc_conf_file 2> /dev/null) ; then + echo_skipped + elif $(grep -E -q "^\s*#\s*${_val_arr[0]}\s+" $opendmarc_conf_file 2> /dev/null); then + perl -i -n -p -e "s&^(\s*#\s*${_val_arr[0]}.*)&\1\n${_val_arr[0]} ${_val_arr[1]}&" $opendmarc_conf_file > "$log_file" 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + opendmarc_needs_restart=true + else + echo_failed + error "$(cat $log_file)" + fi + elif $(grep -E -q "^\s*${_val_arr[0]}\s+" $opendmarc_conf_file 2> /dev/null) ; then + perl -i -n -p -e "s#^(\s*${_val_arr[0]}.*)#\#\1\n${_val_arr[0]} ${_val_arr[1]}#" $opendmarc_conf_file > "$log_file" 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + opendmarc_needs_restart=true + else + echo_failed + error "$(cat $log_file)" + fi + else + cat <> $opendmarc_conf_file 2> "$log_file" + +${_val_arr[0]} ${_val_arr[1]} +EOF + if [[ $? -eq 0 ]] ; then + echo_ok + opendmarc_needs_restart=true + else + echo_failed + error "$(cat $log_file)" + fi + fi +done + + +# - Assign ownership to the opendmarc user and restrict tthe +# - file permissions: +# - +echononl " Assign file permissions to '$opendmarc_conf_file'.." +chmod u=rw,go=r $opendmarc_conf_file 2> $log_file +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + + +# - Create the directories to hold opendmarc's data files, assign +# - ownership to the opendmarc user, and restrict the file +# - permissions: +# - +echononl " Create directory '$opendmarc_base_dir'" +if [[ -d "$opendmarc_base_dir" ]] ; then + echo_skipped +else + opendmarc_needs_restart=true + mkdir ${opendmarc_base_dir} 2> $log_file + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +fi +echononl " Set ownership on directory '${opendmarc_base_dir}' (recursive).." +chown -R opendmarc:opendmarc ${opendmarc_base_dir} 2> $log_file +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + + +echononl " Backup existing file '${opendmarc_base_dir}/ignore.hosts'.." +if [[ -f "${opendmarc_base_dir}/ignore.hosts" ]] ; then + mv "${opendmarc_base_dir}/ignore.hosts" "${opendmarc_base_dir}/ignore.hosts.${backup_date}" + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +# - Create the file ${opendmarc_base_dir}/ignore.hosts +# - +echononl " Create file '${opendmarc_base_dir}/ignore.hosts'.." +if [[ -f "${opendmarc_base_dir}/ignore.hosts" ]] ; then + echo_skipped +else + cat < ${opendmarc_base_dir}/ignore.hosts 2> $log_file +# /etc/opendmarc/ignore.hosts +# +# Aktuell hat OpenDMARC seinen Milter nur am Dienst +# 'localhost:10025' hängen. Dort ist der Client +# immer 127.0.0.1, nicht die externe Gegenstelle. +# +# Deshalb macht es in diesem Setup keinen Sinn, +# hier IP-Adressen von externen Diensten (CRSend etc.) +# einzutragen – sie würden nie matchen. +# +# WICHTIG: +# - KEIN 127.0.0.1 +# - KEIN localhost +# - KEIN ::1 +# +# Eintrag dieser Adressen würde DMARC komplett deaktivieren. +# +# ==> Datei bleibt absichtlich leer. +EOF + opendmarc_needs_restart=true + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +fi + + +# - Create the file ${opendmarc_base_dir}/ignore.hosts +# - + +echononl " Backup existing file '${opendmarc_base_dir}/ignore.mailfrom'.." +if [[ -f "${opendmarc_base_dir}/ignore.mailfrom" ]] ; then + mv "${opendmarc_base_dir}/ignore.mailfrom" "${opendmarc_base_dir}/ignore.mailfrom.${backup_date}" + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +echononl " Create file '${opendmarc_base_dir}/ignore.mailfrom'.." +if [[ -f "${opendmarc_base_dir}/ignore.mailfrom" ]] ; then + echo_skipped +else + cat < ${opendmarc_base_dir}/ignore.mailfrom 2> $log_file +# /etc/opendmarc/ignore.mailfrom +# +# Hier könnte man Absender-Domains von der DMARC-Prüfung +# ausnehmen (z. B. problematische Partner-Domains). +# +# Aktuell ist das für dein Setup nicht notwendig. +# +# Beispiele (NICHT aktiv!): +# @example.org +# example.org +# +# ==> Datei bleibt absichtlich leer. +EOF + opendmarc_needs_restart=true + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +fi + + +# - Edit /etc/default/opendmarc +# - +# - Set: +# - SOCKET="local:${postfix_spool_dir}/opendmarc/opendmarc.sock" +# - +echononl " Set 'SOCKET' at file /etc/default/opendmarc.." +if grep -q -E "^\s*SOCKET" /etc/default/opendmarc 2>/dev/null ; then + if grep -q -E "^\s*SOCKET\s*=\s*\"*local:$opendmarc_socket_file" /etc/default/opendmarc 2>/dev/null ; then + echo_skipped + else + perl -i -n -p -e "s#^\s*SOCKET=.*#SOCKET=\"local:$opendmarc_socket_file\"#" /etc/default/opendmarc 2> $log_file + opendmarc_needs_restart=true + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + fi +else + cat <>/etc/default/opendmarc 2> $log_file +SOCKET="local:$opendmarc_socket_file" +EOF + opendmarc_needs_restart=true + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +fi + + +# - Create the opendmarc socket directory in Postfix’s work area +# - and make sure it has the correct ownership: +# - +echononl " Create the opendmarc socket directory in Postfix's work area.." +if [[ -d "${postfix_spool_dir}/opendmarc" ]] ; then + echo_skipped +else + mkdir ${postfix_spool_dir}/opendmarc 2> $log_file + opendmarc_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}/opendmarc'.." + chown opendmarc:postfix ${postfix_spool_dir}/opendmarc 2> $log_file + 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 opendmarc daemon: +# - +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 " Set Variable non_smtpd_milters at '/etc/postfix/main.cf'.." +if $(grep -q -E "^\s*non_smtpd_milters\s*=\s*.*opendkim.sock" /etc/postfix/main.cf 2> /dev/null) ; then + if $(grep -q -E "^\s*non_smtpd_milters\s*=\s*.*$(basename "${opendmarc_socket_file}")" /etc/postfix/main.cf); then + echo_skipped + else + perl -i -n -p -e "s&^\s*(non_smtpd_milters\s*=.*opendkim.sock)&\1,local:/$(basename "${opendmarc_socket_dir}")/$(basename "${opendmarc_socket_file}")&" \ + /etc/postfix/main.cf > $log_file 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + postfix_needs_restart=true + else + echo_failed + error "$(cat $log_file)" + fi + fi +else + echo_skipped + warn "Postfix is not adjusted. Complete Postfix configuration (main.cf) manually\!" +fi + + +echo "" + + +# - 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 + info "Postfix (main.cf) was not changed - seems already be configured right." + 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 = + +# Was sind non_smtpd_milters? +# +# non_smtpd_milters gilt für alle Postfix-Prozesse, die Mails verarbeiten, aber NICHT +# der smtpd-Daemon sind. +# +# Das betrifft z. B.: +# +# cleanup Header/Content-Bereinigung +# qmgr Queue-Manager +# lmtp / smtp Auslieferung nach extern +# local lokale Zustellung +# +# Das sind z. B.: +# +# - interne Bounces (MAILER-DAEMON) +# +# - Cron-Mails vom Server +# +# - Weiterleitungen, die Postfix selbst generiert +# +# - Mails, die über sendmail CLI gesendet werden +# +# - Mails, die Amavis über LMTP zurückgibt +# +# - etc. +# +# +# DKIM soll auch die ausgehenden Mails signieren, die nicht über smtpd daemon versendet werden. +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 + + +echo "" + + +# - Prevent Postfix from setting the DMARC 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:/opendmarc/opendmarc.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 DMARC 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:/opendmarc/opendmarc.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 + if ! echo "$_line" | grep -i -q -E "^\s*-o\s+smtpd_milters=\s*local:/opendmarc/opendmarc.sock\s*$" ; then + echo " -o smtpd_milters=local:/opendmarc/opendmarc.sock" >> "$tmp_master_file" + _changed=true + continue + fi + + fi + + if echo "$_line" | grep -i -q -E "^\s*(localhost|127.0.0.1):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 + info "Postfix (master.cf) was not changed - seems already be configured right." + 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 "" + +echononl " Enable OpenDMARC Service" +if $SYSTEMD_EXISTS ; then + systemctl enable opendmarc > $log_file 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + warn "Maybe OpenDMARC Service is not enabled, because its an old non-systemd os.." +fi + +# - Restart opendmarc +# - +echononl " Restart opendmarc.." +if $opendmarc_needs_restart ; then + if $SYSTEMD_EXISTS ; then + systemctl restart opendmarc > $log_file 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi + else + /etc/init.d/opendmarc 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 opendmarc 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