Configurazione di qmail

8 marzo 2024 by Roberto Puzzanghera 10 commenti

Changelog

  • Mar 8, 2024
    qmail-smtpd/run and qmail-smtpsd/run files: check if simscan is installed in order to run qmail also in that case
  • Feb 4, 2023
    rc file: the DKIM_ON variable was not evaluated correctly, so DKIM was always active. Fixed
    -if [ -r ${QMAILDIR}/control/filterargs ] && [ -n $DKIM_ON ]; then
    +if [ -r ${QMAILDIR}/control/filterargs ] && [ -n "$DKIM_ON" ]; then
  • Jan 21, 2024
    tcprules spostate su /var/qmail/control
  • Jan 15, 2024
    - the rc file has been updated, as the DKIM configuration has been changed
  • Dec 9, 2023
    - clear service spostato su qmail/supervise
  • Sep 14, 2023
    - simsizelimit control file defined
  • Jun 18, 2023
    - defined the variable QMAILDIR in all run script in order to manage installations of qmail in directories different from default /var/qmail
    - /home/vpopmail is now ~vpopmail in order to manage installations of vpopmail in directories different from default /home/vpopmail
    - defined the variable TCPRULES_DIR on top of all run scripts
  • Mar 2, 2023
    - vusaged moved to daemontools

Creazione dei file alias e control

QMAILDIR=/var/qmail
echo 3 > $QMAILDIR/control/spfbehavior
echo "| ~vpopmail/bin/vdelivermail '' delete" > $QMAILDIR/control/defaultdelivery
echo 200 > $QMAILDIR/control/concurrencyincoming
echo noreply > $QMAILDIR/control/bouncefrom
echo 20000000 > $QMAILDIR/control/databytes
echo 272800 > $QMAILDIR/control/queuelifetime
echo 30000000 > $QMAILDIR/control/softlimit
echo 100 > $QMAILDIR/control/maxrcpt
echo 2 > $QMAILDIR/control/brtlimit
echo 10000000 > /var/qmail/control/simsizelimit

cd /usr/local/src/netqmail-1.06
./config-fast smtp.mydomain.tld

L'ultimo comando riempie i file defaultdomain locals me plusdomain rcpthosts. smtp.yourdomain.tld sarà il nome della MTA e dovrà necessariamente avere un record MX valido.

  • defaultdomain quando si hanno diversi domini nello stesso server (definiti poi nel file virtualhost) questo è il dominio di default
  • locals i domini le cui spedizioni vengono effettuate nel presente server (qmail-send per mezzo del programma qmail-lspawn). I messaggi per gli altri domini sono gestiti dal programma qmail-rspawn e spediti ad altre MTA. I domini listati in locals non dovrebbero essere confusi con i domini virtuali (virtualdomains). Infatti, nel caso il dominio sia presente nel file locals, qmail-send non andrà ad aprire il file virtualdomains e si otterrà un errore di "no mailbox". Questo è il motivo per cui è sconsigliabile usare un dominio virtuale come nome della propria MTA.
  • me il nome del server. Questo è il nome a dominio che compare nel campo from quando si ricevono messaggi di sistema, ad esempio. E' anche il dominio usato nell'HELO (il saluto all'inizio della conversazione SMTP). Esso deve avere un record MX valido nel DNS e anche i record SPF e DKIM, come vedremo in seguito. Inoltre, me dovrebbe essere il dominio definito nel reverse DNS, dal momento che vi sono dei provider che bloccano connessione ove l'HELO domain non è associato all'indirizzo IP.
  • plusdomain qmail-inject aggiunge questo dominio a ogni host name che finisce con un segno "+"
  • rcpthost Domini per i quali accettiamo messaggi. Più tardi vedremo come chkuser rigetta le email per gli utenti non esistenti.
  • spfbehavior riguarda  la configurazione di SPF.
  • softlimit imposta il soft resource limits per qmail-smtpd
  • bouncefrom è lo username dell'account che invia i bounce. Similmente è possibile definire anche bouncefrom, il dominio che compare nel bounce, che però ha come default me.
  • databytes è il numero massimo di bytes in un messaggio (0=nessun limite).
  • queuelifetime sono il numero di secondi che un messaggio può trascorrere nella coda prima di essere definitivamente cancellato.
  • brtlimit è il limite massimo di destinatari non trovati consentito dopo il quale la connessione verrà chiusa (vedi la brtlimit patch).
  • maxrcpt imposta un limite al numero di destinatari di un messaggio (qmail-maxrcpt patch).
  • defaultdelivery è il file .qmail di default. Dice a qmail come recapitare il messaggio. Nel caso non si abbia ancora ben chiaro come funziona il delivery, è meglio leggere il capitolo sul relaying di Life with qmail e soprattutto il file README.vdelivermail che si trova nel pacchetto vpopmail, che spiega come sono usati i file .qmail.
  • simsizelimit definiamo in anticipo una variabile per simscan, che installeremo più tardi. Esso definisce le dimensioni massime in byte dei messaggi che simscan passerà a spamassassin.

E' possibile trovare una presentazione completa di tutti i file di configurazione sul libro Life with qmail qui http://www.lifewithqmail.org/lwq.html#configuration

Ora facciamo il setup dell'indirizzo email di amministrazione del server. Questo indirizzo riceverà le email per root, postmaster, e mailer-daemon.  Sositituire "postmaster@yourdomain.net" con l'indirizzo email dell'amministratore (postmaster):

cd $QMAILDIR/alias
echo "postmaster@mydomain.tld" > .qmail-postmaster
ln -s .qmail-postmaster .qmail-mailer-daemon
ln -s .qmail-postmaster .qmail-root
chmod 644 .qmail*

Impostazione delle cartelle log

Le cartelle log appartengono all'utente qmaill.nofiles e non dovrebbero essere accessibili a nessun altro.

mkdir -p /var/log/qmail

chown -R qmaill.nofiles /var/log/qmail
chgrp root /var/log/qmail
chmod -R og-wrx /var/log/qmail
chmod g+rx /var/log/qmail

Creazione degli script supervise

Scaricare gli startup scripts da qui e scompattarli

cd $QMAILDIR
wget https://notes.sagredo.eu/files/qmail/supervise.tar.gz 
tar xzf supervise.tar.gz
chown -R root:root rc supervise
rm supervise.tar.gz

Puoi vedere che ci sono l'eseguibile rc, che lo script di avvio qmail-start, e la cartella supervise:

rc
supervise/
|
|----qmail-smtpd/
|    |
|    |-----run
|    |-----log/
|          |
|          |---run
|
|----qmail-smtpsd/
|    |
|    |-----run
|    |-----log/
|          |
|          |---run/
|
|----qmail-submission/
|    |
|    |-----run
|    |-----log/
|          |
|          |---run
|
|----qmail-send/
|    |
|    |-----run
|    |-----log/
|          |
|          |---run
|
|----vpopmaild/
|    |
|    |-----run
|    |-----log/
|          |
|          |---run
|
|----vusaged/
     |
     |-----run
     |-----log/
           |
           |---run

Quando vengono creati dei link simbolici a una cartella supervise nella directory /service, il comando run ivi presente verrà eseguito all'avvio della macchina, quando il comando /command/svcscanboot viene lanciato

QMAILDIR=/var/qmail
ln -s $QMAILDIR/supervise/qmail-smtpd      /service
ln -s $QMAILDIR/supervise/qmail-smtpsd     /service
ln -s $QMAILDIR/supervise/qmail-submission /service
ln -s $QMAILDIR/supervise/qmail-send       /service
ln -s $QMAILDIR/supervise/vpopmaild        /service
ln -s $QMAILDIR/supervise/vusaged          /service
ln -s $QMAILDIR/supervise/clear            /service

Vediamo ora in dettaglio gli script che abbiamo appena scaricato. Molte righe sono ancora commentate, perchè riguardano delle funzionalità che attiveremo in seguito. Per il momento sono attive solo le funzionalità di base.

File qmail/rc

#!/bin/sh 

QMAILDIR=/var/qmail 

# Comment out DKIM_ON=1 to disable dkim sign at qmail-remote level 
# You have to define your variables in control/filterargs (DKIM page for more info)
# echo "*:remote:/var/qmail/bin/qmail-dkim:DKIMQUEUE=/bin/cat,DKIMSIGN=/var/qmail/control/domainkeys/%/default,DKIMSIGNOPTIONS=-z 2" > /var/qmail/control/filterargs

# DKIM_ON=1

if [ -r ${QMAILDIR}/control/filterargs ] &&​ [ -n "$DKIM_ON" ]; then 
  exec env - PATH="$QMAILDIR/bin:$PATH" \ 
  QMAILREMOTE=$QMAILDIR/bin/spawn-filter \ 
  qmail-start "`cat $QMAILDIR/control/defaultdelivery`" 
else 
  # Use this if you are signing at qmail-smtpd level or you don't want to sign at all 
  exec env - PATH="$QMAILDIR/bin:$PATH" \ 
  qmail-start "`cat $QMAILDIR/control/defaultdelivery`" 
fi

Per il momento ignorare le righe che riguardano la firma DKIM (anche nei run file successivi). Vedremo queste cose dopo. E' infatti possibile testare il server sin da subito anche con queste righe presenti.

File qmail/supervise/qmail-smtpd/run

#!/bin/sh

QMAILDIR=/var/qmail
QMAILDUID=`id -u vpopmail`
NOFILESGID=`id -g vpopmail`
MAXSMTPD=`cat $QMAILDIR/control/concurrencyincoming`
SOFTLIMIT=`cat $QMAILDIR/control/softlimit`
LOCAL=`head -1 $QMAILDIR/control/me`
TCPRULES_DIR=/var/qmail/control

#export REJECTNULLSENDERS=0
#export SMTPAUTH="!cram"

# qmail-spp plugins
#export ENABLE_SPP=1
#export HELO_DNS_CHECK=PLRIV

# enable greetdelay for qmail-smtpd
export SMTPD_GREETDELAY=20
export DROP_PRE_GREET=1

# greylisting
#export JGREYLIST_DIR="$QMAILDIR/jgreylist"
#export JGREYLIST_LOG_SMTP=1

# enable 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

# If simscan is not installed yet, do not assign QMAILQUEUE
# so that the installation works at the beginning stage as well
if [ -x $QMAILDIR/bin/simscan ]; then
  export QMAILQUEUE=$QMAILDIR/bin/surblqueue # executes surblfilter
  export SURBLQUEUE=$QMAILDIR/bin/simscan    # executes simscan after SURBL
  #export QMAILQUEUE=$QMAILDIR/bin/simscan # do not execute SURBL nor DKIM filtering

  #### qmail-dkim disabled => no dkim verification
  #### to have verification active export SURBLQUEUE=$QMAILDIR/bin/qmail-dkim. Othewise the following will be ignored
  #export SURBLQUEUE=$QMAILDIR/bin/qmail-dkim # executes qmail-dkim after surblfilter

  export DKIMQUEUE=$QMAILDIR/bin/simscan     # simscan is executed after qmail-dkim
fi

# DKIM verification. Use carefully
export DKIMVERIFY="FGHKLMNOQRTVWp"
# allow msg without "subject" in the h= list
export UNSIGNED_SUBJECT=1
# avoid verification of outgoing messages
export RELAYCLIENT_NODKIMVERIFY=1
################################################################################

# turn off TLS on port 25
#export DISABLETLS="1"

# require that authenticated user and 'mail from' are identical
export FORCEAUTHMAILFROM="1"

# rcptcheck-overlimit. Limits the number of emails sent by relayclients
if [ -x $QMAILDIR/bin/rcptcheck-overlimit.sh ]; then
  export RCPTCHECK=$QMAILDIR/bin/rcptcheck-overlimit.sh
  export RCPTCHECKRELAYCLIENT="1"
fi

# enable simscan debug
#export SIMSCAN_DEBUG=4
#export SIMSCAN_DEBUG_FILES=2

exec /usr/local/bin/softlimit -m "$SOFTLIMIT" \
    /usr/local/bin/tcpserver -v -R -l "$LOCAL" \
    -x $TCPRULES_DIR/tcp.smtp.cdb -c "$MAXSMTPD" \
    -u "$QMAILDUID" -g "$NOFILESGID" 0 25 \
    $QMAILDIR/bin/qmail-smtpd /bin/true 2>&1

Notare come il servizio smtpd standard (porta 25) non consente l'autenticazione.

Bisogna adattare alle proprie esigenze il "resource limit" (softlimit in bytes). Ogni sistema è diverso e ha requisiti differenti. Life with qmail suggerisce appena 2MB. Dovresti trovare il tuo valore giusto aumentando il softlimit a passi di  1MB, specialmente una volta che avrai caricato spamassassin, clamAV e simscan (il mail scanner).

Vedremo le caratteristiche di GREETDELAYDKIM in seguito.

File qmail/supervise/qmail-smtpd/log/run

#!/bin/sh

LOGUSER="qmaill"
LOGDIR="/var/log/qmail/smtpd"
LOGDIRQLOG="/var/log/qmail/smtpd/qlog"

if [ -x /usr/local/bin/archive_qmail_qlog ]; then
  exec /usr/local/bin/setuidgid $LOGUSER /usr/local/bin/multilog t n5 s16777215 $LOGDIR \
  	n5 s16777215 '-*' '+*qlog*' !/usr/local/bin/archive_qmail_qlog $LOGDIRQLOG
else
  exec /usr/local/bin/setuidgid qmaill /usr/local/bin/multilog t s16777215 /var/log/qmail/smtpd
fi

Se si vuole salvare separatamente una copia delle righe di "qlogenvelope"

@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

ad esempio nella cartella /var/log/qmail/smtpd/qlog, è necessario creare il file archive_qmail_qlog

cat > /usr/local/bin/archive_qmail_qlog << __EOF__
#!/bin/sh
tai64nlocal >> /var/log/qmail/smtpd/qlog/qmail-smtpd.log
__EOF__
chmod +x /usr/local/bin/archive_qmail_qlog

In questo modo abbiamo il file /var/log/qmail/smtpd/qmail-smtpd.log con le sole righe di qlog e con l'ora scritta in modo leggibile:

2016-01-29 13:15:17.677946500 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
2016-01-29 13:15:17.677946500 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

Dopodichè si potrebbe settare un logrotate. ulla mia Slackware ho un file /etc/logrotate.d/qlog del genere:

cat > /etc/logrotate.d/qlog << __EOF__
/var/log/qmail/smtpd/qlog/qmail-smtpd.log /var/log/qmail/smtpd/qlog/qmail-smtpsd.log {
missingok
notifempty
delaycompress
rotate 50
daily
minsize 2M
create 0644 qmaill root
}
<< __EOF__

File /var/qmail/supervise/qmail-smtpsd/run

#!/bin/sh

QMAILDIR=/var/qmail
QMAILDUID=`id -u vpopmail`
NOFILESGID=`id -g vpopmail`
MAXSMTPD=`cat $QMAILDIR/control/concurrencyincoming`
SOFTLIMIT=`cat $QMAILDIR/control/softlimit`
LOCAL=`head -1 $QMAILDIR/control/me`
TCPRULES_DIR=/var/qmail/control

SSL_DIR="$QMAILDIR/control"
SSL_CHROOT="$SSL_DIR"
SSL_UID=$QMAILDUID
SSL_GID=$NOFILESGID
CERTFILE="$SSL_DIR/servercert.pem"
KEYFILE="$SSL_DIR/servercert.pem"
DHFILE="$SSL_DIR/dh4096.pem"
export SSL_UID SSL_GID SSL_CHROOT
export CERTFILE KEYFILE DHFILE

#export REJECTNULLSENDERS=1
#export SMTPAUTH="!cram"

# qmail-spp plugins
#export ENABLE_SPP=1
#export HELO_DNS_CHECK=PLRIV

# This enables greetdelay for qmail-smtpd
export SMTPD_GREETDELAY=20
export DROP_PRE_GREET=1

# greylisting
#export JGREYLIST_DIR="$QMAILDIR/jgreylist"
#export JGREYLIST_LOG_SMTP=1

# enable 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

# If simscan is not installed yet, do not assign QMAILQUEUE
# so that the installation works at the beginning stage as well
if [ -x $QMAILDIR/bin/simscan ]; then
  export QMAILQUEUE=$QMAILDIR/bin/surblqueue # executes surblfilter
  export SURBLQUEUE=$QMAILDIR/bin/simscan    # executes simscan after SURBL
  #export QMAILQUEUE=$QMAILDIR/bin/simscan # do not execute SURBL nor DKIM filtering

  #### qmail-dkim disabled => no dkim verification
  #### to have verification active export SURBLQUEUE=$QMAILDIR/bin/qmail-dkim. Othewise the following will be ignored
  #export SURBLQUEUE=$QMAILDIR/bin/qmail-dkim # executes qmail-dkim after surblfilter

  export DKIMQUEUE=$QMAILDIR/bin/simscan     # simscan is executed after qmail-dkim
fi

# DKIM verification. Use carefully
export DKIMVERIFY="FGHKLMNOQRTVWp"
# allow msg without "subject" in the h= list
export UNSIGNED_SUBJECT=1
# avoid verification of outgoing messages
export RELAYCLIENT_NODKIMVERIFY=1
################################################################################


# turn off TLS on port 25
#export DISABLETLS="1"

# require that authenticated user and 'mail from' are identical
export FORCEAUTHMAILFROM="1"

# rcptcheck-overlimit. Limits the number of emails sent by relayclients
if [ -x $QMAILDIR/bin/rcptcheck-overlimit.sh ]; then
  export RCPTCHECK=$QMAILDIR/bin/rcptcheck-overlimit.sh
  export RCPTCHECKRELAYCLIENT="1"
fi

# enable simscan debug
#export SIMSCAN_DEBUG=4
#export SIMSCAN_DEBUG_FILES=2

exec /usr/local/bin/softlimit -m "$SOFTLIMIT" \
    /usr/local/bin/sslserver -seV -Rp -l "$LOCAL" \
    -Xx $TCPRULES_DIR/tcp.smtp.cdb -c "$MAXSMTPD" \
    -u "$QMAILDUID" -g "$NOFILESGID" 0 smtps \
    $QMAILDIR/bin/qmail-smtpd /bin/true 2>&1

File qmail/supervise/qmail-smtpsd/log/run

#!/bin/sh

LOGUSER="qmaill"
LOGDIR="/var/log/qmail/smtpsd"
LOGDIRQLOG="/var/log/qmail/smtpsd/qlog"

if [ -x /usr/local/bin/archive_qmail_qlog ]; then
  exec /usr/local/bin/setuidgid $LOGUSER /usr/local/bin/multilog t n5 s16777215 $LOGDIR \
  	n5 s16777215 '-*' '+*qlog*' !/usr/local/bin/archive_qmail_qlog $LOGDIRQLOG
else
  exec /usr/local/bin/setuidgid qmaill /usr/local/bin/multilog t s16777215 /var/log/qmail/smtpsd
fi

File qmail/supervise/qmail-submission/run

Questo servizio fa sì che la nostra MTA possa agire anche da outgoing relay (la posta può essere anche inviata quando ci connette da un IP remoto che imposta il suo smtp server sulla nostra MTA), a condizione che l'utente si identifichi (in connessione sicura criptata con  TLS!).

#!/bin/sh

QMAILDIR=/var/qmail
QMAILDUID=`id -u vpopmail`
NOFILESGID=`id -g vpopmail`
MAXSMTPD=`cat $QMAILDIR/control/concurrencyincoming`
SOFTLIMIT=`cat $QMAILDIR/control/softlimit`
LOCAL=`head -1 $QMAILDIR/control/me`
TCPRULES_DIR=/var/qmail/control

# 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.
export SMTPD_GREETDELAY=3
export DROP_PRE_GREET=1

# This enables chkuser
export CHKUSER_START=ALWAYS

# This makes qmail to allow connections without TLS (default 1)
#export FORCETLS=0

# This turns off TLS on port 587 (default 0)
#export DISABLETLS=1

# Requires that authenticated user and 'mail from' are identical (default 0)
export FORCEAUTHMAILFROM=1

# rcptcheck-overlimit. Limits the number of emails sent by relayclients
#export RCPTCHECK=$QMAILDIR/bin/rcptcheck-overlimit.sh
#export RCPTCHECKRELAYCLIENT=1

exec /usr/local/bin/softlimit -m "$SOFTLIMIT" \
    /usr/local/bin/tcpserver -v -R -l "$LOCAL" \
    -x $TCPRULES_DIR/tcp.submission.cdb -c "$MAXSMTPD" \
    -u "$QMAILDUID" -g "$NOFILESGID" 0 587 \
    $QMAILDIR/bin/qmail-smtpd \
    ~vpopmail/bin/vchkpw /bin/true 2>&1

Notare l'uso vchkpw in unione con qmail-smtpd per assicurare che l'utente si identifichi. La connessione richiede che TLS sia abilitato. Questa è ragione per la quale abbiamo aperto una porta apposita 587: per consentire anche agli utenti remoti di usare la nostra MTA come un relay.

La variabile SMTPAUTH è relativa alla patch per l'autenticazione. Sei invitato a leggere il file README.auth per ulteriori dettagli.

Vedremo le caratteristiche di GREETDELAY in seguito.

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/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/vpopmaild/run

#!/bin/sh
QMAILDUID=`id -u root`
NOFILESGID=`id -g root`
VPOPMAILID=`id -g vpopmail`

exec /usr/local/bin/softlimit -m 30000000 \
    /usr/local/bin/tcpserver -v -H -R -l 0 \
    -u $QMAILDUID -g $NOFILESGID 0 $VPOPMAILID \
    ~vpopmail/bin/vpopmaild 2>&1

vpopmaild è importante quando ci si connette a vpopmail attraverso la webmail per cambiare la password, ad esempio.

File qmail/supervise/vpopmaild/log/run

#!/bin/sh
exec /usr/local/bin/setuidgid qmaill /usr/local/bin/multilog t /var/log/qmail/vpopmaild

File qmail/supervise/vusaged/run

#!/bin/sh
exec ~vpopmail/bin/vusaged 2>&1

File qmail/supervise/vusaged/log/run

#!/bin/sh
exec setuidgid qmaill /usr/local/bin/multilog t /var/log/qmail/vusaged

cronjobs

Per ruotare i log file di qmail useremo lo script convert-multilog di John Simpson (un grazie all'autore e a Marc per il suggerimento), che ne descrive così il funzionamento:

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.

In sostanza i file vengono archiviati con un file separato per data, ad esempio

-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

all'interno dei quali la data è convertita dal timestamp al formato normale, ad esempio

2014-08-23 00:31:49.503947500 tcpserver: status: 1/20

Questo facilita molto eventuali ricerche future.

Installare come segue:

mkdir -p /var/log/qmail/backup
wget -O /usr/local/bin/convert-multilog https://notes.sagredo.eu/files/qmail/convert-multilog
chmod +x /usr/local/bin/convert-multilog

ln -s /var/log/qmail/send /service/qmail-send/log/main 
ln -s /var/log/qmail/smtpd /service/qmail-smtpd/log/main 
ln -s /var/log/qmail/smtpsd /service/qmail-smtpsd/log/main
ln -s /var/log/qmail/submission /service/qmail-submission/log/main

Ora impostare un cronjob una volta al giorno (crontab -e):

59 2 * * * /usr/local/bin/convert-multilog 1> /dev/null

Dal momento che vogliamo convertire il log in formato leggibile una volta al giorno è necessario ruotarlo su base giornaliera. Perciò è necessario aggiungere qualcosa come questo al nostro crontab:

0 0 * * * /usr/local/bin/svc -a /service/qmail-submission/log
0 0 * * * /usr/local/bin/svc -a /service/qmail-smtpd/log
0 0 * * * /usr/local/bin/svc -a /service/qmail-send/log
0 0 * * * /usr/local/bin/svc -a /service/vpopmaild/log

qmailctl script

wget -O /usr/local/bin/qmailctl https://notes.sagredo.eu/files/qmail/qmailctl
chmod +x qmailctl

Lo script qui sotto avvia e arresta i servizi, chiama tcprules per ricaricare tcp.smtp.cdb e tcp.submission.cdb, mostra lo stato dei servizi e della coda (queue). Notare come esso avvii e arresti pure vpopmaild, e avvii sia il normale servizio smtpd sulla porta 25 che il servizio submission sulla porta 587. In ogni caso i servizi da avviare con questo script vanno indicati nella quarta riga.

#!/bin/bash
#
# tx Sam Tang
#
# May 25, 2022
# a few modifications by Roberto Puzzanghera to avoid error strings in the service uptime when service is stopped
#
# Aug 07, 2022
# now the script exits if services are not started with svscanboot or the supervise script is missing
#

# Put here the services you want to manage
svclist="qmail-smtpd qmail-smtpsd qmail-submission qmail-send vpopmaild vusaged"
# Put here the services want monitoring
servicelist="dovecot clamd freshclam spamd httpd solr mariadb fail2ban"

QMAILDIR=/var/qmail
TCPRULES_DIR=/var/qmail/control
QMAILDUID=`id -u qmaild`
NOFILESGID=`id -g qmaild`

PATH=$QMAILDIR/bin:/bin:/usr/bin:/usr/local/bin:/usr/local/sbin
export PATH

function show_uptime() {
	re='^[0-9]+$'
	org="$(svstat /service/$1 | awk '{print $2,$3,$4;}' | sed 's/up/[ up ]/g' | sed 's/down/[ down ]/g' | sed ''/up/s//`printf "\033[1\;32mup\033[0m"`/'' | sed ''/down/s//`printf "\033[1\;31mdown\033[0m"`/'')"
	sec="$(svstat /service/$1 | awk '{print $5;}')"
	if ! [[ $sec =~ $re ]]; then
		sec="$(svstat /service/$1 | awk '{print $3;}')"
    fi
	d=$(( $sec / 86400))
	h=$(( $(($sec - $d * 86400)) / 3600 ))
	m=$(( $(($sec -d * 86400 - $h * 3600)) / 60 ))
	s=$(($sec -d * 86400 - $h * 3600 - $m * 60))

	if [ $sec -le 60 ]; then
		if [[ "$(svstat /service/qmail-smtpd | awk '{print $2}')" = 'down' ]]; then
			printf "%-22s %s %s %s %s %s\n" "$1:" $org
		else
			printf "%-22s %s %s %s %s %s %s seconds\n" "$1:" $org $s
		fi
	else
		printf "%-22s %s %s %s %s %s %3s day(s), %02d:%02d:%02d\n" "$1:" $org $d $h $m $s
	fi
}

# check if qmail has been sttarted at boot time
function svscan_check() {
	if ! pgrep -x "svscanboot" > /dev/null; then
		echo "/command/svscanboot not running. Please stat qmail running:"
		echo "qmailctl boot"
		echo "or"
		echo "/command/svscanboot"
		exit 1
	fi
}

case "$1" in
  start)
    svscan_check
    echo "Starting qmail"

    for svc in $svclist ; do
	if [ ! -x /service/$svc ]; then
	  echo $svc service script not found
    	elif 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)
    svscan_check
    echo "Stopping qmail..."
    for svc in $svclist ; do
      if [ ! -x /service/$svc ]; then
        echo $svc service script not found
      else
      	echo " $svc"
      	svc -d /service/$svc
      fi
    done
    if [ -f /var/lock/subsys/qmail ]; then
    rm /var/lock/subsys/qmail
    fi
    ;;
  stat)
    svscan_check
    for svc in $svclist ; do
      if [ ! -x /service/$svc ]; then
	echo $svc service script not found
      else
        show_uptime $svc
        show_uptime "$svc/log"
      fi
    done
    echo ""
    for service in $servicelist ; do
      printf "%-22s " "$service status:"
      if (( $(ps -ef | grep -v grep | grep $service | wc -l) > 0 ))
      then
          echo -e "[ \033[1;32mup\033[m ]"
      else
          echo -e "[ \033[1;31mdown\033[m ]"
      fi
    done
    if [ -f $QMAILDIR/control/simversions.cdb ]; then
    	printf "\nClamAV database updated at: "
	stat --printf=%y $QMAILDIR/control/simversions.cdb | cut -d. -f1
    fi
    if [ -f $QMAILDIR/users/assign ]; then
	printf "Total Domains: "
	wc -l < $QMAILDIR/users/assign
    fi
    echo ""
    qmail-qstat
    ;;
  doqueue|alrm|flush)
	svscan_check
    echo "Sending ALRM signal to qmail-send."
    svc -a /service/qmail-send
    ;;
  queue)
    svscan_check
    qmail-qstat
    qmail-qread
    ;;
  reload|hup)
    svscan_check
    echo "Sending HUP signal to qmail-send."
    svc -h /service/qmail-send
    ;;
  pause)
    svscan_check
    for svc in $svclist ; do
      echo "Pausing $svc"
      svc -p /service/$svc
    done
    ;;
  cont)
    svscan_check
    for svc in $svclist ; do
      echo "Continuing $svc"
      svc -c /service/$svc
    done
    ;;
  restart)
    svscan_check
    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 $TCPRULES_DIR ; cat tcp.smtp | tcprules tcp.smtp.cdb tcp.smtp.tmp)
      echo "Updated tcp.smtp.cdb."
      (cd $TCPRULES_DIR ; cat tcp.submission | tcprules tcp.submission.cdb tcp.submission.tmp)
      echo "Updated tcp.submission.cdb."
    else
      ~vpopmail/bin/clearopensmtp
      echo "Ran clearopensmtp."
    fi
    ;;
  clear)
    svscan_check
    echo "Clearing readproctitle service errors with ................."
    svc -o /service/clear
    ;;
  kill)
    svscan_check
    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)
    $0 kill
    sleep 5
    $0 boot
    ;;
  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

Modalità di utilizzo

# 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 può anche essere usato per uccidere (kill) tutti i processidi qmail e per fare un reboot del server. Personalmente uso questa opzione dentro il file rc.6 del mio server virtuale Slackware per evitare messaggi di errore quando arresto o riavvio il server virtuale.

Si può anche chiamare il servizio clear.

svtools

Questa è una interessante collezione di script per gestire i servizi di qmail che val la pena installare.  In particolare è molto utile mlcat che senza nessuna fatica consente di visualizzare il log associato a un dato servizio di daemontool con un comando come:

mlcat qmail-smtpd

L'ho leggermente modificato (link) per evitare di digitare sempre il prefisso "qmail-" davanti al nome del servizio:

mlcat smtpd

Installazione

cd /usr/local/src
wget https://github.com/kayahr/svtools/archive/master.zip
unzip master.zip
cd svtools-master
make
make install
mkdir /etc/sv /var/log/sv
chown root.root /etc/sv /var/log/sv
cd /usr/local/bin
rm mlcat
wget https://notes.sagredo.eu/files/qmail/mlcat
chmod +x mlcat

Compilare le tcprules

Se non lo si è già fatto lanciare qmailctl per compilare le tcprules e creare i file cdb:

> qmailctl cdb
Updated tcp.smtp.cdb.
Updated tcp.submission.cdb.

E' necessario lanciare questo comando ogni qual volta si attuano delle modifiche al file tcp.smtp o tcp.submission. Non è necessario riavviare qmail.

Lanciare qmail all'avvio

Il comando /command/svcscanboot è già stato inserito nel file /etc/inittab al momento dell'installazione di daemontools. Nei sistemi basati su systemd abbiamo invece installato un apposito servizio per l'avvio automatico di daemontools, come spiegato qui.

Commenti

Messaggio nei log

Salve Roberto,
non riesco a capire questo messaggio nei log /var/log/qmail/smtpd/current, l'ip anonimizzato è il mio

May 17 12:53:38 2021 qmail-smtpd: read failed (hang up before quit cmd): (null) from 109..xxx.xxx.xxx to (null) helo 161.xxx.xxx.xxx.cust.ip.xxxxxxxxxxxx.it

Grazie

Gabriele

Rispondi |

Messaggio nei log

Credo che significhi che il client abbia chiuso la conversazione prima del comando quit del server. Il messaggio di errore esplicito l'avevo aggiunto io tempo fa al posto di un generico "read failed", ma non ricordo più molto... In ogni caso il messaggio viene correttamente ricevuto

Rispondi |

Messaggio nei log

Grazie del chiarimento.

A presto

G

Rispondi |

Received-SPF: unknown (0: Multiple SPF records returned)

Buongiorno Roberto,

Per bloccare le mail in ingresso con Received-SPF: unknown (0: Multiple SPF records returned) come devo modifcare i file della patch qmail-SPF.

Grazie mille

Rispondi |

Received-SPF: unknown (0: Multiple SPF records returned)

da quello che vedo nella patch lo stato di unknown viene lasciato passare sempre quando spfbehaviour<6... un po' brutto effettivamente. Occorrerebbe in effetti metterci le mani, avendo tempo :-)

Rispondi |

Cambio dominio di default

Buongiorno Roberto, in un server in produzione dovrei cambiare il dominio di default, quello che si imposta con ./config-fast yourdomain.net per intenderci. Se cambio tutte le ricorrenze del vecchio dominio nei vari file in qmail/control e riavvio qmail continua a funzionare tutto?

Grazie

Gabriele

Rispondi |

Cambio dominio di default

si, non mi viene in mente nessun effetto collaterale, ed io l'ho fatto più di una volta... per esempio quando installo un nuovo server clono un virtual server in produzione e poi faccio un config-fast

Rispondi |

impostazione bouncefrom

Ciao Roberto, c'è l'impostazione del bouncefrom che se settata come da te indicata, echo postmaster@yourdomain.net > /var/qmail/control/bouncefrom, mi genera le mail di mailer-daemon con mittente postmaster@yourdomain.net"@yourdomain.net".

Ho cambiato in echo postmaster > /var/qmail/control/bouncefrom, è ugualmente corretto?

Grazie ancora

Rispondi |

impostazione bouncefrom

Mi sa che hai ragione... hai fatto un test con la nuova impostazione?

Rispondi |

impostazione bouncefrom

Grazie della risposta.

Si con la nuova impostazione.

Grazie

Rispondi |