2019-08-07 00:24:56 +00:00
|
|
|
#!/bin/bash
|
|
|
|
|
|
|
|
# expects mask prefix length and the digit
|
|
|
|
function _mask_ip_digit() {
|
2020-06-30 20:43:22 +00:00
|
|
|
if [[ $1 -ge 8 ]]; then
|
|
|
|
MASK=255
|
|
|
|
else
|
|
|
|
if [[ $1 -le 0 ]]; then
|
|
|
|
MASK=0
|
|
|
|
else
|
|
|
|
VALUES=('0' '128' '192' '224' '240' '248' '252' '254' '255')
|
|
|
|
MASK=${VALUES[$1]}
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
echo $(($2 & $MASK))
|
2019-08-07 00:24:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
# transforms a specific ip with CIDR suffix like 1.2.3.4/16
|
|
|
|
# to subnet with cidr suffix like 1.2.0.0/16
|
|
|
|
function _sanitize_ipv4_to_subnet_cidr() {
|
2020-06-30 20:43:22 +00:00
|
|
|
IP=${1%%/*}
|
|
|
|
PREFIX_LENGTH=${1#*/}
|
2019-08-07 00:24:56 +00:00
|
|
|
|
2020-06-30 20:43:22 +00:00
|
|
|
# split IP by . into digits
|
|
|
|
DIGITS=(${IP//./ })
|
2019-08-07 00:24:56 +00:00
|
|
|
|
2020-06-30 20:43:22 +00:00
|
|
|
# mask digits according to prefix length
|
|
|
|
MASKED_DIGITS=()
|
|
|
|
DIGIT_PREFIX_LENGTH="$PREFIX_LENGTH"
|
|
|
|
for DIGIT in "${DIGITS[@]}"; do
|
|
|
|
MASKED_DIGITS+=($(_mask_ip_digit $DIGIT_PREFIX_LENGTH $DIGIT))
|
|
|
|
DIGIT_PREFIX_LENGTH=$(($DIGIT_PREFIX_LENGTH - 8))
|
|
|
|
done
|
2019-08-07 00:24:56 +00:00
|
|
|
|
2020-06-30 20:43:22 +00:00
|
|
|
# output masked ip plus prefix length
|
|
|
|
echo ${MASKED_DIGITS[0]}.${MASKED_DIGITS[1]}.${MASKED_DIGITS[2]}.${MASKED_DIGITS[3]}/$PREFIX_LENGTH
|
|
|
|
}
|
|
|
|
|
|
|
|
# extracts certificates from acme.json and returns 0 if found
|
|
|
|
function extractCertsFromAcmeJson() {
|
|
|
|
WHAT=$1
|
2020-07-19 21:57:16 +00:00
|
|
|
|
|
|
|
KEY=$(cat /etc/letsencrypt/acme.json | python -c "
|
|
|
|
import sys,json
|
|
|
|
acme = json.load(sys.stdin)
|
|
|
|
for key, value in acme.items():
|
|
|
|
certs = value['Certificates']
|
|
|
|
for cert in certs:
|
|
|
|
if 'domain' in cert and 'key' in cert:
|
|
|
|
if 'main' in cert['domain'] and cert['domain']['main'] == '$WHAT' or 'sans' in cert['domain'] and '$WHAT' in cert['domain']['sans']:
|
|
|
|
print cert['key']
|
2020-07-20 09:28:23 +00:00
|
|
|
break
|
2020-07-19 21:57:16 +00:00
|
|
|
")
|
|
|
|
CERT=$(cat /etc/letsencrypt/acme.json | python -c "
|
|
|
|
import sys,json
|
|
|
|
acme = json.load(sys.stdin)
|
|
|
|
for key, value in acme.items():
|
|
|
|
certs = value['Certificates']
|
|
|
|
for cert in certs:
|
|
|
|
if 'domain' in cert and 'certificate' in cert:
|
|
|
|
if 'main' in cert['domain'] and cert['domain']['main'] == '$WHAT' or 'sans' in cert['domain'] and '$WHAT' in cert['domain']['sans']:
|
|
|
|
print cert['certificate']
|
2020-07-20 09:28:23 +00:00
|
|
|
break
|
2020-07-19 21:57:16 +00:00
|
|
|
")
|
2020-06-30 20:43:22 +00:00
|
|
|
|
|
|
|
if [[ -n "${KEY}${CERT}" ]]; then
|
|
|
|
mkdir -p /etc/letsencrypt/live/"$HOSTNAME"/
|
|
|
|
echo $KEY | base64 -d >/etc/letsencrypt/live/"$HOSTNAME"/key.pem || exit 1
|
|
|
|
echo $CERT | base64 -d >/etc/letsencrypt/live/"$HOSTNAME"/fullchain.pem || exit 1
|
|
|
|
echo "Cert found in /etc/letsencrypt/acme.json for $WHAT"
|
|
|
|
return 0
|
|
|
|
else
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
}
|
2020-08-24 18:46:50 +00:00
|
|
|
|
2020-08-24 20:08:11 +00:00
|
|
|
declare -A DEFAULT_VARS
|
|
|
|
DEFAULT_VARS["DMS_DEBUG"]="${DMS_DEBUG:="0"}"
|
|
|
|
|
|
|
|
function notify () {
|
|
|
|
c_red="\e[0;31m"
|
|
|
|
c_green="\e[0;32m"
|
|
|
|
c_brown="\e[0;33m"
|
|
|
|
c_blue="\e[0;34m"
|
|
|
|
c_bold="\033[1m"
|
|
|
|
c_reset="\e[0m"
|
|
|
|
|
|
|
|
notification_type=$1
|
|
|
|
notification_msg=$2
|
|
|
|
notification_format=$3
|
|
|
|
msg=""
|
|
|
|
|
|
|
|
case "${notification_type}" in
|
|
|
|
'taskgrp')
|
|
|
|
msg="${c_bold}${notification_msg}${c_reset}"
|
|
|
|
;;
|
|
|
|
'task')
|
|
|
|
if [[ ${DEFAULT_VARS["DMS_DEBUG"]} == 1 ]]; then
|
|
|
|
msg=" ${notification_msg}${c_reset}"
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
'inf')
|
|
|
|
if [[ ${DEFAULT_VARS["DMS_DEBUG"]} == 1 ]]; then
|
|
|
|
msg="${c_green} * ${notification_msg}${c_reset}"
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
'started')
|
|
|
|
msg="${c_green} ${notification_msg}${c_reset}"
|
|
|
|
;;
|
|
|
|
'warn')
|
|
|
|
msg="${c_brown} * ${notification_msg}${c_reset}"
|
|
|
|
;;
|
|
|
|
'err')
|
|
|
|
msg="${c_red} * ${notification_msg}${c_reset}"
|
|
|
|
;;
|
|
|
|
'fatal')
|
|
|
|
msg="${c_red}Error: ${notification_msg}${c_reset}"
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
msg=""
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
case "${notification_format}" in
|
|
|
|
'n')
|
|
|
|
options="-ne"
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
options="-e"
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
[[ ! -z "${msg}" ]] && echo $options "${msg}"
|
|
|
|
}
|
|
|
|
|
|
|
|
# setup /etc/postfix/relayhost_map
|
|
|
|
# --
|
|
|
|
# @domain1.com [smtp.mailgun.org]:587
|
|
|
|
# @domain2.com [smtp.mailgun.org]:587
|
|
|
|
# @domain3.com [smtp.mailgun.org]:587
|
|
|
|
function populate_relayhost_map() {
|
|
|
|
echo -n > /etc/postfix/relayhost_map
|
|
|
|
chown root:root /etc/postfix/relayhost_map
|
|
|
|
chmod 0600 /etc/postfix/relayhost_map
|
|
|
|
|
|
|
|
if [ -f /tmp/docker-mailserver/postfix-relaymap.cf ]; then
|
|
|
|
notify 'inf' "Adding relay mappings from postfix-relaymap.cf"
|
|
|
|
# Keep lines which are not a comment *and* have a destination.
|
|
|
|
sed -n '/^\s*[^#[:space:]]\S*\s\+\S/p' /tmp/docker-mailserver/postfix-relaymap.cf \
|
|
|
|
>> /etc/postfix/relayhost_map
|
|
|
|
fi
|
2020-08-24 20:53:54 +00:00
|
|
|
{
|
|
|
|
# Note: Won't detect domains when lhs has spaces (but who does that?!).
|
|
|
|
sed -n '/^\s*[^#[:space:]]/ s/^[^@|]*@\([^|]\+\)|.*$/\1/p' /tmp/docker-mailserver/postfix-accounts.cf
|
|
|
|
[ -f /tmp/docker-mailserver/postfix-virtual.cf ] &&
|
|
|
|
sed -n '/^\s*[^#[:space:]]/ s/^\s*[^@[:space:]]*@\(\S\+\)\s.*/\1/p' /tmp/docker-mailserver/postfix-virtual.cf
|
|
|
|
} | while read domain; do
|
2020-08-24 20:08:11 +00:00
|
|
|
if ! grep -q -e "^@${domain}\b" /etc/postfix/relayhost_map &&
|
|
|
|
! grep -qs -e "^\s*@${domain}\s*$" /tmp/docker-mailserver/postfix-relaymap.cf; then
|
|
|
|
# Domain not already present *and* not ignored.
|
|
|
|
notify 'inf' "Adding relay mapping for ${domain}"
|
|
|
|
echo "@${domain} [$RELAY_HOST]:$RELAY_PORT" >> /etc/postfix/relayhost_map
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2020-08-24 18:46:50 +00:00
|
|
|
# File storing the checksums of the monitored files.
|
|
|
|
CHKSUM_FILE=/tmp/docker-mailserver-config-chksum
|
|
|
|
|
|
|
|
# Compute checksums of monitored files.
|
|
|
|
function monitored_files_checksums() {
|
|
|
|
(
|
|
|
|
cd /tmp/docker-mailserver
|
|
|
|
# (2>/dev/null to ignore warnings about files that don't exist)
|
|
|
|
exec sha512sum 2>/dev/null -- \
|
|
|
|
postfix-accounts.cf \
|
|
|
|
postfix-virtual.cf \
|
|
|
|
postfix-aliases.cf \
|
|
|
|
dovecot-quotas.cf \
|
|
|
|
/etc/letsencrypt/acme.json \
|
|
|
|
"/etc/letsencrypt/live/$HOSTNAME/key.pem" \
|
|
|
|
"/etc/letsencrypt/live/$HOSTNAME/fullchain.pem"
|
|
|
|
)
|
|
|
|
return 0
|
|
|
|
}
|