#!/usr/bin/env bash script_dir="$(dirname $(realpath $0))" script_name="$(basename "$0")" conf_dir=$(dirname $0)/conf conf_file="${conf_dir}/install_postfix_base.conf" _TLS_CERT_DIR=/etc/postfix/ssl _TLS_CERT_FILE="${_TLS_CERT_DIR}/mailserver.crt" _TLS_KEY_FILE="${_TLS_CERT_DIR}/mailserver.key" _TLS_CA_FILE=/etc/ssl/certs/ca-certificates.crt log_file=$(mktemp) # ------------- # --- Some functions # ------------- clean_up() { # Perform program exit housekeeping rm -f $log_file exit $1 } echononl(){ echo X\\c > /tmp/shprompt$$ if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then echo -e -n "$*\\c" 1>&2 else echo -e -n "$*" 1>&2 fi rm /tmp/shprompt$$ } fatal(){ echo "" echo -e "fatal error: $*" echo "" echo -e "\t\033[31m\033[1mInstalllation will be interrupted\033[m\033[m" echo "" clean_up 1 } error(){ echo "" echo -e "\t[ \033[31m\033[1mFehler\033[m ]: $*" echo "" } warn (){ echo "" echo -e "\t[ \033[33m\033[1mWarning\033[m ]: $*" echo "" } info (){ echo "" echo -e "\t[ \033[32m\033[1mInfo\033[m ]: $*" echo "" } echo_done() { echo -e "\033[80G[ \033[32mdone\033[m ]" } echo_ok() { echo -e "\033[80G[ \033[32mok\033[m ]" } echo_warning() { echo -e "\033[80G[ \033[33m\033[1mwarn\033[m ]" } echo_failed(){ echo -e "\033[80G[ \033[1;31mfailed\033[m ]" } echo_skipped() { echo -e "\033[80G[ \033[33m\033[1mskipped\033[m ]" } blank_line() { if $terminal ; then echo "" fi } trim() { local var="$*" var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters echo -n "$var" } 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_ADMIN_EMAIL="argus@oopen.de" DEFAULT_RELAY_HOST="b.mx.oopen.de" DEFAULT_RELAY_PORT=25 DEFAULT_SASL_AUTH=false DEFAULT_REWRITE_SENDER_DOMAIN=None # - Is this a systemd system? # - if [[ "X`which systemd`" = "X" ]]; then systemd_exists=false else systemd_exists=true fi echo "" # - Read Configuration File if exists # - if [[ -f "$conf_file" ]]; then source $conf_file fi # ------------- # --- Set default values for some non existent variables (i.e. no configuration file is present) # ------------- [[ -z "$_ADMIN_EMAIL" ]] && _ADMIN_EMAIL="$DEFAULT_ADMIN_EMAIL" [[ -z "$_SASL_AUTH" ]] && _SASL_AUTH="$DEFAULT_SASL_AUTH" if [[ -z "$_HOSTNAME" ]] ; then _HOSTNAME="$(hostname -f)" _HOSTNAME_SHORT="$(hostname)" [[ "$_HOSTNAME" = "$_HOSTNAME_SHORT" ]] && _HOSTNAME="" fi blank_line echononl "Detect distribution/release of running OS.." detect_os_1 > /dev/null 2>&1 if [[ $? -ne 0 ]]; then echo_failed else echo_ok fi blank_line blank_line #clear echo -e "\033[21G\033[32mInstallation script for Postfix basic mailsystem \033[m" echo HOSTNAME= echo "" echo -e "\033[32m--\033[m" echo "" echo "Insert hostname" echo "" if [[ -n "$_HOSTNAME" ]]; then echononl "hostname [${_HOSTNAME}]: " read HOSTNAME if [[ "X${HOSTNAME}" = "X" ]]; then HOSTNAME=$_HOSTNAME fi else while [[ "X${HOSTNAME}" = "X" ]]; do echononl "hostname: " read HOSTNAME if [[ "X${HOSTNAME}" = "X" ]]; then echo -e "\n\t\033[33m\033[1mHostname is reqired\033[m\n" fi done fi # ------------- # --- 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 if [[ -z $_IPV6 ]]; then _IPV6=None fi IPV4= echo "" echo -e "\033[32m--\033[m" echo "" echo "Insert IPv4 address" echo "" if [[ -n "$_IPV4" ]]; then echononl "IPv4 address [${_IPV4}]: " read IPV4 if [[ "X${IPV4}" = "X" ]]; then IPV4=$_IPV4 fi else while [[ "X${IPV4}" = "X" ]]; do echononl "IPv4 address: " read IPV4 if [[ "X${IPV4}" = "X" ]]; then echo -e "\n\t\033[33m\033[1mIPv4 address is reqired\033[m\n" fi done fi IPV6= echo "" echo -e "\033[32m--\033[m" echo "" echo "Insert IPv6 address" echo "Type:" echo -e "\t\033[33mNone\033[m if IPv6 is not suppoerted" echo "" if [[ -n "$_IPV6" ]]; then [[ "X$_IPV6" = "Xdisabled" ]] && _IPV6=None echononl "IPv6 address [${_IPV6}]: " read IPV6 if [[ "X${IPV6}" = "X" ]]; then IPV6=$_IPV6 fi else while [[ "X${IPV6}" = "X" ]]; do echononl "IPv6 address: " read IPV6 if [[ "X${IPV6}" = "X" ]]; then echo -e "\n\t\033[33m\033[1mIPv4 address is reqired\033[m\n" fi done fi if [ "X$IPV6" = "Xnone" -o "X$IPV6" = "XNone" ]; then IPV6=disabled fi ADMIN_EMAIL= echo "" echo "" echo -e "\033[32m--\033[m" echo "" echo "Insert e-mail address where messages to local root should be forwarded" echo "" echo "" if [[ -n "$_ADMIN_EMAIL" ]]; then echononl "Admin e-mail address [$_ADMIN_EMAIL]: " read ADMIN_EMAIL if [[ "X${ADMIN_EMAIL}" = "X" ]]; then ADMIN_EMAIL=$_ADMIN_EMAIL fi else while [[ "X${ADMIN_EMAIL}" = "X" ]]; do echononl "Admin e-mail address: " read ADMIN_EMAIL if [[ "X${ADMIN_EMAIL}" = "X" ]]; then echo -e "\n\t\033[33m\033[1mAdmin e-mail address is reqired\033[m\n" fi done fi SASL_AUTH= echo "" echo "" echo -e "\033[32m--\033[m" echo "" echo "Should this System relay mails through another host using sasl auth?" echo "" if [[ -n "$_SASL_AUTH" ]]; then if $_SASL_AUTH ; then echononl "Relay mails using sasl auth? [yes]; " read SASL_AUTH if [[ "X${SASL_AUTH}" = "X" ]]; then SASL_AUTH=true else SASL_AUTH=${SASL_AUTH,,} if [ "X$SASL_AUTH" != "Xyes" -a "X$SASL_AUTH" != "Xno" ]; then echononl "Wrong entry {yes/no]: " fi fi else echononl "Relay mails using sasl auth? [no]; " read SASL_AUTH if [[ "X${SASL_AUTH}" = "X" ]]; then SASL_AUTH=false else SASL_AUTH=${SASL_AUTH,,} if [ "X$SASL_AUTH" != "Xyes" -a "X$SASL_AUTH" != "Xno" ]; then echononl "Wrong entry [yes/no]: " fi fi fi else echononl "Relay mails using sasl auth? (yes/no); " while [[ "X${SASL_AUTH}" = "X" ]] ; do read SASL_AUTH SASL_AUTH=${SASL_AUTH,,} if [ "X$SASL_AUTH" != "Xyes" -a "X$SASL_AUTH" != "Xno" ]; then SASL_AUTH= echononl "Wrong entry [yes/no]: " fi done fi # ------------- # --- Some further default values depending on sasl authentification # ------------- # - Set default value for relay host / relay port if sasl authentification should be # - supported and value for _RELAY_HOST / _RELAY_PORT not given # - if [[ "$SASL_AUTH" = "yes" ]] || $SASL_AUTH ; then [[ -z "$_RELAY_HOST" ]] && _RELAY_HOST="$DEFAULT_RELAY_HOST" [[ -z "$_RELAY_PORT" ]] && _RELAY_PORT="$DEFAULT_RELAY_PORT" fi if [[ -z ${_REWRITE_SENDER_DOMAIN} ]] ; then _REWRITE_SENDER_DOMAIN="${DEFAULT_REWRITE_SENDER_DOMAIN}" fi if [[ "$SASL_AUTH" = "yes" ]] || $SASL_AUTH ; then SASL_AUTH=true SASL_USER= echo "" echo "Insert SASL user" echo "" if [[ -n "$_SASL_USER" ]];then echononl "SASL user [$_SASL_USER]: " read SASL_USER if [[ "X${SASL_USER}" = "X" ]]; then SASL_USER=$_SASL_USER fi else while [[ "X${SASL_USER}" = "X" ]]; do echononl "SASL user: " read SASL_USER if [[ "X${SASL_USER}" = "X" ]]; then echo -e "\n\t\033[33m\033[1mSASL user is reqired\033[m\n" fi done fi SASL_PASS= echo "" echo "Insert SASL pasword" echo "" if [[ -n "$_SASL_PASS" ]];then echononl "SASL password [$_SASL_PASS]: " read SASL_PASS if [[ "X${SASL_PASS}" = "X" ]]; then SASL_PASS=$_SASL_PASS fi else while [[ "X${SASL_PASS}" = "X" ]]; do echononl "SASL password: " read SASL_PASS if [[ "X${SASL_PASS}" = "X" ]]; then echo -e "\n\t\033[33m\033[1mSASL password is reqired\033[m\n" fi done fi RELAY_HOST= echo "" echo "Insert Relayhost" echo "" if [[ -n "$_RELAY_HOST" ]];then echononl "Relayhost [$_RELAY_HOST]: " read RELAY_HOST if [[ "X${RELAY_HOST}" = "X" ]]; then RELAY_HOST=$_RELAY_HOST fi else while [[ "X${RELAY_HOST}" = "X" ]]; do echononl "Relayhost: " read RELAY_HOST if [[ "X${RELAY_HOST}" = "X" ]]; then echo -e "\n\t\033[33m\033[1mRelayhost is reqired\033[m\n" fi done fi RELAY_PORT= echo "" echo "Insert the target port to connect to ${RELAY_HOST}" echo "" if [[ -n "$_RELAY_PORT" ]];then echononl "(target) Port on ${RELAY_HOST} [$_RELAY_PORT]: " read RELAY_PORT if [[ "X${RELAY_PORT}" = "X" ]]; then RELAY_PORT=$_RELAY_PORT fi else while [[ "X${RELAY_PORT}" = "X" ]]; do echononl "(target) Port on ${RELAY_HOST}: " read RELAY_PORT if [[ "X${RELAY_PORT}" = "X" ]]; then echo -e "\n\t\033[33m\033[1mi(target) Port of ${RELAY_HOST} is reqired\033[m\n" fi done fi else SASL_AUTH=false fi REWRITE_SENDER_DOMAIN= echo "" echo "" echo -e "\033[33m** \033[32m-- \033[33m**\033[m" echo "" echo "Change the sender domain" echo "" echo -e "\t'\033[33mNone\033[m' if no change is desired" echo "" if [[ -n "${_REWRITE_SENDER_DOMAIN}" ]] ; then echononl "New sender domain [${_REWRITE_SENDER_DOMAIN}]: " read REWRITE_SENDER_DOMAIN if [[ "X${REWRITE_SENDER_DOMAIN}" = "X" ]]; then REWRITE_SENDER_DOMAIN="${_REWRITE_SENDER_DOMAIN}" fi else while [[ "X${IPV6}" = "X" ]]; do echononl "New sender domain: " read REWRITE_SENDER_DOMAIN if [[ "X${REWRITE_SENDER_DOMAIN}" = "X" ]]; then REWRITE_SENDER_DOMAIN="None" fi done fi echo "" echo -e "\033[33m** \033[32m-- \033[33m**\033[m" echo "" echo "" echo -e "\033[21G\033[32mStart installation/configuration with the following parameters\033[m" echo "" echo -e "\tHostname.................: $HOSTNAME" echo -e "\tIPv4 address.............: $IPV4" echo -e "\tIPv6 address.............: $IPV6" echo -e "\tAdmin e-mail.............: $ADMIN_EMAIL" echo "" if [[ "$(trim ${REWRITE_SENDER_DOMAIN,,})" = 'none' ]] ; then echo -e "\trewrite sender domain....: \033[33mNone\033[m" else echo -e "\trewrite sender domain....: $REWRITE_SENDER_DOMAIN" fi echo "" echo -e "\tRelay using sasl auth....: $SASL_AUTH" if $SASL_AUTH ; then echo -e "\t sasl user.............: $SASL_USER" echo -e "\t sasl password.........: $SASL_PASS" echo -e "\t Relayhost.............: $RELAY_HOST" echo -e "\t Port on Relayhost.....: $RELAY_PORT" fi echo "" echononl "einverstanden (yes/no): " read OK OK=${OK,,} while [ "X$OK" != "Xyes" -a "X$OK" != "Xno" ]; do echononl "Wrong entry! [yes/no]: " read OK OK=${OK,,} done [ $OK = "yes" ] || fatal Repeat with other settings.. echo "" echo "" echononl " Save Configuration" cat << EOF > $conf_file # --- # - Parameter Settings Postfix Bases System # - # - - automated generated config file - # --- _HOSTNAME=$HOSTNAME _IPV4=$IPV4 _IPV6=$IPV6 _ADMIN_EMAIL=$ADMIN_EMAIL _SASL_AUTH=$SASL_AUTH _SASL_USER=$SASL_USER _SASL_PASS=$SASL_PASS _RELAY_HOST=$RELAY_HOST _RELAY_PORT=$RELAY_PORT _REWRITE_SENDER_DOMAIN=$REWRITE_SENDER_DOMAIN EOF if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fi [[ "$IPV6" = "disabled" ]] && IPV6="" # - Synchronise package index files with the repository # - echononl " Synchronise package index files with the repository.." apt-get update > /dev/null 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fi # - Deinstall debian exim4 packages # - echononl " Deinstall debian exim4 packages" _installed_exim_packages=`dpkg -l | grep exim4 | grep -e "^i" | awk '{print$2}'` for _pkg in $_installed_exim_packages ; do installed_exim_packages="$installed_exim_packages $_pkg" done if [[ -n "$installed_exim_packages" ]] ; then if `dpkg -l | grep bsd-mailx | grep -e "^i" > /dev/null 2>&1` ; then installed_exim_packages="$installed_exim_packages bsd-mailx" fi apt-get remove --purge -qq -y $installed_exim_packages > /dev/null 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fi else echo_skipped fi # - Install Postfix from debian packages system # - echononl " Install Postfix from debian packages system" _needed_packages="postfix postfix-pcre libsasl2-modules bsd-mailx haveged" for _pkg in $_needed_packages ; do if `dpkg -l | grep $_pkg | grep -e "^i" > /dev/null 2>&1` ; then continue else needed_packages="$needed_packages $_pkg" fi done if [[ -n "$needed_packages" ]]; then DEBIAN_FRONTEND=noninteractive apt-get -y install $needed_packages > /dev/null 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fi else echo_skipped fi # - Backup existing postfix configuration file # - echononl " Backup existing postfix configuration file" if [[ -f "/etc/postfix/main.cf" ]]; then cp -a /etc/postfix/main.cf /etc/postfix/main.cf.`date +%Y%m%d-%H%M` if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fi else echo_skipped fi # - Creeate new postfix configuration file # - echononl " Creeate new postfix configuration file" cat < /etc/postfix/main.cf # ============ Basic settings ============ # Disable backwards compatibility compatibility_level = 2 # Debian specific: Specifying a file name will cause the first # line of that file to be used as the name. The Debian default # is /etc/mailname. #myorigin = /etc/mailname myorigin = /etc/mailname smtpd_banner = \$myhostname ESMTP \$mail_name (Debian/GNU) biff = no # appending .domain is the MUA's job. append_dot_mydomain = no # Uncomment the next line to generate "delayed mail" warnings #delay_warning_time = 4h readme_directory = /usr/share/doc/postfix html_directory = /usr/share/doc/postfix/html ## - The Internet protocols Postfix will attempt to use when making ## - or accepting connections. ## - DEFAULT: ipv4 EOF if [ -n "$IPV6" ]; then cat <> /etc/postfix/main.cf inet_protocols = ipv4, ipv6 #inet_interfaces = all inet_interfaces = 127.0.0.1 ::1 #$IPV4 #$IPV6 myhostname = $HOSTNAME mydestination = $HOSTNAME localhost ## - The list of "trusted" SMTP clients that have more ## - privileges than "strangers" ## - mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 ${IPV4}/32 [${IPV6}]/128 #smtp_bind_address = $IPV4 #smtp_bind_address6 = $IPV6 ## - The address type ("ipv6", "ipv4" or "any") that the Postfix SMTP client will try first, ## - when a destination has IPv6 and IPv4 addresses with equal MX preference. This feature ## - has no effect unless the inet_protocols setting enables both IPv4 and IPv6. ## - #smtp_address_preference = ipv4 EOF else cat <> /etc/postfix/main.cf inet_protocols = ipv4 #inet_interfaces = all inet_interfaces = 127.0.0.1 #$IPV4 myhostname = $HOSTNAME mydestination = $HOSTNAME localhost ## - The list of "trusted" SMTP clients that have more ## - privileges than "strangers" ## - mynetworks = 127.0.0.0/8 EOF if [[ ${IPV4} =~ ^127 ]] ; then cat <> /etc/postfix/main.cf smtp_bind_address = smtp_bind_address6 = EOF else cat <> /etc/postfix/main.cf ${IPV4}/32 smtp_bind_address = $IPV4 #smtp_bind_address6 = EOF fi fi cat <> /etc/postfix/main.cf ## - The method to generate the default value for the mynetworks parameter. ## - ## - mynetworks_style = host" when Postfix should "trust" only the local machine ## - mynetworks_style = subnet (default value) "when Postfix should "trust" SMTP ## - clients in the same IP subnetworks as the local machine. ## - mynetworks_style = class" when Postfix should "trust" SMTP clients in the same ## - IP class A/B/C networks as the local machine. ## - #mynetworks_style = host ## - The maximal size of any local(8) individual mailbox or maildir file, ## - or zero (no limit). In fact, this limits the size of any file that is ## - written to upon local delivery, including files written by external ## - commands that are executed by the local(8) delivery agent. ## - mailbox_size_limit = 0 ## - The maximal size in bytes of a message, including envelope information. ## - ## - we user 50MB ## - message_size_limit = 52480000 ## - The system-wide recipient address extension delimiter ## - recipient_delimiter = + ## - The alias databases that are used for local(8) delivery. ## - alias_maps = hash:/etc/aliases ## - The alias databases for local(8) delivery that are updated ## - with "newaliases" or with "sendmail -bi". ## - alias_database = hash:/etc/aliases ## - Optional address mapping lookup tables for envelope and header sender ## - addresses. The table format and lookups are documented in canonical(5). ## - ## - Example: you want to rewrite the SENDER address "user@ugly.domain" ## - to "user@pretty.domain", while still being able to send mail to the ## - RECIPIENT address "user@ugly.domain". ## - ## - Note: \$sender_canonical_maps is processed before \$canonical_maps. ## - sender_canonical_maps = btree:/etc/postfix/sender_canonical ## - smtp_generic_maps (default: empty) ## - ## - Optional lookup tables that perform address rewriting in the Postfix ## - SMTP client, typically to transform a locally valid address into a ## - globally valid address when sending mail across the Internet. This is ## - needed when the local machine does not have its own Internet domain name, ## -but uses something like localdomain.local instead. ## - smtp_generic_maps = btree:/etc/postfix/generic ## - The maximal time a message is queued before it is sent back as ## - undeliverable. Defaults to 5d (5 days) ## - Specify 0 when mail delivery should be tried only once. ## - maximal_queue_lifetime = 3d bounce_queue_lifetime = \$maximal_queue_lifetime ## - delay_warning_time (default: 0h) ## - ## - The time after which the sender receives a copy of the message ## - headers of mail that is still queued. To enable this feature, ## - specify a non-zero time value (an integral value plus an optional ## - one-letter suffix that specifies the time unit). ## - Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks). ## - The default time unit is h (hours). delay_warning_time = 1d EOF if $SASL_AUTH ; then cat <> /etc/postfix/main.cf # ============ Relay parameters ============ #relayhost = # ============ SASL authentication ============ # Allow multiple SASL relay hosts, depending on the sender domain #smtp_sender_dependent_authentication = yes #sender_dependent_relayhost_maps = hash:/etc/postfix/sender_relay # Enable SASL authentication smtp_sasl_auth_enable = yes # Only offer SMTP AUTH when talking over an encrypted connection smtpd_tls_auth_only = yes EOF if [[ ${RELAY_PORT} -ne 25 ]] ; then cat <> /etc/postfix/main.cf # Forwarding to the ip-adress of host b.mx.oopen.de relayhost = [${RELAY_HOST}]:${RELAY_PORT} EOF else cat <> /etc/postfix/main.cf # Forwarding to the ip-adress of host b.mx.oopen.de relayhost = [${RELAY_HOST}] EOF fi cat <> /etc/postfix/main.cf # File including login data smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd # Disallow methods that allow anonymous authentication. smtp_sasl_security_options = noanonymous smtpd_sasl_tls_security_options = \$smtpd_sasl_security_options # Report the SASL authenticated user name in the smtpd(8) Received message header. smtpd_sasl_authenticated_header = no # ============ TLS parameters ============ ## - Aktiviert TLS für den Mailempfang ## - ## - may: ## - Opportunistic TLS. Use TLS if this is supported by the remote ## - SMTP server, otherwise use plaintext ## - ## - This overrides the obsolete parameters smtpd_use_tls and ## - smtpd_enforce_tls. This parameter is ignored with ## - "smtpd_tls_wrappermode = yes". #smtpd_use_tls=yes smtp_tls_security_level=encrypt EOF else cat <> /etc/postfix/main.cf # ============ Relay parameters ============ relayhost = # ============ TLS parameters ============ ## - Aktiviert TLS für den Mailempfang ## - ## - may: ## - Opportunistic TLS. Use TLS if this is supported by the remote ## - SMTP server, otherwise use plaintext ## - ## - This overrides the obsolete parameters smtpd_use_tls and ## - smtpd_enforce_tls. This parameter is ignored with ## - "smtpd_tls_wrappermode = yes". #smtpd_use_tls=yes smtp_tls_security_level=may EOF fi cat <> /etc/postfix/main.cf ## - Aktiviert TLS für den Mailversand ## - ## - may: ## - Opportunistic TLS: announce STARTTLS support to SMTP clients, ## - but do not require that clients use TLS encryption. # smtp_use_tls=yes smtpd_tls_security_level=may ## - 0 Disable logging of TLS activity. ## - 1 Log TLS handshake and certificate information. ## - 2 Log levels during TLS negotiation. ## - 3 Log hexadecimal and ASCII dump of TLS negotiation process. ## - 4 Also log hexadecimal and ASCII dump of complete transmission after STARTTLS. ## - smtpd_tls_loglevel = 1 smtp_tls_loglevel = 1 smtpd_tls_cert_file = $_TLS_CERT_FILE smtpd_tls_key_file = $_TLS_KEY_FILE ## - File with DH parameters that the Postfix SMTP server should use with EDH ciphers. ## - ## - Dont't forget to create it, e.g with openssl: ## - openssl dhparam -out /etc/postfix/ssl/dh_1024.pem -2 1024 ## - #smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_1024.pem ## - also possible to use 2048 key with that parameter ## - smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_2048.pem ## - File with DH parameters that the Postfix SMTP server should use with EDH ciphers. ## - ## - Dont't forget to create it, e.g with openssl: ## - openssl dhparam -out /etc/postfix/ssl/dh_512.pem -2 512 ## - smtpd_tls_dh512_param_file = /etc/postfix/ssl/dh_512.pem ## - File containing CA certificates of root CAs trusted to sign either remote SMTP ## - server certificates or intermediate CA certificates. These are loaded into ## - memory !! BEFORE !! the smtp(8) client enters the chroot jail. ## - smtp_tls_CAfile = $_TLS_CA_FILE ## - Directory with PEM format certificate authority certificates that the Postfix SMTP ## - client uses to verify a remote SMTP server certificate. Don't forget to create the ## - necessary "hash" links with, for example, " ## - $OPENSSL_HOME/bin/c_rehash /etc/postfix/certs". ## - ## - !! Note !! ## - To use this option in chroot mode, this directory (or a copy) must be inside ## - the chroot jail. ## - ## - Note that a chrooted daemon resolves all filenames relative to the Postfix ## - queue directory (/var/spool/postfix) ## - #smtpd_tls_CApath = /etc/postfix/certs # Disable SSLv2 SSLv3 - Postfix SMTP server # # List of TLS protocols that the Postfix SMTP server will exclude or # include with opportunistic TLS encryption. #smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1 # TLS protocols accepted by the Postfix SMTP server with opportunistic TLS encryption. # #smtpd_tls_protocols = >=TLSv1 # TLS protocols accepted by the Postfix SMTP server with mandatory TLS encryption. # #smtpd_tls_mandatory_protocols = >=TLSv1 # TLS protocols that the Postfix SMTP client will use with opportunistic TLS encryption. # #smtp_tls_protocols = >=TLSv1 # The minimum TLS cipher grade that the Postfix SMTP server will use with mandatory TLS encryption. # smtp_tls_mandatory_protocols = >=TLSv1.2 # The Postfix SMTP server security grade for ephemeral elliptic-curve # Diffie-Hellman (EECDH) key exchange. As of Postfix 3.6, the value of this # parameter is always ignored, and Postfix behaves as though the auto value # (described below) was chosen. # # auto # Use the most preferred curve that is supported by both the client and the server. # This setting requires Postfix ≥ 3.2 compiled and linked with OpenSSL ≥ 1.0.2. This # is the default setting under the above conditions (and the only setting used with # Postfix ≥ 3.6). # # none # Don't use EECDH. Ciphers based on EECDH key exchange will be disabled. This is the # default in Postfix versions 2.6 and 2.7. # # strong # Use EECDH with approximately 128 bits of security at a reasonable computational cost. # This is the default in Postfix versions 2.8-3.5. # # ultra # Use EECDH with approximately 192 bits of security at computational cost that is # approximately twice as high as 128 bit strength ECC. # smtpd_tls_eecdh_grade = auto # With SSLv3 and later, use the Postfix SMTP server's cipher preference order instead # of the remote client's cipher preference order. # # By default, the OpenSSL server selects the client's most preferred cipher that the # server supports. With SSLv3 and later, the server may choose its own most preferred # cipher that is supported (offered) by the client. # # Setting "tls_preempt_cipherlist = yes" enables server cipher preferences. # # default: no # #tls_preempt_cipherlist = no # The minimum TLS cipher grade that the Postfix SMTP server will use with mandatory # TLS encryption. The default grade ("medium") is sufficiently strong that any benefit # from globally restricting TLS sessions to a more stringent grade is likely negligible, # especially given the fact that many implementations still do not offer any stronger # ("high" grade) ciphers, while those that do, will always use "high" grade ciphers. # So insisting on "high" grade ciphers is generally counter-productive. Allowing "export" # or "low" ciphers is typically not a good idea, as systems limited to just these are # limited to obsolete browsers. No known SMTP clients fail to support at least one # "medium" or "high" grade cipher. # # default: medium # #smtpd_tls_mandatory_ciphers = medium # The minimum TLS cipher grade that the Postfix SMTP server will use with opportunistic # TLS encryption. Cipher types listed in smtpd_tls_exclude_ciphers are excluded from the # base definition of the selected cipher grade. # # default: medium # #smtpd_tls_ciphers = medium # List of ciphers or cipher types to exclude from the SMTP server cipher list at all # TLS security levels. # # DO NOT exclude ciphers unless it is essential to do so. This is not an OpenSSL cipherlist; # it is a simple list separated by whitespace and/or commas. The elements are a single cipher, # or one or more "+" separated cipher properties, in which case only ciphers matching all the # properties are excluded. # #smtpd_tls_exclude_ciphers = # Additional list of ciphers or cipher types to exclude from the Postfix SMTP client cipher # list at mandatory TLS security levels. This list works in addition to the exclusions listed # with smtp_tls_exclude_ciphers # #smtp_tls_mandatory_exclude_ciphers = smtpd_tls_session_cache_database = btree:\${data_directory}/smtpd_scache smtp_tls_session_cache_database = btree:\${data_directory}/smtp_scache #======= smtpd Restrictions ============ # smtpd_relay_restrictions # # IMPORTANT: Either the smtpd_relay_restrictions or the smtpd_recipient_restrictions # parameter must specify at least one of the following restrictions. Otherwise Postfix # will refuse to receive mail: # # reject, reject_unauth_destination # # defer, defer_if_permit, defer_unauth_destination # # # The upstream default is: # # smtpd_relay_restrictions = \${{\$compatibility_level} < {1} ? {} : # {permit_mynetworks, permit_sasl_authenticated, defer_unauth_destination}} # # AGAIN, that means: if parameter compatibility_level is not set or compatibility_level is # set to '0', you MUST specify this value. Otherwise Postfix will refuse to receive mail # and you get the following error message: # # fatal: in parameter smtpd_relay_restrictions or smtpd_recipient_restrictions, specify # at least one working instance of: reject_unauth_destination, defer_unauth_destination, # reject, defer, defer_if_permit or check_relay_domains # #smtpd_relay_restrictions = # permit_mynetworks, # permit_sasl_authenticated, # defer_unauth_destination EOF echo_ok echononl " Configure SASL authentification" if $SASL_AUTH ; then _sasl_pw_file="/etc/postfix/sasl_passwd" if [[ -f "${_sasl_pw_file}" ]] && $(grep -q -E "^\[${RELAY_HOST}\]" ${_sasl_pw_file} 2> /dev/null); then sed -i "/^\[${RELAY_HOST}/d" ${_sasl_pw_file} if [[ "$?" != "0" ]]; then error "Setting \"/etc/postfix/sasl_passwd\" failed! " _failed=true fi fi _failed=false if [[ ${RELAY_PORT} -ne 25 ]] ; then echo "[$RELAY_HOST]:${RELAY_PORT} ${SASL_USER}@${RELAY_HOST}:$SASL_PASS" >> /etc/postfix/sasl_passwd else echo "[$RELAY_HOST] ${SASL_USER}@${RELAY_HOST}:$SASL_PASS" >> /etc/postfix/sasl_passwd fi if [[ "$?" != "0" ]]; then error "Setting \"/etc/postfix/sasl_passwd\" failed! " _failed=true fi chown root:root /etc/postfix/sasl_passwd if [[ "$?" != "0" ]]; then error "Setting ownership of \"/etc/postfix/sasl_passwd\" failed! " _failed=true fi chmod 600 /etc/postfix/sasl_passwd if [[ "$?" != "0" ]]; then error "Setting permissions on \"/etc/postfix/sasl_passwd\" failed! " _failed=true fi postmap /etc/postfix/sasl_passwd chown root:root /etc/postfix/sasl_passwd.db if [[ "$?" != "0" ]]; then error "Creating \"/etc/postfix/sasl_passwd\" failed! " _failed=true fi chown root:root /etc/postfix/sasl_passwd.db if [[ "$?" != "0" ]]; then error "Setting ownership of \"/etc/postfix/sasl_passwd.db\" failed! " _failed=true fi if $_failed ; then echo_failed else echo_ok fi else echo_skipped fi ## - /etc/mailname ## - echononl " Set \"/etc/mailname\"" echo $HOSTNAME > /etc/mailname if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fi ## - /etc/aliases ## - echononl " Adjust \"/etc/aliases\"" cat << EOF > /etc/aliases # See man 5 aliases for format mailer-daemon: postmaster postmaster: root nobody: root hostmaster: root usenet: root news: root webmaster: root www: root ftp: root abuse: root noc: root security: root do-not-reply: /dev/null root: $ADMIN_EMAIL EOF if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fi ## - create directory for certificates and copy certificates ## - and coresponding keys to /etc/postfix/ssl/ ## - echononl " Create directory for certificates \"/etc/postfix/ssl\"" if [[ -d "/etc/postfix/ssl" ]] ; then echo_skipped else mkdir -p /etc/postfix/ssl if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fi fi ## - generate DH parameters that the Postfix SMTP server should use ## - with EDH ciphers (length 512 and 1024 ## - echononl " Generate DH key length=512 \"/etc/postfix/ssl/dh_512.pem\"" if [[ ! -f /etc/postfix/ssl/dh_512.pem ]]; then if [[ "$os_dist" = "debian" ]] && [[ $os_version -gt 11 ]] ; then openssl dhparam -out /etc/postfix/ssl/dh_512.pem 512 > /dev/null 2>&1 else openssl dhparam -dsaparam -out /etc/postfix/ssl/dh_512.pem 512 > /dev/null 2>&1 fi if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fi else if [[ "$os_dist" = "debian" ]] && [[ $os_version -gt 11 ]] ; then if $(grep -q -E "X9.42" /etc/postfix/ssl/dh_512.pem 2> /dev/null); then openssl dhparam -out /etc/postfix/ssl/dh_512.pem 512 > /dev/null 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fi else echo_skipped fi else echo_skipped fi fi echononl " Generate DH key length=1024 \"/etc/postfix/ssl/dh_1024.pem\"" if [[ ! -f /etc/postfix/ssl/dh_1024.pem ]]; then if [[ "$os_dist" = "debian" ]] && [[ $os_version -gt 11 ]] ; then openssl dhparam -out /etc/postfix/ssl/dh_1024.pem 1024 > /dev/null 2>&1 else openssl dhparam -dsaparam -out /etc/postfix/ssl/dh_1024.pem 1024 > /dev/null 2>&1 fi if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fi else if [[ "$os_dist" = "debian" ]] && [[ $os_version -gt 11 ]] ; then if $(grep -q -E "X9.42" /etc/postfix/ssl/dh_1024.pem 2> /dev/null); then openssl dhparam -out /etc/postfix/ssl/dh_1024.pem 1024 > /dev/null 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fi else echo_skipped fi else echo_skipped fi fi echononl " Generate DH key length=2048 \"/etc/postfix/ssl/dh_2048.pem\"" if [[ ! -f /etc/postfix/ssl/dh_2048.pem ]]; then if [[ "$os_dist" = "debian" ]] && [[ $os_version -gt 11 ]] ; then openssl dhparam -out /etc/postfix/ssl/dh_2048.pem 2048 > /dev/null 2>&1 else openssl dhparam -dsaparam -out /etc/postfix/ssl/dh_2048.pem 2048 > /dev/null 2>&1 fi if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fi else if [[ "$os_dist" = "debian" ]] && [[ $os_version -gt 11 ]] ; then if $(grep -q -E "X9.42" /etc/postfix/ssl/dh_2048.pem 2> /dev/null); then openssl dhparam -out /etc/postfix/ssl/dh_2048.pem 2048 > /dev/null 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fi else echo_skipped fi else echo_skipped fi fi echononl " Create Symlink \"$_TLS_CERT_FILE\"" if [ ! -h "$_TLS_CERT_FILE" ]; then ln -s /etc/ssl/certs/ssl-cert-snakeoil.pem $_TLS_CERT_FILE if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fi else echo_skipped fi echononl " Create Symlink \"$_TLS_KEY_FILE\"" if [ ! -h "$_TLS_KEY_FILE" ]; then ln -s /etc/ssl/private/ssl-cert-snakeoil.key $_TLS_KEY_FILE if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fi else echo_skipped fi ## - Install a cronjob for checking if mailservice is running.. ## - echononl " Install a cronjob for checking if mailservice is running.." crontab -l > /tmp/tmp_crontab if ! grep -q -E "/root/bin/monitoring/check_postfix.sh" /tmp/tmp_crontab 2> /dev/null ; then echo "" >> /tmp/tmp_crontab echo "# - Check if postfix mailservice is running. Restart service if needed." >> /tmp/tmp_crontab echo "# -" >> /tmp/tmp_crontab echo "*/5 * * * * /root/bin/monitoring/check_postfix.sh" >> /tmp/tmp_crontab crontab /tmp/tmp_crontab > $log_file 2>&1 if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat $log_file)" fi else echo_skipped fi ## - Install a cronjob that checks the LOG file for fatal errors.. ## - echononl " Install a cronjob that checks the LOG file for fatal errors.." crontab -l > /tmp/tmp_crontab if ! grep -q -E "/root/bin/postfix/check-postfix-fatal-errors.sh" /tmp/tmp_crontab 2> /dev/null ; then echo "" >> /tmp/tmp_crontab echo "# - Check Postfix E-Mail LOG file for 'fatal' errors.." >> /tmp/tmp_crontab echo "# -" >> /tmp/tmp_crontab echo "*/5 * * * * /root/bin/postfix/check-postfix-fatal-errors.sh" >> /tmp/tmp_crontab crontab /tmp/tmp_crontab > $log_file 2>&1 if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat $log_file)" fi else echo_skipped fi ## - rebuld alias database ## - echononl " Rebuld alias database" newaliases > /dev/null 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fi echononl " Create file \"sender_canonical\"" if [[ ! -f /etc/postfix/sender_canonical ]]; then cat < /etc/postfix/sender_canonical @localhost @$(hostname -f) EOF fi postmap btree:/etc/postfix/sender_canonical if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fi echononl " Create file \"generic\"" if [[ "$(trim ${REWRITE_SENDER_DOMAIN,,})" = 'none' ]] ; then touch /etc/postfix/generic else cat < /etc/postfix/generic @$(cat cat /etc/mailname) $(hostname)@$(trim ${REWRITE_SENDER_DOMAIN,,}) EOF fi postmap btree:/etc/postfix/generic if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fi ## - restart postfix ## - echononl " Restart postfix" if $systemd_exists ; then systemctl restart postfix > /dev/null 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fi else /etc/init.d/postfix restart > /dev/null 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fi fi ## - Omitt logging into system.log ## - echononl " Create \"/etc/rsyslog.d/postfix.conf\"" cat << EOF > /etc/rsyslog.d/postfix.conf # Create an additional socket in postfix's chroot in order not to break # mail logging when rsyslog is restarted. If the directory is missing, # rsyslog will silently skip creating the socket. \$AddUnixListenSocket /var/spool/postfix/dev/log # # Logging for the mail system. Split it up so that # it is easy to write scripts to parse these files. # #mail.info -/var/log/mail.info #mail.warn -/var/log/mail.warn #mail.err /var/log/mail.err mail.* -/var/log/mail.log & stop EOF if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fi echononl " Restart rsyslog daemon" if $systemd_exists ; then systemctl restart rsyslog > /dev/null 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fi else /etc/init.d/rsyslog restart > /dev/null 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed fi fi if [[ ${RELAY_PORT} -ne 25 ]] ; then echo "" warn "Please do not forget to allow port \033[1m${RELAY_PORT}\033[m on both sides, outgoing on this host here and incoming on the relay host '${RELAY_HOST}'." fi echo "" clean_up 0