Index
Contents
Copyright
The following document is originally based on Dovecot, Postfix with PAM authentication page written by J.W. Janssen. This Italian translation is written and maintained by Alfredo Amontagna. All copyrights on the mentioned documents belong to their rightful owners.
Introduzione
In questo documento descriverò le modalità per far autenticare Dovecot e Postfix via PAM e PostgreSQL. Questa pagina si basa sui contenuti del wiki di Dovecot e di L'Xtreme. Ho deciso di scriverlo in quanto ho dovuto modificare la configurazione proposta nei documenti originali per meglio adattarsi alla configurazione del mio server.
Software utilizzato
Questo documento è stato scritto ed è stato testato su un PC con Debian/Linux Sarge poi aggiornato ad Etch con il seguente software installato:
Debian Sarge:
- PostgreSQL
- PAM
- SASL2
- Postfix
- Dovecot
Debian Etch:
- PostgreSQL
- PAM
- SASL2
- Postfix
- Dovecot
Inoltre sono stati scritti alcuni script in Bash ed in Perl per l'amministrazione del server. L'utilizzo di questi script è caldamente consigliato.
Configurazione di PostgreSQL
Dobbiamo prima di tutto permetter i client che si connettono il locale di poter accedere al database di PostgreSQL utilizzando l'autenticazione basata su password. Avendo già alcuni database attivi che accettano già connessioni con metodo ident sameuser ho modificato il file /etc/postgresql/pg_hba.conf aggiungendo la seguente riga
host all all 192.168.0.1 255.255.255.255 password
e modificando la segeunte riga in postgresql.conf:
client_encoding = UTF8
Creiamo il database (mail_miodominio) per immagazzinare varie informazioni su utenti e transport. Inoltre creiamo un utente (mailreader) con privilegi limitati a cui permettiamo accessi a sola lettura allle informazioni memorizzate.
[localhost]$ su - postgres [localhost]$ createdb -E UTF8 mail_miodominio [localhost]$ createuser -A -D -P -E mailreader [localhost]$ psql mail_miodominio
Ora creiamo le diverse tabelle:
CREATE TABLE domains
(
gid INTEGER UNIQUE NOT NULL,
domain VARCHAR(128) NOT NULL,
transport VARCHAR(64) NOT NULL DEFAULT 'virtual:',
PRIMARY KEY ( gid )
);La tabella domains fornisce l'elenco dei domini che sono mappati in modo numerico in group id e fornisce informazioni sul trasporto da utilizzare a Postfix.
CREATE TABLE user_accounts
(
username VARCHAR(12) UNIQUE NOT NULL,
uid INTEGER NOT NULL,
gid INTEGER REFERENCES domains ( gid ),
password VARCHAR(32),
email VARCHAR(128) NOT NULL,
mailbox VARCHAR(128) NOT NULL,
quota INTEGER NOT NULL DEFAULT 25,
active INTEGER NOT NULL DEFAULT 1,
PRIMARY KEY ( uid, gid )
);Nella tabella user_account vengono memorizzate le informazioni sugli utenti. In questo modo si permette di raggruppare in modo simile agli utenti UNIX "convenzionali". I uids/gids utilizzati devono rispecchiare le proprietà delle directory delle mailbox, altrimenti agli utenti verrà negato l'accesso alle loro mailbox. Il campo mailbox è relativo al parametro di configurazione assegnato a virtual_mailbox_base utilizzato da Postfix. Il campo password contiene la password criptata dell'utente. L'algoritmo utilizzato è (lo standard UNIX) crypt. Il campo email corrisponde all'indirizzo email dell'utente.
CREATE TABLE user_addresses
(
username VARCHAR(12) REFERENCES user_accounts ( username ),
alias VARCHAR(128) UNIQUE NOT NULL,
PRIMARY KEY ( username, alias )
);La tabella user_addresses contiene tutti gli indirizzi email riconosciuti dal server per gli utenti. Deve essere incluso anche l'indirizzo reale di ogni utente.
CREATE VIEW postfix_mailboxes AS
SELECT alias AS address, mailbox||'/' AS mailbox
FROM user_accounts RIGHT JOIN user_addresses
ON user_accounts.username = user_addresses.username;CREATE VIEW postfix_aliases AS
SELECT email AS address, alias
FROM user_accounts RIGHT JOIN user_addresses
ON user_accounts.username = user_addresses.username;Le viste postfix_mailboxes e postfix_aliases forniscono un semplice accesso a Postfix sulle informazioni degli utenti. Il campo mailbox è concatenato con un "/". In questo modo Postfix invierà tutte le email degli utenti in stile Maildir, utilizzato da IMAP.
Ora che le tabelle sono state create, limitiamo gli accessi ai nostri dati:
GRANT SELECT ON domains, user_accounts, user_addresses,
postfix_mailboxes, postfix_aliases TO mailreader;Se tutto è andato per il verso giusto, ora possiamo inserire qualche dato:
INSERT INTO domains ( gid, domain ) VALUES ( 10001, 'miodominio.it' );
INSERT INTO user_accounts ( username, uid, gid, password, email, mailbox, active )
VALUES ( 'albertot', 10001, 10001, 'passwd-criptata', 'alfredo@miodominio.it',
'miodominio.it/alfredo', '1' );
INSERT INTO user_accounts ( username, uid, gid, password, email, mailbox, active )
VALUES ( 'carlol', 10002, 10001, 'altra-passwd-criptata', 'carlo@miodominio.it',
'miodominio.it/carlo', '1' );INSERT INTO user_addresses ( username, alias )
VALUES ( 'albertot', 'postmaster@miodominio.it' );
INSERT INTO user_addresses ( username, alias )
VALUES ( 'albertot', 'info@miodominio.it' );
INSERT INTO user_addresses ( username, alias )
VALUES ( 'albertot', 'webmaster@miodominio.it' );
INSERT INTO user_addresses ( username, alias )
VALUES ( 'albertot', 'hostmaster@miodominio.it' );
INSERT INTO user_addresses ( username, alias )
VALUES ( 'albertot', 'alberto@linuxfan.it' );
INSERT INTO user_addresses ( username, alias )
VALUES ( 'albertot', 'albertot@linuxfan.it' );
INSERT INTO user_addresses ( username, alias )
VALUES ( 'albertot', 'alberto.tuonomeinventato@miodominio.it' );
INSERT INTO user_addresses ( username, alias )
VALUES ( 'carlol', 'carlo@miodominio.it' );Da notare che la password deve essere criptata con l'algoritmo (standard) crypt. J.W. Janssen ha scritto un semplice script in perl che chiede una password (testo in chiaro) e la restituisce in forma criptata (leggere la documentazione nel file).
Configurazione di Postfix
Postfix fornisce diverse direttive per interrogare sorgenti esterne per recuperare informazioni su come consegnare. Queste sorgenti esterne sono chiamate maps da Postfix, e possono essere raffigurate come tabelle di ricerca (consultazione).
In questo documento definiremo ed utilizzeremo le seguenti direttive:
- transport_maps, è utilizzata per determinare il metodo di trasporto per un determinato dominio;
- virtual_uid_maps, è utilizzata per determinare il proprietario di una determinata mailbox e di conseguenza a mappare gli indirizzi email in uid numerici;
- virtual_gid_maps, è simile a virtual_uid_maps ed è utilizzata per il proprietario del gruppo di una determinata mailbox. Gli indirizzi email vengono mappati in gid numerici;
- virtual_maps, è utilizzata per determinare l'indirizzo email reale degli utenti, usato per la consegna finale dell'email. Gli indirizzi email (virtuali) vengono mappati negli indirizzi email reali;
- virtual_mailbox_maps, è utilizzata per determinare, in combinazione con virtual_mailbox_base, il percorso completo della mailbox degli utenti.
Postfix utilizza una sintassi simile agli URI per utilizzare una sorgente esterna per una determinata mappa. Per esempio per utilizzare un database di PostgreSQL come sorgente, si utilizzerà il seguente URI: pgsql:/path/to/query_file, in cui "query_file" contiene la query di ricerca per PostgreSQL.
Inseriamo le seguenti entry nel file main.cf di Postfix:
transport_maps = pgsql:/etc/postfix/pg_transport.cf virtual_minimum_uid = 10000 virtual_uid_maps = pgsql:/etc/postfix/pg_uids.cf virtual_minimum_gid = 10000 virtual_gid_maps = pgsql:/etc/postfix/pg_gids.cf virtual_alias_maps = pgsql:/etc/postfix/pg_virtual.cf virtual_mailbox_domains = pgsql:/etc/postfix/pg_transport.cf virtual_mailbox_base = /var/mail virtual_mailbox_maps = pgsql:/etc/postfix/pg_mailboxes.cf virtual_mailbox_limit = 51200000 mydestination = $myhostname
In questo estratto possiamo vedere che PostgreSQL è utilizzato in maniera estensiva pe la ricerca di qualsiasi tipo di informazione. Inoltre vediamo che tutte le mailbox sono memorizzate in /var/mail con un limite massimo e impostato a circa 50 megabyte. Ci sono le direttive che indicano a Postix che i uid ed i gid partono da 10000 in su.
Senza entrare nello specifico (i dettagli sono qui), ecco i file utilizzati:
Sintassi specifica per Debian Sarge
pg_transport.cf
# domain transport information hosts = 192.168.0.1 user = mailreader password = secret dbname = mail_miodominio table = domains select_field = transport where_field = domain
pg_uids.cf
# user id information hosts = 192.168.0.1 user = mailreader password = secret dbname = mail_miodominio table = user_accounts select_field = uid where_field = email
pg_gids.cf
# group id information hosts = 192.168.0.1 user = mailreader password = secret dbname = mail_miodominio table = user_accounts select_field = gid where_field = email
pg_virtual.cf
# email address (real+virtual) information hosts = 192.168.0.1 user = mailreader password = secret dbname = mail_miodominio table = postfix_aliases select_field = address where_field = alias
pg_mailboxes.cf
# user information hosts = 192.168.0.1 user = mailreader password = secret dbname = mail_miodominio table = postfix_mailboxes select_field = mailbox where_field = address
Sintassi specifica per Debian Etch
pg_transport.cf
# domain transport information hosts = 192.168.0.1 user = mailreader password = secret dbname = mail_miodominio query = SELECT transport FROM domains WHERE domain='%s'
pg_uids.cf
# user id information hosts = 192.168.0.1 user = mailreader password = secret dbname = mail_miodominio query = SELECT uid FROM user_accounts WHERE email='%s'
pg_gids.cf
# group id information hosts = 192.168.0.1 user = mailreader password = secret dbname = mail_miodominio query = SELECT gid FROM user_accounts WHERE email='%s'
pg_virtual.cf
# email address (real+virtual) information hosts = 192.168.0.1 user = mailreader password = secret dbname = mail_miodominio query = SELECT address FROM postfix_aliases WHERE alias='%s'
pg_mailboxes.cf
# user information hosts = 192.168.0.1 user = mailreader password = secret dbname = mail_miodominio query = SELECT mailbox FROM postfix_mailboxes WHERE address='%s'
Directory e owner dello spool
Ora accertiamoci che la directory virtual_mailbox_base esista e che abbia i permessi corretti. Dovrebbe essere leggibile scrivibile e browseable da Postfix. Qualsiasi dominio virtuale posizionato all'interno di virtual_mailbox_base dovrebbe essere di proprietò dell'utente di postfix ed avere i corretti gid numerici. Gli utenti virtuali dovrebbero avere i corretti uid e gid. Ecco un esempio di permessi corretti:
[localhost]$ ls -al /var/mail/miodominio.it/ drwxr-sr-x 5 mail mail 4096 Jun 19 02:59 . drwxrwsr-x 3 root mail 4096 Jun 19 18:25 .. drwxr-sr-x 6 10001 10001 4096 Jun 19 16:24 alberto drwxr-sr-x 2 10002 10001 4096 Jun 19 02:59 carlo
Configurazione di Dovecot
Le impostazioni di default di Dovecot sono perfettamente ragionevoli, per cui modificheremo solo le variabili indicate di seguito.
Sintassi specifica per Debian Sarge
/etc/dovecot/dovecot.conf
default_mail_env = maildir:/var/mail/%d/%n auth_userdb = pgsql /etc/dovecot-pgsql.conf auth_passdb = pgsql /etc/dovecot-pgsql.conf # Tell Dovecot more about the used uids/gids. first_valid_uid = 10000 last_valid_uid = 60000 first_valid_gid = 10000 last_valid_gid = 60000
In questo modo abbiamo comunicato a Dovecot dove trovare le mailbox degli utenti ed il metodo per verificare gli utenti e le loro password utilizzando il seguente file /etc/dovecot/dovecot-pgsql.conf:
# Dovecot queries
connect = host=192.168.0.1 dbname=mail_miodominio user=mailreader password=secret
default_pass_scheme = CRYPT
password_query = SELECT password FROM user_accounts WHERE username='%u'
user_query = SELECT '/var/mail/'||mailbox AS mail, uid, gid FROM
user_accounts WHERE username='%u'
Sintassi specifica per Debian Etch
/etc/dovecot/dovecot.conf
mail_location = maildir:/var/mail/%d/%n
first_valid_gid = 10000
last_valid_gid = 60000
#passdb pam {
#}
passdb sql {
args = /etc/dovecot/dovecot-sql.conf
}
#userdb passwd {
#}
userdb sql {
# Path for SQL configuration file, see /etc/dovecot/dovecot-sql.conf for example
args = /etc/dovecot/dovecot-sql.conf
}In questo modo abbiamo comunicato a Dovecot dove trovare le mailbox degli utenti ed il metodo per verificare gli utenti e le loro password utilizzando il seguente file /etc/dovecot/dovecot-sql.conf:
driver = pgsql connect = host=192.168.0.1 dbname=mail_miodominio user=mailreader password=secret default_pass_scheme = CRYPT password_query = SELECT password FROM user_accounts WHERE username='%u' user_query = SELECT '/var/mail/'||mailbox AS mail, uid, gid FROM user_accounts WHERE username='%u'
Primo test: consegna della posta ed accesso
Sia Postfix che Dovecot possono essere riavviati per poter testare la configurazione. Spiegazioni dettaglate su come effettuare i test sono al di fuori dello scopo di questo documento. Comunque controllate il seguente elenco (potrebbe essere incompleto):
- Telnettando localhost sulla porta 25 dovreste vedere il banner di Postfix.
- L'invio di email ad indirizzi reali di utenti virtuali o reali locali è accettato parte di Postfix.
- L'invio di email ad indirizzi virtuali è consentito e vengono consegnate ai loro utenti reali.
- Email ad utenti non presenti sulla vostra macchina dovrebbero essere inviate direttamente al mailserver/relay responsabile.
- Utenti al di fuori della vostra rete dovrebbero essere in grado di inviare email ad utenti virtuali o reali (e loro alias).
- Utenti al di fuori della vostra retenon dovrebbero essere in grado di inviare email se il destinatario non corrisponde a nessuno degli utenti virtuali o reali (ed alias).
- Gli utenti possono accedere alle loro mailbox attraverso POP3 ed IMAP. Le email possono essere lette e cancellate.
Se tutti i test vengono passati, possiamo procedere alla fase successiva: permettere il relay agli utenti in hosting ed aumentare la sicurezza.
Alcuni degli errori ricorrenti:
- PostgreSQL permette l'accesso all'utente mailreader al database mail_miodominio? Potete controllare in /var/log/postgresql/postgres.log, deve contenere linee tipo: connection authorized: user=mailreader database=mail_miodominio!
- I tre daemon postgresql, postfix e dovecot sono stati riavviati? I file di configurazione devono essere riletti dopo essere stati modificati!
- La passwords dell'utente mailreader è la stessa per i file di configurazione di Postfix e Dovecot?
- Il file /var/log/mail.log contiene alcune (dettagliate) informazione sulle attività di Postfix e Dovecot. Sono stati loggati degli errori?
Permettere il relay agli utenti in hosting
Nella maggior parte dei casi non si vuole che Postfix si comporti come "open relay". Comunque vogliamo permettere agli utenti in hosting di inviare email attraverso il nostro server utilizzando il loro mailreader preferito da casa. Dobbiamo mettere al corrente Postfix su chi può e chi non può inviare email attraverso il server. Postfix di default permette l'invio di email solo alle macchine presenti nella rete locale, come impostato da mynetworks in main.cf.
La soluzione al problema è di utilizzare l'autenticazione SMTP descritta in RFC 2554. Utilizzando questo metodo di autenticazione, poi restringiamo l'accesso al nostro server SMTP a tutti coloro che hanno un account.
Abilitazione del supporto SASL di Postfix
Postfix usa SASL (RFC 2222, implementazione SASL2 di Cyrus) per fornire l'autenticazione SMTP ai suoi client.
Per abilitare l'autenticazione SMTP utilizzando SASL, dobbiamo inserire le seguenti entry in main.cf.
# Enable SMTP authentication support
smtp_sasl_auth_enable = no
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $mydomain
unknown_local_recipient_reject_code = 450
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destinationIn parole semplici abbiamo detto a Postfix di richiedere l'autenticazione SMTP non anonima per qualsiasi destinatario non conosciuto in locale. Email da parte di client non autorizzati verso destinatari non conosciuti in locale saranno respinte.
Configurazione di SASL2
Il daemon SASL per l'autenticazione (saslauthd) utilizza gli socket UNIX per comunicare con altri programmi. Siccome Postfix viene eseguito in ambiente chroot'ed, abbiamo bisogno di essere certi che il daemon SASL e Postfix siano in grado di comunicare tra loro. In altre parole dobbiamo forzare SASL a creare uno socket UNIX in un punto all'interno dell'ambiente chroot'ed. Per fare ciò dobbiamo creare (o modificare) il file di configurazione di saslauthd /etc/default/saslauthd:
Sintassi specifica per Debian Sarge
START=yes MECHANISMS=pam PARAMS="-m /var/spool/postfix/etc"
Sintassi specifica per Debian Etch
START=yes MECHANISMS=pam MECH_OPTIONS="" THREADS=10 PARAMS="-c -m /var/spool/postfix/etc"
Inoltre dobbiamo dire al layer SASL di Postfix che può comunicare col daemon saslauthd via socket UNIX. Notate che il parametro saslauthd_path è relativo alla directory chroot! Creiamo il file /etc/postfix/sasl/smtpd.conf:
pwcheck_method: saslauthd saslauthd_path: /etc/mux mech_list: login plain
L'ultima opzione restringe i meccanismi di autenticazione a login o plain.
Configurazione di PAM
Debian utilizza in modo estensivo PAM per tutti i generi di autenticazione. In /etc/default/saslauthd noi impostiamo SASL ad utilizzare PAM come meccanismo di autenticazione. Quindi visto che tutte le password degli utenti sono immagazzinate in un database di PostgreSQL, dobbiamo abilitare PAM per effettuare lì le ricerche. Il modulo pam_pgsql è configurato in /etc/pam_pgsql.conf:
database = mail_miodominio host = 192.168.0.1 user = mailreader password = secret table = user_accounts user_column = username pwd_column = password pw_type = crypt
Questo semplice file di configurazione dice al modulo pam_pgsql di utilizzare la tabella user_accounts del database mail_miodominio. In questa tabella controllerà lo user name e la password corrispondenti alle colonne username e password.
PAM deve inoltre comunicare quali programmi devono utilizzare quel metodo di autenticazione. Questo avviene creando il file /etc/pam.d/smtp:
auth required pam_pgsql.so account required pam_pgsql.so password required pam_pgsql.so
Provare l' autenticazione
Ora dovremo essere in grado di verificare se l'autenticazione SMTP funziona correttamente. Per prima cosa dobbiamo riavviare i daemon saslauthd e postfix:
/etc/init.d/saslauthd restart /etc/init.d/postfix restart
Controllate i processi ed i file di log per verificare che i daemon funzionino correttamente.
Se tutto e in ordine, l'invio di email senza autenticazione dovrebbe fallire. Effettuate la prova su una macchina che non è riconosciuta da Postfix, per esempio non elencata in mynetworks.
Ora modificate la configurazione del mailreader per utilizzare l' autenticazione SMTP (SMTP AUTH) per l'invio dei email attraverso il vostro server. Nuovamente provate ad inviare una email attraverso il vostro server. Questa volta dovrebbe aver successo. Altrimenti controllate /var/log/auth.log e /var/log/mail.log per capire dove sia il problema.
Rendere più stretta la configurazione di Postfix
A questo punto dovreste avere una configurazione di Postfix funzionante, in grado di autenticare gli utenti autorizzati e di prevenire il relay da parte degli spammer. Ora possiamo restringere gli accessi ed aumentare la sicurezza del mail server. Quello che vogliamo fare è rendere difficoltoso per gli spammer utilizzare il nostro sistema come relay e di restringere gli accessi da parte di host blacklistati. Modificate il file /etc/postfix/main.cf come segue (ma solo se avete una configurazione corretta di Postfix. Evitate di esffettuare le seguenti modifiche mentre effettuate il debugging della configurazione):
disable_vrfy_command = yes
smtpd_helo_required = yes
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_pipelining,
reject_unknown_recipient_domain,
reject_non_fqdn_sender,
reject_non_fqdn_recipient,
reject_unauth_destination
reject_unknown_sender_domain
smtpd_client_restrictions =
permit_mynetworks,
reject_rbl_client relays.ordb.org,
reject_rbl_client ipwhois.rfc-ignorant.org,
permit_sasl_authenticated
smtpd_sender_restrictions =
permit_mynetworks,
reject_rhsbl_sender dsn.rfc-ignorant.org,
permit_sasl_authenticated,
reject_sender_login_mismatch
# Setup a spam tarpit...
smtpd_error_sleep_time = 60
smtpd_soft_error_limit = 60
smtpd_hard_error_limit = 10
default_process_limit = 3
Monitoraggio e manutenzione di Postfix
La maggior parte del tempo, la coda del vostro mail server si svuoterà dopo aver iviato l'email. Potrebbe anche accadere che delle email restino a lungo nella coda, per esempio a causa del fatto che il destinatario non esiste. Se l'indirizzo email del mittente esiste, questo problema si risolverà da solo nel momento in qui Postfix invierà un messaggio di errore al mittente. Viceversa se l'indirizzo del mittente non esiste, Postfix non sarà in grado di inviare un messaggio di errore e manterrà l'email nella coda per un tempo indefinito. La presenza di molte email "deferred" possono fare degradare le performance del server. Dobbiamo quindi rimuoverle utilizzando il seguente cronjob:
mailq | grep MAILER-DAEMON | awk '{printf $1} {print " deferred"}' | \
tr -d '*!' | xargs -n 2 postsuper -d >/dev/null 2>&1C'è la remota possibilità che il precedente script cancelli una email errata a causa del riutilizzo dell'ID delle coda di postfix. Questa possibilità è remota e necessitò di un carico veramente elevato di email per poter far si che accada.
Se state seguendo questo howto per configurare il vostro mailserver, potete ricavare alcuve statistiche interessanti con questo ottimo script di Jim Seymour.
J.W. Janssen ha scritto questo script wrapper che invia una email con l'output di pflogsummary all'utente postmaster del server. Deve essere eseguito in un cron-job ogni notte:
PATH=/bin:/usr/bin:/usr/local/sbin
LOG_FILE=/var/log/mail.log.0*
PFLOGSUMM=/usr/local/sbin/pflogsummary.pl
$PFLOGSUMM -d yesterday --problems_first `ls -rt $LOG_FILE*` | \
mail -s "Postfix :: report" postmaster