From 2828c30a3fc41dc5d6b1bcf9cd8438116a6f356f Mon Sep 17 00:00:00 2001 From: Christoph Date: Tue, 21 Feb 2017 02:32:44 +0100 Subject: [PATCH] Initial import --- get_addresslist_for_domain.sh | 159 +++++++++++++++++ get_mail_pass.sh | 50 ++++++ get_sum_of_defined_domain_quotas.sh | 18 ++ postfix.txt | 53 ++++++ postfix_add_mailboxes.sh | 266 ++++++++++++++++++++++++++++ sent_userinfo_postfix.sh | 102 +++++++++++ 6 files changed, 648 insertions(+) create mode 100755 get_addresslist_for_domain.sh create mode 100755 get_mail_pass.sh create mode 100755 get_sum_of_defined_domain_quotas.sh create mode 100644 postfix.txt create mode 100755 postfix_add_mailboxes.sh create mode 100755 sent_userinfo_postfix.sh diff --git a/get_addresslist_for_domain.sh b/get_addresslist_for_domain.sh new file mode 100755 index 0000000..a76db43 --- /dev/null +++ b/get_addresslist_for_domain.sh @@ -0,0 +1,159 @@ +#!/usr/bin/env bash + +function usage() { + + echo + + if [ -n "$1" ];then + echo -e "Error: $1\n" + fi + echo -e "\nPrints a summary of mailboxes and forward addresse for the given domain.\n" + echo -e "\tusage: `basename $0` \n" + exit 1 +} + + +trim() { + local var="$*" + var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters + var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters + echo -n "$var" +} + + + +[ $# -eq "0" -o $# -gt "2" ] && usage "wrong number of arguments" + +address="$1" + +domain=`echo $address | cut -d'@' -f2` + +mysql=true +# - mysql_credential_args +# - +# - MySQL / MariaDB credentials +# - +# - Giving password on command line is insecure an sind mysql 5.5 +# - you will get a warning doing so. +# - +# - Reading username/password fro file ist also possible, using MySQL/MariaDB +# - commandline parameter '--defaults-file'. +# - +# - Since Mysql Version 5.6, you can read username/password from +# - encrypted file. +# - +# - Create (encrypted) option file: +# - $ mysql_config_editor set --login-path=local --socket=/tmp/mysql.sock --user=root --password +# - $ Password: +# - +# - Use of option file: +# - $ mysql --login-path=local ... +# - +# - Example +# - mysql_credential_args="--login-path=local" +# - mysql_credential_args="--defaults-file=/etc/mysql/debian.cnf" (Debian default) +# - mysql_credential_args="--defaults-file=/usr/local/mysql/sys-maint.cnf" +# - +mysql_credential_args="--defaults-file=/usr/local/mysql/sys-maint.cnf" +mysql_db=postfix + +#echo "address...: $address" +#echo "domain....: $domain" + +declare -A address_arr +declare -a orders +declare -a _tmp_mbox_arr +declare -a alias_arr +declare -a mbox_arr +declare -a mbox_alias_arr + + +echo "" +if $mysql ; then + _addresses=$(mysql $mysql_credential_args $mysql_db -N -s -e "select address from alias where domain = '$domain' ORDER BY address") + for _address in $_addresses ; do + address_arr[$_address]=$(trim $(mysql $mysql_credential_args $mysql_db -N -s -e "select goto from alias where address = '$_address'")) + orders+=("$(trim $_address)") + done +else + + _addresses=$(su - postgres -c"psql postfix -t -q -c\"select address from alias where domain = '$domain' ORDER BY address\"") + for _address in $_addresses ; do + address_arr[$_address]=$(trim $(su - postgres -c"psql postfix -t -q -c\"select goto from alias where address = '$_address'\"")) + orders+=("$(trim $_address)") + done +fi + +# - Mailbox or only forward address? +# - +for i in ${!orders[@]}; do + if [[ ${address_arr[${orders[$i]}]} =~ ${orders[$i]} ]]; then + _tmp_mbox_arr+=(${orders[$i]}) + else + alias_arr+=(${orders[$i]}) + fi +done + +# - Mailbox with or witout forward addresses? +# - +for i in ${!_tmp_mbox_arr[@]} ; do + found=false + IFS=',' read -a _addr_list <<<"${address_arr[${_tmp_mbox_arr[$i]}]}" + for j in ${!_addr_list[@]} ; do + [[ ${_addr_list[$j]} =~ ${_tmp_mbox_arr[$i]} ]] && continue + [[ ${_addr_list[$j]} =~ @autoreply ]] && continue + found=true + _forward_addresses="$_forward_addresses ${_addr_list[$j]}" + done + if ! $found ; then + mbox_arr+=(${_tmp_mbox_arr[$i]}) + else + mbox_alias_arr+=(${_tmp_mbox_arr[$i]}) + address_arr[${_tmp_mbox_arr[$i]}]=$(trim $_forward_addresses) + fi +done + +echo "" +echo "--------------------" +echo "- Zusammenfassung E-Mail Adressen der Domain \"$domain\"" +echo "--------------------" + + + + +echo "" +echo "E-Mail Adressen: Postfach ohne Weiterleitungen:" +echo "-----------------------------------------------" + +for i in ${!mbox_arr[@]} ; do + echo "${mbox_arr[$i]}" +done + +echo "" +echo "E-Mail Adressen: Postfach mit Weiterleitungen:" +echo "----------------------------------------------" + +for i in ${!mbox_alias_arr[@]} ; do + echo -e "${mbox_alias_arr[$i]}\n --> ${address_arr[${mbox_alias_arr[$i]}]}" + echo +done + +echo "" +echo "E-Mail Adressen: Nur Weiterleitungen:" +echo "-------------------------------------" + +for i in ${!alias_arr[@]} ; do + [[ ${alias_arr[$i]} =~ ^abuse@ ]] && continue + [[ ${alias_arr[$i]} =~ ^postmaster@ ]] && continue + echo -en "${alias_arr[$i]}\n -->" + + IFS=',' read -a _addr_list <<<"${address_arr[${alias_arr[$i]}]}" + for j in ${!_addr_list[@]} ; do + echo -n " ${_addr_list[$j]}" + done + echo + echo +done + +echo "" +exit 0 diff --git a/get_mail_pass.sh b/get_mail_pass.sh new file mode 100755 index 0000000..306129a --- /dev/null +++ b/get_mail_pass.sh @@ -0,0 +1,50 @@ +#!/bin/sh + +function usage() { + + echo + + if [ -n "$1" ];then + echo -e "Error: $1\n" + fi + echo -e "\nPrints the password for a given email address or" + echo -e "prints all username/password combinations from a give domain\n" + echo -e "\tusage: `basename $0` \n" + exit 1 +} + + + +[ $# -eq "0" -o $# -gt "2" ] && usage "wrong number of arguments" + +address="$1" + +domain=`echo $address | cut -d'@' -f2` + +mysql=false +mysql_user=backup +mysql_password=backup +mysql_db=postfix + +#echo "address...: $address" +#echo "domain....: $domain" + +echo "" +if $mysql ; then + if [ "$domain" = "$address" ] ; then + mysql -u$mysql_user -p$mysql_password $mysql_db -N -s -e "select username,password from mailbox where domain = '$address'" + else + mysql -u$mysql_user -p$mysql_password $mysql_db -N -s -e "select username,password from mailbox where username = '$address'" + fi +else + if [ "$domain" = "$address" ] ; then + su - postgres -c"psql postfix -t -q -c\"select username,password from mailbox where domain = '$address'\"" + else + su - postgres -c"psql postfix -t -q -c\"select username,password from mailbox where username = '$address'\"" + fi +fi +echo "" + + + +exit 0 diff --git a/get_sum_of_defined_domain_quotas.sh b/get_sum_of_defined_domain_quotas.sh new file mode 100755 index 0000000..0046f43 --- /dev/null +++ b/get_sum_of_defined_domain_quotas.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +mysql=false +mysql_credentilas="--login-path=local" +mysql_db=postfix + +echo "" +if $mysql ; then + sum_quota_mb=`mysql $mysql_credentilas $mysql_db -N -s -e "SELECT SUM(quota) FROM domain"` +else + sum_quota_mb=`su - postgres -c"psql postfix -t -q -c\"SELECT sum(quota) FROM domain\""` +fi +echo -e "\t$sum_quota_mb MB" +echo "" + + + +exit 0 diff --git a/postfix.txt b/postfix.txt new file mode 100644 index 0000000..ba0cd72 --- /dev/null +++ b/postfix.txt @@ -0,0 +1,53 @@ +## - Postfix Commadozeile + +## - flush queue +## - +postqueue -f + +## - Mail-Queue ansehen (sicherheitshalber mit less): +## - +mailq | less + +## - Anzahl der Mails in der Queue: +## - +mailq | egrep '^--' + +## - gesamte Mail-Queue löschen: +## - +postsuper -d ALL + +## - einzelne Mails aus der Queue löschen: +## - +mailq | less +## - die entsprechende queue_id merken/kopieren +## - +postsuper -d ID + +## - Trickreicher wird es wenn man alle Emails von oder zu einer Adresse löschen möchte: +## - +mailq | tail +2 | awk 'BEGIN { RS = "" } / user@huschi\.net$/ { print $1 } ' \ + | tr -d '*!' | postsuper -d - + +## - oder auch so: +## - +for i in `mailq | egrep "^[0-9A-F]" | grep 'MAILER-DAEMON' | cut -c1-12 | sed s/\*//g` ; \ + do echo "delete msg: $i" ; postsuper -d $i ; done + + +## - --- + +## - alle Mails auf "hold": +## - +postsuper -h ALL + +## - einzelne Mails auf "hold": +## - +postsuper -h ID + +## - alle Mails von "hold" wieder releasen: +## - +postsuper -H ALL + +## - einzelne Mails releasen: +## - +postsuper -H ID diff --git a/postfix_add_mailboxes.sh b/postfix_add_mailboxes.sh new file mode 100755 index 0000000..1c50e71 --- /dev/null +++ b/postfix_add_mailboxes.sh @@ -0,0 +1,266 @@ +#!/usr/bin/env bash + +## -------------------------------------- +## - +## - Add mailboxes read from a flat file +## - +## -------------------------------------- + + +## - a.mx.oopen.de +db_name=postfix +db_user=postfix + +## - mailbox related +## - +# - 2GB +#quota=2147483648 +# - 512MB +quota=536870912 +#_passwd='$E%R&T/Z(U' + +in_file=/root/mailboxes_ak.lst + +log_file=/tmp/postfix_add_mailboxes.log + +## --- 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 "[ \033[31m\033[1mError\033[m ]: $*" + echo "" + echo -e "\t\033[31m\033[1mInstalllation is canceled\033[m\033[m" + echo "" + exit 1 +} + +warn (){ + echo "" + echo -e "\t[ \033[33m\033[1mWarning\033[m ]: $*" + echo "" +} + +info (){ + echo "" + echo -e "\t[ \033[33m\033[1mInfo\033[m ]: $*" + echo "" +} + +ok (){ + echo "" + echo -e "\t[ \033[36m\033[1mOk\033[m ]: $*" + echo "" +} + +error(){ + echo "" + echo -e "\t[ \033[31m\033[1mFehler\033[m ]: $*" + echo "" +} + +echo_ok() { + echo -e "\033[75G[ \033[32mok\033[m ]" +} +echo_failed(){ + echo -e "\033[75G[ \033[1;31mfailed\033[m ]" +} +echo_skipped() { + echo -e "\033[75G[ \033[33m\033[1mskipped\033[m ]" +} + + +## - remove leading/trailling whitespaces +## - +trim() { + local var="$*" + var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters + var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters + echo -n "$var" +} + +## --- +## --- END: functions + +date_suffix="`date +%Y%m%d-%H%M`" + +echo + +## - +## - Logfile +## - +echononl "\tBackup existing log file.." +if [ -f "$log_file" ]; then + mv "$log_file" "${log_file}.${date_suffix}" + if [ "$?" = "0" ]; then + echo_ok + else + echo_failed + fi +else + echo_skipped +fi + +echononl "\tCreate log file $log_file.." +touch $log_file +if [ "$?" = "0" ]; then + echo_ok +else + echo_failed +fi + +echo "" + +curdir=`pwd` +cd /tmp + + +while read email passwd ; do + + ## - get rid of empty lines + [[ -z "$email" ]] && continue + ## - get rid of comment lines + [[ $email =~ ^[[:space:]]*# ]] && continue + + ## - remove leading/trailling whitespaces + ## - + email=`trim "$email"` + password=`trim $passwd` + + ## - regex tha email addresses must matc + ## - + #regex_email="^[a-z0-9!#\$%&'*+/=?^_\`{|}~-]+(\.[a-z0-9!#$%&'*+/=?^_\`{|}~-]+)*@([a-z0-9]([a-z0-9-]*[a-z0-9])?\.)+[a-z0-9]([a-z0-9-]*[a-z0-9])?\$" + regex_email="^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$" + + if [[ ! $email =~ $regex_email ]]; then + error "email: give e-mail address ($email) is NOT VALID" + echo "[ FAILED ]: The given e-mail address \"${user}@$domain\" is not VALID" >> $log_file + echo " Domain $domain is not configured as maildomain." >> $log_file + continue + fi + + ## - splitt in name and domain part + ## - + read user domain <<<$(IFS="@" ; echo $email) + + echo + echo -e "\t\033[37m\033[1mHandling E-Mail addess ${user}@${domain}..\033[m" + + ## - check if domain is already configured + ## - + domain_exists=`su postgres -c"psql $db_name -At -c\"SELECT 1 FROM domain WHERE domain = '$domain'\""` + if [[ "X$domain_exists" = "X" ]] ; then + warn "Domain $domain is not configured as maildomain." + echo "[ FAILED ]: Cannot create e-mail address \"${user}@$domain\"" >> $log_file + echo " Domain $domain is not configured as maildomain." >> $log_file + continue + fi + + if [[ "$user" = "abuse" ]]; then + warn "E-mail address $email is not supported" + echo "[ FAILED ]: Cannot create e-mail address \"${user}@$domain\"" >> $log_file + echo " E-mail address $email is not supported." >> $log_file + continue + elif [[ "$user" = "postmaster" ]];then + warn "E-mail address $email is not supported" + echo "[ FAILED ]: Cannot create e-mail address \"${user}@$domain\"" >> $log_file + echo " E-mail address $email is not supported." >> $log_file + continue + fi + + ## - If password is not given, then take a default + ## - + if [[ -z "$passwd" ]]; then + if [[ -z "$_passwd" ]]; then + passwd=`tr -cd '[:alnum:]\!@#$%' < /dev/urandom | fold -w10 | head -n1` + password_accepted=false + while ! $password_accepted ; do + passwd=`tr -cd '[:alnum:]\!@#$%' < /dev/urandom | fold -w10 | head -n1` + regex="[\!@#$%_]" + [[ $passwd =~ $regex ]] || continue + regex="[0123456789].*[0123456789]" + [[ $passwd =~ $regex ]] || continue + password_accepted=true + done + else + passwd=$_passwd + fi + fi + #password="${password/\'/\\\'}" + #password=`echo $password | sed "d/'/"` + + mb_exists=`su postgres -c"psql $db_name -At -c\"SELECT 1 FROM mailbox WHERE username = '${user}@$domain'\""` + if [[ "X$mb_exists" == "X1" ]] ; then + warn "A Mailbox ${user}@$domain already exists." + echo "[ FAILED ]: Cannot create e-mail address \"${user}@$domain\"" >> $log_file + echo " A Mailbox ${user}@$domain already exists." >> $log_file + continue + fi + + alias_exists=`su postgres -c"psql $db_name -At -c\"SELECT 1 FROM alias WHERE address = '${user}@$domain'\""` + if [[ "X$alias_exists" == "X1" ]] ; then + warn "A Forwarding Address ${user}@$domain already exists." + echo "[ FAILED ]: Cannot create e-mail address \"${user}@$domain\"" >> $log_file + echo " A Forwarding Address ${user}@$domain already exists." >> $log_file + continue + fi + + echononl "\tCreate entry in table \"mailbox\".." + + #insert_mb_stmt="SET client_encoding to 'UTF8';\nINSERT INTO mailbox (username,password,name,maildir,local_part,quota,domain,created,modified,active) VALUES ('${user}@$domain','$passwd','','${domain}/${user}/','$user','$quota','$domain',NOW(),NOW(),'t')" + #echo -e "$insert_mb_stmt" | psql -U$db_user $db_name > /dev/null + + #sql_file=`mktemp` + #echo "SET client_encoding to 'UTF8';\nINSERT INTO mailbox (username,password,name,maildir,local_part,quota,domain,created,modified,active) VALUES ('${user}@$domain','$passwd','','${domain}/${user}/','$user','$quota','$domain',NOW(),NOW(),'t')" > $sql_file + #psql -Upostfix postfix < $sql_file + #rm $sql_file + + su postgres -c"psql $db_name -c\"\ + SET client_encoding to 'UTF8'; \ + INSERT INTO mailbox (username,password,name,maildir,local_part,quota,domain,created,modified,active) \ + VALUES ('${user}@$domain', '$passwd','','${domain}/${user}/','$user','$quota','$domain',NOW(),NOW(),'t')\"" \ + > /dev/null 2>&1 + + if [ "$?" = "0" ]; then + echo_ok + else + echo_failed + echo "[ FAILED ]: Cannot create e-mail address \"${user}@$domain\"" >> $log_file + continue + fi + + echononl "\tCreate entry in table \"alias\".." + su postgres -c "psql $db_name -c\"\ + SET client_encoding to 'UTF8'; \ + INSERT INTO alias (address,goto,domain,created,modified) \ + VALUES ('${user}@$domain','${user}@$domain','$domain',NOW(),NOW())\"" > /dev/null 2>&1 + if [ "$?" = "0" ]; then + echo_ok + echo -e "\t email: ${user}@$domain" + echo -e "\t password: $passwd" + echo "[ OK ]: e-mail: ${user}@$domain -- password: $passwd" >> $log_file + else + echo_failed + echo "[ FAILED ]: Cannot create e-mail address \"${user}@$domain\"" >> $log_file + echo " Note: Entry in table \"alias\" was done; Take care, to" >> $log_file + echo " remove that Entry." >> $log_file + fi + +done < $in_file + +echo +echo -e "See \033[37m\033[1m$log_file\033[m to see the results again." +echo "" + +cd $pwd + +exit 0 diff --git a/sent_userinfo_postfix.sh b/sent_userinfo_postfix.sh new file mode 100755 index 0000000..16e4b65 --- /dev/null +++ b/sent_userinfo_postfix.sh @@ -0,0 +1,102 @@ +#!/bin/bash + + +user_info_file="/root/Heartbleed-Bug_userinfo.txt" + +email_from="oo@oopen.de" + +mail_user=vmail +mail_group=vmail + +mail_basedir=/var/vmail + +logfile=/tmp/user_mail.log +> $logfile + + +curdir=`pwd` +rc_done="\033[71G[ \033[32mdone\033[m ]" +rc_failed="\033[71G[ \033[31m\033[1mfailed\033[m ]" + + +## - Functions +## - +echononl(){ + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo "$*\\c" 1>&2 + else + echo -e -n "$*" 1>&2 + fi + rm /tmp/shprompt$$ +} + + +fatal(){ + echo "" + echo Fehler: $* + echo -e "\n\t\033[31m\033[1mSkript wird abgebrochen\033[m\033[m\n" + echo + exit 1 +} + +## - +## - End: Functions + +if [ ! -f $user_info_file ]; then + fatal "Kann Mailtext nicht finden" +fi + +pwd=`pwd` +cd /tmp + +clear +echo -e "\n\t --- Sending userinfo into all local virtual mailboxes --\n" | tee -a $logfile + +if [ ! -f $user_info_file ];then + echo "[FATAL]: Info-file to send does not exist !!" >> $logfile + fatal "User Info-file to send does not exist !!" +fi + + +## - list of local virtual domains +## - +domains=`su postgres -c"psql -At -F ' ' postfix -c\"SELECT domain FROM domain WHERE domain != 'ALL' ORDER BY domain\""` + +declare -i num_dom=0; +declare -i num_mbox_failed=0; +declare -i num_mbox=0; + +for domain in $domains ;do + echo -e "\nDOMAIN: $domain\n" | tee -a $logfile + local_parts=`su postgres -c"psql -At -F ' ' postfix -c\"SELECT local_part FROM mailbox WHERE domain = '$domain'\""` + for local_part in $local_parts ; do + cp $user_info_file /tmp/ + perl -i -n -p -e "s/%email_to%/$local_part\@$domain/" /tmp/`basename $user_info_file` + echononl "\tSend userinfo to $local_part@$domain.." + cat /tmp/`basename $user_info_file` | /usr/sbin/sendmail -F 'Christoph Kuchenbuch' -f $email_from -t "$local_part@$domain" + if [ "$?" = "0" ]; then + num_mbox=num_mbox+1 + echo -e "$rc_done" + else + echo -e "$rc_failed" + echo " [ERROR]: Cannot sent userinfo to \"$local_part\@$domain\"!" >> $logfile + num_mbox_failed=num_mbox_failed+1 + fi + done + num_dom=num_dom+1 +done + +echo -e "\n\n----- Statistics -----\n\n\tSent mail to $num_mbox mailboxe(s) of $num_dom domain(s)" | tee -a $logfile + +if [ $num_mbox_failed -gt 0 ];then + echo -e "\n\tFailed sending mail to $num_mbox_failed mailboxe(s)" >> $logfile + echo -e "\n\t\033[31m\033[1mFailed sending mail to $num_mbox_failed mailboxe(s)\033[m\033[m" + echo -e "\n\n-- See $logfile for details\n" | tee -a $logfile +fi + +echo +cd $pwd +rm /tmp/`basename $user_info_file` + +exit