143 lines
3.9 KiB
Bash
143 lines
3.9 KiB
Bash
#!/bin/sh
|
|
set -eu
|
|
|
|
: "${MAIL_HOSTNAME:=mail.gentic.email}"
|
|
: "${MAIL_DOMAIN:=gentic.email}"
|
|
: "${INBOUND_DOMAINS:=${MAIL_DOMAIN}}"
|
|
: "${RELAY_DOMAINS_FILE:=/data/relay_domains/domains.list}"
|
|
: "${RELAY_DOMAINS_REFRESH:=60}"
|
|
: "${BACKEND_INGEST_HOST:=backend}"
|
|
: "${BACKEND_INGEST_PORT:=2525}"
|
|
|
|
case "${MAIL_HOSTNAME}" in
|
|
""|*[!A-Za-z0-9._-]*)
|
|
echo "MAIL_HOSTNAME contains invalid characters" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
case "${BACKEND_INGEST_HOST}" in
|
|
""|*[!A-Za-z0-9._-]*)
|
|
echo "BACKEND_INGEST_HOST must be an IPv4 address or DNS hostname" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
case "${BACKEND_INGEST_PORT}" in
|
|
""|*[!0-9]*)
|
|
echo "BACKEND_INGEST_PORT must be numeric" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
if [ "${BACKEND_INGEST_PORT}" -lt 1 ] || [ "${BACKEND_INGEST_PORT}" -gt 65535 ]; then
|
|
echo "BACKEND_INGEST_PORT must be between 1 and 65535" >&2
|
|
exit 1
|
|
fi
|
|
|
|
validate_domain() {
|
|
domain="$1"
|
|
printf '%s\n' "${domain}" | awk '
|
|
/^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/ {
|
|
valid = 1
|
|
}
|
|
END { exit !valid }
|
|
'
|
|
}
|
|
|
|
install_relay_maps() {
|
|
relay_domains_tmp="$(mktemp)"
|
|
transport_tmp="$(mktemp)"
|
|
seen_tmp="$(mktemp)"
|
|
|
|
add_domain() {
|
|
raw_domain="$1"
|
|
domain="$(printf '%s' "${raw_domain}" | tr -d '[:space:]' | tr '[:upper:]' '[:lower:]')"
|
|
if [ -z "${domain}" ]; then
|
|
return 0
|
|
fi
|
|
if ! validate_domain "${domain}"; then
|
|
echo "Skipping invalid relay domain: ${raw_domain}" >&2
|
|
return 0
|
|
fi
|
|
if grep -Fxq "${domain}" "${seen_tmp}" 2>/dev/null; then
|
|
return 0
|
|
fi
|
|
printf '%s\n' "${domain}" >> "${seen_tmp}"
|
|
printf '%s OK\n' "${domain}" >> "${relay_domains_tmp}"
|
|
printf '%s smtp:[%s]:%s\n' \
|
|
"${domain}" "${BACKEND_INGEST_HOST}" "${BACKEND_INGEST_PORT}" \
|
|
>> "${transport_tmp}"
|
|
}
|
|
|
|
old_ifs="${IFS}"
|
|
IFS=','
|
|
for raw_domain in ${INBOUND_DOMAINS}; do
|
|
add_domain "${raw_domain}"
|
|
done
|
|
IFS="${old_ifs}"
|
|
|
|
if [ -f "${RELAY_DOMAINS_FILE}" ]; then
|
|
while IFS= read -r line || [ -n "${line}" ]; do
|
|
add_domain "${line}"
|
|
done < "${RELAY_DOMAINS_FILE}"
|
|
fi
|
|
|
|
if [ ! -s "${relay_domains_tmp}" ]; then
|
|
rm -f "${relay_domains_tmp}" "${transport_tmp}" "${seen_tmp}"
|
|
echo "At least one inbound relay domain is required" >&2
|
|
return 1
|
|
fi
|
|
|
|
install -m 0644 "${relay_domains_tmp}" /etc/postfix/relay_domains
|
|
install -m 0644 "${transport_tmp}" /etc/postfix/transport
|
|
postmap /etc/postfix/relay_domains
|
|
postmap /etc/postfix/transport
|
|
rm -f "${relay_domains_tmp}" "${transport_tmp}" "${seen_tmp}"
|
|
}
|
|
|
|
install_relay_maps
|
|
|
|
postconf -e "myhostname = ${MAIL_HOSTNAME}"
|
|
postconf -e "mydomain = ${MAIL_DOMAIN}"
|
|
postconf -e "myorigin = \$mydomain"
|
|
postconf -e "smtp_header_checks = regexp:/etc/postfix/outbound_header_checks"
|
|
|
|
# STARTTLS cert for inbound providers (Gmail, Zoho, etc.)
|
|
mkdir -p /etc/postfix/certs
|
|
if [ ! -f /etc/postfix/certs/smtpd.crt ]; then
|
|
openssl req -new -x509 -days 825 -nodes \
|
|
-subj "/CN=${MAIL_HOSTNAME}" \
|
|
-keyout /etc/postfix/certs/smtpd.key \
|
|
-out /etc/postfix/certs/smtpd.crt
|
|
chmod 600 /etc/postfix/certs/smtpd.key
|
|
chmod 644 /etc/postfix/certs/smtpd.crt
|
|
fi
|
|
|
|
# Postfix chroot cannot see Docker's resolver unless we copy these in.
|
|
mkdir -p /var/spool/postfix/etc
|
|
mkdir -p /var/spool/postfix/etc/postfix/certs
|
|
cp /etc/postfix/certs/smtpd.crt /var/spool/postfix/etc/postfix/certs/smtpd.crt
|
|
cp /etc/postfix/certs/smtpd.key /var/spool/postfix/etc/postfix/certs/smtpd.key
|
|
chmod 644 /var/spool/postfix/etc/postfix/certs/smtpd.crt
|
|
chmod 600 /var/spool/postfix/etc/postfix/certs/smtpd.key
|
|
|
|
for file in resolv.conf hosts nsswitch.conf; do
|
|
if [ -f "/etc/${file}" ]; then
|
|
cp "/etc/${file}" "/var/spool/postfix/etc/${file}"
|
|
fi
|
|
done
|
|
|
|
postfix check
|
|
|
|
if [ "${RELAY_DOMAINS_REFRESH}" -gt 0 ] 2>/dev/null; then
|
|
(
|
|
while true; do
|
|
sleep "${RELAY_DOMAINS_REFRESH}"
|
|
if install_relay_maps; then
|
|
postfix reload >/dev/null 2>&1 || true
|
|
fi
|
|
done
|
|
) &
|
|
fi
|
|
|
|
exec postfix start-fg
|