diff --git a/helpers/create_client_whitelist.sh b/helpers/create_client_whitelist.sh new file mode 100755 index 0000000..ef1e3a7 --- /dev/null +++ b/helpers/create_client_whitelist.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash + +tmp_err_msg=$(mktemp) + +# ------------- +# --- Some functions +# ------------- +clean_up() { + + # Perform program exit housekeeping + rm -f $tmp_err_msg + exit $1 +} + +echononl(){ + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo -e -n "$*\\c" 1>&2 + else + echo -e -n "$*" 1>&2 + fi + rm /tmp/shprompt$$ +} + +fatal(){ + echo "" + echo -e "fatal error: $*" + echo "" + echo -e "\t\033[31m\033[1mInstalllation will be interrupted\033[m\033[m" + echo "" + 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 ]" +} + +echononl " Create file \"client_whitelist\"" +if [[ ! -f "/etc/postfix/client_whitelist" ]]; then + cat < /etc/postfix/client_whitelist +# onion - tor hidden service +127.0.0.25 OK +EOF + if [[ $? -eq 0 ]] ; then + echo_ok + postmap btree:/etc/postfix/client_whitelist + else + echo_failed + fi +else + echo_skipped +fi + + +clean_up 0 diff --git a/helpers/create_greylist_client_access_pcre.sh b/helpers/create_greylist_client_access_pcre.sh new file mode 100755 index 0000000..d10ad39 --- /dev/null +++ b/helpers/create_greylist_client_access_pcre.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash + +tmp_err_msg=$(mktemp) + +# ------------- +# --- Some functions +# ------------- +clean_up() { + + # Perform program exit housekeeping + rm -f $tmp_err_msg + exit $1 +} + +echononl(){ + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo -e -n "$*\\c" 1>&2 + else + echo -e -n "$*" 1>&2 + fi + rm /tmp/shprompt$$ +} + +fatal(){ + echo "" + echo -e "fatal error: $*" + echo "" + echo -e "\t\033[31m\033[1mInstalllation will be interrupted\033[m\033[m" + echo "" + 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 ]" +} + +echononl " Create file \"greylist_client_access_pcre\"" +if [[ ! -f /etc/postfix/greylist_client_access_pcre ]]; then + cat < /etc/postfix/greylist_client_access_pcre +# --- +# Check Client Access for greylisting (selective greylisting) +# --- +# +# - Note: +# - +# - Action 'check_greylist' must be defined by 'smtpd_restriction_classes' +# - and also set with an action (check_policy_service inet:127.0.0.1:10023) +# - in file /etc/postfix/ main.cf. +# - +# - Your main.cf may looks like: +# - +# - smtpd_restriction_classes = check_greylist +# - check_greylist = check_policy_service inet:127.0.0.1:10023 +# - +# - smtpd_recipient_restrictions = +# - ... +# - check_client_access pcre:/etc/postfix/greylist_client_access_pcre, +# - ... +# - +# - smtpd_relay_restrictions = +# - ... +# - check_client_access pcre:/etc/postfix/greylist_client_access_pcre, +# - ... + +# --- +# - For clients matching the following rules greylisting check is applied. +# --- + +# unkown clients +/^unknown$/ check_greylist + +# everything with 3 or more hyphens in the hostname +/(\\-.+){3}$/ check_greylist +# everything with 4 or more dots in the hostname +/(\\..+){4}$/ check_greylist + +# dialups +/(^|[0-9.x_-])(abo|br(e|oa)dband|cabel|(hk)?cablep?|catv|cbl|cidr|d?client2?|cust(omer)?s?|dhcp|dial?(in|up)?|d[iu]p|[asx]?dsld?|dyn(a(dsl|mic)?)?|home|in-addr|modem(cable)?|(di)?pool|ppp|ptr|rev|static|user|YahooBB[0-9]{12}|c[[:alnum:]]{6,}(\\.[a-z]{3})?\\.virtua|[1-9]Cust[0-9]+|AC[A-Z][0-9A-F]{5}\\.ipt|pcp[0-9]{6,}pcs|S0106[[:alnum:]]{12,}\\.[a-z]{2})[0-9.x_-]/ check_greylist + +EOF + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + + +clean_up 0 diff --git a/helpers/create_header_checks_pcre.sh b/helpers/create_header_checks_pcre.sh new file mode 100755 index 0000000..35580af --- /dev/null +++ b/helpers/create_header_checks_pcre.sh @@ -0,0 +1,97 @@ +#!/usr/bin/env bash + +tmp_err_msg=$(mktemp) + +# ------------- +# --- Some functions +# ------------- +clean_up() { + + # Perform program exit housekeeping + rm -f $tmp_err_msg + exit $1 +} + +echononl(){ + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo -e -n "$*\\c" 1>&2 + else + echo -e -n "$*" 1>&2 + fi + rm /tmp/shprompt$$ +} + +fatal(){ + echo "" + echo -e "fatal error: $*" + echo "" + echo -e "\t\033[31m\033[1mInstalllation will be interrupted\033[m\033[m" + echo "" + 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 ]" +} + +echononl " Create file \"header_checks_pcre\"" +if [[ ! -f "/etc/postfix//header_checks_pcre" ]]; then + cat < /etc/postfix//header_checks_pcre +# --- +# - Replace headers +# --- + +# - Replace recieved from +/^Received: from (.* \\([-._[:alnum:]]+ \\[[.[:digit:]]{7,15}\\]\\)).*?([[:space:]]+).*\\(Authenticated sender: ([^)]+)\\)(.*)/ REPLACE Received: from [127.0.0.1] (localhost [127.0.0.1])\$2(Authenticated sender: \$3)\$4 + +# --- +# - Ignore Headers +# --- + +/^\s*User-Agent/ IGNORE +/^\s*X-Enigmail/ IGNORE +/^\s*X-Mailer/ IGNORE +/^\s*X-Originating-IP/ IGNORE +EOF + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + + +clean_up 0 diff --git a/install_postfwd.sh b/install_postfwd.sh new file mode 100755 index 0000000..ee4d5f3 --- /dev/null +++ b/install_postfwd.sh @@ -0,0 +1,261 @@ +#!/usr/bin/env bash + +tmp_err_msg=$(mktemp) + +# ------------- +# --- Some functions +# ------------- +clean_up() { + + # Perform program exit housekeeping + rm -f $tmp_err_msg + exit $1 +} + +echononl(){ + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo -e -n "$*\\c" 1>&2 + else + echo -e -n "$*" 1>&2 + fi + rm /tmp/shprompt$$ +} + +fatal(){ + echo "" + echo -e "fatal error: $*" + echo "" + echo -e "\t\033[31m\033[1mInstalllation will be interrupted\033[m\033[m" + echo "" + 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 ]" +} + +## - Install Postfix Firewall Daemon from debian packages system +## - +echononl " Install Postfix Firewall Daemon from debian packages system" +_pkg="postfwd" +if aptitude search $_pkg | grep " $_pkg " | grep -e "^i" > /dev/null 2>&1 ; then + echo_skipped +else + DEBIAN_FRONTEND=noninteractive apt-get -y install $_pkg > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +fi + +echononl " Adjust /etc/default/postfwd" +perl -i -n -p -e "s#^(\s*)(STARTUP=.*)#\#\1\2\nSTARTUP=1#" \ + /etc/default/postfwd > $tmp_err_msg 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $tmp_err_msg)" +fi + +_file="/etc/postfix/postfwd.wl-user" +echononl " Create whitelist file '$_file' for postfwd" +if [[ ! -f "$_file" ]]; then + cat << EOF > "$_file" +# --- +# SASL Users whitelisted by postfwd +# --- + +EOF + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + +_file="/etc/postfix/postfwd.bl-user" +echononl " Create whitelist file '$_file' for postfwd" +if [[ ! -f "$_file" ]]; then + cat << EOF > "$_file" +# --- +# SASL Users blocked by postfwd +# --- + +EOF + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + +_file="/etc/postfix/postfwd.bl-sender" +echononl " Create whitelist file '$_file' for postfwd" +if [[ ! -f "$_file" ]]; then + cat << EOF > "$_file" +# --- +# Sender addresses blocked by postfwd +# --- + +EOF + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + +echononl " Create configuration file '/etc/postfix/postfwd.cf'.." +if [[ ! -f "/etc/postfix/postfwd.cf" ]]; then + cat << EOF > /etc/postfix/postfwd.cf + +#======= Definitions ============ + +# Match messages with an associated SASL username +&&SASL_AUTH { + sasl_username!~^\$ +} + +# Whitelist users +&&TRUSTED_USERS { + sasl_username==file:/etc/postfix/postfwd.wl-user +} + +# Blacklist users +&&BLOCK_USERS { + sasl_username==file:/etc/postfix/postfwd.bl-user +} + +# Blacklist sender adresses +&&BLOCK_SENDER { + sender==file:/etc/postfix/postfwd.bl-sender +} + +# Inbound emails only +&&INCOMING { + client_address!=127.0.0.1 +} + + +#======= Rule Sets ============ + +# Whitelists + +# Whitelist sasl users +id=WHL_USERS + &&TRUSTED_USERS + action=DUNNO + + +# Blacklist users + +id=BL_USERS + &&BLOCK_USERS + action=REJECT User is blocked by so36.NET admins. Error: BL_USERS + +# Blacklist sender +# +# Claim successful delivery and silently discard the message. +# +id=BL_SENDER + &&BLOCK_SENDER + action=DISCARD + #action=REJECT Sender address is blocked by so36.NET admins. Error: BL_SENDER + + +# Rate Limits + +# Block messages with more than 50 recipients +id=BLOCK_MSG_RCPT + &&INCOMING + &&SASL_AUTH + recipient_count=50 + action=REJECT Too many recipients, please reduce to less than 50 or consider using a mailing list. Error: BLOCK_MSG_RCPT + +# Block users sending more than 50 messages/hour +id=RATE_MSG + &&INCOMING + &&SASL_AUTH + action=rate(\$\$sasl_username/50/3600/450 4.7.1 Number messages per hour exceeded. Error:RATE_MSG) + +# Block users sending more than 250 recipients total/hour +id=RATE_RCPT + &&INCOMING + &&SASL_AUTH + action=rcpt(\$\$sasl_username/250/3600/450 4.7.1 Number recipients per hour exceeded. Error:RATE_RCPT) + +EOF + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + +echononl " Restart Postfix firewall daemon 'postfwd'.." +if $systemd_exists ; then + systemctl restart postfwd > /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/postfwd restart > /dev/null 2> $tmp_err_msg + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $tmp_err_msg)" + fi +fi + + +warn "OpenDKIM is installed, bur not integrated in postfix mailsystem (/etc/postfix/main.cf" + + + +clean_up 0