From ac065275d9f68cdf078af4fa438c1ba15128b35d Mon Sep 17 00:00:00 2001 From: Erik Osterman Date: Tue, 22 Dec 2015 03:06:30 -0800 Subject: [PATCH] first commit --- Dockerfile | 42 ++++++ LICENSE | 28 ++++ README.md | 91 ++++++++++++ master.cf | 128 +++++++++++++++++ pam.d/smtp | 8 ++ rsyslogd.conf | 8 ++ saslauthd | 62 ++++++++ smtpd.conf | 2 + start | 390 ++++++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 759 insertions(+) create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 README.md create mode 100644 master.cf create mode 100644 pam.d/smtp create mode 100644 rsyslogd.conf create mode 100644 saslauthd create mode 100644 smtpd.conf create mode 100755 start diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..c08196f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,42 @@ +FROM ubuntu:14.04 +MAINTAINER Alex Sanz +ENV DEBIAN_FRONTEND noninteractive +ENV POSTMASTER_USER postmaster +ENV POSTMASTER_PASS password + +ENTRYPOINT ["/start"] +EXPOSE 25 + +RUN echo "force-unsafe-io" > /etc/dpkg/dpkg.cfg.d/02apt-speedup && \ + apt-get update && \ + apt-get --no-install-recommends -y install postfix sipcalc sasl2-bin libsasl2-modules && \ + postconf -e 'smtpd_sasl_auth_enable = yes' && \ + postconf -e 'smtpd_sasl_path = smtpd' && \ + postconf -e 'smtpd_sasl_local_domain =' && \ + postconf -e 'smtpd_sasl_authenticated_header = yes' && \ + rm /etc/ssl/certs/ssl-cert-snakeoil.pem /etc/ssl/private/ssl-cert-snakeoil.key && \ + find /etc/ssl/certs -type l -xtype l -delete && \ + apt-get clean && \ + rm -f /etc/dpkg/dpkg.cfg.d/02apt-speedup && \ + find /var/lib/apt/lists -mindepth 1 -delete -print && \ + find /tmp /var/tmp -mindepth 2 -delete -print && \ + rm -f /etc/rsyslog.d/50-default.conf && \ + adduser postfix sasl && \ + adduser --quiet --disabled-password -shell /bin/bash --home /home/$POSTMASTER_USER --gecos "Postmaster" $POSTMASTER_USER && \ + echo "$POSTMASTER_USER:$POSTMASTER_PASS" | chpasswd + +# Inspired by: +# http://uname.pingveno.net/blog/index.php/post/2014/02/01/Configure-Postfix-as-STMP-standalone-single-domain-server-using-Unix-users-and-PAM-on-Debian + +ADD start /start +ADD rsyslogd.conf /etc/rsyslog.d/stdout.conf +ADD master.cf /etc/postfix/ +ADD pam.d/ /etc/pam.d/ +ADD saslauthd /etc/default/saslauthd +ADD smtpd.conf /etc/postfix/sasl/smtpd.conf + +# Test with: testsaslauthd -u postmaster -p password -f /var/spool/postfix/var/run/saslauthd/mux +# perl -MMIME::Base64 -e 'print encode_base64("\000postmaster\000password")' +# openssl s_client -starttls smtp -crlf -connect localhost:587 +# AUTH PLAIN AHBvc3RtYXN0ZXIAcGFzc3dvcmQ= + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d668ffd --- /dev/null +++ b/LICENSE @@ -0,0 +1,28 @@ +Copyright (c) 2014, Alex Sanz +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the {organization} nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..902a5d1 --- /dev/null +++ b/README.md @@ -0,0 +1,91 @@ + +postfix mail server with configurable hostname and trusted hosts and proper +shutdown handling + +Notes +=== + +By default, connected rfc1918 networks are detected and allowed. Local networks +(127.0.0.1, ::1) are also allowed. + +Syslog +=== + +Rsyslog is started automatically and sends logs to stdout + +Suggested Volumes +=== + + * `/var/spool/postfix` is the spool directory. Its also where postfix chroots to by default. + * `/etc/postfix` is the configuation directory + +Options +=== + +You can customize the image behavior using environmental variables or entrypoint +arguments. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Enviromental Variable(s)Entrypoint OptionDescription
(use --hostname)--mail-nameMail name to use (appears in mail headers). Defaults to hostname
RELAYHOST="[relay hostname]--relayhost []The host to relay mail to.
TRUST="local" or TRUST_LOCAL="0"--trust-localTrust addresses on the lo interface. Enabled by default
TRUST="connected-rfc1918" or TRUST_CONNECTED_RFC="1"--trust-connected-rfc1918Trust all locally connected rfc1918 subnets. Enabled by default
TRUST="connected" or TRUST_CONNECTED="1"--trust-connectedTrust all addresses connected (excluding IPv6 local-link addresses). Disabled by default
TRUST="rfc1918" or TRUST_RFC1918="1"--trust-rfc1918Trust all rfc1918 address. Disabled by default
TRUST_LLA="1"--trust-llaTrust the fe80::/64 IPv6 subnet. Disabled by default
TRUST_SUBNETS="[space separated list of subnets]"--trust-subnet []Trust the specified subnet (IPv4 and IPv6 supported). Disabled by default
TRUST_INTERFACES="[space separated list of interfaces]"--trust-interface []Trust all network address on the interface (excluding IPv6 LLA). Disabled by default
--skip-trust-*Use with local, connected-rfc1918, connected, rfc1918, or lla to skip trusting it. Disabled by default
--skip-allDisable/reset all trusts. Disabled by default
diff --git a/master.cf b/master.cf new file mode 100644 index 0000000..b6fc4aa --- /dev/null +++ b/master.cf @@ -0,0 +1,128 @@ +# +# Postfix master process configuration file. For details on the format +# of the file, see the master(5) manual page (command: "man 5 master" or +# on-line: http://www.postfix.org/master.5.html). +# +# Do not forget to execute "postfix reload" after editing this file. +# +# ========================================================================== +# service type private unpriv chroot wakeup maxproc command + args +# (yes) (yes) (yes) (never) (100) +# ========================================================================== +smtp inet n - - - - smtpd +#smtp inet n - - - 1 postscreen +#smtpd pass - - - - - smtpd +#dnsblog unix - - - - 0 dnsblog +#tlsproxy unix - - - - 0 tlsproxy +submission inet n - - - - smtpd + -o syslog_name=postfix/submission + -o smtpd_tls_security_level=encrypt + -o smtpd_sasl_auth_enable=yes + -o smtpd_relay_restrictions=permit_sasl_authenticated,reject + -o milter_macro_daemon_name=ORIGINATING +# -o smtpd_reject_unlisted_recipient=no +# -o smtpd_client_restrictions=$mua_client_restrictions +# -o smtpd_helo_restrictions=$mua_helo_restrictions +# -o smtpd_sender_restrictions=$mua_sender_restrictions +# -o smtpd_recipient_restrictions= + +smtps inet n - - - - smtpd + -o syslog_name=postfix/smtps + -o smtpd_tls_wrappermode=yes + -o smtpd_sasl_auth_enable=yes + -o smtpd_relay_restrictions=permit_sasl_authenticated,reject + -o milter_macro_daemon_name=ORIGINATING +# -o smtpd_reject_unlisted_recipient=no +# -o smtpd_client_restrictions=$mua_client_restrictions +# -o smtpd_helo_restrictions=$mua_helo_restrictions +# -o smtpd_sender_restrictions=$mua_sender_restrictions +# -o smtpd_recipient_restrictions= + +#628 inet n - - - - qmqpd +pickup unix n - - 60 1 pickup +cleanup unix n - - - 0 cleanup +qmgr unix n - n 300 1 qmgr +#qmgr unix n - n 300 1 oqmgr +tlsmgr unix - - - 1000? 1 tlsmgr +rewrite unix - - - - - trivial-rewrite +bounce unix - - - - 0 bounce +defer unix - - - - 0 bounce +trace unix - - - - 0 bounce +verify unix - - - - 1 verify +flush unix n - - 1000? 0 flush +proxymap unix - - n - - proxymap +proxywrite unix - - n - 1 proxymap +smtp unix - - - - - smtp +relay unix - - - - - smtp +# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 +showq unix n - - - - showq +error unix - - - - - error +retry unix - - - - - error +discard unix - - - - - discard +local unix - n n - - local +virtual unix - n n - - virtual +lmtp unix - - - - - lmtp +anvil unix - - - - 1 anvil +scache unix - - - - 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} + + + diff --git a/pam.d/smtp b/pam.d/smtp new file mode 100644 index 0000000..46a95f1 --- /dev/null +++ b/pam.d/smtp @@ -0,0 +1,8 @@ +# +# /etc/pam.d/smtp - specify PAM SMTP behavior +# + +@include common-auth +@include common-account +@include common-password +@include common-session diff --git a/rsyslogd.conf b/rsyslogd.conf new file mode 100644 index 0000000..42cb84a --- /dev/null +++ b/rsyslogd.conf @@ -0,0 +1,8 @@ +$PrivDropToUser root +$PrivDropToGroup root + +mail.* { + /proc/1/fd/1 + stop +} + diff --git a/saslauthd b/saslauthd new file mode 100644 index 0000000..b0c45e0 --- /dev/null +++ b/saslauthd @@ -0,0 +1,62 @@ +# +# 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" + +# 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=1 + +# 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/spool/postfix/var/run/saslauthd" diff --git a/smtpd.conf b/smtpd.conf new file mode 100644 index 0000000..33c1f23 --- /dev/null +++ b/smtpd.conf @@ -0,0 +1,2 @@ +pwcheck_method: saslauthd +mech_list: PLAIN LOGIN diff --git a/start b/start new file mode 100755 index 0000000..38a1e21 --- /dev/null +++ b/start @@ -0,0 +1,390 @@ +#!/bin/sh + + +# Parse options +if [ -n "$MAILNAME" ] +then + mailname="$MAILNAME" +elif [ "$FQDN" = "1" ] +then + mailname=`hostname -f` +fi + +local_all_subnets=no +local="no" +option_value="" +interfaces="" +relayhost="" +subnets="" +verbose=0 + +trust_local=1 +trust_connected=0 +trust_rfc1918=0 +trust_connected_rfc1918=1 +trust_lla=0 + +if [ -n "$RELAYHOST" ] +then + relayhost="$RELAYHOST" +fi + +if [ -n "$TRUST" ] +then + trust_connected_rfc1918=0 + if [ "$TRUST" = "connected" ] + then + trust_connected=1 + elif [ "$TRUST" = "rfc1918" ] + then + trust_rfc1918=1 + elif [ "$TRUST" = "connected" ] + then + trust_connected=1 + elif [ "$TRUST" = "connected-rfc1918" ] + then + trust_connected_rfc1918=1 + fi +fi + +if [ -n "$TRUST_INTERFACES" ] +then + interfaces="$TRUST_INTERFACES" +elif [ -n "$TRUST_INTERFACE" ] +then + interfaces="$TRUST_INTERFACE" +fi + +if [ -n "$TRUST_SUBNETS" ] +then + subnets="$TRUST_SUBNETS" +elif [ -n "$TRUST_SUBNET" ] +then + subnets="$TRUST_SUBNET" +fi + +if [ "$TRUST_LOCAL" = "0" ] +then + trust_local=0 +fi + +if [ "$TRUST_CONNECTED" = "1" ] +then + trust_connected=1 +fi + +if [ "$TRUST_RFC1918" = "1" ] +then + trust_rfc1918=1 +fi + +if [ "$TRUST_CONNECTED_RFC1918" = "1" ] +then + trust_connected_rfc1918=1 +fi + +if [ "$TRUST_LLA" = "1" ] +then + trust_lla=1 +fi + +while [ $# -gt 0 ] +do + case "$1" in + (-h | --help) + cat <&2; + exit 1 + fi + ;; + + esac + shift +done + +trusted4="" +trusted6="" + +get_v4_network() { + xargs --no-run-if-empty sipcalc | awk '/Network address/ { printf "%s/", $4 } /Network mask \(bits\)/ { print $5 }' +} +get_v6_network() { + xargs --no-run-if-empty sipcalc | awk '/Subnet prefix/ { print $5 }' +} +get_compact_v6_network() { + get_v6_network | xargs --no-run-if-empty xargs sipcalc | awk '/Compressed address/ { printf "%s/", $4 } /Prefix length/ { print $4 }' +} + +exclude_local() { + awk '!/inet 127.0.0.1/ && !/inet6 ::1/' +} +exclude_rfc1918() { + rfc1918_addresses='10(\.(2[0-9]{2}|1?[0-9]{1,2})){3}' + rfc1918_addresses="$rfc1918_addresses|"'192\.168\.[12]?[0-9]{1,2}' + rfc1918_addresses="$rfc1918_addresses|"'172\.(1[6-9]|2[0-9]|31)\.(25[1-4]|2[1-4][0-9]|1[0-9]{2}|[1-9]?[0-9])' + awk "!/inet ($rfc1918_addresses)/" +} +exclude_lla() { + awk '!/inet6 fe80::/' +} + +for address in $trusted; +do + # Check to see if the address specified is an interface instead + # sipcalc doesn't seem to return IPv6 information, so first use it + # to detect whether the input is an interface + sip_calc=`sipcalc -u $address` + is_interface=`echo $sip_calc | grep -c int-` + + if [ $is_interface -eq 0 ] + then + # $address is an ip address (v4 or v6) + is_ipv6=`echo "$sip_calc" | grep -c ipv6` + if [ $is_ipv6 -eq 0 ] + then + subnet=`sipcalc $address | get_v4_network` + trusted4="${trusted4}$subnet " + else + subnet=`sipcalc $address | get_v6_network` + trusted6="${trusted6}$subnet " + fi + else + # $address is an interface + if [ $trust_rfc1918 -eq 1 ] + then + addresses4=`ip addr show dev $address | exclude_rfc1918 | awk '/inet / { print $2 }' | get_v4_network` + else + addresses4=`ip addr show dev $address | awk '/inet / { print $2 }' | get_v4_network` + fi + + addresses6=`ip addr show dev $address | exclude_lla | awk '/inet6/ { print $2 }' | get_compact_v6_network` + + trusted4="${trusted4}$addresses4 " + trusted6="${trusted6}$addresses6 " + fi +done + +if [ ! "$option_value" = "" ] +then + echo "$0: error - missing value for --$option_value" + exit 1 +fi + +include_rfc1918() { + rfc1918_addresses='10(\.(2[0-9]{2}|1?[0-9]{1,2})){3}' + rfc1918_addresses="$rfc1918_addresses|"'192\.168\.[12]?[0-9]{1,2}' + rfc1918_addresses="$rfc1918_addresses|"'172\.(1[6-9]|2[0-9]|31)\.(25[1-4]|2[1-4][0-9]|1[0-9]{2}|[1-9]?[0-9])' + awk "/inet ($rfc1918_addresses)/" +} + +if [ $trust_local -eq 1 ] +then + local4_addresses=`ip addr show dev lo | awk '/inet / {print $2 }' | get_v4_network` + local6_addresses=`ip addr show dev lo | awk '/inet6 / {print $2 }' | get_compact_v6_network` + trusted4="$local4_addresses " + trusted6="$local6_addresses " +fi + +if [ $trust_rfc1918 -eq 1 ] +then + trusted4="${trusted4}10.0.0.0/8 172.16.0.0/12 192.168.0.0/24 " +fi + +if [ $trust_lla -eq 1 ] +then + trusted6="${trusted6}fe80::/64 " +fi + +if [ $trust_connected -eq 1 ] +then + if [ $trust_rfc1918 -eq 1 ] + then + connected4=`ip addr show | exclude_local | exclude_rfc1918 | awk '/inet / { print $2 }' | get_v4_network` + else + connected4=`ip addr show | exclude_local | awk '/inet / { print $2 }' | get_v4_network` + fi + connected6=`ip addr show | exclude_lla | awk '/inet6/ && !/inet6 ::1/ { print $2}' | get_compact_v6_network` + trusted4="${trusted4}${connected4}" + trusted6="${trusted6}${connected6} " +fi + +if [ $trust_connected_rfc1918 -eq 1 -a $trust_rfc1918 -eq 0 -a $trust_connected -eq 0 ] +then + connected1918=`ip addr show | include_rfc1918 | awk '/inet / { print $2 }' | get_v4_network` + trusted4="${trusted4}${connected1918} " +fi + +# Build mynetworks +mynetworks="" +for subnet in $trusted4 +do + mynetworks="${mynetworks}${subnet} " + network=`echo $subnet | cut -d/ -f1` + subnet_size=`echo $subnet | cut -d/ -f2` + ipv6_size=`expr 96 + $subnet_size` + trusted6="${trusted6}::ffff:$network/$ipv6_size " +done + +for subnet in $trusted6 +do + network=`echo $subnet | cut -d/ -f1` + subnet_size=`echo $subnet | cut -d/ -f2` + mynetworks="${mynetworks}[$network]/$subnet_size " +done + +# Generate an automatically generated private key if not generated +if [ ! -f /etc/ssl/certs/ssl-cert-snakeoil.pem ] +then + DEBIAN_FRONTEND=noninteractive make-ssl-cert generate-default-snakeoil +fi + +# Update the hostname +if [ -n "$mailname" ] +then + sed -i "s#myhostname =.*#myhostname = $mailname#" /etc/postfix/main.cf +fi + + +seded_mynetworks=`echo $MYNETWORK | sed 's/#/\\#/g'` +sed -i -r "s#mynetworks = (.*)#mynetworks = $mynetworks#g" /etc/postfix/main.cf + +sed -i -r "s#relayhost = (.*)#relayhost = $relayhost#g" /etc/postfix/main.cf + +# Utilize the init script to configure the chroot (if needed) +/etc/init.d/postfix start > /dev/null +/etc/init.d/postfix stop > /dev/null + +# The init script doesn't always stop +# Ask postfix to stop itself as well, in case there's an issue +postfix stop > /dev/null 2>/dev/null + +trap_hup_signal() { + echo "Reloading (from SIGHUP)" + postfix reload + /etc/init.d/saslauthd restart +} + +trap_term_signal() { + echo "Stopping (from SIGTERM)" + postfix stop + /etc/init.d/saslauthd stop + /etc/init.d/rsyslog stop + exit 0 +} + +# Postfix conveniently, doesn't handle TERM (sent by docker stop) +# Trap that signal and stop postfix if we recieve it +trap "trap_hup_signal" HUP +trap "trap_term_signal" TERM + +/usr/lib/postfix/master -c /etc/postfix -d & +pid=$! + +/etc/init.d/saslauthd start +/etc/init.d/rsyslog start + +# Loop "wait" until the postfix master exits +while wait $pid; test $? -gt 128 +do + kill -0 $pid 2> /dev/null || break; +done