#!/bin/sh # # service-qmail-smtpd-run (formerly "run.smtp" and "run.smtp.sslserver") # John Simpson 2003-07-05 to 2008-03-24 # # Generic daemontools "run" script for qmail "smtp" or "smtpssl" service. # # Documentation: http://qmail.jms1.net/scripts/service-qmail-smtpd-run.shtml # ############################################################################### # # Copyright (C) 2003-2011 John Simpson. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # or visit http://www.gnu.org/licenses/gpl.txt # ############################################################################### exec 2>&1 VQ="/var/qmail" PATH="$VQ/bin:/usr/local/bin:/usr/bin:/bin" QUSER=qmaild LOCAL=`head -1 $VQ/control/me` ############################################################################### # # options for tcpserver/sslserver IP=unset PORT=25 SSL=0 SSL_CERT="$VQ/control/servercert.pem" SMTP_CDB="/etc/tcp/smtp.cdb" MAX=30 # these require the "tcpserver limits" patch for ucspi-tcp, available here: # http://linux.voyager.hr/ucspi-tcp/ #MAXLOAD=750 #MAXCONNIP=2 #MAXCONNC=5 #DIEMSG="421 $LOCAL Service temporarily unavailable" # my newer version of the tcpserver limits patch allows you to specify # individual DIEMSG values for each policy. # http://qmail.jms1.net/ucspi-tcp/ #DIEMSG_MAXLOAD="421 $LOCAL Server busy, try again later." #DIEMSG_MAXCONNIP="421 $LOCAL Too many connections from your IP." #DIEMSG_MAXCONNC="421 $LOCAL Too many connections from your network." ############################################################################### # # options for programs which run before qmail-smtpd # rblsmtpd: checks sender IP before qmail-smtpd ever runs. IPs which are # found in RBL_GOOD zones will always have mail accepted. IPs which are found # in RBL_BAD zones will always have mail rejected. Multiple zones should be # separated with spaces. # If RBLSMTPD_TIMEOUT is set (and non-zero), rblsmtpd will give any rejected # clients a phony SMTP conversation, which lasts no more than the timeout # value (specified in seconds.) If this value is set to zero, rblsmtpd simply # hangs up on the client without any conversation. #RBLSMTPD_PROG="rblsmtpd" #RBLSMTPD_TIMEOUT=5 #RBL_GOOD="" #RBL_BAD="zen.spamhaus.org dnsbl.njabl.org dnsbl.sorbs.net bl.spamcop.net" # jgreylist: see http://qmail.jms1.net/scripts/jgreylist.shtml #GREYLIST="jgreylist" #JGREYLIST_DIR="$VQ/jgreylist" #JGREYLIST_NOREV=1 #JGREYLIST_BY_IP=0 #JGREYLIST_HOLDTIME=120 #JGREYLIST_LOG=1 #JGREYLIST_LOG_PID=1 #JGREYLIST_LOG_SMTP=0 #JGREYLIST_TIMEOUT=60 #JGREYLIST_LIMIT=0 # djb's "recordio" can be used to log the raw SMTP conversations. # http://qmail.jms1.net/scripts/#maybe-recordio is a script which allows you # to log only certain conversations (for debugging issues with specific # clients, without killing your log files.) #RECORDIO="recordio" ############################################################################### # # options for qmail-smtpd itself SMTPD="qmail-smtpd" #SMTPGREETING="$LOCAL NO UCE" #GREETDELAY=30 #DROP_PRE_GREET=1 FORCE_TLS=0 DENY_TLS=0 MFCHECK=3 #MAXRCPT=100 #RELAYREJ=1 QMAILSMTPD_LOG_MAIL=1 QMAILSMTPD_LOG_RCPT=1 #QMAILSMTPD_HELP_VERSION=1 ############################################################################### # # options pertaining to the AUTH command. AUTH=0 REQUIRE_AUTH=0 ALLOW_INSECURE_AUTH=0 # if using the AUTH_CDB method #AUTH_CDB="$VQ/control/auth.cdb" # if using the CHECKPW method CHECKPW=~vpopmail/bin/vchkpw TRUE=`which true` # to change the environment whenever somebody authenticates #AUTH_SET_MFCHECK=0 #AUTH_SET_MAXRCPT=0 #AUTH_SET_DATABYTES=0 #AUTH_SET_SPFBEHAVIOR=1 #AUTH_SET_VALIDRCPTTO_LIMIT=10 #AUTH_SET_VALIDRCPTTO_LOG=1 #AUTH_SET_SPF_LOG=1 #AUTH_SET_RELAYREJ=0 #AUTH_SET_VALIDRCPTTO_CDB="" #AUTH_SET_QMAILSMTPD_LOG_MAIL=1 #AUTH_SET_QMAILSMTPD_LOG_RCPT=1 #AUTH_SET_QMAILSMTPD_HELP_VERSION=1 ############################################################################### # # options pertaining to the "validrcptto.cdb" mechanism. # see http://qmail.jms1.net/patches/validrcptto.cdb.shtml for details. VALIDRCPTTO_CDB="$VQ/control/validrcptto.cdb" VALIDRCPTTO_LIMIT=10 VALIDRCPTTO_LOG=2 ############################################################################### # # options pertaining to the SPF mechanism. SPFBEHAVIOR=3 SPF_LOG=1 SPF_BLOCK_PLUS_ALL=1 ############################################################################### # # options pertaining to the Domainkeys mechanism. # this requires an add-on patch. #DOMAINKEYS=0 #DKVERIFY=DEfGhIJK #AUTH_SET_DKSIGN=/etc/domainkeys/%/default ############################################################################### # # options for programs which run after qmail-smtpd # if you are using simscan... #QMAILQUEUE="$VQ/bin/simscan" NOP0FCHECK=1 #SIMSCAN_DEBUG=0 #SIMSCAN_DEBUG_FILES=0 # if you are using qmail-scanner, un-comment ONE of these lines. #QMAILQUEUE="$VQ/bin/qmail-scanner-queue" #QMAILQUEUE="$VQ/bin/qmail-scanner-queue.pl" # if you're using some other qmail-queue replacement, add your own line here # with the correct value. ############################################################################### ############################################################################### ############################################################################### # # THERE SHOULD BE NO NEED TO CHANGE ANYTHING BELOW THIS LINE. of course, the # script is on your system and you're free to edit it however you want, but # changing things below this point may cause strange things to happen. make # sure you understand what you're doing if you change anything below... QDUID=`id -u $QUSER` QDGID=`id -g $QUSER` if [ -z "$IP" -o "$IP" = "unset" ] then echo "The IP variable is not set in the run script. Cannot start." sleep 5 exit 1 fi if [ -z "$QDUID" -o -z "$QDGID" -o -z "$MAX" -o -z "$LOCAL" \ -o -z "$SSL" -o -z "$AUTH" ] then echo "One of the variables QDUID, QDGID, MAX, LOCAL, SSL, or AUTH" echo "is not set in the run script. Cannot start." sleep 5 exit 1 fi if [ ! -f $VQ/control/rcpthosts ] then echo Creating emtpy $VQ/control/rcpthosts file to prevent open relay. touch $VQ/control/rcpthosts chmod 644 $VQ/control/rcpthosts fi if [ "$SSL" = "1" ] then if ! which sslserver > /dev/null 2>&1 then echo ERROR: sslserver not found in PATH [$PATH] exit 1 fi if [ ! -f $SSL_CERT ] then echo ERROR: $SSL_CERT does not exist exit 1 fi export CERTFILE=${SSL_CERT} export KEYFILE="" export DHFILE="" SCMD="sslserver -e" else if [ -n "$SSL_CERT" ] then export TLS_SERVER_CERT=${SSL_CERT} fi SCMD="tcpserver" fi if [ "$IP" = "127.0.0.1" ] then export RELAYCLIENT="" RBLSMTPD_PROG="" ACMD="" elif [ -z "${SMTP_CDB:-}" ] then ACMD="" else if [ ! -f "$SMTP_CDB" ] then echo ERROR: $SMTP_CDB does not exist exit 1 fi ACMD="-x $SMTP_CDB" fi if [ "$AUTH" = "1" ] then if [ -n "$AUTH_CDB" ] then if [ ! -f $AUTH_CDB ] then echo ERROR: AUTH_CDB file [$AUTH_CDB] does not exist exit 1 fi export AUTH_CDB ARGS="" elif [ -n "$CHECKPW" ] then if [ ! -f $CHECKPW ] then echo ERROR: $CHECKPW [$CHECKPW] program does not exist exit 1 fi if [ -z "$LOCAL" ] then echo ERROR: LOCAL is not set in the run script exit 1 elif [ -z "$TRUE" ] then echo ERROR: TRUE is not set in the run script exit 1 elif [ ! -e $TRUE ] then echo ERROR: $TRUE [$TRUE] is not an executable exit 1 fi ARGS=" $LOCAL $CHECKPW $TRUE" else echo ERROR: AUTH=1 but no AUTH_CDB or CHECKPW exit 1 fi else ARGS="" AUTH_CDB="" fi ######################################## # make RBL command (if needed) RBLCMD="" if [ -n "$RBLSMTPD_PROG" ] then if [ -n "$RBL_GOOD" ] then for name in $RBL_GOOD do RBLCMD="$RBLCMD -a $name" done fi if [ -n "$RBL_BAD" ] then for name in $RBL_BAD do RBLCMD="$RBLCMD -r $name" done fi if [ -n "$RBLCMD" ] then if [ -n "$RBLSMTPD_TIMEOUT" ] then RBLCMD="$RBLCMD -t $RBLSMTPD_TIMEOUT" fi RBLCMD="$RBLSMTPD_PROG $RBLCMD" fi fi ######################################## # make domainkeys command (if needed) if [ "$DOMAINKEYS" = "1" ] then if [ -f "$VQ/bin/qmail-dk" ] then if [ -n "$QMAILQUEUE" ] then export DKQUEUE="$QMAILQUEUE" fi export AUTH_UNSET_DKVERIFY=1 export QMAILQUEUE="$VQ/bin/qmail-dk" if [ -n "$DKVERIFY" ] ; then export DKVERIFY ; fi if [ -n "$DKSIGN" ] ; then export DKSIGN ; fi else echo ERROR: $VQ/bin/qmail-dk not found, cannot use domainkeys fi fi ######################################## # handle variables which may not have been set, but need to exist even # if they contain blank values if [ -z "$RECORDIO" ] then RECORDIO="" fi if [ -z "$GREYLIST" ] then GREYLIST="" fi ######################################## # do the deed for n in SSL \ MAXLOAD \ MAXCONNIP \ MAXCONNC \ DIEMSG \ DIEMSG_MAXLOAD \ DIEMSG_MAXCONNIP \ DIEMSG_MAXCONNC \ JGREYLIST_DIR \ JGREYLIST_NOREV \ JGREYLIST_BY_IP \ JGREYLIST_HOLDTIME \ JGREYLIST_LOG \ JGREYLIST_LOG_PID \ JGREYLIST_LOG_SMTP \ JGREYLIST_TIMEOUT \ JGREYLIST_LIMIT \ SMTPGREETING \ GREETDELAY \ DROP_PRE_GREET \ FORCE_TLS \ DENY_TLS \ MFCHECK \ MAXRCPT \ RELAYREJ \ QMAILSMTPD_LOG_MAIL \ QMAILSMTPD_LOG_RCPT \ QMAILSMTPD_HELP_VERSION \ REQUIRE_AUTH \ ALLOW_INSECURE_AUTH \ AUTH_CDB \ AUTH_SET_MFCHECK \ AUTH_SET_MAXRCPT \ AUTH_SET_DATABYTES \ AUTH_SET_SPFBEHAVIOR \ AUTH_SET_VALIDRCPTTO_LIMIT \ AUTH_SET_VALIDRCPTTO_LOG \ AUTH_SET_SPF_LOG \ AUTH_SET_RELAYREJ \ AUTH_SET_VALIDRCPTTO_CDB \ AUTH_SET_QMAILSMTPD_LOG_MAIL \ AUTH_SET_QMAILSMTPD_LOG_RCPT \ AUTH_SET_QMAILSMTPD_HELP_VERSION \ VALIDRCPTTO_CDB \ VALIDRCPTTO_LIMIT \ VALIDRCPTTO_LOG \ SPFBEHAVIOR \ SPF_LOG \ SPF_BLOCK_PLUS_ALL \ DKVERIFY \ AUTH_SET_DKSIGN \ QMAILQUEUE \ NOP0FCHECK \ SIMSCAN_DEBUG \ SIMSCAN_DEBUG_FILES do # note: not 100% sure "eval" works under old-school /bin/sh eval "if [ -n \"\$$n\" ];then echo \"$n=\\\"\$$n\\\"\";export $n;fi" done CMD="$SCMD -vR -l $LOCAL -c $MAX -u $QDUID -g $QDGID $ACMD $IP $PORT" CMD="$CMD $RBLCMD $GREYLIST $RECORDIO $SMTPD $ARGS" echo "command-line: exec $CMD 2>&1" exec $CMD 2>&1 ######################################## # this will only be reached if the exec fails echo ERROR: command did not run correctly exit 1