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
- Creare un trasporto sotto la sezione "transports", che chiameremo "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