first commit

This commit is contained in:
debu-2 2026-10-03 21:14:44 +05:30
commit cce9a8c9ba
73 changed files with 8665 additions and 0 deletions

17
smtp/Dockerfile Normal file
View file

@ -0,0 +1,17 @@
FROM alpine:3.21
RUN apk add --no-cache postfix openssl
COPY main.cf /etc/postfix/main.cf
COPY master.cf /etc/postfix/master.cf
COPY entrypoint.sh /entrypoint.sh
RUN chmod 0644 /etc/postfix/main.cf /etc/postfix/master.cf && \
chmod 0755 /entrypoint.sh && \
mkdir -p /var/spool/postfix/pid
EXPOSE 25
HEALTHCHECK --interval=10s --timeout=3s --retries=5 \
CMD postfix status >/dev/null 2>&1 || exit 1
CMD ["/entrypoint.sh"]

142
smtp/entrypoint.sh Normal file
View file

@ -0,0 +1,142 @@
#!/bin/sh
set -eu
: "${MAIL_HOSTNAME:=mail.getall.help}"
: "${MAIL_DOMAIN:=getall.help}"
: "${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"
# 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

43
smtp/main.cf Normal file
View file

@ -0,0 +1,43 @@
# Internet-facing inbound relay + trusted outbound for Agmail.
compatibility_level = 3.6
myhostname = mail.getall.help
mydomain = getall.help
myorigin = $mydomain
inet_interfaces = all
inet_protocols = ipv4
mydestination =
local_recipient_maps =
local_transport = error:local delivery disabled
relay_domains = lmdb:/etc/postfix/relay_domains
transport_maps = lmdb:/etc/postfix/transport
# Internet clients may only send to relay_domains (inbound).
# Docker/backend clients in mynetworks may relay outbound to the public internet.
mynetworks = 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
smtpd_relay_restrictions = permit_mynetworks, reject_unauth_destination
smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination
# Match the backend's 25 MiB inbound limit.
message_size_limit = 26214400
mailbox_size_limit = 0
# Keep transient backend failures queued for retry.
minimal_backoff_time = 60s
maximal_backoff_time = 3600s
maximal_queue_lifetime = 1d
bounce_queue_lifetime = 1d
# Opportunistic TLS for internet senders and the backend hop.
# Gmail/Zoho require a working STARTTLS offer; certs are generated in entrypoint.sh.
smtpd_tls_cert_file = /etc/postfix/certs/smtpd.crt
smtpd_tls_key_file = /etc/postfix/certs/smtpd.key
smtpd_tls_security_level = may
smtpd_tls_loglevel = 1
smtp_tls_security_level = may
# Log directly to the container output.
maillog_file = /dev/stdout
alias_maps =
alias_database =

25
smtp/master.cf Normal file
View file

@ -0,0 +1,25 @@
smtp inet n - n - - smtpd
pickup unix n - n 60 1 pickup
cleanup unix n - n - 0 cleanup
qmgr unix n - n 300 1 qmgr
tlsmgr unix - - n 1000? 1 tlsmgr
rewrite unix - - n - - trivial-rewrite
bounce unix - - n - 0 bounce
defer unix - - n - 0 bounce
trace unix - - n - 0 bounce
verify unix - - n - 1 verify
flush unix n - n 1000? 0 flush
proxymap unix - - n - - proxymap
proxywrite unix - - n - 1 proxymap
smtp unix - - n - - smtp
relay unix - - n - - smtp
showq unix n - n - - showq
error unix - - n - - error
retry unix - - n - - error
discard unix - - n - - discard
local unix - n n - - local
virtual unix - n n - - virtual
lmtp unix - - n - - lmtp
anvil unix - - n - 1 anvil
scache unix - - n - 1 scache
postlog unix-dgram - - n - 1 postlog