Initial commit with previous code
This commit is contained in:
commit
abff60dcfe
33 changed files with 1983 additions and 0 deletions
84
defaults/main.yml
Normal file
84
defaults/main.yml
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
---
|
||||||
|
mail_server_fqdn: mail.example.org
|
||||||
|
mail_db_user: mail_admin
|
||||||
|
mail_db_password: "{{ vault_mail_admin_password }}"
|
||||||
|
mail_db_name: 'mail'
|
||||||
|
admin_password: "{{ mail_admin_password }}"
|
||||||
|
mail_admin_username: 'mail_admin'
|
||||||
|
dns_resolver: 1.1.1.1
|
||||||
|
mail_domains:
|
||||||
|
- example.org
|
||||||
|
- example.net
|
||||||
|
mail_own_networks:
|
||||||
|
- 1.2.3.4
|
||||||
|
mail_own_networks_hosts:
|
||||||
|
- host1.example.org
|
||||||
|
- host1.example.com
|
||||||
|
update_spam_db_user: "{{ vault_update_spam_db_user }}"
|
||||||
|
mail_users:
|
||||||
|
- fullname: User number 1
|
||||||
|
email: user1@example.org
|
||||||
|
password: "{{ vault_user1_md5_password_hash }}"
|
||||||
|
quota: 104857600000
|
||||||
|
mail_transports:
|
||||||
|
- domain: example.com
|
||||||
|
transport: smtp
|
||||||
|
mail_forwardings:
|
||||||
|
- source: user_1@example.org
|
||||||
|
destination: user1@example.org
|
||||||
|
porpouse: Alias for user1. Mail sent to user_1 it's redirected to user1
|
||||||
|
postfix_master_extra: |
|
||||||
|
dbmail-lmtp unix - - n - - lmtp
|
||||||
|
-o disable_dns_lookups=yes
|
||||||
|
postfix_config:
|
||||||
|
alias_database: hash:/etc/aliases
|
||||||
|
alias_maps: hash:/etc/aliases
|
||||||
|
append_dot_mydomain: no
|
||||||
|
biff: no
|
||||||
|
body_checks: regexp:/etc/postfix/maps/body_checks.map
|
||||||
|
broken_sasl_auth_clients: yes
|
||||||
|
compatibility_level: 2
|
||||||
|
header_checks: regexp:/etc/postfix/maps/whitelist_senders.map regexp:/etc/postfix/maps/spam_filter_header_check
|
||||||
|
html_directory: /usr/share/doc/postfix/html
|
||||||
|
inet_interfaces: all
|
||||||
|
inet_protocols: all
|
||||||
|
mailbox_size_limit: 0
|
||||||
|
mydestination: "{{ mail_server_fqdn }}; localhost; localhost.localdomain"
|
||||||
|
myhostname: "{{ mail_server_fqdn }}"
|
||||||
|
mynetworks: "127.0.0.0/8 /etc/postfix/allowed_clients{% if mail_own_networks %}{% for ip in mail_own_networks %} {{ ip }}{% endfor %}{% endif %}"
|
||||||
|
myorigin: /etc/mailname
|
||||||
|
policy-spf_time_limit: 3600s
|
||||||
|
proxy_read_maps: $local_recipient_maps $mydestination $virtual_alias_maps $virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks $virtual_mailbox_limit_maps
|
||||||
|
readme_directory: /usr/share/doc/postfix
|
||||||
|
recipient_delimiter: +
|
||||||
|
relay_recipient_maps: ''
|
||||||
|
smtpd_banner: $myhostname ESMTP $mail_name
|
||||||
|
# Block clients that speak too early.
|
||||||
|
smtpd_data_restrictions: reject_unauth_pipelining
|
||||||
|
# Don't talk to mail systems that don't know their own hostname.
|
||||||
|
smtpd_helo_restrictions: reject_unknown_helo_hostname
|
||||||
|
smtpd_recipient_restrictions: permit_mynetworks, permit_sasl_authenticated, permit_auth_destination, reject_unauth_destination, check_policy_service unix:private/policy-spf
|
||||||
|
smtpd_relay_restrictions: permit_mynetworks permit_sasl_authenticated defer_unauth_destination
|
||||||
|
smtpd_sasl_auth_enable: 'yes'
|
||||||
|
smtpd_sasl_authenticated_header: 'yes'
|
||||||
|
smtpd_tls_cert_file: "/etc/letsencrypt/live/{{ mail_server_fqdn }}/fullchain.pem"
|
||||||
|
smtpd_tls_dh1024_param_file: /etc/ssl/private/dhparams.pem
|
||||||
|
smtpd_tls_exclude_ciphers: aNULL, eNULL, EXPORT, DES, RC4, MD5, PSK, aECDH, EDH-DSS-DES-CBC3-SHA, EDH-RSA-DES-CDC3-SHA, KRB5-DE5, CBC3-SHA
|
||||||
|
smtpd_tls_key_file: "/etc/letsencrypt/live/{{ mail_server_fqdn }}/privkey.pem"
|
||||||
|
smtpd_tls_session_cache_database: btree:/var/lib/postfix/smtpd_scache
|
||||||
|
smtpd_use_tls: yes
|
||||||
|
# If this is a backupmx or satellite then smtp_sasl_auth_enable: 'yes'
|
||||||
|
smtp_sasl_auth_enable: 'no'
|
||||||
|
smtp_sasl_security_options: noanonymous
|
||||||
|
smtp_sasl_type: cyrus
|
||||||
|
smtp_tls_session_cache_database: btree:/var/lib/postfix/smtp_scache
|
||||||
|
smtp_use_tls: 'yes'
|
||||||
|
transport_maps: proxy:mysql:/etc/postfix/mysql-virtual_transports.cf
|
||||||
|
virtual_alias_domains: ''
|
||||||
|
virtual_alias_maps: proxy:mysql:/etc/postfix/mysql-virtual_forwardings.cf, mysql:/etc/postfix/mysql-virtual_email2email.cf
|
||||||
|
virtual_gid_maps: static:5000
|
||||||
|
virtual_mailbox_base: /home/vmail
|
||||||
|
virtual_mailbox_domains: proxy:mysql:/etc/postfix/mysql-virtual_domains.cf
|
||||||
|
virtual_mailbox_limit_maps: proxy:mysql:/etc/postfix/mysql-virtual_mailbox_limit_maps.cf
|
||||||
|
virtual_mailbox_maps: proxy:mysql:/etc/postfix/mysql-virtual_mailboxes.cf
|
||||||
|
virtual_uid_maps: static:5000
|
7
files/compress_stored_messages.sh
Normal file
7
files/compress_stored_messages.sh
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
FILTER_PATH='/var/spool/filter'
|
||||||
|
while read -r FOLDER
|
||||||
|
do
|
||||||
|
tar cjf "${FOLDER}.tar.bz2" "${FOLDER}" &> /dev/null && rm -rf "${FOLDER}"
|
||||||
|
done <<< "$(find "${FILTER_PATH}/" -maxdepth 1 -type d -regex "^${FILTER_PATH}/2[0-9]*$")"
|
331
files/disclaimer.sh
Normal file
331
files/disclaimer.sh
Normal file
|
@ -0,0 +1,331 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# http://www.postfix.org/FILTER_README.html
|
||||||
|
# Clean up when done or when aborting.
|
||||||
|
finished=false
|
||||||
|
|
||||||
|
SENDMAIL=$(which sendmail)
|
||||||
|
if [ -z ${SENDMAIL} ]; then
|
||||||
|
if [ -x "/usr/sbin/sendmail" ]; then
|
||||||
|
SENDMAIL="/usr/sbin/sendmail"
|
||||||
|
else
|
||||||
|
nessage "Sendmail command not found"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
function finish {
|
||||||
|
${finished} || logger -t disclaimer "Disclaimer script not finished cleanly."
|
||||||
|
message "Sendmail command: ${SENDMAIL} -v -v ${ARGUMENTS} <in.$$"
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
result=$("${SENDMAIL}" -v -v ${ARGUMENTS} <"in.$$")
|
||||||
|
return_code="${?}"
|
||||||
|
if [[ "${return_code}" != "0" ]]; then
|
||||||
|
message "Error ${return_code} sending file to sendmail"
|
||||||
|
message "result: ${result}"
|
||||||
|
echo "Error ${return_code} sending file to sendmail with disclaimer.sh. result: ${result}" | mail -s "Error in disclaimer.sh filter" ad@susurrando.com
|
||||||
|
exit ${return_code}
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
#trap "$SENDMAIL '$@' <in.$$" 0 1 2 3 15
|
||||||
|
trap finish exit
|
||||||
|
|
||||||
|
LOGFILE=/var/log/disclaimer.log
|
||||||
|
if [ ! -w "${LOGFILE}" ]; then
|
||||||
|
LOGFILE="${HOME}/log/disclaimer.log"
|
||||||
|
if [ ! -w "${LOGFILE}" ]; then
|
||||||
|
LOGFILE="./disclaimer.log"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
function message() {
|
||||||
|
HIDE="${2}"
|
||||||
|
CDATE=$(date '+%Y-%m-%d %H:%M:%S')
|
||||||
|
APP=$(basename "${0}")
|
||||||
|
MSG="[$$] ${1}"
|
||||||
|
if [[ "${HIDE}" != "true" ]]; then
|
||||||
|
echo "${MSG}"
|
||||||
|
fi
|
||||||
|
/usr/bin/logger -t "${APP}" "${MSG}"
|
||||||
|
echo "${CDATE} ${MSG}" >> "${LOGFILE}"
|
||||||
|
}
|
||||||
|
ARGUMENTS=${*}
|
||||||
|
|
||||||
|
inspect_dir=/var/spool/filter
|
||||||
|
export HOME="${inspect_dir}"
|
||||||
|
out_stat_folder="${inspect_dir}/out.stats"
|
||||||
|
mkdir -p "${out_stat_folder}"
|
||||||
|
in_stat_folder="${inspect_dir}/in.stats"
|
||||||
|
mkdir -p "${in_stat_folder}"
|
||||||
|
|
||||||
|
DISCLAIMER_ADDRESSES=/etc/postfix/disclaimer_addresses
|
||||||
|
|
||||||
|
TEXT_DISCLAIMER=/etc/postfix/text_disclaimer.txt
|
||||||
|
HTML_DISCLAIMER_FILE=/etc/postfix/html_disclaimer.htm
|
||||||
|
|
||||||
|
# Exit codes from <sysexits.h>
|
||||||
|
EX_TEMPFAIL=75
|
||||||
|
EX_UNAVAILABLE=69
|
||||||
|
|
||||||
|
DATE=$(date +%s)
|
||||||
|
|
||||||
|
#GetRecordID $FROM mail_addresses mail_address mail
|
||||||
|
function GetRecordID() {
|
||||||
|
TEXT=$(echo "$1" | sed "s/'/\'/g" -)
|
||||||
|
ERR="${?}"
|
||||||
|
if [[ "$ERR" != "0" ]]
|
||||||
|
then
|
||||||
|
message "Error $ERR escaping single quotes from TEXT in GetRecordID"
|
||||||
|
fi
|
||||||
|
if [[ "$TEXT" == "" ]]; then
|
||||||
|
echo NULL
|
||||||
|
else
|
||||||
|
TABLE=$(echo "$2" | sed "s/'/\'/g" -)
|
||||||
|
ERR="${?}"
|
||||||
|
if [[ "$ERR" != "0" ]]
|
||||||
|
then
|
||||||
|
message "Error $ERR escaping single quotes from TABLE in GetRecordID"
|
||||||
|
fi
|
||||||
|
FIELD=$(echo "$3" | sed "s/'/\'/g" -)
|
||||||
|
ERR="${?}"
|
||||||
|
if [[ "$ERR" != "0" ]]
|
||||||
|
then
|
||||||
|
message "Error $ERR escaping single quotes from FIELD in GetRecordID"
|
||||||
|
fi
|
||||||
|
DATABASE=$(echo "$4" | sed "s/'/\'/g" -)
|
||||||
|
ERR="${?}"
|
||||||
|
if [[ "$ERR" != "0" ]]
|
||||||
|
then
|
||||||
|
message "Error $ERR escaping single quotes from DATABASE in GetRecordID"
|
||||||
|
fi
|
||||||
|
if [[ "$DATABASE" == "" ]]; then
|
||||||
|
message "No database indicated." true
|
||||||
|
else
|
||||||
|
ACTION=$(echo "$5" | sed "s/'/\'/g" -)
|
||||||
|
ERR="${?}"
|
||||||
|
if [[ "$ERR" != "0" ]]
|
||||||
|
then
|
||||||
|
message "Error $ERR escaping single quotes from $ACTION in GetRecordID"
|
||||||
|
fi
|
||||||
|
QUERY="SELECT id FROM $TABLE WHERE $FIELD='$TEXT';"
|
||||||
|
result=$(echo "$QUERY" | /usr/bin/env mysql "$DATABASE")
|
||||||
|
resultID=$(echo "$result" | grep -v id)
|
||||||
|
return_code="${?}"
|
||||||
|
if [[ "$return_code" != "0" ]]; then
|
||||||
|
message "Error getting $FIELD id for $TEXT from database with query '$QUERY'. result: $result" true
|
||||||
|
else
|
||||||
|
if [[ "$resultID" == "" ]]; then
|
||||||
|
message "The field '$TABLE.$FIELD' in database '$DATABASE' doesn't contain a record '$TEXT', adding it."
|
||||||
|
QUERY="INSERT INTO $TABLE (id, $FIELD) VALUES (NULL, '$TEXT');"
|
||||||
|
temp_file=$(mktemp /tmp/tmp.XXXXX)
|
||||||
|
echo "$QUERY" | /usr/bin/env mysql -v -v -v "$DATABASE" &> "${temp_file}"
|
||||||
|
return_code="${?}"
|
||||||
|
result=$(cat "${temp_file}")
|
||||||
|
if [[ "$return_code" != "0" ]]; then
|
||||||
|
message "Error $return_code adding $FIELD to database '$DATABASE' with query '$QUERY'. result: $result" true
|
||||||
|
else
|
||||||
|
QUERY="SELECT id FROM $TABLE WHERE $FIELD='$FROM';"
|
||||||
|
result=$(echo "$QUERY" | /usr/bin/env mysql "${DATABASE}")
|
||||||
|
resultID=$(echo "$result" | grep -v id)
|
||||||
|
return_code="${?}"
|
||||||
|
if [[ "$return_code" != "0" ]]; then
|
||||||
|
message "Error $return_code obtaining $FIELD id with query '$QUERY'. result: $result" true
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo "${resultID}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
function FromID() {
|
||||||
|
FROM="$1"
|
||||||
|
SENDER_ID=$(GetRecordID "$FROM" senders sender mail "Getting Id for From $1")
|
||||||
|
echo "${SENDER_ID}"
|
||||||
|
}
|
||||||
|
function RecipientID() {
|
||||||
|
RECIPIENT="$1"
|
||||||
|
RECIPIENT_ID=$(GetRecordID "$FROM" recipients recipient mail "Getting Id for To $1")
|
||||||
|
echo "${RECIPIENT_ID}"
|
||||||
|
}
|
||||||
|
# Start processing.
|
||||||
|
|
||||||
|
message "Processing message 'in.$$' as user '$(whoami)'..."
|
||||||
|
|
||||||
|
cd "${inspect_dir}" || exit
|
||||||
|
return_code="${?}"
|
||||||
|
if [[ "$return_code" != "0" ]]; then
|
||||||
|
message "Error $return_code changing to directory '$inspect_dir'"
|
||||||
|
exit $EX_TEMPFAIL;
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat >in.$$
|
||||||
|
return_code="${?}"
|
||||||
|
if [[ "$return_code" != "0" ]]; then
|
||||||
|
message "Cannot save mail to file"
|
||||||
|
exit $EX_TEMPFAIL
|
||||||
|
fi
|
||||||
|
message "Adding labels..."
|
||||||
|
/usr/bin/env python3 /etc/postfix/labeler.py in.$$ > in.$$.labeler.log
|
||||||
|
cp in.$$.labeler.log /var/spool/filter/last_message.eml.labeler.log -rfp
|
||||||
|
#Save last message
|
||||||
|
message "Saving as last_message.eml..."
|
||||||
|
cp in.$$ /var/spool/filter/last_message.eml -rfp
|
||||||
|
#Save copy of the messages. DANGEROUS!! Will consumpt disk space
|
||||||
|
message "Saving copy of message (this might fill the disk)..."
|
||||||
|
mkdir -p "/var/spool/filter/$(date +%Y%m%d)/"
|
||||||
|
cp in.$$ "/var/spool/filter/$(date +%Y%m%d)/$(date +%Y%m%d%H%M%S%N).eml" -rfp
|
||||||
|
# obtain headers
|
||||||
|
message "Obtaining headers..."
|
||||||
|
HEADERS=$(sed ':a;N;$!ba;s/\n\n.*//g' in.$$)
|
||||||
|
messageID=$(echo "$HEADERS" | sed ':a;N;$!ba;s/\n\s/ /g' | grep -m 1 -i "^message-id: " | sed 's/^message-id: //g' | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
message "message ID: '$messageID'"
|
||||||
|
FROMLONG=$(echo "$HEADERS" | sed ':a;N;$!ba;s/\n\s/ /g' | grep -m 1 "^From:" | sed "s/From: //" -)
|
||||||
|
SENDER_ID=$(FromID "$FROM")
|
||||||
|
message "From(long): '${FROMLONG}' (Id: $SENDER_ID)"
|
||||||
|
FROM=$(echo "${FROMLONG}" | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
message "From(short): '${FROM}'"
|
||||||
|
SUBJECT=$(echo "$HEADERS" | sed ':a;N;$!ba;s/\n\s/ /g' | grep -m 1 "^Subject:" | sed "s/Subject: //" - | sed "s/'/\'/g" - )
|
||||||
|
message "Subject: '$SUBJECT'"
|
||||||
|
RECIPIENT=$(echo "$HEADERS" | sed ':a;N;$!ba;s/\n\s/ /g' | grep -m 1 "^To:" | sed "s/To: //g" - | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
RECIPIENT_ID=$(RecipientID "$RECIPIENT")
|
||||||
|
message "TO: '$RECIPIENT'"
|
||||||
|
CCRECIPIENT=$(echo "$HEADERS" | sed ':a;N;$!ba;s/\n\s/ /g' | grep -m 1 "^Cc:" | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
message "CC: '$CCRECIPIENT'"
|
||||||
|
BCRECIPIENT=$(echo "$HEADERS" | sed ':a;N;$!ba;s/\n\s/ /g' | grep -m 1 "^Bcc:" | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
message "CCO: '$BCRECIPIENT'"
|
||||||
|
DELIVEREDTO=$(echo "$HEADERS" | sed ':a;N;$!ba;s/\n\s/ /g' | grep -m 1 "^Delivered-To:" | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
message "Delivered to: '$DELIVEREDTO'"
|
||||||
|
RETURNPATH=$(echo "$HEADERS" | sed ':a;N;$!ba;s/\n\s/ /g' | grep -m 1 "^Return-Path:" | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
message "Return path: '$RETURNPATH'"
|
||||||
|
REPLYTO=$(echo "$HEADERS" | sed ':a;N;$!ba;s/\n\s/ /g' | grep -m 1 "^Reply-To:" | sed "s/Sender: //g" - | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
message "Reply to: '$REPLYTO'"
|
||||||
|
XORIGINALSENDER=$(echo "$HEADERS" | sed ':a;N;$!ba;s/\n\s/ /g' |grep -m 1 "^X-Original-Sender:" | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
message "Reply to (original sender): '$XORIGINALSENDER'"
|
||||||
|
SENDER=$(echo "$HEADERS" | sed ':a;N;$!ba;s/\n\s/ /g' | grep -m 1 "^Sender:" | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
message "Reply to (sender): '$SENDER'"
|
||||||
|
XFORWARDEDTO=$(echo "$HEADERS" | sed ':a;N;$!ba;s/\n\s/ /g' | grep -m 1 "^X-Forwarded-To:" | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
message "Reply to (forwarded to): '$XFORWARDEDTO'"
|
||||||
|
XFORWARDEDFOR=$(echo "$HEADERS" | sed ':a;N;$!ba;s/\n\s/ /g' |grep -m 1 "^X-Forwarded-For:" | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
message "Reply to (forwarded for): '$XFORWARDEDFOR'"
|
||||||
|
XBEENTHERE=$(echo "$HEADERS" | sed ':a;N;$!ba;s/\n\s/ /g' | grep -m 1 "^X-BeenThere:" | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
message "Reply to (been there): '$XBEENTHERE'"
|
||||||
|
|
||||||
|
if grep -qi "^${FROM}$" "${DISCLAIMER_ADDRESSES}"; then
|
||||||
|
message "This is a mail from a local user '$FROM' with a disclaimer text, adding it to the message..."
|
||||||
|
DIRECTION=0
|
||||||
|
CURHOUR=$(date +%Y%m%d%H)
|
||||||
|
if [[ -e $in_stat_folder/$CURHOUR.stats ]]; then
|
||||||
|
CURHOURSTAT=$(cat "$in_stat_folder/$CURHOUR.stats")
|
||||||
|
else
|
||||||
|
CURHOURSTAT=0
|
||||||
|
fi
|
||||||
|
CURHOURSTAT=$((CURHOURSTAT + 1))
|
||||||
|
echo "$CURHOURSTAT" > "$in_stat_folder/$CURHOUR.stats"
|
||||||
|
QUERY="INSERT INTO messages (id, sender_id, subject, date, messageid) VALUES (NULL, '$SENDER_ID', '$SUBJECT', '$DATE', '$messageID');"
|
||||||
|
temp_file=$(mktemp /tmp/tmp.XXXX)
|
||||||
|
echo "$QUERY" | /usr/bin/env mysql -v -v -v mailview &> "${temp_file}"
|
||||||
|
return_code="${?}"
|
||||||
|
result=$(cat "${temp_file}")
|
||||||
|
if [[ "$return_code" != "0" ]]; then
|
||||||
|
message "Error $return_code while adding message to database 'mailview' with query '$QUERY'. result: '${result}'"
|
||||||
|
fi
|
||||||
|
QUERY="SELECT id FROM messages WHERE sender_id='$SENDER_ID' AND subject='$SUBJECT' AND date='$DATE';"
|
||||||
|
# MSG_ID=$(echo "$QUERY" | /usr/bin/env mysql mailview | grep -v id)
|
||||||
|
return_code="${?}"
|
||||||
|
if [[ "$return_code" != "0" ]]; then
|
||||||
|
message "Error $return_code while obtaining message id with query '$QUERY' from database 'mailview'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
TMP_HTML_DISCLAIMER_FILE=$(/bin/mktemp /tmp/disclaimer.XXXXX)
|
||||||
|
if [[ -r /etc/postfix/$FROM.disclaimer.html ]]; then
|
||||||
|
HTML_DISCLAIMER="/etc/postfix/$FROM.disclaimer.html"
|
||||||
|
echo "${HTML_DISCLAIMER}" > /dev/null
|
||||||
|
fi
|
||||||
|
sed "s/id=MSGID/id=$DB_MSG_ID/g" $HTML_DISCLAIMER_FILE > "$TMP_HTML_DISCLAIMER_FILE"
|
||||||
|
TMP_HTML_DISCLAIMER_FILE_BIS=$(/bin/mktemp /tmp/disclaimer.XXXXX)
|
||||||
|
sed "s/SENDERID/$SENDER_ID/g" "$TMP_HTML_DISCLAIMER_FILE" > "$TMP_HTML_DISCLAIMER_FILE_BIS"
|
||||||
|
sed "s/RECIPIENTID/$RECIPIENT_ID/g" "$TMP_HTML_DISCLAIMER_FILE_BIS" > "$TMP_HTML_DISCLAIMER_FILE"
|
||||||
|
message "Disclaimer HTML at '$TMP_HTML_DISCLAIMER_FILE'"
|
||||||
|
if [[ -r /etc/postfix/$FROM.disclaimer.txt ]]; then
|
||||||
|
TEXT_DISCLAIMER=/etc/postfix/$FROM.disclaimer.txt
|
||||||
|
fi
|
||||||
|
|
||||||
|
message "Running altermime with: /usr/bin/altermime --input=in.$$ --log-syslog --log-stdout --disclaimer=$TEXT_DISCLAIMER --disclaimer-html=$TMP_HTML_DISCLAIMER_FILE --xheader=\"X-MTA: $(cat /etc/mailname)\""
|
||||||
|
ALTERMIMEresult=$(/usr/bin/altermime --input=in.$$ --log-syslog --log-stdout --disclaimer="$TEXT_DISCLAIMER" --disclaimer-html="$TMP_HTML_DISCLAIMER_FILE" --xheader="X-MTA: $(cat /etc/mailname)")
|
||||||
|
message "altermime result: $ALTERMIMEresult"
|
||||||
|
return_code="${?}"
|
||||||
|
if [[ "$return_code" != "0" ]]; then
|
||||||
|
message "Error $return_code message content rejected."
|
||||||
|
exit $EX_UNAVAILABLE;
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
DIRECTION=1
|
||||||
|
message "Sender '$FROMLONG' ($FROM) is NOT in disclaimer addresses file"
|
||||||
|
CURHOUR=$(date +%Y%m%d%H)
|
||||||
|
if [[ -e $out_stat_folder/$CURHOUR.stats ]]; then
|
||||||
|
CURHOURSTAT=$(cat "$out_stat_folder/$CURHOUR.stats")
|
||||||
|
else
|
||||||
|
CURHOURSTAT=0
|
||||||
|
fi
|
||||||
|
CURHOURSTAT=$((CURHOURSTAT + 1))
|
||||||
|
echo $CURHOURSTAT > "$out_stat_folder/$CURHOUR.stats"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#Stats
|
||||||
|
FROMID=$(GetRecordID "$FROM" mail_addresses mail_address mail "Get ID of From $FROM")
|
||||||
|
message "From $FROM with ID $FROMID"
|
||||||
|
if [[ "$RECIPIENT" != "" ]]; then
|
||||||
|
TOID=$(GetRecordID "$RECIPIENT" mail_addresses mail_address mail "Get ID of To $TO")
|
||||||
|
else
|
||||||
|
TOID="0"
|
||||||
|
fi
|
||||||
|
message "To $RECIPIENT with ID $TOID"
|
||||||
|
if [[ -z "$CCRECIPIENT" ]]; then
|
||||||
|
CCID=$(GetRecordID "$CCRECIPIENT" mail_addresses mail_address mail "Get ID of CC")
|
||||||
|
else
|
||||||
|
CCID="0"
|
||||||
|
fi
|
||||||
|
if [[ -z "$BCRECIPIENT" ]]; then
|
||||||
|
CCOID=$(GetRecordID "$BCRECIPIENT" mail_addresses mail_address mail "Get ID of BCC")
|
||||||
|
else
|
||||||
|
CCOID="0"
|
||||||
|
fi
|
||||||
|
if [[ -z "$DELIVEREDTO" ]]; then
|
||||||
|
DTID=$(GetRecordID "$DELIVEREDTO" mail_addresses mail_address mail "Get ID of DeliveredTo")
|
||||||
|
else
|
||||||
|
DTID="0"
|
||||||
|
fi
|
||||||
|
if [[ -z "$RETURNPATH" ]]; then
|
||||||
|
RPID=$(GetRecordID "$RETURNPATH" mail_addresses mail_address mail)
|
||||||
|
else
|
||||||
|
RPID="0"
|
||||||
|
fi
|
||||||
|
if [[ -z "$XORIGINALSENDER" ]]; then
|
||||||
|
XOSID=$(GetRecordID "$XORIGINALSENDER" mail_addresses mail_address mail)
|
||||||
|
else
|
||||||
|
XOSID="0"
|
||||||
|
fi
|
||||||
|
if [[ -z "$SENDER" ]]; then
|
||||||
|
SID=$(GetRecordID "$SENDER" mail_addresses mail_address mail)
|
||||||
|
else
|
||||||
|
SID="0"
|
||||||
|
fi
|
||||||
|
if [[ -z "$XFORWARDEDTO" ]]; then
|
||||||
|
XFTID=$(GetRecordID "$XFORWARDEDTO" mail_addresses mail_address mail)
|
||||||
|
else
|
||||||
|
XFTID="0"
|
||||||
|
fi
|
||||||
|
if [[ -z "$XFORWARDEDFOR" ]]; then
|
||||||
|
XFFID=$(GetRecordID "$XFORWARDEDFOR" mail_addresses mail_address mail)
|
||||||
|
else
|
||||||
|
XFFID="0"
|
||||||
|
fi
|
||||||
|
|
||||||
|
QUERY="INSERT INTO stats (msgid, from_id, to_id,cc_id, cco_id, subject, direction, delivered_to_id, return_path_id, s_original_sender_id, sender_id, x_forwarded_to, x_forwarded_for) VALUES ('$messageID',$FROMID, $TOID, $CCID, $CCOID, '$SUBJECT', $DIRECTION, $DTID, $RPID, $XOSID, $SID, $XFTID, $XFFID);"
|
||||||
|
temp_file=$(mktemp /tmp/tmp.XXXX)
|
||||||
|
echo "${QUERY}" | /usr/bin/env mysql -v -v -v mail &> "${temp_file}"
|
||||||
|
return_code="${?}"
|
||||||
|
result=$(cat "${temp_file}")
|
||||||
|
if [[ "${return_code}" != "0" ]]; then
|
||||||
|
message "Error ${return_code} saving stats with query '${QUERY}'. result: ${result}"
|
||||||
|
fi
|
||||||
|
finished=true
|
9
files/mail.local
Normal file
9
files/mail.local
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[courier-auth]
|
||||||
|
enabled = true
|
||||||
|
|
||||||
|
[sasl]
|
||||||
|
enabled = true
|
||||||
|
port = smtp
|
||||||
|
filter = postfix-sasl
|
||||||
|
logpath = /var/log/mail.log
|
||||||
|
maxretry = 5
|
291
files/mysql_mail_db.sql
Normal file
291
files/mysql_mail_db.sql
Normal file
|
@ -0,0 +1,291 @@
|
||||||
|
-- MySQL dump 10.19 Distrib 10.3.34-MariaDB, for debian-linux-gnu (x86_64)
|
||||||
|
--
|
||||||
|
-- Host: localhost Database: mail
|
||||||
|
-- ------------------------------------------------------
|
||||||
|
-- Server version 10.3.34-MariaDB-0ubuntu0.20.04.1
|
||||||
|
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||||
|
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||||
|
/*!40101 SET NAMES utf8mb4 */;
|
||||||
|
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
||||||
|
/*!40103 SET TIME_ZONE='+00:00' */;
|
||||||
|
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||||
|
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||||
|
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||||
|
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `bannedcontent`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `bannedcontent`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
CREATE TABLE `bannedcontent` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`creation_date` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||||
|
`regexp` varchar(255) NOT NULL,
|
||||||
|
`action` varchar(20) NOT NULL DEFAULT 'DROP',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `regexp` (`regexp`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `bannedsenders`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `bannedsenders`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
CREATE TABLE `bannedsenders` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`sender` varchar(255) NOT NULL,
|
||||||
|
`creation_date` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||||
|
`frommsgid` varchar(255) NOT NULL,
|
||||||
|
`banned` tinyint(1) NOT NULL DEFAULT 1,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=26705 DEFAULT CHARSET=latin1;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `bannedservers`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `bannedservers`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
CREATE TABLE `bannedservers` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`server` varchar(255) NOT NULL,
|
||||||
|
`creation_date` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||||
|
`frommsgid` varchar(255) NOT NULL,
|
||||||
|
`banned` tinyint(1) NOT NULL DEFAULT 1,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `server` (`server`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=18537 DEFAULT CHARSET=latin1;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `bannedsubjects`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `bannedsubjects`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
CREATE TABLE `bannedsubjects` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`subject` varchar(255) NOT NULL,
|
||||||
|
`count` int(11) NOT NULL DEFAULT 0,
|
||||||
|
`creation_date` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||||
|
`frommsgid` varchar(255) NOT NULL,
|
||||||
|
`banned` tinyint(1) NOT NULL DEFAULT 1,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `subject` (`subject`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=14505 DEFAULT CHARSET=utf8;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `domains`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `domains`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
CREATE TABLE `domains` (
|
||||||
|
`domain` varchar(50) NOT NULL,
|
||||||
|
`creationdate` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||||
|
PRIMARY KEY (`domain`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `forwardings`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `forwardings`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
CREATE TABLE `forwardings` (
|
||||||
|
`creation_date` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||||
|
`source` varchar(80) NOT NULL,
|
||||||
|
`destination` text NOT NULL,
|
||||||
|
`porpouse` varchar(255) NOT NULL,
|
||||||
|
PRIMARY KEY (`source`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `logins`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `logins`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
CREATE TABLE `logins` (
|
||||||
|
`creation_date` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||||
|
`ip` varchar(16) NOT NULL,
|
||||||
|
`user` varchar(255) NOT NULL,
|
||||||
|
`ipxmlinfo` longtext NOT NULL,
|
||||||
|
`city` varchar(255) NOT NULL,
|
||||||
|
`region` varchar(255) NOT NULL,
|
||||||
|
`country` varchar(255) NOT NULL
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `mail_addresses`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `mail_addresses`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
CREATE TABLE `mail_addresses` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`mail_address` varchar(255) NOT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `mail_address` (`mail_address`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=115336 DEFAULT CHARSET=latin1;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `notifiedmtas`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `notifiedmtas`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
CREATE TABLE `notifiedmtas` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`mta_mail` varchar(255) NOT NULL,
|
||||||
|
`creation_date` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||||
|
PRIMARY KEY (`id`,`mta_mail`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=18395 DEFAULT CHARSET=latin1;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `recipients`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `recipients`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
CREATE TABLE `recipients` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`creation_date` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||||
|
`recipient` varchar(255) NOT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `recipient` (`recipient`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1889 DEFAULT CHARSET=latin1;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `senders`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `senders`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
CREATE TABLE `senders` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`creation_date` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||||
|
`sender` varchar(255) NOT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `sender` (`sender`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1885 DEFAULT CHARSET=latin1;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `stats`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `stats`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
CREATE TABLE `stats` (
|
||||||
|
`msgid` varchar(255) NOT NULL,
|
||||||
|
`from_id` int(11) NOT NULL,
|
||||||
|
`to_id` int(11) NOT NULL,
|
||||||
|
`cc_id` int(11) NOT NULL,
|
||||||
|
`cco_id` int(11) NOT NULL,
|
||||||
|
`subject` varchar(255) NOT NULL,
|
||||||
|
`direction` tinyint(1) NOT NULL COMMENT '0 inbound, 1 outbound',
|
||||||
|
`delivered_to_id` int(11) NOT NULL,
|
||||||
|
`return_path_id` int(11) NOT NULL,
|
||||||
|
`s_original_sender_id` int(11) NOT NULL,
|
||||||
|
`sender_id` int(11) NOT NULL,
|
||||||
|
`x_forwarded_to` int(11) NOT NULL,
|
||||||
|
`x_forwarded_for` int(11) NOT NULL,
|
||||||
|
UNIQUE KEY `msgid` (`msgid`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `transactions`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `transactions`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
CREATE TABLE `transactions` (
|
||||||
|
`start_timestamp` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||||
|
`pid` int(11) NOT NULL,
|
||||||
|
`from_IP` varchar(15) NOT NULL,
|
||||||
|
`from_host` varchar(255) NOT NULL,
|
||||||
|
`transaction_id` varchar(12) NOT NULL DEFAULT 'unknown',
|
||||||
|
`message_id` varchar(255) NOT NULL DEFAULT 'unknown',
|
||||||
|
`from` varchar(255) NOT NULL DEFAULT 'unknown',
|
||||||
|
`size` int(11) NOT NULL DEFAULT 0,
|
||||||
|
`nrcpt` int(11) NOT NULL DEFAULT 0,
|
||||||
|
`to` varchar(255) NOT NULL DEFAULT 'unknown',
|
||||||
|
`relay` varchar(255) NOT NULL DEFAULT 'unknown',
|
||||||
|
`delay` int(11) NOT NULL DEFAULT 0,
|
||||||
|
`delays` varchar(22) NOT NULL DEFAULT 'unknown',
|
||||||
|
`dsn` varchar(7) NOT NULL DEFAULT 'unknown',
|
||||||
|
`status` varchar(255) NOT NULL DEFAULT 'unknown',
|
||||||
|
`orig_to` varchar(255) NOT NULL DEFAULT 'unknown',
|
||||||
|
`end_timestamp` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `transport`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `transport`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
CREATE TABLE `transport` (
|
||||||
|
`domain` varchar(128) NOT NULL DEFAULT '',
|
||||||
|
`transport` varchar(128) NOT NULL DEFAULT '',
|
||||||
|
UNIQUE KEY `domain` (`domain`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `users`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `users`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
CREATE TABLE `users` (
|
||||||
|
`email` varchar(80) NOT NULL,
|
||||||
|
`password` varchar(256) DEFAULT NULL,
|
||||||
|
`quota` bigint(20) DEFAULT 104857600000,
|
||||||
|
`fullname` varchar(255) NOT NULL,
|
||||||
|
PRIMARY KEY (`email`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||||
|
|
||||||
|
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||||
|
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||||
|
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||||
|
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||||
|
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||||
|
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||||
|
|
||||||
|
-- Dump completed on 2022-10-04 20:45:17
|
111
files/new_mail_alias
Normal file
111
files/new_mail_alias
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
[ -r /var/lib/from_repos/scripts/shared_functions.sh ] && . /var/lib/from_repos/scripts/shared_functions.sh
|
||||||
|
function usage() {
|
||||||
|
echo "Usage:"
|
||||||
|
echo "$(basename "${0}") -p|--porpouse <porpouse> [-o|--domain <DOMAIN>] [-l|--length <ALIAS_LENGTH>] [-e|--destination <DESTINATION>]"
|
||||||
|
echo ""
|
||||||
|
echo " -d|--debug Show more debug information."
|
||||||
|
echo " -p|--porpouse <PORPOUSE> Porpouse of this forwarding that will help you remember why you created it."
|
||||||
|
echo " -o|--domain <DOMAIN> Domain name for the alias. From the list:"
|
||||||
|
while read -r DOMAIN
|
||||||
|
do
|
||||||
|
echo " # ${DOMAIN}"
|
||||||
|
done <<< "$(echo 'select domain FROM mail.domains' | mysql mail|grep -v '^domain$')"
|
||||||
|
echo " -l|--length <ALIAS_LENGTH> Length of pseudo-random character of the alias."
|
||||||
|
echo " -e|--destination <DESTINATION> Destination of the forwarding."
|
||||||
|
echo " -a|--alias <ALIAS> Use a defined alias."
|
||||||
|
}
|
||||||
|
domain="susurrando.com"
|
||||||
|
alias_length=6
|
||||||
|
destination="ad@susurrando.com"
|
||||||
|
alias=""
|
||||||
|
while [ $# -gt 0 ]
|
||||||
|
do
|
||||||
|
case "${1}" in
|
||||||
|
"-h"|"-?"|"--help")
|
||||||
|
shift
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
"-d"|"--debug")
|
||||||
|
shift
|
||||||
|
export DEBUG=true
|
||||||
|
;;
|
||||||
|
"-o"|"--domain")
|
||||||
|
shift
|
||||||
|
domain="${1}"
|
||||||
|
existing=$(echo "select domain FROM mail.domains WHERE domain = '${domain}';" | mysql mail | grep -v '^domain$')
|
||||||
|
if [ -z "${existing}" ]; then
|
||||||
|
message "The domain '${domain}' doesn't exist in the database. Add it first." p
|
||||||
|
echo "Current list of domains:"
|
||||||
|
while read -r DOMAIN
|
||||||
|
do
|
||||||
|
echo " # ${DOMAIN}"
|
||||||
|
done <<< "$(echo 'select domain FROM mail.domains' | mysql mail|grep -v '^domain$')"
|
||||||
|
exit 4
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
"-l"|"--length")
|
||||||
|
shift
|
||||||
|
alias_length="${1}"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
"-e"|"--destination")
|
||||||
|
shift
|
||||||
|
destination="${1}"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
"-p"|"--porpouse")
|
||||||
|
shift
|
||||||
|
porpouse="${1}"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
"-a"|"--alias")
|
||||||
|
shift
|
||||||
|
alias="${1}"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
message "Unknown parameter '$1'" p
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "${porpouse}" ]; then
|
||||||
|
message "You have to provide a porpouse." p
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
existing=$(echo "SELECT * FROM mail.forwardings where porpouse = '${porpouse}';" | mysql mail)
|
||||||
|
if [ -n "${existing}" ]; then
|
||||||
|
message "There is already an alias for that porpouse:" p
|
||||||
|
message "${existing}" p
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${alias}" ]; then
|
||||||
|
existing=$(echo "SELECT source FROM mail.forwardings where source = '${alias}';" |mysql mail | grep -v '^source$')
|
||||||
|
if [ -n "${existing}" ]; then
|
||||||
|
message "Alias already exist in the database:" p
|
||||||
|
message "'${existing}'" p
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
while [ "${alias}" == "" ]
|
||||||
|
do
|
||||||
|
random_string=$(LC_ALL=C tr -dc A-Za-z0-9 </dev/urandom | head -c "${alias_length}")
|
||||||
|
existing=$(echo "SELECT source FROM mail.forwardings where source = '${random_string}@${domain}';" |mysql mail |grep -v '^source$')
|
||||||
|
if [ -z "${existing}" ]; then
|
||||||
|
alias="${random_string}@${domain}"
|
||||||
|
message "Generated alias: '${alias}'"
|
||||||
|
else
|
||||||
|
message "Generated alias '${random_string}@${domain}' exists in the database."
|
||||||
|
message "'${existing}'"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo "INSERT INTO mail.forwardings (source, destination, porpouse) VALUES ('${alias}','${destination}','${porpouse}');"| mysql mail
|
||||||
|
message "Inserted forwarding from '${alias}' to '${destination}' for the porpouse of '${porpouse}'." p
|
75
files/new_mail_user.sh
Executable file
75
files/new_mail_user.sh
Executable file
|
@ -0,0 +1,75 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
[ -r /var/lib/from_repos/scripts/shared_functions.sh ] && . /var/lib/from_repos/scripts/shared_functions.sh
|
||||||
|
|
||||||
|
fullname=''
|
||||||
|
quota=104857600000
|
||||||
|
db_name='mail'
|
||||||
|
DEFAULT_DOMAIN='susurrando.com'
|
||||||
|
function usage() {
|
||||||
|
message "$(basename "${0}") --user|-u <USEREMAIL> [--password|-p <PASSWORD>] [--fullname|-n <FULL USER NAME>] [--quota|-q <QUOTA>] [--debug|-d]" p
|
||||||
|
}
|
||||||
|
while [ "${#}" -gt 0 ]
|
||||||
|
do
|
||||||
|
case "${1}" in
|
||||||
|
'--user'|'-u')
|
||||||
|
shift
|
||||||
|
username="${1}"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
'--password'|'-p')
|
||||||
|
shift
|
||||||
|
password="${1}"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
'--full-name'|'-n')
|
||||||
|
shift
|
||||||
|
fullname="${1}"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
'--quota'|'-q')
|
||||||
|
shift
|
||||||
|
quota=$(echo "${1}" | grep -o '[0-9]*' | head -n 1)
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
'--debug'|'-d')
|
||||||
|
shift
|
||||||
|
export DEBUG=true
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
parameters="${parameters} ${1}"
|
||||||
|
message "Ignoring parameter '${1}'." p
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
if [[ "${username}" == "" ]]; then
|
||||||
|
usage
|
||||||
|
exit 65
|
||||||
|
fi
|
||||||
|
if [[ "${password}" == "" ]]; then
|
||||||
|
password=$(/usr/bin/pwgen -c -n -B 9 1)
|
||||||
|
message "User password is ${password}" p
|
||||||
|
fi
|
||||||
|
if ! [[ "${username}" =~ .*@[a-zA-Z0-9]*\.[a-zA-Z0-9]{2,} ]]
|
||||||
|
then
|
||||||
|
username="${username}@${DEFAULT_DOMAIN}"
|
||||||
|
message "Username: '${username}'" p
|
||||||
|
fi
|
||||||
|
|
||||||
|
query="insert into users (email, password, fullname, quota) VALUES ('${username}', ENCRYPT('${password}'), '${fullname}', ${quota});"
|
||||||
|
message "Calling query: '${query}'"
|
||||||
|
echo "${query}" | mysql "${db_name}"
|
||||||
|
error_code="${?}"
|
||||||
|
if [[ "${error_code}" != "0" ]]; then
|
||||||
|
message "Error ${error_code} while adding user to the mail database" p
|
||||||
|
exit "${error_code}"
|
||||||
|
else
|
||||||
|
message "Added sucessfully to mail database" p
|
||||||
|
echo "Welcome to Susurrando.com mail service" | mail -s "Welcome to Susurrando mail service" "${username}"
|
||||||
|
error_code="${?}"
|
||||||
|
if [[ "${error_code}" != "0" ]]; then
|
||||||
|
message "Error ${error_code} sending welcome message" p
|
||||||
|
exit "${error_code}"
|
||||||
|
fi
|
||||||
|
fi
|
6
files/postfix-sasl.conf
Normal file
6
files/postfix-sasl.conf
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# Fail2Ban filter for postfix authentication failures
|
||||||
|
[INCLUDES]
|
||||||
|
before = common.conf
|
||||||
|
[Definition]
|
||||||
|
_daemon = postfix/smtpd
|
||||||
|
failregex = ^%(__prefix_line)swarning: [-._\w]+\[<HOST>\]: SASL (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed(: [ A-Za-z0-9+/]*={0,2})?\s*$
|
11
files/remove_queued_messages.sh
Executable file
11
files/remove_queued_messages.sh
Executable file
|
@ -0,0 +1,11 @@
|
||||||
|
#!/bin/bash
|
||||||
|
if [[ "$1" == "" ]]
|
||||||
|
then
|
||||||
|
echo "Indicate a string to search in the postqueue."
|
||||||
|
exit 54
|
||||||
|
fi
|
||||||
|
postqueue -p | grep -v '^-' | sed ':a;N;$!ba;s/\n\n/ENTER/g' | sed ':a;N;$!ba;s/\n/ /g' | sed 's/ENTER/\n/g' | grep "$1" |awk '{print($1)}' | while read -r KMSGID
|
||||||
|
do
|
||||||
|
echo "Removing message with ID '${KMSGID}'..."
|
||||||
|
postsuper -d "$KMSGID"
|
||||||
|
done
|
66
files/saslauthd
Normal file
66
files/saslauthd
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
#
|
||||||
|
# Settings for saslauthd daemon
|
||||||
|
# Please read /usr/share/doc/sasl2-bin/README.Debian for details.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Should saslauthd run automatically on startup? (default: no)
|
||||||
|
START=yes
|
||||||
|
|
||||||
|
# Description of this saslauthd instance. Recommended.
|
||||||
|
# (suggestion: SASL Authentication Daemon)
|
||||||
|
DESC="SASL Authentication Daemon"
|
||||||
|
|
||||||
|
# Short name of this saslauthd instance. Strongly recommended.
|
||||||
|
# (suggestion: saslauthd)
|
||||||
|
NAME="saslauthd"
|
||||||
|
|
||||||
|
# Which authentication mechanisms should saslauthd use? (default: pam)
|
||||||
|
#
|
||||||
|
# Available options in this Debian package:
|
||||||
|
# getpwent -- use the getpwent() library function
|
||||||
|
# kerberos5 -- use Kerberos 5
|
||||||
|
# pam -- use PAM
|
||||||
|
# rimap -- use a remote IMAP server
|
||||||
|
# shadow -- use the local shadow password file
|
||||||
|
# sasldb -- use the local sasldb database file
|
||||||
|
# ldap -- use LDAP (configuration is in /etc/saslauthd.conf)
|
||||||
|
#
|
||||||
|
# Only one option may be used at a time. See the saslauthd man page
|
||||||
|
# for more information.
|
||||||
|
#
|
||||||
|
# Example: MECHANISMS="pam"
|
||||||
|
MECHANISMS="pam"
|
||||||
|
#MECHANISMS="rimap"
|
||||||
|
|
||||||
|
# Additional options for this mechanism. (default: none)
|
||||||
|
# See the saslauthd man page for information about mech-specific options.
|
||||||
|
MECH_OPTIONS=""
|
||||||
|
|
||||||
|
# How many saslauthd processes should we run? (default: 5)
|
||||||
|
# A value of 0 will fork a new process for each connection.
|
||||||
|
THREADS=5
|
||||||
|
|
||||||
|
# Other options (default: -c -m /var/run/saslauthd)
|
||||||
|
# Note: You MUST specify the -m option or saslauthd won't run!
|
||||||
|
#
|
||||||
|
# WARNING: DO NOT SPECIFY THE -d OPTION.
|
||||||
|
# The -d option will cause saslauthd to run in the foreground instead of as
|
||||||
|
# a daemon. This will PREVENT YOUR SYSTEM FROM BOOTING PROPERLY. If you wish
|
||||||
|
# to run saslauthd in debug mode, please run it by hand to be safe.
|
||||||
|
#
|
||||||
|
# See /usr/share/doc/sasl2-bin/README.Debian for Debian-specific information.
|
||||||
|
# See the saslauthd man page and the output of 'saslauthd -h' for general
|
||||||
|
# information about these options.
|
||||||
|
#
|
||||||
|
# Example for chroot Postfix users: "-c -m /var/spool/postfix/var/run/saslauthd"
|
||||||
|
# Example for non-chroot Postfix users: "-c -m /var/run/saslauthd"
|
||||||
|
#
|
||||||
|
# To know if your Postfix is running chroot, check /etc/postfix/master.cf.
|
||||||
|
# If it has the line "smtp inet n - y - - smtpd" or "smtp inet n - - - - smtpd"
|
||||||
|
# then your Postfix is running in a chroot.
|
||||||
|
# If it has the line "smtp inet n - n - - smtpd" then your Postfix is NOT
|
||||||
|
# running in a chroot.
|
||||||
|
#OPTIONS="-c -m /var/run/saslauthd"
|
||||||
|
#OPTIONS="-c -m /var/spool/postfix/var/run/saslauthd -r"
|
||||||
|
#OPTIONS="-c -m /var/spool/postfix/var/run/courier/authdaemon -r -d"
|
||||||
|
OPTIONS="-r -c -m /var/spool/postfix/var/run/saslauthd"
|
14
files/update_clients.sh
Normal file
14
files/update_clients.sh
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
declare clients=( hiljainen.susurrando.com www.susurrando.com oc.koti.site)
|
||||||
|
|
||||||
|
rm /etc/postfix/allowed_clients
|
||||||
|
touch /etc/postfix/allowed_clients
|
||||||
|
chown postfix.postfix /etc/postfix/allowed_clients
|
||||||
|
chmod o-rwx /etc/postfix/allowed_clients
|
||||||
|
|
||||||
|
for client in "${clients[@]}"
|
||||||
|
do
|
||||||
|
client_ip=$(dig "${client}" | grep -v '^;' |grep "\sA\s" | awk '{print($5)}')
|
||||||
|
echo "${client_ip}" >> /etc/postfix/allowed_clients
|
||||||
|
done
|
8
handlers/main.yml
Normal file
8
handlers/main.yml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
- name: Refresh aliases
|
||||||
|
shell: newaliases
|
||||||
|
|
||||||
|
- name: Restart postfix
|
||||||
|
service:
|
||||||
|
name: postfix
|
||||||
|
state: restarted
|
207
tasks/configure.yml
Normal file
207
tasks/configure.yml
Normal file
|
@ -0,0 +1,207 @@
|
||||||
|
---
|
||||||
|
- name: Create mailname file
|
||||||
|
copy:
|
||||||
|
dest: /etc/mailname
|
||||||
|
content: "{{ inventory_hostname }}"
|
||||||
|
backup: true
|
||||||
|
mode: '0644'
|
||||||
|
notify: Restart postfix
|
||||||
|
|
||||||
|
- name: Template file authmysqlrc
|
||||||
|
template:
|
||||||
|
src: templates/authmysqlrc.j2
|
||||||
|
dest: /etc/courier/authmysqlrc
|
||||||
|
owner: root
|
||||||
|
group: postfix
|
||||||
|
mode: '0550'
|
||||||
|
backup: true
|
||||||
|
notify: Restart postfix
|
||||||
|
|
||||||
|
- name: Template file mysql-body_checks.cf
|
||||||
|
template:
|
||||||
|
src: templates/mysql-body_checks.cf.j2
|
||||||
|
dest: /etc/postfix/mysql-body_checks.cf
|
||||||
|
owner: root
|
||||||
|
group: postfix
|
||||||
|
mode: '0550'
|
||||||
|
backup: true
|
||||||
|
notify: Restart postfix
|
||||||
|
|
||||||
|
- name: Template file mysql-virtual_domains.cf
|
||||||
|
template:
|
||||||
|
src: templates/mysql-virtual_domains.cf.j2
|
||||||
|
dest: /etc/postfix/mysql-virtual_domains.cf
|
||||||
|
owner: root
|
||||||
|
group: postfix
|
||||||
|
mode: '0550'
|
||||||
|
backup: true
|
||||||
|
notify: Restart postfix
|
||||||
|
|
||||||
|
- name: Template file mysql-virtual_email2email.cf
|
||||||
|
template:
|
||||||
|
src: templates/mysql-virtual_email2email.cf.j2
|
||||||
|
dest: /etc/postfix/mysql-virtual_email2email.cf
|
||||||
|
owner: root
|
||||||
|
group: postfix
|
||||||
|
mode: '0550'
|
||||||
|
backup: true
|
||||||
|
notify: Restart postfix
|
||||||
|
|
||||||
|
- name: Template file mysql-virtual_forwardings.cf
|
||||||
|
template:
|
||||||
|
src: templates/mysql-virtual_forwardings.cf.j2
|
||||||
|
dest: /etc/postfix/mysql-virtual_forwardings.cf
|
||||||
|
owner: root
|
||||||
|
group: postfix
|
||||||
|
mode: '0550'
|
||||||
|
backup: true
|
||||||
|
notify: Restart postfix
|
||||||
|
|
||||||
|
- name: Template file mysql-virtual_mailbox_limit_maps.cf
|
||||||
|
template:
|
||||||
|
src: templates/mysql-virtual_mailbox_limit_maps.cf.j2
|
||||||
|
dest: /etc/postfix/mysql-virtual_mailbox_limit_maps.cf
|
||||||
|
owner: root
|
||||||
|
group: postfix
|
||||||
|
mode: '0550'
|
||||||
|
backup: true
|
||||||
|
notify: Restart postfix
|
||||||
|
|
||||||
|
- name: Template file mysql-virtual_mailboxes.cf
|
||||||
|
template:
|
||||||
|
src: templates/mysql-virtual_mailboxes.cf.j2
|
||||||
|
dest: /etc/postfix/mysql-virtual_mailboxes.cf
|
||||||
|
owner: root
|
||||||
|
group: postfix
|
||||||
|
mode: '0550'
|
||||||
|
backup: true
|
||||||
|
notify: Restart postfix
|
||||||
|
|
||||||
|
- name: Template file mysql-virtual_transports.cf
|
||||||
|
template:
|
||||||
|
src: templates/mysql-virtual_transports.cf.j2
|
||||||
|
dest: /etc/postfix/mysql-virtual_transports.cf
|
||||||
|
owner: root
|
||||||
|
group: postfix
|
||||||
|
mode: '0550'
|
||||||
|
backup: true
|
||||||
|
notify: Restart postfix
|
||||||
|
|
||||||
|
- name: Template file smtp
|
||||||
|
template:
|
||||||
|
src: templates/smtp.j2
|
||||||
|
dest: /etc/pam.d/smtp
|
||||||
|
owner: root
|
||||||
|
group: postfix
|
||||||
|
mode: '0550'
|
||||||
|
backup: true
|
||||||
|
notify: Restart postfix
|
||||||
|
|
||||||
|
- name: Template file smtpd.conf
|
||||||
|
template:
|
||||||
|
src: templates/smtpd.conf.j2
|
||||||
|
dest: /etc/postfix/sasl/smtpd.conf
|
||||||
|
owner: root
|
||||||
|
group: postfix
|
||||||
|
mode: '0550'
|
||||||
|
backup: true
|
||||||
|
notify: Restart postfix
|
||||||
|
|
||||||
|
- name: Generate DH param certificate
|
||||||
|
shell:
|
||||||
|
cmd: /usr/bin/openssl dhparam -out /etc/ssl/private/dhparams.pem 2048 && /bin/chmod 600 /etc/ssl/private/dhparams.pem
|
||||||
|
creates: /etc/ssl/private/dhparams.pem
|
||||||
|
notify: Restart postfix
|
||||||
|
|
||||||
|
- name: Ensure SASL Authdaemond folder exists
|
||||||
|
file:
|
||||||
|
path: /var/spool/postfix/var/run/saslauthd
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: sasl
|
||||||
|
mode: '0770'
|
||||||
|
|
||||||
|
- name: Ensure Postfix spool folders exists
|
||||||
|
file:
|
||||||
|
path: /var/spool/postfix/var
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Ensure Postfix spool folders exists
|
||||||
|
file:
|
||||||
|
path: /var/spool/postfix/var/run/courier
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Ensure SASL authentication daemon starts
|
||||||
|
lineinfile:
|
||||||
|
path: /etc/default/saslauthd
|
||||||
|
regexp: '^START='
|
||||||
|
line: 'START=yes'
|
||||||
|
backup: true
|
||||||
|
create: true
|
||||||
|
|
||||||
|
- name: Ensure SASL authentication daemon spool directory match postfix
|
||||||
|
lineinfile:
|
||||||
|
path: /etc/default/saslauthd
|
||||||
|
regexp: '^OPTIONS='
|
||||||
|
line: 'OPTIONS="-r -c -m /var/spool/postfix/var/run/saslauthd"'
|
||||||
|
backup: true
|
||||||
|
create: true
|
||||||
|
|
||||||
|
- name: Ensure CRON job to update clients exists
|
||||||
|
cron:
|
||||||
|
name: "Update SMTPD trusted clients"
|
||||||
|
job: '/etc/postfix/scripts/update_clients.sh'
|
||||||
|
user: root
|
||||||
|
minute: '20'
|
||||||
|
|
||||||
|
- name: Ensure cron to check if authdaemond is stuck exists
|
||||||
|
cron:
|
||||||
|
name: check authdaemond stuck
|
||||||
|
job: /etc/postfix/scripts/authdaemond_check_stuck.sh
|
||||||
|
minute: '*/5'
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Resolve host names
|
||||||
|
set_fact:
|
||||||
|
mail_own_networks: "{{ mail_own_networks + [ lookup('community.general.dig', item + '.', '@' + dns_resolver) ] }}"
|
||||||
|
loop: "{{ mail_own_networks_hosts }}"
|
||||||
|
|
||||||
|
- name: Remove duplicates
|
||||||
|
set_fact:
|
||||||
|
mail_own_networks: "{{ mail_own_networks | unique | select | list }}"
|
||||||
|
###################
|
||||||
|
# #
|
||||||
|
# This at the end #
|
||||||
|
# #
|
||||||
|
###################
|
||||||
|
- name: Configure postfix main.cf
|
||||||
|
template:
|
||||||
|
src: templates/main.cf.j2
|
||||||
|
dest: /etc/postfix/main.cf
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
backup: true
|
||||||
|
notify: Restart postfix
|
||||||
|
|
||||||
|
- name: Configure postfix master.cf
|
||||||
|
template:
|
||||||
|
src: templates/master.cf.j2
|
||||||
|
dest: /etc/postfix/master.cf
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
backup: true
|
||||||
|
notify: Restart postfix
|
||||||
|
|
||||||
|
- name: Ensure postifx service is started and enabled
|
||||||
|
service:
|
||||||
|
name: postfix
|
||||||
|
enabled: true
|
||||||
|
state: started
|
78
tasks/configure_database.yml
Normal file
78
tasks/configure_database.yml
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
---
|
||||||
|
- name: Initialize fact create_database
|
||||||
|
set_fact:
|
||||||
|
create_database: true
|
||||||
|
|
||||||
|
- name: Check for existing database
|
||||||
|
shell: mysql -Bqe 'show databases'
|
||||||
|
register: databases
|
||||||
|
|
||||||
|
- name: Check for existing tables in database
|
||||||
|
shell: "mysql {{ mail_db_name }} -Bqe 'show tables'"
|
||||||
|
register: tables
|
||||||
|
when: "mail_db_name in databases.stdout"
|
||||||
|
|
||||||
|
- name: Update fact create_database
|
||||||
|
set_fact:
|
||||||
|
create_database: false
|
||||||
|
when:
|
||||||
|
- "mail_db_name in databases.stdout"
|
||||||
|
- "'transport' in tables.stdout"
|
||||||
|
|
||||||
|
- name: Copy database dump file
|
||||||
|
copy:
|
||||||
|
src: files/mysql_mail_db.sql
|
||||||
|
dest: /tmp
|
||||||
|
when: create_database
|
||||||
|
|
||||||
|
- name: Create a new database with name 'mail' from structure file
|
||||||
|
mysql_db:
|
||||||
|
name: "{{ mail_db_name }}"
|
||||||
|
state: import
|
||||||
|
target: /tmp/mysql_mail_db.sql
|
||||||
|
login_unix_socket: /var/run/mysqld/mysqld.sock
|
||||||
|
when: create_database
|
||||||
|
|
||||||
|
- name: Create database user with name '{{ mail_db_user}}' with mail database privileges
|
||||||
|
mysql_user:
|
||||||
|
name: "{{ mail_db_user}}"
|
||||||
|
password: "{{ mail_db_password }}"
|
||||||
|
priv: "{{ mail_db_name }}.*:ALL"
|
||||||
|
state: present
|
||||||
|
login_unix_socket: /var/run/mysqld/mysqld.sock
|
||||||
|
|
||||||
|
- name: Insert forwarding in database
|
||||||
|
community.mysql.mysql_query:
|
||||||
|
login_db: "{{ mail_db_name }}"
|
||||||
|
query: "INSERT INTO forwardings (source, destination, porpouse) VALUES ('{{ item['source'] }}', '{{ item['destination'] }}', '{{ item['porpouse'] }}')"
|
||||||
|
single_transaction: yes
|
||||||
|
login_unix_socket: /var/run/mysqld/mysqld.sock
|
||||||
|
ignore_errors: true
|
||||||
|
loop: "{{ mail_forwardings }}"
|
||||||
|
|
||||||
|
- name: Insert domains in database
|
||||||
|
community.mysql.mysql_query:
|
||||||
|
login_db: "{{ mail_db_name }}"
|
||||||
|
query: "INSERT INTO domains (domain) VALUES ('{{ item }}')"
|
||||||
|
single_transaction: yes
|
||||||
|
login_unix_socket: /var/run/mysqld/mysqld.sock
|
||||||
|
ignore_errors: true
|
||||||
|
loop: "{{ mail_domains }}"
|
||||||
|
|
||||||
|
- name: Insert users in database
|
||||||
|
community.mysql.mysql_query:
|
||||||
|
login_db: "{{ mail_db_name }}"
|
||||||
|
query: "INSERT INTO users (email, password, fullname, quota) VALUES ('{{ item['email'] }}', '{{ item['password'] }}', '{{ item['fullname'] }}', '{{ item['quota'] }}')"
|
||||||
|
single_transaction: yes
|
||||||
|
login_unix_socket: /var/run/mysqld/mysqld.sock
|
||||||
|
ignore_errors: true
|
||||||
|
loop: "{{ mail_users }}"
|
||||||
|
|
||||||
|
- name: Insert transports in database
|
||||||
|
community.mysql.mysql_query:
|
||||||
|
login_db: "{{ mail_db_name }}"
|
||||||
|
query: "INSERT INTO transport (domain, transport) VALUES ('{{ item['domain'] }}', '{{ item['transport'] }}')"
|
||||||
|
single_transaction: yes
|
||||||
|
login_unix_socket: /var/run/mysqld/mysqld.sock
|
||||||
|
ignore_errors: true
|
||||||
|
loop: "{{ mail_transports }}"
|
55
tasks/configure_disclaimer.yml
Normal file
55
tasks/configure_disclaimer.yml
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
---
|
||||||
|
- name: Deploy script disclaimer.sh
|
||||||
|
copy:
|
||||||
|
src: files/disclaimer.sh
|
||||||
|
dest: /etc/postfix/scripts/disclaimer.sh
|
||||||
|
owner: postfix
|
||||||
|
group: root
|
||||||
|
mode: '0775'
|
||||||
|
backup: true
|
||||||
|
|
||||||
|
- name: Ensure filter group exists
|
||||||
|
group:
|
||||||
|
name: filter
|
||||||
|
|
||||||
|
- name: Ensure filter user exists
|
||||||
|
user:
|
||||||
|
name: filter
|
||||||
|
group: filter
|
||||||
|
create_home: false
|
||||||
|
home: /var/spool/filter
|
||||||
|
|
||||||
|
- name: Ensure filter home exists with the right permissions
|
||||||
|
file:
|
||||||
|
path: /var/spool/filter
|
||||||
|
state: directory
|
||||||
|
owner: filter
|
||||||
|
group: root
|
||||||
|
mode: 0770
|
||||||
|
|
||||||
|
- name: Ensure filter user can write disclaimer log
|
||||||
|
file:
|
||||||
|
path: /var/log/disclaimer.log
|
||||||
|
owner: filter
|
||||||
|
group: postfix
|
||||||
|
mode: 0660
|
||||||
|
state: touch
|
||||||
|
|
||||||
|
- name: Compress stored incoming messages labeler logs
|
||||||
|
shell: find /var/spool/filter/ -maxdepth 1 -type f -iname in.\*.log -exec bzip2 -z9 {} \;
|
||||||
|
|
||||||
|
- name: Compress stored incoming messages
|
||||||
|
shell: find /var/spool/filter/ -maxdepth 1 -type f -regex '^/var/spool/filter/in\.[0-9]*' -exec bzip2 -z9 {} \;
|
||||||
|
|
||||||
|
- name: Deploy script to compress stored messages
|
||||||
|
copy:
|
||||||
|
src: files/compress_stored_messages.sh
|
||||||
|
dest: /usr/local/bin/compress_stored_messages.sh
|
||||||
|
mode: 0755
|
||||||
|
backup: yes
|
||||||
|
|
||||||
|
- name: Ensure cron to compress stored messages exists
|
||||||
|
cron:
|
||||||
|
name: Compress Stored messages
|
||||||
|
job: /usr/local/bin/compress_stored_messages.sh
|
||||||
|
hour: '2'
|
13
tasks/configure_ufw.yml
Normal file
13
tasks/configure_ufw.yml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
---
|
||||||
|
- name: Allow traffic to Postfix
|
||||||
|
ufw:
|
||||||
|
rule: allow
|
||||||
|
name: Postfix
|
||||||
|
- name: Allow traffic to Postfix SMTPS
|
||||||
|
ufw:
|
||||||
|
rule: allow
|
||||||
|
name: Postfix SMTPS
|
||||||
|
- name: Allow traffic to Postfix Submission
|
||||||
|
ufw:
|
||||||
|
rule: allow
|
||||||
|
name: Postfix Submission
|
70
tasks/deploy_scripts.yml
Normal file
70
tasks/deploy_scripts.yml
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
---
|
||||||
|
- name: Ensure Postfix scripts folder exists
|
||||||
|
file:
|
||||||
|
path: /etc/postfix/scripts
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: postfix
|
||||||
|
mode: '0775'
|
||||||
|
|
||||||
|
- name: Ensure Courier scripts folder exists
|
||||||
|
file:
|
||||||
|
path: /etc/courier/scripts
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0750'
|
||||||
|
|
||||||
|
- name: Template file letsencrypt_update.sh
|
||||||
|
template:
|
||||||
|
src: templates/letsencrypt_update.sh.j2
|
||||||
|
dest: /etc/courier/scripts/letsencrypt_update.sh
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0750'
|
||||||
|
backup: true
|
||||||
|
|
||||||
|
# - name: Deploy script authdaemond_check_stuck.sh
|
||||||
|
# copy:
|
||||||
|
# src: files/authdaemond_check_stuck.sh
|
||||||
|
# dest: /etc/postfix/scripts/authdaemond_check_stuck.sh
|
||||||
|
# owner: root
|
||||||
|
# group: root
|
||||||
|
# mode: '0750'
|
||||||
|
# backup: true
|
||||||
|
|
||||||
|
- name: Deploy script update_clients.sh
|
||||||
|
copy:
|
||||||
|
src: files/update_clients.sh
|
||||||
|
dest: /etc/postfix/scripts/update_clients.sh
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0750'
|
||||||
|
backup: true
|
||||||
|
|
||||||
|
- name: Deploy script remove_queues_messages.sh
|
||||||
|
copy:
|
||||||
|
src: files/remove_queued_messages.sh
|
||||||
|
dest: /etc/postfix/scripts/remove_queued_messages.sh
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0750'
|
||||||
|
backup: true
|
||||||
|
|
||||||
|
- name: Deploy new_mail_alias script
|
||||||
|
copy:
|
||||||
|
src: files/new_mail_alias
|
||||||
|
dest: /usr/local/bin/new_mail_alias
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0755
|
||||||
|
backup: true
|
||||||
|
|
||||||
|
- name: Deploy new_mail_user.sh script
|
||||||
|
copy:
|
||||||
|
src: files/new_mail_user.sh
|
||||||
|
dest: /usr/local/bin/new_mail_user.sh
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0755
|
||||||
|
backup: true
|
22
tasks/install.yml
Normal file
22
tasks/install.yml
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
---
|
||||||
|
- name: Ensure mail server software is present
|
||||||
|
apt:
|
||||||
|
name:
|
||||||
|
- postfix-mysql
|
||||||
|
- postfix-doc
|
||||||
|
- certbot
|
||||||
|
- libsasl2-2
|
||||||
|
- libsasl2-modules
|
||||||
|
- libsasl2-modules-sql
|
||||||
|
- sasl2-bin
|
||||||
|
- libpam-mysql
|
||||||
|
- openssl
|
||||||
|
- postfix-policyd-spf-python
|
||||||
|
- altermime
|
||||||
|
- gamin
|
||||||
|
- amavisd-new
|
||||||
|
- spamassassin
|
||||||
|
- opendkim
|
||||||
|
- opendkim-tools
|
||||||
|
state: latest
|
||||||
|
update_cache: true
|
27
tasks/main.yml
Normal file
27
tasks/main.yml
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
---
|
||||||
|
- name: Ensure installation of Postfix
|
||||||
|
include_tasks: install.yml
|
||||||
|
when: postfix_only_populate_db == False
|
||||||
|
|
||||||
|
- name: Ensure scripts are deployed
|
||||||
|
include_tasks: deploy_scripts.yml
|
||||||
|
when: postfix_only_populate_db == False
|
||||||
|
|
||||||
|
- name: Ensure configuration of Postfix
|
||||||
|
include_tasks: configure.yml
|
||||||
|
when: postfix_only_populate_db == False
|
||||||
|
|
||||||
|
- name: Ensure configuration of UFW
|
||||||
|
include_tasks: configure_ufw.yml
|
||||||
|
when:
|
||||||
|
- configure_ufw
|
||||||
|
- postfix_only_populate_db == False
|
||||||
|
|
||||||
|
- name: Ensure configuration of Postfix disclaimer
|
||||||
|
include_tasks: configure_disclaimer.yml
|
||||||
|
when:
|
||||||
|
- postfix_only_populate_db == False
|
||||||
|
|
||||||
|
- name: Ensure configuration of Postfix database
|
||||||
|
include_tasks: configure_database.yml
|
||||||
|
when: inventory_hostname == ansible_play_hosts[0]
|
17
templates/authmysqlrc.j2
Normal file
17
templates/authmysqlrc.j2
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
MYSQL_SERVER localhost
|
||||||
|
MYSQL_USERNAME {{ mail_db_user}}
|
||||||
|
MYSQL_PASSWORD {{ mail_db_password }}
|
||||||
|
MYSQL_PORT 0
|
||||||
|
MYSQL_DATABASE {{ mail_db_name }}
|
||||||
|
MYSQL_USER_TABLE users
|
||||||
|
MYSQL_CRYPT_PWFIELD password
|
||||||
|
#MYSQL_CLEAR_PWFIELD password
|
||||||
|
MYSQL_UID_FIELD 5000
|
||||||
|
MYSQL_GID_FIELD 5000
|
||||||
|
MYSQL_LOGIN_FIELD email
|
||||||
|
MYSQL_HOME_FIELD "/home/vmail"
|
||||||
|
MYSQL_MAILDIR_FIELD CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',SUBSTRING_INDEX(email,'@',1),'/')
|
||||||
|
#MYSQL_NAME_FIELD
|
||||||
|
MYSQL_QUOTA_FIELD quota
|
||||||
|
MYSQL_OPT 0
|
||||||
|
##NAME: MARKER:0 # # Do not remove this section from this configuration file. This section # must be present at the end of this file.
|
269
templates/disclaimer.sh.j2
Normal file
269
templates/disclaimer.sh.j2
Normal file
|
@ -0,0 +1,269 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Clean up when done or when aborting.
|
||||||
|
trap "rm -f in.$$" 0 1 2 3 15
|
||||||
|
|
||||||
|
INSPECT_DIR=/var/spool/filter
|
||||||
|
SENDMAIL=/usr/sbin/sendmail
|
||||||
|
LOGFILE=/var/log/disclaimer.log
|
||||||
|
OUTSTATFOLDER=/var/spool/filter/out.stats
|
||||||
|
mkdir -p $OUTSTATFOLDER
|
||||||
|
INSTATFOLDER=/var/spool/filter/in.stats
|
||||||
|
mkdir -p $INSTATFOLDER
|
||||||
|
|
||||||
|
DISCLAIMER_ADDRESSES=/etc/postfix/disclaimer_addressess
|
||||||
|
|
||||||
|
TEXT_DISCLAIMER=/etc/postfix/text_disclaimer.txt
|
||||||
|
HTML_DISCLAIMER_FILE=/etc/postfix/html_disclaimer.htm
|
||||||
|
|
||||||
|
# Exit codes from <sysexits.h>
|
||||||
|
EX_TEMPFAIL=75
|
||||||
|
EX_UNAVAILABLE=69
|
||||||
|
|
||||||
|
DATE=$(date +%s)
|
||||||
|
APP=$(basename $0 .sh)
|
||||||
|
|
||||||
|
function Message() {
|
||||||
|
HIDE=$2
|
||||||
|
CDATE=$(date +%s)
|
||||||
|
MSG="[$$] $CDATE $1"
|
||||||
|
if [[ "$HIDE" != "true" ]]; then
|
||||||
|
echo "$MSG"
|
||||||
|
fi
|
||||||
|
/usr/bin/env logger -t "$APP" "$MSG"
|
||||||
|
echo "$MSG" >> $LOGFILE
|
||||||
|
#logger -t disclaimer.sh "$MSG"
|
||||||
|
}
|
||||||
|
#GetRecordID $FROM mail_addresses mail_address mail
|
||||||
|
function GetRecordID() {
|
||||||
|
TEXT="$1"
|
||||||
|
if [[ "$TEXT" == "" ]]; then
|
||||||
|
echo NULL
|
||||||
|
else
|
||||||
|
TABLE="$2"
|
||||||
|
FIELD="$3"
|
||||||
|
DATABASE="$4"
|
||||||
|
if [[ "$DATABASE" == "" ]]; then
|
||||||
|
Message "No database indicated." true
|
||||||
|
else
|
||||||
|
ACTION="$5"
|
||||||
|
QUERY="SELECT id FROM $TABLE WHERE $FIELD='$TEXT';"
|
||||||
|
RESULT=$(echo "$QUERY" | /usr/bin/env mysql --defaults-file=/var/spool/filter/.my.cnf $DATABASE)
|
||||||
|
RESULTID=$(echo "$RESULT" | grep -v id)
|
||||||
|
error_code=$?
|
||||||
|
if [[ "$error_code" != "0" ]]; then
|
||||||
|
Message "Error getting $FIELD id for $TEXT from database with query '$QUERY'. Result: $RESULT" true
|
||||||
|
else
|
||||||
|
if [[ "$RESULTID" == "" ]]; then
|
||||||
|
QUERY="INSERT INTO $TABLE (id, $FIELD) VALUES (NULL, '$TEXT');"
|
||||||
|
RESULT=$(echo "$QUERY" | /usr/bin/env mysql --defaults-file=/var/spool/filter/.my.cnf $DATABASE)
|
||||||
|
error_code=$?
|
||||||
|
if [[ "$error_code" != "0" ]]; then
|
||||||
|
Message "Error $error_code adding $FIELD to database with query '$QUERY'. Result: $RESULT" true
|
||||||
|
else
|
||||||
|
QUERY="SELECT id FROM $TABLE WHERE $FIELD='$FROM';"
|
||||||
|
RESULT=$(echo "$QUERY" | /usr/bin/env mysql --defaults-file=/var/spool/filter/.my.cnf $DATABASE)
|
||||||
|
RESULTID=$(echo "$RESULT" | grep -v id)
|
||||||
|
error_code=$?
|
||||||
|
if [[ "$error_code" != "0" ]]; then
|
||||||
|
Message "Error $error_code obtaining $FIELD id with query '$QUERY'. Result: $RESULT" true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo $RESULTID
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
function FromID() {
|
||||||
|
FROM=$1
|
||||||
|
SENDER_ID=$(GetRecordID $FROM senders sender mailview "Getting Id for From $1")
|
||||||
|
echo $SENDER_ID
|
||||||
|
}
|
||||||
|
function RecipientID() {
|
||||||
|
RECIPIENT=$1
|
||||||
|
RECIPIENT_ID=$(GetRecordID $FROM recipients recipient mailview "Getting Id for To $1")
|
||||||
|
echo $RECIPIENT_ID
|
||||||
|
}
|
||||||
|
# Start processing.
|
||||||
|
|
||||||
|
Message "Processing message 'in.$$'"
|
||||||
|
|
||||||
|
cd $INSPECT_DIR
|
||||||
|
error_code=$?
|
||||||
|
if [[ "$error_code" != "0" ]]; then
|
||||||
|
Message "Error $error_code changing to directory '$INSPECT_DIR'"
|
||||||
|
exit $EX_TEMPFAIL;
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat >in.$$
|
||||||
|
error_code=$?
|
||||||
|
if [[ "$error_code" != "0" ]]; then
|
||||||
|
Message "Cannot save mail to file"
|
||||||
|
exit $EX_TEMPFAIL
|
||||||
|
fi
|
||||||
|
#Save last message
|
||||||
|
cp in.$$ /var/spool/filter/last_message.eml -rfp
|
||||||
|
#Save copy of the messages. DANGEROUS!! Will consumpt disk space
|
||||||
|
mkdir -p /var/spool/filter/)date +%Y%m%d)/
|
||||||
|
cp in.$$ /var/spool/filter/)date +%Y%m%d)/)date +%Y%m%d%H%M%S%N).eml -rfp
|
||||||
|
# obtain header
|
||||||
|
FROMLONG=$(grep -m 1 "From:" in.$$ | sed "s/From://" -)
|
||||||
|
FROM=$(echo $FROMLONG | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
SENDER_ID=$(FromID $FROM)
|
||||||
|
Message "From: $FROMLONG (Id: $SENDER_ID)"
|
||||||
|
MESSAGEID=$(grep -m 1 -i "^Message-id:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
Message "Message ID: $MESSAGEID"
|
||||||
|
SUBJECT=$(grep -m 1 "Subject:" in.$$ | sed "s/Subject://" - | sed "s/'/\'/g" - )
|
||||||
|
Message "Subject: $SUBJECT"
|
||||||
|
RECIPIENT=$(grep -m 1 "^To:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
RECIPIENT_ID=$(RecipientID $RECIPIENT)
|
||||||
|
Message "TO: $RECIPIENT"
|
||||||
|
CCRECIPIENT=$(grep -m 1 "Cc:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
Message "CC: $CCRECIPIENT"
|
||||||
|
BCRECIPIENT=$(grep -m 1 "Bcc:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
Message "CCO: $BCRECIPIENT"
|
||||||
|
DELIVEREDTO=$(grep -m 1 "Delivered-To:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
Message "Delivered to: $DELIVEREDTO"
|
||||||
|
RETURNPATH=$(grep -m 1 "Return-Path:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
Message "Return path: $RETURNPATH"
|
||||||
|
REPLYTO=$(grep -m 1 "Reply-To:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
Message "Reply to: $REPLYTO"
|
||||||
|
XORIGINALSENDER=$(grep -m 1 "X-Original-Sender:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
Message "Reply to: $XORIGINALSENDER"
|
||||||
|
SENDER=$(grep -m 1 "Sender:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
Message "Reply to: $SENDER"
|
||||||
|
XFORWARDEDTO=$(grep -m 1 "X-Forwarded-To:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
Message "Reply to: $XFORWARDEDTO"
|
||||||
|
XFORWARDEDFOR=$(grep -m 1 "X-Forwarded-For:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
Message "Reply to: $XFORWARDEDFOR"
|
||||||
|
XBEENTHERE=$(grep -m 1 "X-BeenThere:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1 | sed "s/'/\'/g" - )
|
||||||
|
Message "Reply to: $XBEENTHERE"
|
||||||
|
|
||||||
|
if [[ $(grep -wi ^${FROM}$ ${DISCLAIMER_ADDRESSES}) ]]; then
|
||||||
|
DIRECTION=0
|
||||||
|
CURHOUR=$(date +%Y%m%d%H)
|
||||||
|
if [[ -e $INSTATFOLDER/$CURHOUR.stats ]]; then
|
||||||
|
CURHOURSTAT=$(cat $INSTATFOLDER/$CURHOUR.stats)
|
||||||
|
else
|
||||||
|
CURHOURSTAT=0
|
||||||
|
fi
|
||||||
|
CURHOURSTAT=$(expr $CURHOURSTAT + 1)
|
||||||
|
echo $CURHOURSTAT > $INSTATFOLDER/$CURHOUR.stats
|
||||||
|
Message "Sender '$FROMLONG' ($FROM) is in disclaimer addresses file"
|
||||||
|
QUERY="INSERT INTO messages (id, sender_id, subject, date, messageid) VALUES (NULL, '$SENDER_ID', '$SUBJECT', '$DATE', '$MESSAGEID');"
|
||||||
|
echo "$QUERY" | /usr/bin/env mysql --defaults-file=/var/spool/filter/.my.cnf mailview
|
||||||
|
error_code=$?
|
||||||
|
if [[ "$error_code" != "0" ]]; then
|
||||||
|
Message "Error $error_code while adding message to database with query '$QUERY'"
|
||||||
|
fi
|
||||||
|
QUERY="SELECT id FROM messages WHERE sender_id='$SENDER_ID' AND subject='$SUBJECT' AND date='$DATE';"
|
||||||
|
MSG_ID=$(echo "$QUERY" | /usr/bin/env mysql --defaults-file=/var/spool/filter/.my.cnf mailview | grep -v id)
|
||||||
|
error_code=$?
|
||||||
|
if [[ "$error_code" != "0" ]]; then
|
||||||
|
Message "Error $error_code while obtaining message id with query '$QUERY'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
TMP_HTML_DISCLAIMER_FILE=$(/bin/mktemp /tmp/disclaimer.XXXXX)
|
||||||
|
if [[ -r /etc/postfix/$FROM.disclaimer.html ]]; then
|
||||||
|
HTML_DISCLAIMER=/etc/postfix/$FROM.disclaimer.html
|
||||||
|
fi
|
||||||
|
sed "s/id=MSGID/id=$DB_MSG_ID/g" $HTML_DISCLAIMER_FILE > $TMP_HTML_DISCLAIMER_FILE
|
||||||
|
TMP_HTML_DISCLAIMER_FILE_BIS=$(/bin/mktemp /tmp/disclaimer.XXXXX)
|
||||||
|
sed "s/SENDERID/$SENDER_ID/g" $TMP_HTML_DISCLAIMER_FILE > $TMP_HTML_DISCLAIMER_FILE_BIS
|
||||||
|
sed "s/RECIPIENTID/$RECIPIENT_ID/g" $TMP_HTML_DISCLAIMER_FILE_BIS > $TMP_HTML_DISCLAIMER_FILE
|
||||||
|
Message "Disclaimer HTML at '$TMP_HTML_DISCLAIMER_FILE'"
|
||||||
|
if [[ -r /etc/postfix/$FROM.disclaimer.txt ]]; then
|
||||||
|
TEXT_DISCLAIMER=/etc/postfix/$FROM.disclaimer.txt
|
||||||
|
fi
|
||||||
|
|
||||||
|
ALTERMIMERESULT=$(/usr/bin/altermime --input=in.$$
|
||||||
|
--log-syslog
|
||||||
|
--log-stdout
|
||||||
|
--disclaimer=$TEXT_DISCLAIMER
|
||||||
|
--disclaimer-html=$TMP_HTML_DISCLAIMER_FILE
|
||||||
|
--xheader="X-MTA: mudito.susurrando.com")
|
||||||
|
Message "altermime result: $ALTERMIMERESULT"
|
||||||
|
error_code=$?
|
||||||
|
if [[ "$error_code" != "0" ]]; then
|
||||||
|
Message "Error $error_code Message content rejected."
|
||||||
|
exit $EX_UNAVAILABLE;
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
DIRECTION=1
|
||||||
|
Message "Sender '$FROMLONG' ($FROM) is NOT in disclaimer addresses file"
|
||||||
|
CURHOUR=$(date +%Y%m%d%H)
|
||||||
|
if [[ -e $OUTSTATFOLDER/$CURHOUR.stats ]]; then
|
||||||
|
CURHOURSTAT=$(cat $OUTSTATFOLDER/$CURHOUR.stats)
|
||||||
|
else
|
||||||
|
CURHOURSTAT=0
|
||||||
|
fi
|
||||||
|
CURHOURSTAT=$(expr $CURHOURSTAT + 1)
|
||||||
|
echo $CURHOURSTAT > $OUTSTATFOLDER/$CURHOUR.stats
|
||||||
|
fi
|
||||||
|
|
||||||
|
#Stats
|
||||||
|
FROMID=$(GetRecordID $FROM mail_addresses mail_address mail "Get ID of From $FROM")
|
||||||
|
Message "From $FROM with ID $FROMID"
|
||||||
|
if [[ "$RECIPIENT" != "" ]]; then
|
||||||
|
TOID=$(GetRecordID $RECIPIENT mail_addresses mail_address mail "Get ID of To $TO")
|
||||||
|
else
|
||||||
|
TOID="0"
|
||||||
|
fi
|
||||||
|
Message "To $RECIPIENT with ID $TOID"
|
||||||
|
if [[ "$CCRECIPIENT" != "" ]]; then
|
||||||
|
CCID=$(GetRecordID $CCRECIPIENT mail_addresses mail_address mail "Get ID of CC")
|
||||||
|
else
|
||||||
|
CCID="0"
|
||||||
|
fi
|
||||||
|
if [[ "$BCRECIPIENT" != "" ]]; then
|
||||||
|
CCOID=$(GetRecordID $BCRECIPIENT mail_addresses mail_address mail "Get ID of BCC")
|
||||||
|
else
|
||||||
|
CCOID="0"
|
||||||
|
fi
|
||||||
|
if [[ "$DELIVEREDTO" != "" ]]; then
|
||||||
|
DTID=$(GetRecordID $DELIVEREDTO mail_addresses mail_address mail "Get ID of DeliveredTo")
|
||||||
|
else
|
||||||
|
DTID="0"
|
||||||
|
fi
|
||||||
|
if [[ "$RETURNPATH" != "" ]]; then
|
||||||
|
RPID=$(GetRecordID $RETURNPATH mail_addresses mail_address mail)
|
||||||
|
else
|
||||||
|
RPID="0"
|
||||||
|
fi
|
||||||
|
if [[ "$XORIGINALSENDER" != "" ]]; then
|
||||||
|
XOSID=$(GetRecordID $XORIGINALSENDER mail_addresses mail_address mail)
|
||||||
|
else
|
||||||
|
XOSID="0"
|
||||||
|
fi
|
||||||
|
if [[ "$SENDER" != "" ]]; then
|
||||||
|
SID=$(GetRecordID $SENDER mail_addresses mail_address mail)
|
||||||
|
else
|
||||||
|
SID="0"
|
||||||
|
fi
|
||||||
|
if [[ "$XFORWARDEDTO" != "" ]]; then
|
||||||
|
XFTID=$(GetRecordID $XFORWARDEDTO mail_addresses mail_address mail)
|
||||||
|
else
|
||||||
|
XFTID="0"
|
||||||
|
fi
|
||||||
|
if [[ "$XFORWARDEDFOR" != "" ]]; then
|
||||||
|
XFFID=$(GetRecordID $XFORWARDEDFOR mail_addresses mail_address mail)
|
||||||
|
else
|
||||||
|
XFFID="0"
|
||||||
|
fi
|
||||||
|
|
||||||
|
QUERY="INSERT INTO stats (msgid, from_id, to_id,cc_id, cco_id, subject, direction, delivered_to_id, return_path_id, s_original_sender_id, sender_id, x_forwarded_to, x_forwarded_for) VALUES ('$MESSAGEID',$FROMID, $TOID, $CCID, $CCOID, '$SUBJECT', $DIRECTION, $DTID, $RPID, $XOSID, $SID, $XFTID, $XFFID);"
|
||||||
|
RESULT=$(echo "$QUERY" | /usr/bin/env mysql --defaults-file=/var/spool/filter/.my.cnf mail)
|
||||||
|
error_code=$?
|
||||||
|
if [[ "$error_code" != "0" ]]; then
|
||||||
|
Message "Error $error_code saving stats with query '$QUERY'. Result: $RESULT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
Message "Arguments: $*"
|
||||||
|
$SENDMAIL "$@" <in.$$
|
||||||
|
error_code=$?
|
||||||
|
if [[ "$error_code" != "0" ]]; then
|
||||||
|
Message "Error $error_code sending file to sendmail"
|
||||||
|
exit $error_code
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
11
templates/letsencrypt_update.sh.j2
Normal file
11
templates/letsencrypt_update.sh.j2
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#/bin/bash
|
||||||
|
FQDN='{{ mail_server_fqdn }}'
|
||||||
|
cat "/etc/letsencrypt/live/${FQDN}/privkey.pem" "/etc/letsencrypt/live/${FQDN}/fullchain.pem" > /etc/courier/${FQDN}.imapd.pem
|
||||||
|
chmod 600 "/etc/courier/${FQDN}.imapd.pem"
|
||||||
|
chown courier.courier "/etc/courier/${FQDN}.imapd.pem"
|
||||||
|
cp "/etc/letsencrypt/live/${FQDN}/privkey.pem" /etc/postfix/smtpd.key -rfpL
|
||||||
|
chmod 0600 /etc/postfix/smtpd.key
|
||||||
|
chown root.courier /etc/postfix/smtpd.key
|
||||||
|
cp "/etc/letsencrypt/live/${FQDN}/fullchain.pem" /etc/postfix/smtpd.crt -rfpL
|
||||||
|
chmod 0600 /etc/postfix/smtpd.crt
|
||||||
|
chown root.courier /etc/postfix/smtpd.crt
|
11
templates/main.cf.j2
Normal file
11
templates/main.cf.j2
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{% for key, value in postfix_config.items() %}
|
||||||
|
{% if value == True %}
|
||||||
|
{{ key }} = yes
|
||||||
|
{% else %}
|
||||||
|
{% if value == False %}
|
||||||
|
{{ key }} = no
|
||||||
|
{% else %}
|
||||||
|
{{ key }} = {{ value }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
142
templates/master.cf.j2
Normal file
142
templates/master.cf.j2
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
#
|
||||||
|
# Postfix master process configuration file.
|
||||||
|
# ATTENTION! Managed by Ansible
|
||||||
|
# For details on the format
|
||||||
|
# of the file, see the master(5) manual page (command: "man 5 master").
|
||||||
|
#
|
||||||
|
# Do not forget to execute "postfix reload" after editing this file.
|
||||||
|
#
|
||||||
|
# ==========================================================================
|
||||||
|
# service type private unpriv chroot wakeup maxproc command + args
|
||||||
|
# (yes) (yes) (no) (never) (100)
|
||||||
|
# ==========================================================================
|
||||||
|
# SMTP: Port 25
|
||||||
|
smtp inet n - y - - smtpd
|
||||||
|
# -o content_filter=filter:
|
||||||
|
# Submission: Port 587
|
||||||
|
submission inet n - y - - smtpd
|
||||||
|
-o smtpd_tls_security_level=encrypt
|
||||||
|
-o smtpd_sasl_auth_enable=yes
|
||||||
|
-o smtpd_client_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
|
||||||
|
-o milter_macro_daemon_name=ORIGINATING
|
||||||
|
-o content_filter=filter:
|
||||||
|
# SMTPS: Port 465
|
||||||
|
smtps inet n - y - - smtpd
|
||||||
|
-o smtpd_tls_wrappermode=yes
|
||||||
|
-o smtpd_sasl_auth_enable=yes
|
||||||
|
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
|
||||||
|
-o milter_macro_daemon_name=ORIGINATING
|
||||||
|
-o content_filter=filter:
|
||||||
|
#628 inet n - y - - qmqpd
|
||||||
|
pickup unix n - y 60 1 pickup
|
||||||
|
cleanup unix n - y - 0 cleanup
|
||||||
|
qmgr unix n - n 300 1 qmgr
|
||||||
|
#qmgr unix n - n 300 1 oqmgr
|
||||||
|
tlsmgr unix - - y 1000? 1 tlsmgr
|
||||||
|
rewrite unix - - y - - trivial-rewrite
|
||||||
|
bounce unix - - y - 0 bounce
|
||||||
|
defer unix - - y - 0 bounce
|
||||||
|
trace unix - - y - 0 bounce
|
||||||
|
verify unix - - y - 1 verify
|
||||||
|
flush unix n - y 1000? 0 flush
|
||||||
|
proxymap unix - - n - - proxymap
|
||||||
|
proxywrite unix - - n - 1 proxymap
|
||||||
|
smtp unix - - y - - smtp
|
||||||
|
# When relaying mail as backup MX, disable fallback_relay to avoid MX loops
|
||||||
|
relay unix - - y - - smtp
|
||||||
|
-o smtp_fallback_relay=
|
||||||
|
# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
|
||||||
|
showq unix n - y - - showq
|
||||||
|
error unix - - y - - error
|
||||||
|
retry unix - - y - - error
|
||||||
|
discard unix - - y - - discard
|
||||||
|
local unix - n n - - local
|
||||||
|
virtual unix - n n - - virtual
|
||||||
|
lmtp unix - - y - - lmtp
|
||||||
|
anvil unix - - y - 1 anvil
|
||||||
|
scache unix - - y - 1 scache
|
||||||
|
#
|
||||||
|
# ====================================================================
|
||||||
|
# Interfaces to non-Postfix software. Be sure to examine the manual
|
||||||
|
# pages of the non-Postfix software to find out what options it wants.
|
||||||
|
#
|
||||||
|
# Many of the following services use the Postfix pipe(8) delivery
|
||||||
|
# agent. See the pipe(8) man page for information about ${recipient}
|
||||||
|
# and other message envelope options.
|
||||||
|
# ====================================================================
|
||||||
|
#
|
||||||
|
# maildrop. See the Postfix MAILDROP_README file for details.
|
||||||
|
# Also specify in main.cf: maildrop_destination_recipient_limit=1
|
||||||
|
#
|
||||||
|
maildrop unix - n n - - pipe
|
||||||
|
flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient}
|
||||||
|
#
|
||||||
|
# ====================================================================
|
||||||
|
#
|
||||||
|
# Recent Cyrus versions can use the existing "lmtp" master.cf entry.
|
||||||
|
#
|
||||||
|
# Specify in cyrus.conf:
|
||||||
|
# lmtp cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4
|
||||||
|
#
|
||||||
|
# Specify in main.cf one or more of the following:
|
||||||
|
# mailbox_transport = lmtp:inet:localhost
|
||||||
|
# virtual_transport = lmtp:inet:localhost
|
||||||
|
#
|
||||||
|
# ====================================================================
|
||||||
|
#
|
||||||
|
# Cyrus 2.1.5 (Amos Gouaux)
|
||||||
|
# Also specify in main.cf: cyrus_destination_recipient_limit=1
|
||||||
|
#
|
||||||
|
#cyrus unix - n n - - pipe
|
||||||
|
# user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user}
|
||||||
|
#
|
||||||
|
# ====================================================================
|
||||||
|
# Old example of delivery via Cyrus.
|
||||||
|
#
|
||||||
|
#old-cyrus unix - n n - - pipe
|
||||||
|
# flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user}
|
||||||
|
#
|
||||||
|
# ====================================================================
|
||||||
|
#
|
||||||
|
# See the Postfix UUCP_README file for configuration details.
|
||||||
|
#
|
||||||
|
uucp unix - n n - - pipe
|
||||||
|
flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
|
||||||
|
#
|
||||||
|
# Other external delivery methods.
|
||||||
|
#
|
||||||
|
ifmail unix - n n - - pipe
|
||||||
|
flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
|
||||||
|
bsmtp unix - n n - - pipe
|
||||||
|
flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient
|
||||||
|
scalemail-backend unix - n n - 2 pipe
|
||||||
|
flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension}
|
||||||
|
mailman unix - n n - - pipe
|
||||||
|
flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py
|
||||||
|
${nexthop} ${user}
|
||||||
|
|
||||||
|
amavis unix y y y - 2 smtp
|
||||||
|
-o smtp_data_done_timeout=1200
|
||||||
|
-o smtp_send_xforward_command=yes
|
||||||
|
|
||||||
|
127.0.0.1:10025 inet n y y - - smtpd
|
||||||
|
-o content_filter=
|
||||||
|
-o local_recipient_maps=
|
||||||
|
-o relay_recipient_maps=
|
||||||
|
-o smtpd_restriction_classes=
|
||||||
|
-o smtpd_client_restrictions=
|
||||||
|
-o smtpd_helo_restrictions=
|
||||||
|
-o smtpd_sender_restrictions=
|
||||||
|
-o smtpd_recipient_restrictions=permit_mynetworks,reject
|
||||||
|
-o mynetworks=127.0.0.0/8
|
||||||
|
-o strict_rfc821_envelopes=yes
|
||||||
|
-o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
|
||||||
|
filter unix - n n - - pipe
|
||||||
|
flags=Rq user=filter argv=/etc/postfix/scripts/disclaimer.sh -f ${sender} -- ${recipient}
|
||||||
|
policy-spf unix - n n - - spawn
|
||||||
|
user=nobody argv=/usr/bin/policyd-spf
|
||||||
|
greypolicy unix - n n - - spawn
|
||||||
|
user=nobody argv=/usr/bin/perl
|
||||||
|
/usr/local/libexec/postfix/greylist.pl
|
||||||
|
|
||||||
|
{{ postfix_master_extra }}
|
5
templates/mysql-body_checks.cf.j2
Normal file
5
templates/mysql-body_checks.cf.j2
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
user = {{ mail_db_user}}
|
||||||
|
password = {{ mail_db_password }}
|
||||||
|
dbname = {{ mail_db_name }}
|
||||||
|
query = SELECT action FROM bannedcontent WHERE regexp='%s'
|
||||||
|
hosts = 127.0.0.1
|
5
templates/mysql-virtual_domains.cf.j2
Normal file
5
templates/mysql-virtual_domains.cf.j2
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
user = {{ mail_db_user}}
|
||||||
|
password = {{ mail_db_password }}
|
||||||
|
dbname = {{ mail_db_name }}
|
||||||
|
query = SELECT domain AS virtuald FROM domains WHERE domain='%s'
|
||||||
|
hosts = 127.0.0.1
|
5
templates/mysql-virtual_email2email.cf.j2
Normal file
5
templates/mysql-virtual_email2email.cf.j2
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
user = {{ mail_db_user}}
|
||||||
|
password = {{ mail_db_password }}
|
||||||
|
dbname = {{ mail_db_name }}
|
||||||
|
query = SELECT email FROM users WHERE email='%s'
|
||||||
|
hosts = 127.0.0.1
|
5
templates/mysql-virtual_forwardings.cf.j2
Normal file
5
templates/mysql-virtual_forwardings.cf.j2
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
user = {{ mail_db_user}}
|
||||||
|
password = {{ mail_db_password }}
|
||||||
|
dbname = {{ mail_db_name }}
|
||||||
|
query = SELECT destination FROM forwardings WHERE source='%s'
|
||||||
|
hosts = 127.0.0.1
|
5
templates/mysql-virtual_mailbox_limit_maps.cf.j2
Normal file
5
templates/mysql-virtual_mailbox_limit_maps.cf.j2
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
user = {{ mail_db_user}}
|
||||||
|
password = {{ mail_db_password }}
|
||||||
|
dbname = {{ mail_db_name }}
|
||||||
|
query = SELECT quota FROM users WHERE email='%s'
|
||||||
|
hosts = 127.0.0.1
|
5
templates/mysql-virtual_mailboxes.cf.j2
Normal file
5
templates/mysql-virtual_mailboxes.cf.j2
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
user = {{ mail_db_user}}
|
||||||
|
password = {{ mail_db_password }}
|
||||||
|
dbname = {{ mail_db_name }}
|
||||||
|
query = SELECT CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',SUBSTRING_INDEX(email,'@',1),'/') FROM users WHERE email='%s'
|
||||||
|
hosts = 127.0.0.1
|
5
templates/mysql-virtual_transports.cf.j2
Normal file
5
templates/mysql-virtual_transports.cf.j2
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
user = {{ mail_db_user}}
|
||||||
|
password = {{ mail_db_password }}
|
||||||
|
dbname = {{ mail_db_name }}
|
||||||
|
query = SELECT transport FROM transport WHERE domain='%s'
|
||||||
|
hosts = 127.0.0.1
|
2
templates/smtp.j2
Normal file
2
templates/smtp.j2
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
auth required pam_mysql.so user={{ mail_db_user}} passwd={{ mail_db_password }} host=127.0.0.1 db={{ mail_db_name }} table=users usercolumn=email passwdcolumn=password crypt=1
|
||||||
|
account sufficient pam_mysql.so user={{ mail_db_user}} passwd={{ mail_db_password }} host=127.0.0.1 db={{ mail_db_name }} table=users usercolumn=email passwdcolumn=password crypt=1
|
11
templates/smtpd.conf.j2
Normal file
11
templates/smtpd.conf.j2
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
pwcheck_method: saslauthd
|
||||||
|
mech_list: plain login
|
||||||
|
allow_plaintext: true
|
||||||
|
auxprop_plugin: sql
|
||||||
|
sql_engine: mysql
|
||||||
|
sql_hostnames: 127.0.0.1
|
||||||
|
sql_user: {{ mail_db_user}}
|
||||||
|
sql_passwd: {{ mail_db_password }}
|
||||||
|
sql_database: {{ mail_db_name }}
|
||||||
|
sql_select: select password from users where email = '%u@%r'
|
||||||
|
log_level: 9
|
Loading…
Reference in a new issue