<- SL: Apache - Copertina - SL: JFS ->

Sistemi Liberi


Un pinguino per postino

di Tommaso Di Donato


L'articolo...

La posta elettronica è diventata, per le ditte come per il navigatore occasionale, un servizio imprescindibile. Questo articolo vuole essere il primo di una serie dedicata ai mail server, ed in particolare a Postfix, a partire della configurazione dei servizi basilari smtp e pop3, fino ad arrivare a qualcosa di un po' più avanzato, ad esempio web-mail e mailing list.
In questa prima puntata vedremo l'installazione e la configurazione di Postfix come SMTP server; nel prossimo numero ci focalizzeremo sulla creazione degli utenti, e sulla configurazione del servizio POP3; vedremo anche come utilizzare Postfix in unione a Mojo, un mailing list manager completamente gestito via web.


Indice


Sendmail, Postfix, qmail...

    In passato, parlare di mail server linux era equivalente a parlare di Sendmail, il più noto e diffuso software SMTP per *nix. Nonostante questa sua diffusione, non si può certo dire che Sendmail godesse di buona fama in quanto a sicurezza... anche se le ultimissime versoni hanno subìto un pesante lavoro di riprogettazione, ed ora sono molto affidabili! Ma fu questa fama di "mail server bacato" che, in passato, spinse alcuni virtuosi a scrivere da zero dei nuovi software SMTP, interamente pensati in funzione della sicurezza. E fu così che nacquero Postfix e Qmail: l'idea che sta alla base è avere un programma di facile configurazione e amministrazione, con potenti funzionalità di sicurezza e filtri anti-spamming, stabile e veloce.
    Nell'articolo tratteremo di Postfix, scaricabile direttamente dalla Home Page www.postfix.org o da uno dei numerosi mirror. Anche se ormai molte distribuzioni lo includono già nei CD in forma di binario precompilato, per motivi "didattici" lo installeremo partendo direttamente dai sorgenti.
Una piccola nota per gli utenti Red Hat: per poter compilare i sorgenti, sarà necessario installare prima il pacchetto db3-devel (che potrete poi rimuovere al termine dell'installazione).

Anatomia

    Postfix è stato interamente progettato, sin dall'inizio, per essere sicuro e veloce: esso è costituito da numerosi demoni, ognuno dei quali si occupa di un processo ben definito. Solo uno di essi, master, è eseguito con privilegi "elevati", tutti gli altri possono essere facilmente eseguiti con bassissimi privilegi (creando un utente ad hoc), e soprattutto possono essere tutti confinati in una gabbia "chroot" (vedi Appendice A).

Fig.1: Anatomia di Postfix: le ellissi gialle rappresentano i vari processi, i rettangoli gialli sono
i file delle mailbox o delle code di posta, quelli azzurri sono i file di configurazione

    Il processo master è un demone residente, che si occupa di richiamare di volta in volta gli altri processi: ad esempio, a seguito di una richiesta di connessione SMTP, master invocherà il sottoprocesso smtpd, il quale si occupa di aprire la connessione e di passare l'input al demone cleanup; quest'ultimo, a sua volta, si occupa di aggiungere (o eventualmente modificare) eventuali header mancanti, per poi inserire il messaggio nella coda di arrivo.
    Lo scopo di Postfix è quello di sostituire interamente Sendmail, mantenendone però in tutto e per tutto la compatibilità: ciò significa che migrare un server da Sendmail a Postfix risulterà completamente trasparente ad ogni altra applicazione! Come Sendmail, le mailbox corrispondono agli utenti di sistema operativo (vedremo nel prossimo articolo come questo sia solo parzialmente vero...), e quindi per creare una nuova casella di posta basterà semplicemente utilizzare adduser o, se preferiamo, il buon vecchio linuxconf (nelle ultime versioni, esce addirittura con un modulo appositamente creato per la configurazione di Postfix!).

Installazione

    Il sistema su cui vogliamo installare Postfix non necessita di particolari configurazioni. In generale, non sarebbe una cattiva idea creare una partizione separata per il mountpoint /var/spool: pur non essendo indispensabile, risulta comunque decisamente più comodo, ad esempio nel caso in cui si voglia assegnare una quota alle singole mailbox. Ulteriore requisito (fondamentale solo nel caso in cui il nostro mail server invii mail verso internet, e non solo localmente) è la corretta configurazione per la risoluzione dei nomi.
    Per prima cosa, occorre innanzi tutto creare almeno un utente di sistema operativo: in questa fase però ne aggiungeremo 2, in modo tale da avere la possibilità di creare una gabbia chroot per i vari demoni. Verifichiamo innanzi tutto di non avere precedentemente installato Sendmail: per una distribuzione Red Hat, ad esempio, il pacchetto viene installato automaticamente, e va pertanto rimosso; da esso dipendono altri programmi, per cui sarà necessario il flag --nodeps.

  rpm -e sendmail --nodeps

Verifichiamo anche di non avere già un utente "mail" (grep mail /etc/passwd), quindi procediamo alla creazione dei 2 nuovi account, ad esempio "postfix" e "mail":

  adduser postfix -s /bin/false -d /dev/null  
  passwd -l postfix
  adduser mail -s /bin/false -d /dev/null
  passwd -l mail

A questo punto, siamo pronti per compilare i sorgenti: dopo esserci posizionati nella directory in cui abbiamo scompattato l'archivio, procediamo col comando

  ./make

Se abbiamo installato il compilatore C, e se il nostro sistema è uno di quelli supportati (mi meraviglierei del contrario!!!), tutto dovrebbe procedere senza particolari intoppi; a questo punto, installiamo quanto compilato:

  ./make install

Ci verranno ora richieste alcune informazioni sul nostro sistema, ad esempio dove posizionare i file di configurazione, gli eseguibili e le pagine di help. Non c'è molto da dire su questo, dipende dalla distribuzione in esame e dai gusti personali... Facciamo invece attenzione agli ultimi 2 parametri, mail_owner e setgid: il primo è l'utente proprietario dei vari demoni, mentre il secondo è il proprietario della directory maildrop, e serve principalmente per motivi di sicurezza. Chi vuole approfondire il motivo della sua esistenza (non temete, nessuna disquisizione filosofica sull'Essere!) troverà qualcosa in Appendice A. Lo script di installazione creerà le directory di configurazione (/etc/postfix) e quelle relative alle code dei messaggi (/var/spool/postfix); al termine consiglierà di andare immediatamente a modificare il file di configurazione principale main.cf.
    L'installazione è terminata, e siamo pronti per configurarci il nostro mail server! Io pero' consiglio un paio di operazioni ulteriori; lo script di installazione crea nella directory /etc/postfix tutti i file di configurazione, e una serie di file di esempio: a mio avviso, sarebbe più "pulito" mantenere in questa directory lo stretto necessario, e spostare gli esempi altrove... Ad esempio:

  mkdir /usr/share/doc/postfix
  mv /etc/postfix/sample* /usr/share/doc/postfix/
  mv /etc/postfix/LIC* /usr/share/doc/postfix/
  mv /etc/postfix/*.default /usr/share/doc/postfix/
  mv /etc/aliases /etc/postfix

Configurazione di base

    La configurazione di Postfix è veramente intuitiva: nessun parametro dal nome astruso, ed una abbondanza di commenti incredibile. Per una configurazione tipica, i file che ci interessano sono aliases e main.cf: il primo definisce gli alias per gli utenti di sistema operativo, mentre il secondo contiene la configurazione vera e propria.

/etc/postfix/aliases
    Contiene la "mappatura" di un un utente di posta elettronica con un utente di s.o. Questo è molto importante per 2 motivi: in primis, è fondamentale che esistano gli alias per l'utente postfix (per il corretto funzionamento del programma) e per root (che sarebbe preferibile non ricevesse mail direttamente). Questo è vero in ogni caso, sia che il nostro Postfix funga da mail server interno, sia che si tratti del mail server di un ISP.
    Il secondo motivo per cui è importante la creazione di alias è l'esistenza di alcuni account "di ruolo" che vanno creati nel rispetto della cosidetta netiquette, ad esempio postmaster, info, abuse, ecc; dal momento che, nella pratica, spesso è un solo utente a svolgere tutte le sovracitate funzioni, è possibile fare in modo che le relative e-mail vengano automaticamente "girate" nella casella dell'utente. Vediamo un esempio: sul mio sistema, io svolgo le funzioni di sistemista e postmaster; avrò quindi un account, ad esempio tom. Il mio file /etc/postfix/aliases conterrà quindi le voci:

  postmaster:	tom
  abuse:	tom
  info:		tom
  postfix:	root
  root:		tom

Come vedete, è possibile utilizzare anche degli alias "ricorsivi" (Postfix->root->tom). A questo punto, occorrerà utilizzare il comando /usr/bin/newaliases per rendere effettive le modifiche (vedrete che verrà creato un file aliases.db, sul cui significato torneremo nel prossimo articolo).

/etc/postfix/main.cf
    Veniamo ora alla configurazione vera e propria di Postfix; vedremo che i parametri da modificare per ottenere un sistema immediatamente funzionante sono davvero pochissimi! Per prima cosa, visto che abbiamo posizionato il file degli alias in /etc/postfix/, dovremo rendere partecipe Postfix della nostra decisione: aggiungeremo (o modificheremo, qui va verificato che i parametri non siano già impostati) le righe

  alias_maps = hash:/etc/postfix/aliases
  alias_database = hash:/etc/postfix/aliases

    A questo punto, passiamo ai settaggi fondamentali: il nome del server, e il dominio che verrà considerato "locale"; ipotizzando di voler configurare il mail server primario del dominio plutojournal.it, scriveremo:

  myhostname = mail.plutojournal.it		
  mydestination = $myhostname, $mydomain

Il parametro myhostname definisce il nome del server (che apparirà negli header dei messaggi inviati), mentre mydestination specifica quali destinatari vanno considerati locali: per "locale" si intende il dominio che ha le relative mailbox proprio sul nostro server (nel nostro esempio, solo user@plutojournal.it e user@mail.plutojournal.it saranno considerati locali). Ovviamente, se si sta configurando un mail server pubblico (cioè corrispondente a un dominio effettivamente presente sul DNS), bisognerà anche dire al DNS di considerare la nostra machina come mail server primario per quel dominio (per i dettagli, si veda l'Appendice C).
    A questo punto, il nostro server è pronto? Si! Cioè, no... Abbiamo già un server funzionante, ma che tutti quanti, là fuori, possono usare come server di invio... e noi non vogliamo lo spamming!! Bisogna allora decidere quali client saranno autorizzati ad inviare mail tramite il nostro Postfix: la cosa più comoda è utilizzare il parametro mynetworks, specificando un range di indirizzi IP. Ad esempio, ipotizzando di voler concedere il servizio SMTP alla nostra LAN (la cui subnet potrebbe essere 192.168.1.x) e ad un client esterno (con IP 1.2.3.4), scriveremo:

  mynetworks = 192.168.1.0/24, 1.2.3.4

Perfetto, siamo pronti! Controlliamo di non aver fatto macro-errori di configurazione

  postfix check

Se tutto è andato bene, vedremo che vengono create alcune directory in /var/spool/postfix/, a seguito di una serie di merraggi del tipo
postfix-script: warning: creating missing Postfix xxx directory
Ora siamo pronti ad avviarlo

  postfix start

Congratulazioni! Verifichiamo che tutto sia andato bene, dando un'occhiata a eventuali messaggi di errore:

  cat /var/log/maillog

Conclusioni

    Questo articolo vuole essere il primo di una serie dedicata alla configurazione di Postfix come server di posta elettronica. In questa prima "puntata" si è trattato della configurazione di base, ma le possibilità offerte da questo software sono decisamente più ampie e certamente scalabili fino alla cosiddetta fascia "enterprise": vedremo più avanti come sarà possibile progettare architetture molto complesse, con un livello di scalabilità praticamente illimitato.
    Postfix nasce per essere in grado di sostituire interamente il vecchio Sendmail, pur mantenendo la compatibilità con tutte le applicazioni ed il software di terze parti scritto originalmente per il suo predecessore (vedi, ad esempio, programmi commerciali antivirus, server POP, list manager, ecc...)


Appendice A
Un po' di sicurezza

Chroot jail
    In estrema sintesi, una chroot jail è una sottodirectory entro cui viene eseguito un applicativo, che l'applicativo stesso vede come se fosse la root del file system. Questo implica che, in caso di un baco del programma, ogni eventuale comando che potrà essere lanciato non avrà modo di interagire con quanto sta al di fuori della gabbia (da qui il termine). Confinare quindi gli applicativi in una chroot jail risulta un ottimo metodo per aumentare la sicurezza del sistema (Bind 8.x docet).
    Com'è stato già detto nell'articolo, il programma Postfix non è un applicativo "monolitico", ma è composto da numerosi processi semi-indipendenti: ad esempio, una volta che postfix è in esecuzione, nella lista dei processi appariranno i programmi master, pickup e qmgr (ed altri, a seconda che vi siano o meno messaggi da processare). In pratica, master si occupa di lanciare i vari sottoprocessi, i quali sono eseguiti con privilegi minimi; di seguito vedremo anche come sia possibile confinarli in un ambiente chroot'ed; io consiglio vivamente di optare per questo settaggio: sappiamo che la cossiddetta "chroot jail" non è la panacea per tutti i problemi di sicurezza, ma vista la facilità con cui in questo caso è possibile realizzarla, il gioco vale sicuramente la candela!
    Per prima cosa, sarà necessario editare il file di configurazione /etc/postfix/master.cf: esso contiene le impostazioni dei singoli processi che compongono Postfix; è necessario modificare in "y" la quinta colonna (quella denominata "chroot", appunto) di ogni servizio, ad eccezione di local e pipe. A questo punto, basterà andare nella cartella <sorgenti-postfix>/examples/chroot-setup, e lanciare lo script corrispondente alla vostra piattaforma, ad esempio "LINUX2" (dovete prima renderlo eseguibile, di default non lo è). In pratica, lo script non fa altro che creare in /var/spool/postfix le directory etc, lib e usr; all'interno di esse, copia i file indispensabili all'esecuzione dei processi e quelli relativi alle impostazioni di sistema (localtime, resolve.conf, ecc). Fatto questo, lo script fa ricaricare a Postfix il file di configurazione, e il gioco è fatto! Va solo ricordato che d'ora in poi, ogni modifica a uno dei file copiati dallo script genererà un warning: ecco ad esempio il messaggio che trovo in /var/log/maillog, se avvio postfix dopo aver aggiunto un utente:
postfix-script: warning: /var/spool/postfix/etc/passwd and /etc/passwd differ
Quindi, nel caso si trovino messaggi come questo, bisognerà ricordarsi di copiare i file aggiornati nella directory corrispondente.

Setgid e Maildrop
    Abbiamo visto che, all'atto dell'installazione, abbiamo optato per assegnare un gid (Grup ID) alla directory Maildrop. Praticamente, questo significa che la directory non è world-writeable (w-w); ma a cosa serve, in effetti, questa directory? Come si vede dalla figura 1, la directory Maildrop entra in gioco solo nel caso di invio locale di posta (cioè nel caso in cui l'invio avvenga senza una connessione SMTP): l'utente in console (o in telnet) invia una mail, e questa operazione si traduce, in pratica, nella scrittura di un file contenente il messaggio proprio nella directory in questione. A questo punto, il demone pickup preleva il messaggio e lo inserisce nella coda delle mail in arrivo, pronto per essere processato.
    Assegnare un GID alla Maildrop significa che questa non sarà più scrivibile da tutti, ma solo del demone di posta: è chiaro a questo punto che, al contrario di quanto accade nel caso di una directory w-w, anche gli utenti in console potranno inviare posta solo a demone avviato. Perchè preferire questa scelta? Il problema di una Maildrop w-w è che un utente potrebbe creare in questa directory un link alla posta di qualcun'altro, o creare un falso messaggio contenente un link a file di sistema. L'eventualità è remota (anche grazie a scrupolosi controlli della coda dei messaggi), ma possibile.
    Utilizzando invece una Maildrop non w-w, i problemi di sicurezza sono completamente superati, per giunta senza nessun inconveniente, a patto di spedire sempre la posta con Postfix attivo (il che non mi sembra una limitazione troppo forte!).

Appendice B
Automatizzare l'avvio di Postfix

    Come abbiamo sperimentato, una volta compilato e installato, Postfix crea una serie di file, tra cui /usr/sbin/postfix. Questo eseguibile ci permette di avviare ed arrestare il programma, ma molto probabilmente noi vogliamo che, all'avvio del sistema, il nostro nuovo demone della posta sia avviato automaticamente! Per fare questo, basterebbe inserire il comando postfix start negli script di avvio, ma la ritengo una soluzione veramente poco elegante
Lo Zen e l'arte degli init script...
    Se avessimo installato Postfix tramite un binario precompilato (come ad esempio l'RPM di Red Hat) avremmo trovato uno script in /etc/init.d da utilizzare con il comando chkconfig; vediamone uno di esempio:

  #!/bin/sh
  #
  # Script per l'avvio automatico di Postfix tramite ntsysv
  #
  # chkconfig: 2345 11 92 
  #
  # description: Script per l'avvio automatico di Postfix tramite ntsysv
  # by Tommaso Di Donato (dido@sicurweb.com)
  #
  #
 
  # Source 
  . /etc/init.d/functions
 
  start() {
        action $"Starting postfix..." postfix start
        RETVAL=$?
        [ $RETVAL -eq 0 ] && touch /var/lock/subsys/postfix
        return $RETVAL
  }
  stop() {
        if [ -f /var/lock/subsys/postfix ]
	then
        action $"Stopping postfix..." postfix stop
        RETVAL=$?
        [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/postfix
        return $RETVAL
        else
        echo Postfix is not running
        exit 0
        fi
  }
  reload() {
        if [ ! -f /var/lock/subsys/postfix ]
	then
        echo Cannot reload config: postfix is not runnig...
        exit 0
        fi
        action $"Reloading postfix config..." postfix reload
        RETVAL=$?
        [ $RETVAL -eq 0 ]
        return $RETVAL
  }
  check() {
        postfix check && \
           success $"Checking configuration..." || \
           failure $"Checking configuration..."
  }
  case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    reload)
        reload
        ;;
    check)
        check
        ;;
    *)
        echo $"Usage: $0 {start|stop|reload|check}"
        exit 1
  esac
 
  exit 0

A questo punto, basta creare un eseguibile in /etc/init.d (per Red Hat, o /etc/rc.d/init.d per altre distribuzioni), e salvarvi queste poche righe. Un unico accorgimento: affinchè Postfix si avvii correttamente, è necessario che sia già avviato il supporto di rete! Andrà quindi modificato, alla riga 5, il numero "11" in un valore superiore a quello presente nel file /etc/init.d/network. Una volta fatto questo, basterà utilizzare il comando


  chkconfig --add postfix

Fatto questo, il nostro script sarà automaticamente aggiunto alla lista dei demoni disponibili: potete verificarlo con il classico ntsysv

Appendice C
Mail server e record DNS

    Se tramite il nostro mail server inviamo un messaggio di posta ad un altro utente, anch'esso avente una mailbox sullo stesso server, il recapito del mail è locale. Ma cosa avviene, invece, se scriviamo a un utente "remoto", ad esempio pinco.pallino@pluto.linux.it?
    Una volta che Postfix ha ricevuto il messaggio tramite connessione SMTP, ed ha verificato che il dominio pluto.linux.it non va considerato locale (tramite il parametro mydestination nel file /etc/postfix/main.cf), il nostro server interroga il DNS (secondo quanto specificato in /etc/resolve.conf) per ottenere una informazione fondamentale: qual'è il mail server principale per il dominio in questione. Tralasciando i dettagli della struttura di un record DNS, possiamo dire che, affinché un dominio (di qualsiasi livello superiore al primo) possa ricevere posta, il relativo record DNS deve contenere il "parametro" MX (Mail eXchanger). Un server di posta non fa altro che chiedere al DNS il valore MX per il dominio in questione. Vediamo in dattaglio una query DNS, tramite il comando dig, richedendo esplicitamente solo il record MX:

# dig pluto.linux.it mx +noadditional +noauthority +nocomments +nocmd

;; global options:  printcmd
;pluto.linux.it.                        IN      MX
pluto.linux.it.         77156   IN      MX      5 mail.pluto.linux.it.
;; Query time: 90 msec
;; SERVER: 151.1.1.1#53(151.1.1.1)
;; WHEN: Mon Dec 31 16:04:56 2001
;; MSG SIZE  rcvd: 197

Come possiamo vedere, dig ci restituisce il valore 5 mail.pluto.linux.it: esso è proprio il server a cui il nostro Postfix invierà il messaggio per l'utente pinco.pallino. Il numero "5" indica "l'importanza" del server: è infatti possibile avere più server di posta; quello col numero più basso è il principale, gli altri sono considerati "di backup". In caso un server principale sia irraggiungibile, tutte le mail vengono inviate al primo server di backup, che si occuperà di riconsegnarle al primario non appena questo risulti nuovamente in linea. Vedremo in un prossimo articolo come si configura un server di backup.



L'autore

Tommaso Di Donato è sistemista Linux e Microsoft dal 1998; è stato dba Oracle presso la PA, nell'ambito del progetto di informatizzazione dei Centri Protesi INAIL in Italia.
Attualmente lavora presso un portale Internet, in qualità di sistemista e dba; si occupa inoltre di sicurezza informatica e TLC per un importante gruppo industriale italiano.


<- SL: Apache - Copertina - SL: JFS ->