====== System Filters in Exim ======
Il system filter e` un filtro (un file con delle regole) che viene applicato a TUTTE le email in transito. Puo` essere utile per elaborare le email in tempo reale, ad esempio per fare un backup delle email in transito sul server.
==== Configurazione di un System Filter ====
Per abilitare un system filter occorre inserire nella configurazione di Exim una riga che indica il nome del file contenente il system filter, cosi`:
system_filter = /etc/exim4/system_filter
system_filter_user = mail
system_filter_group = mail
system_filter_file_transport = address_file
Notate che vi sono diverse opzioni in Exim che rigurdano il system filter. Per esempio qui ho impostato l'utente e il gruppo che verranno usati dal system filter quando dovesse fare operazioni sul file system, e ho indicato un trasporto da usare sempre allo scopo di salvare email su file. Non sempre e` necessario specificare informazioni aggiuntive come queste, dipende da quali comandi vogliamo poter usare nel system filter. Siccome in questo caso voglio poter scrivere su disco, mi serve specificare queste impostazioni.
===== Uso di un system filter per fare il backup delle email =====
Questo semplice system filter fa un backup delle email in uscita dal sistema. Le email in entrata vengono backuppate usando uno shadow transport. Vediamo i pezzi di configurazione coinvolti, facendo sempre riferimento alla mia configurazione "di base" di Exim.
In Exim4.conf:
* Abilitare il system filter come indicato sopra
* Impostare il nome del file che se presente blocca il delivery delle email. Questo serve se si vuole usare lo script di backup per targzippare i files delle email.
queue_only_file = /etc/exim4/queue_only
* Impostare una variabile che identifichi tutte le email che escono dal nostro server verso l'esterno. Inserire queste due sezioni subito prima dell' "accept" alla fine del blocco "acl_check_contents"
# Queste ACL hanno lo scopo di verificare se il mittente del messaggio
# e` un utente locale, per poter poi dire al system filter che si occupa
# del backup delle mail spedite di trattare questa mail come "spedita da noi".
# Qui verifico se il mittente e` un host della LAN a cui e` consentito il relay, e se
# il sender e` fra i nostri domini locali. Se le condizioni sono vere, setto la variabile
# acl_m9 che poi testero` nel system filter dopo.
warn
sender_domains = +local_domains
hosts = +relay_from_hosts
set acl_m9 = 1
# Come sopra, pero` il test e` se il sender e` autenticato e se e` fra i nostri domini locali.
warn
sender_domains = +local_domains
authenticated = *
set acl_m9 = 1
* Aggiungere uno shadow transport al trasporto che salva le mail in INGRESSO (il system filter si occupa solo di quelle in USCITA). Per farlo, occorre:
* Creare un trasporto sotto la sezione "transports", che chiameremo "local_backup":
# Trasporto per il backup delle mail ricevute.
# Viene usato dagli altri trasporti come shadow_transport
local_backup:
driver = appendfile
directory_mode = 0700
mode = 0600
create_directory = true
file = /var/mail_backups/incoming/${domain}/${local_part}
group = mail
user = mail
delivery_date_add
envelope_to_add
return_path_add
* Aggiungere una riga ad ogni trasporto della mail in ingresso, in modo da invocare lo shadow transport che abbiamo appena creato. La seguente riga e` stata aggiunta a questi trasporti: ''address_directory, virtual_user_delivery, virtual_user_spam_delivery''
# Shadow per il backup
shadow_transport = local_backup
Dopo aver modificato exim4.conf, occorre creare il file ''/etc/exim4/system_filter'' contenente le regole per eseguire il backup delle mail in uscita:
# System Filter per salvare la mail in uscita nella directory di backup
# se e` un errore, non salvare nulla e procedi
if error_message then finish endif
# se non e` il primo delivery, e` gia stata salvata al primo delivery,
# non salvare nulla e procedi
if not first_delivery then finish endif
# se e` settata la variabile acl_m9, significa che e` una mail classificata
# come "in uscita dal nostro server" e quindi la salvi nel backup delle mail in uscita
if $acl_m9 is 1
then
unseen save /var/mail_backups/outgoing/$sender_address_domain/$sender_address_local_part
endif
Per finire, creiamo la directory /var/mail_backups e la rendiamo scrivibile dall'utente "mail" (come indicato nella configurazione, vedi "system_filter_user").
A questo punto e` sufficiente ricaricare la configurazione di Exim, ed avremo un backup delle email divise per "incoming", "outgoing", e poi dominio e utente.
Se si vuole creare dei files targzippati con dentro la mail settimanale, si puo` eseguire questo scriptino da cron:
# Script per il backup settimanale delle copie della mail
# prima di tutto, blocco il delivery di exim
touch /etc/exim4/queue_only
# poi, aspetto 5 minuti perche` la coda si svuoti del tutto
# forse e` una misura eccessiva, ma sono paranoico
sleep 5m
# poi faccio il backup dei files in /var/mail_backups/incoming e outgoing
# avendo cura di nominare i files con la data dell'esecuzione del backup
# e dicendo al tar di cancellare i files mentre crea l'archivio..
tar czf /var/mail_backups/`date -I'date'`-incoming.tgz /var/mail_backups/incoming/* --remove-files
tar czf /var/mail_backups/`date -I'date'`-outgoing.tgz /var/mail_backups/outgoing/* --remove-files
# finita la tarratura, sblocco il lock
rm /etc/exim4/queue_only
# abbiamo finito.
===== Uso di un system filter per inoltrare tutte le mail di un utente a un altro utente =====
Questo e` un uso forse non proprio etico, ma puo` venire utile. Lo scopo e` inoltrare tutte le email inviate / ricevute da un utente locale del server a un altro utente, locale o remoto, del server.
Dopo aver configurato exim4 per usare i system filter, come al paragrafo precedente "Configurazione di un System Filter", si puo` creare un system filter cosi` fatto:
# System Filter per salvare la mail in uscita nella directory di backup
# se e` un errore, non salvare nulla e procedi
if error_message then finish endif
# se la mail e` da o per un utente specifico, inoltrala ad un altro utente
if ("$h_to:, $h_cc:, $h_bcc" contains "user@domain.com")
or ("$h_from:" contains "user@domain.com")
then
unseen deliver "archive-address@domain.com"
endif