Abilitare le mail di Cron in ArchLinux (ed altro)

Crone Anacron sono due servizi che si occupano di eseguire dei comandi a scadenza periodica. Vengono usati specialmente per lanciare script di manutenzione, i quali possono comunicare eventuali errori ed avvisi.

Ad esempio: directory e file di sistema impostati con proprietario o permessi sbagliati, file mancanti, eventuali rootkit trovati, incoerenze fra /etc/passwd e /etc/shadow.
ArchLinux non ha impostazioni predefinite. Viene assemblata pezzo per pezzo dall'utente sin dal momento della prima installazione. Una scelta intenzionale, per lasciare l'utente libero di conoscere e controllare il sistema che utilizzerà quotidianamente, dipendendo il meno possibile dalle scelte predefinite imposte dai manutentori della distribuzione. Si preferisce fornire un'ottima documentazione mantenuta dalla comunità, ad una serie di automatismi che deresponsabilizzino l'utente e non migliorano granché le sue conoscenze.

Installare e configurare il MTA

Nel nostro caso, significa che dev'essere l'utente stesso a scegliere se installare e configurare un sistema detto MTA (Mail Transfer Agent), fra i molti disponibili, che permetta a Cron e Anacron di comunicare gli avvisi. Ho scelto esmtp per via della sua leggerezza e della semplicità d'installazione. Il programma non viene più aggiornato dal 2009, ma è ancora presente e regolarmente verificato e patchato nei repository ufficiali di Arch, quindi lo considero sufficientemente valido ed affidabile.

Per la consegna della posta abbiamo due possibilità: inviarla ad una casella email esterna - un nostro indirizzo che utilizziamo abitualmente - oppure consegnarla direttamente in locale. Personalmente preferisco la seconda soluzione.

Installiamo i pacchetti necessari con pacman -S esmtp procmail. Dopodiché creiamo il file /etc/esmtprc contenente queste due semplici righe.

mda '/usr/bin/formail -a "Date: `date -R`" | /usr/bin/procmail -d%T'
force_mda="utente

La prima riga imposta il comando del Mail Delivery Agent, cioè il programma che si occupa della consegna della posta in locale. Nel nostro caso utilizziamo procmail. Dato che altrimenti non verrebbe inserita nell'email la data di invio, ed a noi fa comodo per poter ordinare correttamente i messaggi che ci arriveranno, la facciamo aggiungere utilizzando il comando formail (mail re-formatter, che fa parte del pacchetto di procmail) e passiamo il risultato, tramite pipe, a procmail.
La seconda riga dice di forzare la consegna di qualsiasi email locale all'utente specificato, che sarà l'utente che si occupa della manutenzione del sistema, cioè noi.

Tutte le comunicazioni andranno nel file /var/spool/mail/utente invece che in /var/spool/mail/root, permettendoci di leggerle più comodamente. Il file creato è una casella di tipo mbox, utilizzabile da qualsiasi programma di posta elettronica.

Possiamo fare un veloce test creando un semplice file di testo ed inviandolo tramite il comando: sendmail root < messaggio.txt. Se andrete a leggere il file /var/spool/mail/utente (non root, bensì l'utente specificato in esmtprc), troverete il messaggio appena inviato.

Ora potete anche configurare la crontab dell'utente (quindi tornate ad esso, se stavate lavorando con root), con il comando crontab -e ed aggiungendovi in cima la riga MAILTO=utente.

MAILTO=utente
*/10 * * * * /usr/bin/getmail -q -rgetmailrc.account1 -rgetmailrc.account2

Da questo momento in poi, qualsiasi comunicazione di Cron, Anacron od eventuali altri demoni impostati per inviare email a root, vi verrà consegnata localmente.

Possiamo sfruttare questo per fare altre cose utili.

Controllo giornaliero degli aggiornamenti

Creiamo uno script che controlli se ci sono aggiornamenti per i pacchetti ufficiali, oppure installati da AUR, ed invii l'eventuale lista al nostro utente.

#!/bin/sh
pacman -Sy > /dev/null
pacupd=$(pacman -Qu)
[[ -f /usr/bin/cower ]] && aurupd=$(cower -u)
[[ $pacupd ]] && text="Arch packages to be updated\n${pacupd}\n"
[[ $aurupd ]] && text="${text}AUR packaged to be updated\n${aurupd}"
[[ $text ]] && echo -ne "${text}" | mail -s "Updates for $HOSTNAME $(date +%F)" root
exit 0

Il mio script utilizza pacman per controllare gli aggiornamenti ufficiali e cower per quelli dei repository utente (AUR). Se uno qualsiasi dei due ha dato risultati, allora viene composta un email con l'elenco dei pacchetti aggiornabili, ed inviata a root (che verrà poi consegnata all'utente). Se utilizzate yaourt o altri programmi per gestire AUR, adattate lo script alle vostre esigente.

Salvatelo in /etc/cron.daily e dategli proprietario root:root ed il permesso di esecuzione.

# cp archupdates /etc/cron.daily/
# cd /etc/cron.daily/
# chown 0.0 archupdates
# chmod 744 archupdates

Se preferite che il controllo venga fatto settimanalmente o mensilmente, mettete lo script rispettivamente in cron.weekly o cron.monthly.

Utilizzare esmtp per l'invio di email all'esterno

Avere un MTA locale con una propria coda di invio può avere dei vantaggi. Ad esempio, è possibile usarlo per velocizzare l'invio della posta da proprio client email preferito. Il programma, invece di rimanere occupato durante tutto l'invio delle vostre email al server SMTP esterno, le passerà localmente al vostro MTA, il quale le metterà in coda e si occuperà di consegnarle al server SMTP esterno, tenendo impegnato il programma di posta elettronica per molto meno tempo.

Per fare questo, bisogna creare una configurazione utente di esmtp, cioè un file nella propria home chiamato .esmtprc.

identity mioindirizzo1@dominio1.net
       hostname smtp.dominio1.net:25
       username "mioutenteemail
       password "miapasswordemail
       starttls enabled
       default

identity mioindirizzo2@dominio2.org
       hostname smtp.dominio2.org:25

mda '/usr/bin/formail -a "Date: `date -R`" | /usr/bin/procmail -d%T'

Questo è un esempio con due identità. La prima è quella predefinita, cioè quella utilizzata nel caso si richiami il comando sendmail per l'invio verso l'esterno di un messaggio, senza specificare il mittente tramite l'opzione -f.
Come nella configurazione di sistema, la riga con mda indica che tutta la posta locale, cioè verso utenti della macchina, quindi privi del @dominio.do, deve passare per procmail. Quest'ultimo è il caso di quando si usa una crontab dal proprio utente. Senza questo, esmtp cercherebbe di inviare all'esterno anche le email locali.

Il programma di posta elettronica va configurato per inviare la posta in uscita tramite sendmail. Io utilizzo mutt e per inviare tramite MTA ho dovuto aggiungere due righe alle configurazioni dei miei account:

set use_envelope_from = yes
set sendmail          = "/usr/bin/esmtp

La prima dice di passare il mittente, precedentemente specificato con set from = "mioindirizzo1@dominio1.net' a sendmail. La seconda fornisce il comando, compatibile con la sintassi di sendmail, da usare.
Come gestire più identità con mutt, è un argomento che magari tratterò in futuro.

Come far consegnare la posta di sistema nella propria maildir

Scarico abitualmente la posta tramite POP3, salvandola tutta in locale all'interno di diverse maildir. Utilizzo il programma getmail, abbinato a procmail per poter smistare e filtrare i messaggi in arrivo. Dopodiché leggo le mail salvate in locale tramite mutt.
Al contrario del formato mbox, nella maildir ogni messaggio è un singolo file. È un sistema più sicuro e comodo di mbox, dato che l'eventuale corruzione di un file, va ad intaccare solo quel messaggio, inoltre non richiede periodiche compattazioni per recuperare lo spazio lasciato occupato dai messaggi cancellati.

Procmail è un programma molto potente e versatile, consiglio la lettura del manuale o della Wiki di Arch per un approfondimento. Qua mi limiterò a riportare un esempio di configurazione.

La configurazione utente si fa creando un file .procmailrc nella propria home.

MAILDIR=$HOME/maildir
DEFAULT=$MAILDIR/INBOX/
LOGFILE=/dev/null
SPR=9876543210

:0:
* $ $SPR^0 ^To.*(root|cron)
* $ $SPR^0 ^From.*Cron\ Daemon
admin/

:0
* ^X-Spam-Flag: YES
{
    :0 c #copia le mail di spam in spam
    spam
    :0 ai #marcale com lette
    * LASTFOLDER ?? ()\/[^/]+^^
    |mv "$LASTFOLDER" "$MAILDIR/spam/cur/$MATCH:2,S"
}

:0:
* ^From.*info@miabanca
banca/

:0:
* $ $SPR^0 ^From.*(notifications@github|bugs@archlinux|notify@aur\.archlinux)
temp/

links

social