Defining alias and control files
echo 3 > /var/qmail/control/spfbehavior
echo "| /home/vpopmail/bin/vdelivermail '' bounce-no-mailbox" > /var/qmail/control/defaultdelivery
echo 20 > /var/qmail/control/concurrencyincoming
echo postmaster@yourdomain.net > /var/qmail/control/bouncefrom
echo 20000000 > /var/qmail/control/databytes
echo yourdomain.net > /var/qmail/control/doublebouncehost
echo postmaster > /var/qmail/control/doublebounceto
echo 272800 > /var/qmail/control/queuelifetime
echo 30000000 > /var/qmail/control/softlimit
echo 100 > /var/qmail/control/maxrcpt
cd /usr/local/src/netqmail-1.06
./config-fast yourdomain.net
When you run ./config-fast it will automatically populate these files: defaultdomain, locals, me, plusdomain, rcpthosts.
- defaultdomain when you have many domains on the same server (defined later in the virtualhost file) this is the default domain
- locals domains that we deliver locally (qmail-send via qmail-lspawn program). Other domains are spawned by qmail-rspawn and delivered to other MTAs.
- me the name of the server. This is the domain name that appers in the from field when you receive system messages, for instance
- plusdomain domain substituted for trailing "+"
- rcpthosts Domains that we accept mail for. Later you will see how simscan/chkuser reject incoming emails for non existing recipients.
- spfbehavior concerns the spf patch.
- softlimit sets soft resource limits for qmail-smtpd
- databytes is the max number of bytes in message (0=no limit)
- doublebounceto is the account which will receive double-bounce messages. If you’re using my combined patch, you can erase the first line of /var/qmail/control/doublebounceto to delete these unwanted messages before they’re injected into the local queue.
defaultdelivery is the default .qmail file. It tells qmail how to deliver the email. In this case Maildir is our choice. In case you didn't understand yet how delivery is done, please read at this point the relaying chapter of Life with qmail and expecially the README.vdelivermail that comes with vpopmail, which explains how the .qmail files are used.
You can find an exhaustive presentation of all control configuration file on Life with qmail book http://www.lifewithqmail.org/lwq.html#configuration
Setup the primary administrator's email address. This address will receive mail for root, postmaster, and mailer-daemon. Replace "postmaster@yourdomain.net" with the administrator email address (postmaster):
cd /var/qmail/alias
echo "postmaster@yourdomain.net" > .qmail-postmaster
ln -s .qmail-postmaster .qmail-mailer-daemon
ln -s .qmail-postmaster .qmail-root
chmod 644 .qmail*
Setup the log dirs
The log dirs belong to qmaill.nofiles user and should not be accessible by other users
mkdir -p /var/log/qmail
cd /var/log/qmail
chown -R qmaill.nofiles .
chgrp root .
chmod -R og-wrx .
chmod g+rx .
Defining supervise scripts
References: tcpserver page
Download the startup scripts from here and untar
cd /var/qmail
wget http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/supervise.tar.gz
tar xzf supervise.tar.gz
rm supervise.tar.gz
chown -R root.root rc supervise
You can see the rc excutable, which is the qmail-start script, and the supervise folder:
-supervise
|
|----qmail-smtpd/
| |
| |-----run
| |-----log/
| |
| |---run
|
|----qmail-submission/
| |
| |-----run
| |-----log/
| |
| |---run
|
|----qmail-send/
| |
| |-----run
| |-----log/
| |
| |---run
|
|----vpopmaild/
| |
| |-----run
| |-----log/
|
|---run
When you create symbolic links to a supervise directory in the /service dir, the run command will be executed at boot time when /command/svcscanboot is launched
cd /service
ln -s /var/qmail/supervise/qmail-smtpd
ln -s /var/qmail/supervise/qmail-send
ln -s /var/qmail/supervise/vpopmaild
And if you’re going to build an SMTP relay, you may want to run a separate SMTP instance for authentication on port 587:
ln -s /var/qmail/supervise/qmail-submission
File qmail/rc
#!/bin/sh
# Using stdout for logging
# Using control/defaultdelivery from qmail-local to deliver messages by default
# DKIM signign
#exec env - PATH="/var/qmail/bin:$PATH" \
#QMAILREMOTE=/var/qmail/bin/spawn-filter \
#FILTERARGS=/var/qmail/bin/dk-filter \
#qmail-start "`cat /var/qmail/control/defaultdelivery`"
exec env - PATH="/var/qmail/bin:$PATH" \
qmail-start "`cat /var/qmail/control/defaultdelivery`"
File qmail/supervise/qmail-smtpd/run
#!/bin/sh
QMAILDUID=`id -u vpopmail`
NOFILESGID=`id -g vpopmail`
MAXSMTPD=`cat /var/qmail/control/concurrencyincoming`
SOFTLIMIT=`cat /var/qmail/control/softlimit`
# This enables greetdelay for qmail-smtpd. Put 0 if you decide to delay rblsmtpd instead.
export SMTPD_GREETDELAY=20
export DROP_PRE_GREET=1
# This enables greetdelay for rblsmtpd
#export GREETDELAY=15
# This disables rblsmtpd reject
#export RBLSMTPD=""
# This enables chkuser
export CHKUSER_START=ALWAYS
# DKIM - SURBL configuration
# DKIMQUEUE and SURBLQUEUE are front-ends of qmail-queue
#export SURBL=1 # Comment out to enable SURBL filtering
#export QMAILQUEUE=/var/qmail/bin/surblqueue # executes surblfilter
#export SURBLQUEUE=/var/qmail/bin/qmail-dkim # executes qmail-dkim afer sublfilter
#export DKIMQUEUE=/var/qmail/bin/simscan # simscan is executed after qmail-dkim
# DKIM verification. Use carefully
#export DKIMVERIFY="FGHKLMNOQRTVW"
# This is to avoid verification of outgoing messages
#export RELAYCLIENT_NODKIMVERIFY=1
# This turns off TLS on port 25
export DISABLETLS="1"
# This enables simscan debug
#export SIMSCAN_DEBUG=2
exec /usr/local/bin/softlimit -m "$SOFTLIMIT" \
/usr/local/bin/tcpserver -v -H -R -l 0 \
-x /home/vpopmail/etc/tcp.smtp.cdb -c "$MAXSMTPD" \
-u "$QMAILDUID" -g "$NOFILESGID" 0 25 \
/var/qmail/bin/qmail-smtpd 2>&1
Note that the standard smtp (port 25) does not allow the authentication.
You have to adjust the resource limit (softlimit in bytes). Each system is different, and has different requirements. Life with qmail suggests just 2MB. You have to experiment the correct value increasing by steps of 1MB, especially once you have loaded spamassassin, clamAV and simscan (the mail scanner).
We'll cover GREETDELAY, RBL and DKIM later.
File qmail/supervise/qmail-smtpd/log/run
#!/bin/sh
exec /usr/local/bin/setuidgid qmaill /usr/local/bin/multilog t s16000000 n200 /var/log/qmail/smtpd
# comment out the following to save the "qlogenvelope" lines also in a separate file
# you must have the file /usr/local/bin/archive_qmail_qlog executable and working!
#LOGUSER="qmaill"
#LOGDIR="/var/log/qmail/smtpd"
#LOGDIRQLOG="/var/log/qmail/smtpd/qlog"
#n5 s10000000 '-*' '+* qlog*' !/usr/local/bin/archive_qmail_qlog $LOGDIRQLOG
If you like, you can have the qlogenvelope lines saved in a separate file as well:
@400000005855db3028811e24 qlogenvelope: result=accepted code=250 reason=rcptto detail=chkuser helo=smtp.senderdomain.com mailfrom=sender@senderdomain.com rcptto=user@rcptdomain.com relay=no rcpthosts=yes size= authuser= authtype= encrypted= sslverified=no localip=10.0.0.4 localport=25 remoteip=83.103.72.231 remoteport=43618 remotehost= qp= pid=11928
@400000005855db322a892324 qlogreceived: result=accepted code=250 reason=queueaccept detail= helo=smtp.senderdomain.com mailfrom=sender@senderdomain.com rcptto=user@rcptdomain.com relay=no rcpthosts= size=2689 authuser= authtype= encrypted= sslverified=no localip=10.0.0.4 localport=25 remoteip=83.103.72.231 remoteport=43618 remotehost= qp=11934 pid=11928
In this case create the archive_qmail_qlog
cat > /usr/local/bin/archive_qmail_qlog << __EOF__
#!/bin/sh
tai64nlocal >> /var/log/qmail/qmail-smtpd.log
__EOF__
and assign the +x flag
chmod +x /usr/local/bin/archive_qmail_qlog
File qmail/supervise/qmail-send/run
#!/bin/sh
exec /var/qmail/rc
File qmail/supervise/qmail-send/log/run
#!/bin/sh
exec /usr/local/bin/setuidgid qmaill /usr/local/bin/multilog t s16000000 n200 /var/log/qmail/send
File qmail/supervise/qmail-submission/run
This service makes the MTA also act as an outgoing relay, but the user must authenticate (with TLS encryption).
#!/bin/sh
QMAILDUID=`id -u vpopmail`
NOFILESGID=`id -g vpopmail`
MAXSMTPD=`cat /var/qmail/control/concurrencyincoming`
SOFTLIMIT=`cat /var/qmail/control/softlimit`
# You MUST export this, otherwise you'd get a 30 sec timeout
# "!" if you want the submission feature (auth required)
export SMTPAUTH="!"
# This enables greetdelay for qmail-smtpd.
# comment out if using fail2ban on port 587
export SMTPD_GREETDELAY=5
export DROP_PRE_GREET=1
# This enables chkuser
export CHKUSER_START=ALWAYS
# This enables simscan debug
#export SIMSCAN_DEBUG=2
exec /usr/local/bin/softlimit -m "$SOFTLIMIT" \
/usr/local/bin/tcpserver -v -H -R -l 0 \
-x /home/vpopmail/etc/tcp.submission.cdb -c "$MAXSMTPD" \
-u "$QMAILDUID" -g "$NOFILESGID" 0 587 \
/var/qmail/bin/qmail-smtpd \
/home/vpopmail/bin/vchkpw /bin/true 2>&1
Note the use of vchkpw in conjunction with qmail-smtpd to ensure authentication. The connection requires TLS enabled. This is the reason why we opened a separate secure connection on port 587 to allow remote clients to use our MTA as a relay.
The variable SMTPAUTH is related to the auth patch. You are invited to take a look to the README.auth file for further details.
File qmail/supervise/qmail-submission/log/run
#!/bin/sh
exec /usr/local/bin/setuidgid qmaill /usr/local/bin/multilog t s16000000 n200 /var/log/qmail/submission
File qmail/supervise/vpopmaild/run
#!/bin/sh
QMAILDUID=`id -u root`
NOFILESGID=`id -g root`
exec /usr/local/bin/softlimit -m 25000000 \
/usr/local/bin/tcpserver -v -H -R -l 0 \
-u "$QMAILDUID" -g "$NOFILESGID" 0 89 \
/home/vpopmail/bin/vpopmaild 2>&1
vpopmaild is important when connecting to vpopmail via webmail to change the password, for instance.
File qmail/supervise/vpopmaild/log/run
#!/bin/sh
exec /usr/local/bin/setuidgid qmaill /usr/local/bin/multilog t /var/log/qmail/vpopmaild
cronjobs
To backup the log files from the qmail
services we'll use the convert-multilog script from John Simpson (thanks to the author and to Marc for the suggestion) who describes the script function as follows:
convert-multilog is a script which searches "/service/*/log/main" for any "@4*" files (the automatic cut-off files generated by multilog), converts their timestamps from tai64n to human-readable format, and writes them to /var/log/{service}.{date}. Once the lines from a given "@4*" file have been converted, the file is deleted.
The log files are saved separated by date, for example
-rw-r--r-- 1 root root 259558 Aug 24 12:21 qmail-smtpd.2014-08-20
-rw-r--r-- 1 root root 806917 Aug 24 12:21 qmail-smtpd.2014-08-21
-rw-r--r-- 1 root root 1523116 Aug 24 12:21 qmail-smtpd.2014-08-22
-rw-r--r-- 1 root root 364022 Aug 24 12:21 qmail-smtpd.2014-08-23
Inside each file the date is now human-readable
2014-08-23 00:31:49.503947500 tcpserver: status: 1/20
This is very useful when you have to do quick searches.
Install like this:
mkdir -p /var/log/qmail/backup
cd /usr/local/bin
wget http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/convert-multilog
chmod +x convert-multilog
cd /service/qmail-send/log/
ln -s /var/log/qmail/send main
cd /service/qmail-smtpd/log/
ln -s /var/log/qmail/smtpd main
cd /service/qmail-submission/log/
ln -s /var/log/qmail/submission main
cd /service/vpopmaild/log/
ln -s /var/log/qmail/vpopmaild main
Now set up a cronjob once a day (crontab -e):
59 2 * * * /usr/local/bin/convert-multilog 1> /dev/null
qmailctl script
As usual we will put the script in /usr/local/bin and give it the +x flag.
cd /usr/local/bin
wget http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/qmailctl
chmod +x qmailctl
The startup script below does the following:
-
Starts/stops the services
-
Calls tcprules to reload tcp.smtp.cdb and tcp.submission.cdb
-
Shows the status of the services and the queue
Note that it starts and stops vpopmaild also, and starts both normal SMTP on port 25, and the submission service on port 587, where SMTP authentication is required to perform outgoing relay for remote users. If you decide to disable the submission service, delete qmail-submission from the svclist variable on the 4th line below. In any event, be sure to review the service list to make sure it reflects the services you want to provide.
#!/bin/sh
# Put here the services you want to manage
svclist="qmail-send qmail-smtpd qmail-submission vpopmaild"
PATH=/var/qmail/bin:/bin:/usr/bin:/usr/local/bin:/usr/local/sbin
export PATH
QMAILDUID=`id -u qmaild`
NOFILESGID=`id -g qmaild`
case "$1" in
start)
echo "Starting qmail"
for svc in $svclist ; do
if svok /service/$svc ; then
svc -u /service/$svc
else
echo $svc service not running
fi
done
if [ -d /var/lock/subsys ]; then
touch /var/lock/subsys/qmail
fi
;;
stop)
echo "Stopping qmail..."
for svc in $svclist ; do
echo " $svc"
svc -d /service/$svc
done
if [ -f /var/lock/subsys/qmail ]; then
rm /var/lock/subsys/qmail
fi
;;
stat)
for svc in $svclist ; do
svstat /service/$svc
svstat /service/$svc/log
done
qmail-qstat
;;
doqueue|alrm|flush)
echo "Sending ALRM signal to qmail-send."
svc -a /service/qmail-send
;;
queue)
qmail-qstat
qmail-qread
;;
reload|hup)
echo "Sending HUP signal to qmail-send."
svc -h /service/qmail-send
;;
pause)
for svc in $svclist ; do
echo "Pausing $svc"
svc -p /service/$svc
done
;;
cont)
for svc in $svclist ; do
echo "Continuing $svc"
svc -c /service/$svc
done
;;
restart)
echo "Restarting qmail:"
for svc in $svclist ; do
if [ "$svc" != "qmail-send" ] ; then
echo "* Stopping $svc."
svc -d /service/$svc
fi
done
echo "* Sending qmail-send SIGTERM and restarting."
svc -t /service/qmail-send
for svc in $svclist ; do
if [ "$svc" != "qmail-send" ] ; then
echo "* Restarting $svc."
svc -u /service/$svc
fi
done
;;
cdb)
if ! grep '\#define POP_AUTH_OPEN_RELAY 1' ~vpopmail/include/config.h >/dev/null; then
(cd ~vpopmail/etc ; cat tcp.smtp | tcprules tcp.smtp.cdb tcp.smtp.tmp)
echo "Updated tcp.smtp.cdb."
(cd ~vpopmail/etc ; cat tcp.submission | tcprules tcp.submission.cdb tcp.submission.tmp)
echo "Updated tcp.submission.cdb."
else
~vpopmail/bin/clearopensmtp
echo "Ran clearopensmtp."
fi
;;
clear)
echo "Clearing readproctitle service errors with ................."
svc -o /service/clear
;;
kill)
echo "First stopping services ... "
for svc in $svclist ; do
if svok /service/$svc ; then
svc -d /service/$svc
svc -d /service/$svc/log
fi
done
echo "Now sending processes the kill signal ... "
killall -g svscanboot
echo "done"
;;
boot)
echo "Starting qmail"
/command/svscanboot &
;;
reboot)
echo "First stopping services ... "
for svc in $svclist ; do
if svok /service/$svc ; then
svc -d /service/$svc
svc -d /service/$svc/log
fi
done
echo "Now sending processes the kill signal ... "
killall -g svscanboot
echo "done"
echo "Starting qmail"
/command/svscanboot &
;;
help)
cat <<HELP
stop -- stops mail service (smtp connections refused, nothing goes out)
start -- starts mail service (smtp connection accepted, mail can go out)
pause -- temporarily stops mail service (connections accepted, nothing leaves)
cont -- continues paused mail service
stat -- displays status of mail service
cdb -- rebuild the tcpserver cdb file for smtp
restart -- stops and restarts smtp, sends qmail-send a TERM & restarts it
doqueue -- sends qmail-send ALRM, scheduling queued messages for delivery
reload -- sends qmail-send HUP, rereading locals and virtualdomains
queue -- shows status of queue
alrm -- same as doqueue
flush -- same as doqueue
hup -- same as reload
clear -- clears the readproctitle service errors with .....................
kill -- svc -d processes in svclist, then do 'killall -g svscanboot'
boot -- Boots qmail and all services in /service running /command/svscanboot
reboot -- kill & boot commands in sequence
HELP
;;
*)
echo "Usage: $0 {start|stop|restart|doqueue|flush|reload|stat|pause|cont|cdb|queue|clear|kill|boot|reboot|help}"
exit 1
;;
esac
exit 0
Usage
# qmailctl help
stop -- stops mail service (smtp connections refused, nothing goes out)
start -- starts mail service (smtp connection accepted, mail can go out)
pause -- temporarily stops mail service (connections accepted, nothing leaves)
cont -- continues paused mail service
stat -- displays status of mail service
cdb -- rebuild the tcpserver cdb file for smtp
restart -- stops and restarts smtp, sends qmail-send a TERM & restarts it
doqueue -- sends qmail-send ALRM, scheduling queued messages for delivery
reload -- sends qmail-send HUP, rereading locals and virtualdomains
queue -- shows status of queue
alrm -- same as doqueue
flush -- same as doqueue
hup -- same as reload
clear -- clears the readproctitle service errors with .....................
kill -- svc -d processes in svclist, then do 'killall -g svscanboot'
boot -- Boots qmail and all services in /service running /command/svscanboot
reboot -- kill & boot commands in sequence
qmailctl can be used to kill all qmail processes and to reboot the server. I use this option inside the rc.6 of my Slackware virtual server to avoid errors messages when stopping or rebooting the guest. You can easily call the clear service as well.
svtools
This is a nice collection of tools to manage daemontools
' services that you may want to consider. mlcat
is one of those; it can cat a service's log with human readable dates with a short command like:
mlcat qmail-smtpd
I slightly modified that script here, just to use it without the need of the "qmail-" prefix:
mlcat smtpd
Allowing selected clients to send outgoing messages
Create /home/vpopmail/etc/tcp.smtp and /home/vpopmail/etc/tcp.submission (the latter one in case you want to enable the submission service).
Enable outgoing relay in this way:
10.0.0.:allow,RELAYCLIENT=""
127.:allow,RELAYCLIENT=""
1.2.3.4:deny
:allow
Localhost and 10.0.0.0 subnet can use our MTA as an outgoing relay, 1.2.3.4 is denied, the other IPs can only send messages to the domains listed inside /var/qmail/control/rcpthosts.
tcp.smtp
0.0.0.0:allow,RELAYCLIENT=""
10.0.0.:allow,RELAYCLIENT=""
127.:allow,RELAYCLIENT=""
:allow,CHKUSER_WRONGRCPTLIMIT="3"
chkuser will ban clients' IP after 3 consecutive failures.
tcp.submission
:allow,CHKUSER_WRONGRCPTLIMIT="3"
Updating cdb files
qmailctl can invoke tcprules to create the cdb file in this way:
# qmailctl cdb
Updated tcp.smtp.cdb.
Updated tcp.submission.cdb.
You must run this command every time you modify tcp.smtp or tcp.submission.
Configuring the standard SMTP service on 25 in tcp.smtp ensures that only localhost and authorized IPs can use the SMTP service as an outgoing relay. We will accept inbound messages from outside as long as the recipient domain is included in the file /var/qmail/control/rcpthosts. When someone sends a message to a domain name not listed in rcpthosts, qmail will respond with “Sorry, that domain isn’t in my list of allowed rcpthosts (#5.7.1)”.
When you enable SMTP authentication on port 587, remote users who successfully authenticate will be allowed to send messages using our MTA.
Improved qmail-send log
I modified extra.h
in the source code (see the patch here) to record the Message-ID in the qmail-send
log as explained here towards the bottom of the page. Therefore an alias ~alias/.qmail-log
will be automatically added as well to store the awk
command with the regex which retrieves the Message-ID.
Be aware that you must have a valid MX record for your FQDN (look at /var/qmail/control/me
), otherwise you will get an error like this:
Sorry, No mailbox here #5.1.1
The qmail-send
log now appears as follows. Note that a copy of each mail is apparently sent to the address specified in the alias above.
2014-11-05 12:00:47.930384500 status: local 1/10 remote 1/20
2014-11-05 12:00:47.952694500 delivery 11: success: Received:_(qmail_17359_invoked_by_uid_89);_5_Nov_2014_12:00:47_+0100/Received:_(qmail_17359_invoked_by_uid_89);_5_Nov_2014_12:00:47_+0100/Received:_from_unknown_(HELO_mx.test.net)_(1.2.3.4)/Received:_from_unknown_(HELO_mx.test.net)_(1.2.3.4)/__by_0_with_ESMTPS_(DHE-RSA-AES256-GCM-SHA384_encrypted);_5_Nov_2014_12:00:47_+0100/Received:_(qmail_17349_invoked_by_uid_89);_5_Nov_2014_12:00:47_+0100/Received:_(qmail_17349_invoked_by_uid_89);_5_Nov_2014_12:00:47_+0100/Received:_from_unknown_(HELO_mail-wg0-f47.google.com)_(74.125.82.47)/Received:_from_unknown_(HELO_mail-wg0-f47.google.com)_(74.125.82.47)/__by_0_with_ESMTPS_(RC4-SHA_encrypted);_5_Nov_2014_12:00:46_+0100/Received:_by_mail-wg0-f47.google.com_with_SMTP_id_a1so597995wgh.6/Received:_by_mail-wg0-f47.google.com_with_SMTP_id_a1so597995wgh.6/Received:_by_mail-wg0-f47.google.com_with_SMTP_id_a1so597995wgh.6/________for_<info@test.net>;_Wed,_05_Nov_2014_03:00:48_-0800_(PST)/X-Received:_by_10.180.23.98_with_SMTP_id_l2mr4797959wif.51.1415185247978;_Wed,/X-Received:_by_10.180.23.98_with_SMTP_id_l2mr4797959wif.51.1415185247978;_Wed,/Received:_by_10.27.203.139_with_HTTP;_Wed,_5_Nov_2014_03:00:47_-0800_(PST)/Received:_by_10.27.203.139_with_HTTP;_Wed,_5_Nov_2014_03:00:47_-0800_(PST)/Date:_Wed,_5_Nov_2014_12:00:47_+0100/Message-ID:_<CAD=Xf-WdCFwED9DiMqRj=bUR5RsRA9mPah1OXgA-tB1ffk-3sw@mail.gmail.com>/Message-ID:_<CAD=Xf-WdCFwED9DiMqRj=bUR5RsRA9mPah1OXgA-tB1ffk-3sw@mail.gmail.com>/Subject:_dasda/From:_xxx_<someone@@gmail.com>/From:_xxx_<someone@gmail.com>/To:_info@test.net/---/did_0+0+2/
2014-11-05 12:00:47.952726500 status: local 0/10 remote 1/20
2014-11-05 12:00:48.326103500 delivery 12: success: 1.2.3.4_accepted_message./Remote_host_said:_250_ok_1415185248_qp_17366/