====== Postfix ====== * **[[http://www.postfix.org/postconf.5.html|Postfix Configuration Parameters]]** * **[[http://www.postfix.org/SASL_README.html|Postfix SASL Howto]]** ===== Configurazione ===== Il file di configurazione principale è **''/etc/postfix/main.cf''**. Per vedere tutti i parametri di configurazione in uso (le impostazioni di default e quelle specificate) si esegue **''postconf(1)''**. Per vedere solo le impostazioni modificate rispetto al default aggiungere l'opzione **''-n''**. La stessa utility ''postconf(1)'' può essere usata per editare da riga di comando il file di configurazione. ===== Apertura porta 25 ===== Per mettere Postfix in ascolto su tutte le interfacce includere in **''/etc/postfix/main.cf''**: inet_interfaces = all ===== Utilizzo delle Maildir ===== La configurazione predefinita di Postfix è di consegnare la posta locale nella Unix mbox **''/var/mail/login''**, per utilizzare la **''$HOME/Maildir''** basta aggiungere in **''/etc/postfix/main.cf''**: home_mailbox = Maildir/ Attenzione alla posta per **root**, se in ''/etc/aliases'' non viene definito un alias, Postfix decide di consegnarla a **nobody** che probabilmente non ha un home directory né una Maildir, pertanto va a finire in ''/var/mail/nobody''. Sempre in ''main.cf'' si imposta la dimensione massima della mailbox (file) e del singolo messaggio. Utilizzando le Maildir non ha molto senso la dimensione della mailbox perché non viene gestita come singolo file, pertanto si disabilita impostando zero: mailbox_size_limit = 0 message_size_limit = 52428800 ===== Procmail ===== Per indicare a Postfix di effettuare la consegna locale tramite **procmail** si aggiunge la seguente direttiva in **''/etc/postfix/main.cf''**: # Use procmail for local delivery. mailbox_command = /usr/bin/procmail -a "$EXTENSION" Il passaggio di ulteriori parametri con l'opzione **''-a''** è facoltativo. Ogni utente potrà configurarsi le proprie regole **''$HOME/.procmailrc''**, vedere questo [[..:..:prog:esempi_procmail|esempio]]. ===== Maildrop ===== Un'alternativa a ''procmail'' è **''maildrop''** che tra le altre cose consente la gestione della quota //volontaria// (bisogna che tutti i servizi SMTP/IMAP/POP collaborino a mantenere ''$HOME/Maildir/maildirsize''). In questo caso basta mettere: # Use maildrop for local delivery. mailbox_command = /usr/bin/maildrop Questa configurazione usa ''maildrop'' come **local delivery agent**, non troppo efficiente ma consente ampia libertà all'utente Unix di configurarsi filtri, forward, ecc. In alternativa si usa il **direct delivery**, vedere [[http://www.postfix.org/MAILDROP_README.html|Postfix + Maildrop Howto]]. Con l'installazione predefinita Debian si deve abilitare il comportamento predefinito di ''maildrop'' in **''/etc/maildroprc''**: DEFAULT="$HOME/Maildir" Ogni utente può configurare il funzionamento di maildrop con un proprio **''$HOME/.mailfilter''**. Vedere questo [[..:..:prog:esempi_maildrop|esempio]]. ===== Domini virtuali ===== Per una configurazione minimale basta dichiarare l'elenco dei domini virtuali gestiti e memorizzare la mappa degli alias in un file Berkeley DB. Queste le direttive da mettere in **''/etc/postfix/main.cf''**: virtual_alias_domains = virtual.domain1.com virtual.domain2.com virtual_alias_maps = hash:/etc/postfix/virtual_alias_maps Il file **''virtual_alias_maps.db''** (l'estensione .db è sottointesa nel file di configurazione) viene compilato a partire dal file di testo **''virtual_alias_maps''**, di questo tipo: user.name@virtual.domain1.com username1 user.name@virtual.domain2.com username2, username3 user.name@virtual.domain2.com email@other.host.com La compilazione avviene con il il comando postmap virtual_alias_maps === File map di dominio multipli === Una configurazione più complessa prevede che l'elenco dei domini sia in un file separato e l'elenco degli alias sia suddiviso in tanti file, uno per dominio. virtual_alias_domains = /etc/postfix/virtual_alias_domains virtual_alias_maps = hash:/etc/postfix/virtual_alias_maps L'elenco dei domini è un semplice file di testo **''/etc/postfix/virtual_alias_domains''**. Gli alias per ogni dominio sono contenuti in altrettanti file di testo **''/etc/postfix/virtual_alias/*.map''**. Per assemblare tutti i virtual alias map in un unico DB Berkley si può usare il seguente **''Makefile''**: all: virtual_alias_maps.db virtual_alias_maps.in: touch virtual_alias_maps.in virtual_alias_maps.db: virtual_alias_domains virtual_alias/*.map virtual_alias_maps.in @echo '#' > virtual_alias_maps.in @echo '# WARNING!!! This file is auto-generated: do not edit!' >> virtual_alias_maps.in @echo '# Edit instead .map files under virtual_alias directory and re-run the "make" command.' >> virtual_alias_maps.in @echo '#' >> virtual_alias_maps.in cat virtual_alias/*.map >> virtual_alias_maps.in postmap virtual_alias_maps.in mv virtual_alias_maps.in.db virtual_alias_maps.db In questo caso l'aggiunta di un dominio **richiede il reload di Postfix**, mentre l'aggiunta di un alias richiede solo la ricompilazione del **''virtual_alias_maps.db''**. ==== Problema virtual_alias_domains, myorigin e mydestination ==== Dopo che un indirizzo è stato valutato come locale (quando il dominio è contenuto in **virtual_alias_domains**), viene consultata la **virtual_alias_maps** per identificare l'**account Unix** a cui consegnare il messaggio. La mappa contiene infatti righe di questo tipo: nome.cognome@domain.tld login_name A tutti gli effetti si ha quindi un **destinatario locale non qualificato**; in questo caso il destinatario viene qualificato automaticamente con **$myorigin**, diventando l'indirizzo **%%login_name@$myorigin%%**. È quindi necessario che **$myorigin** sia contenuto in **$mydestination** perché la consegna venga effettuata. Il pacchetto Postfix di Debian configura **myorigin = /etc/mailname** e giustamente mette lo stesso mailname anche in **mydestination**. Se però si desidera un **virtual domain con lo stesso nome**, otterremo il seguente warning nei file di log: warning: do not list domain mydomain.org in BOTH mydestination and virtual_alias_domains Se esiste un virtual domain con quel nome, la soluzione più corretta è utilizzare un **nome ad-hoc** per **myorigin** e aggiungerlo **mydestination**: #myorigin = /etc/mailname myorigin = mail.mydomain.org mydestination = mail.mydomain.org localhost.localdomain localhost :!: **ATTENZIONE 1**: Il contenuto di **myorigin** viene usato anche per qualificare l'//envelope sender// dei messaggi generati automaticamente (ad esempio dal tool ''vacation''). È opportuno quindi che si tratti di un dominio completo, altrimenti è probabile che il messaggio venga rifiutato dal ricevente con l'errore **//Sender address rejected: need fully-qualified address//**. Non è strettamente necessario che si tratti di un dominio che riceve mail (cioè con record MX), in genere dovrebbe essere sufficiente che un mittente valido sia indicato nell'header ''From:''. :!: **ATTENZIONE 2**: Il contenuto di **myorigin** viene usato anche per qualificare i messaggi di errore **MAILER-DAEMON@**, è opportuno quindi che consenta di individuare il sistema di origine piuttosto che un dominio email. Quindi anche in questo caso si suggerisce di usare qualcosa del tipo ''mail.mydomain.org''. ===== Crittografia TLS ===== Per abilitare il **[[wp>Transport_Layer_Security|TLS]]** bisogna anzitutto generare il certificato (autofirmato). L'installazione predefinita di Postfix usa il certificato **''/etc/ssl/certs/ssl-cert-snakeoil.pem''** e la corrispondente chiave **''/etc/ssl/private/ssl-cert-snakeoil.key''**, noi creeremo due file: * **''/etc/postfix/ssl/postfix.crt''** * **''/etc/postfix/ssl/postfix.key''** Questo è uno script basato sull'analogo **exim-gencert**: #!/bin/sh -e DIR=/etc/postfix/ssl CERT=$DIR/postfix.crt KEY=$DIR/postfix.key # valid for four years DAYS=1461 if [ [ -f $CERT ] && [ -f $KEY ]; then echo "[*] $CERT and $KEY exists!" exit 0 fi SSLEAY="$(tempfile -m600 -pexi)" cat > $SSLEAY < Editare **''/etc/postfix/main.cf''** e impostare: # TLS parameters smtpd_tls_security_level = may smtpd_tls_cert_file = /etc/postfix/ssl/postfix.crt smtpd_tls_key_file = /etc/postfix/ssl/postfix.key Riavviare Postfix e verificare che il server annunci **''STARTTLS''** tra le opzioni disponibili: server:~# telnet localhost 25 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. 220 mail.rigacci.org ESMTP Postfix (Debian/GNU) EHLO test 250-mail.rigacci.org 250-PIPELINING 250-SIZE 20480000 250-VRFY 250-ETRN 250-STARTTLS 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN ===== Autenticazione SMTP con SASL su PAM ===== Questa autenticazione si basa sul sistema PAM (in pratica loing e password di **/etc/shadow**) tramite il demone **/usr/sbin/saslauthd**. La catena di autenticazione è la seguente: * Postfix => saslauthd => PAM => /etc/shadow Questa implementazione è fornita dal pacchetto **sasl2-bin** e va sotto il nome **Cyrus SASL**. In alternativa è possibile appoggiare Postfix all'autenticazione **Courier** oppure a quella **Dovecot**, si tratta di sistemi POP/IMAP che offrono possibilità aggiuntive, come quella di poter fare l'autenticazione con utenti virtuali usando l'indirizzo email invece del login Unix. Per istruzioni su queste due alternative vedere **[[#autenticazione_smtp_su_courier_authdaemon|Autenticazione SMTP su Courier Authdaemon]]** oppure **[[postfix_spamassassin_clamav_dovecot#postfix_sasl_over_dovecot_auth|Postfix SASL su Dovecot]]**. Installare i pacchetti **sasl2-bin** e **libsasl2-modules**. **Attenzione:** Debian fa girare Postfix in un chroot, quindi il socket di sasl2 deve stare in esso. Eventualmente Leggere le istruzioni in **''/usr/share/doc/sasl2-bin/README.Debian.gz''**. Configurare **''/etc/default/saslauthd''** impostando: START=yes OPTIONS="-c -m /var/spool/postfix/var/run/saslauthd" Se si fanno girare altri clienti di ''saslauthd'' (ad esempio l'autenticazione Apache con **''libapache2-mod-authn-sasl''** conviene rendere raggiungibile il socket anche dal suo percorso tradizionale, con un symlink: systemctl stop saslauthd.service rmdir /var/run/saslauthd mkdir -p /var/spool/postfix/var/run/saslauthd chown root:sasl /var/spool/postfix/var/run/saslauthd chmod 0710 /var/spool/postfix/var/run/saslauthd ln -s /var/spool/postfix/var/run/saslauthd /var/run systemctl start saslauthd.service Invece di PAM si potrebbe utilizzare direttamente il file ''/etc/shadow'' impostando l'opzione **''MECHANISMS="shadow"''**, ma non c'è alcun reale vantaggio. Poiché abbiamo spostato il socket nella chroot di postfix, informiamo il gestore dei pacchetti Debian: dpkg-statoverride --add root sasl 710 /var/spool/postfix/var/run/saslauthd Per vedere se l'opzione è stata attivata si usa ''%%dpkg-statoverride --list%%''. Testare il funzionamento del demone di autenticazione (l'utente che chiede l'autenticazione deve appartenere al gruppo sasl): testsaslauthd -u myusername -p mypassword -f /var/spool/postfix/var/run/saslauthd/mux **ATTENZIONE!** Il test usa il ''MECHANISMS'' di autenticazione SASL indicato in ''/etc/default/saslauthd'' (default PAM), non l'eventuale metodo **''authdaemond''** configurato in ''/etc/postfix/sasl/smtpd.conf''. Quindi il test con **indirizzo email come login non funziona**. Aggiungere l'utente postfix al gruppo sasl: adduser postfix sasl Configurare postfix mettendo in **''/etc/postfix/sasl/smtpd.conf''** pwcheck_method: saslauthd mech_list: PLAIN LOGIN Aggiungere nella configurazione principale **''/etc/postfix/main.cf''** # Enable authentication via saslauthd. smtpd_sasl_auth_enable = yes # Set the service name passed to saslauthd. smtpd_sasl_local_domain = Riavviare postfix con ''systemctl restart postfix.service''. Verificare che l'autenticazione sia annunciata, deve comparire la stringa **''AUTH LOGIN PLAIN''**: telnet localhost 25 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. 220 mail.rigacci.org ESMTP Postfix (Debian/GNU) EHLO test 250-mail.rigacci.org 250-PIPELINING 250-SIZE 20480000 250-VRFY 250-ETRN 250-STARTTLS 250-AUTH LOGIN PLAIN 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN Per consentire il **relay della posta agli utenti autenticati** si aggiunge in **''/etc/postfix/main.cf''**: smtpd_recipient_restrictions = permit_sasl_authenticated, ... reject_unauth_destination Per richiedere obbligatoriamente l'uso della crittografia durante l'autenticazione, si aggiunge anche la direttiva (**ATTENZIONE!** in questo modo ''AUTH'' viene annunciato solo dopo ''STARTTLS''): smtpd_tls_auth_only = yes Il parametro di cui sopra è implicito se si attiva **''smtpd_tls_security_level = encrypt''**. ===== Autenticazione SMTP su Courier Authdaemon ===== **ATTENZIONE**: se si utilizza l'**autenticazione Dovecot** invece di **Courier**, la configurazione è diversa (e anche un po' più semplice), vedere **[[postfix_spamassassin_clamav_dovecot#postfix_sasl_over_dovecot_auth|Postfix SASL over Dovecot Auth]]**. Postfix può utilizzare l'autenticazione fornita da **Courier Authdaemon** invece di appoggiarsi al demone **''saslauthd''** e al sottostante sistema //PAM//. Questo può tornare utile ad esempio se è attiva l'autenticazione **''/etc/courier/userdb''** che utilizza l'indirizzo di posta elettronica come login, al posto dello username Unix. La configurazione è del tutto simile al caso saslauthd/PAM, cambia solo il file **''/etc/postfix/sasl/smtpd.conf''**: pwcheck_method: authdaemond authdaemond_path: /var/run/courier/authdaemon/socket mech_list: PLAIN LOGIN **ATTENZIONE:** Postfix (da **Debian 5 Lenny** in poi) gira in ambiente chroot (**''/var/spool/postfix/''**), così anche ''saslauthd''; pertanto il socket di Authdaemon deve trovarsi in esso. La directory ''authdaemon'' appartiene a **''courier:courier''** (almeno in Debian Stretch), nel nostro caso deve essere accessibile a saslauthd che viene eseguito da postfix. Questa ricetta è stata verificata su **Debian 9 Stretch**, verificare il proprietario e i permessi della directory originale ''/var/run/courier/authdaemon'' prima di spostarla nel chroot e aggiustare di conseguenza. Ad esempio per Debian 8 Jessie sostituire gruppo e utente //courier// con //daemon//. mkdir -p /var/spool/postfix/var/run/courier/authdaemon chown root:courier /var/spool/postfix/var/run/courier/ chown courier:courier /var/spool/postfix/var/run/courier/authdaemon/ chmod 0755 /var/spool/postfix/var/run/courier/authdaemon/ dpkg-statoverride --add courier courier 750 /var/spool/postfix/var/run/courier/authdaemon adduser postfix courier È necessario rendere disponibile il socket sia alla **posizione originale** (per i servizi Courier POP/IMAP) sia nel **chroot di Postfix**. Il sistema più moderno è un **mount bind**. Invece di aggiungere una entry in ''/etc/fstab'', vedere più avanti come montare in automatico la directory con il sistema di init **systemd**. mount /var/run/courier/authdaemon /var/spool/postfix/var/run/courier/authdaemon \ -t bind -o defaults,nodev,bind Una **alternativa obsoleta** (valida fino alla Debian 6 Squeeze) era creare un symlink. Questo non funziona più con le distribuzioni moderne, perché **la gerarchia ''/var/run/'' è in tmpfs** e viene cancellata ad ogni reboot. # Obsolete: use only in Debian <= 6 (Squeeze). systemctl stop courier-authdaemon.service rm -r /var/run/courier/authdaemon ln -s /var/spool/postfix/var/run/courier/authdaemon /var/run/courier/authdaemon systemctl start courier-authdaemon.service ==== Socket in /var/run/ e nel chroot di Postfix: problema con tmpfs ==== Per **Debian 12 Bookworm** vedere la pagina dedicata **[[postfix_courier_authdaemon_debian_12]]**. Nelle moderne distribuzioni Debian (da 7 Wheezy in poi) la directory **''/var/run/''** viene creata in tmpfs e quindi al reboot è totalmente vuota. Questo è un problema perché la soluzione con il link simbolico vista al paragrafo precedente non sopravvive al reboot. Una soluzione poco elegante è modificare lo script **''/etc/init.d/courier-authdaemon''**, in modo che crei il link prima di avviare il servizio; inoltre questo è sconsigliato se si utilizza il moderno **systemd** (a partire da Debian 8 Jessie). La **soluzione ottimale** è utilizzare un **mount bind** della directory che contiene il socket e **incaricare systemd** di effettuare il mount prima di avviare Postfix. Il punto di montaggio deve essere creato come visto nel paragrafo precedente, la //mount unit// va creata in **/etc/systemd/system/**, deve avere il nome esatto **var-spool-postfix-var-run-courier-authdaemon.mount** e contiene: [Unit] Description=Mount Courier Authdaemon into Postfix chroot Wants=courier-authdaemon.service # A stronger dependency may cause a Systemd ordering cycle problem. #Requires=courier-authdaemon.service #After=courier-authdaemon.service [Mount] What=/var/run/courier/authdaemon Where=/var/spool/postfix/var/run/courier/authdaemon Type=bind Options=defaults,nodev,bind [Install] WantedBy=postfix.service Infine si abilita la unit: systemctl daemon-reload systemctl enable var-spool-postfix-var-run-courier-authdaemon.mount Al successivo reboot troveremo il socket authdaemon disponibile nel chroot di Postfix. ===== Smarthost (relayhost) ===== Per consegnare tutta la posta in uscita ad un relay SMTP si aggiunge in **''/etc/postfix/main.cf''**: relayhost = smtp.example.org:587 Nell'esempio sopra si utilizza il servizio **submission** sulla porta **TCP/587**, se non viene specificata la porta verrà utilizzato **snmp** su porta **TCP/25**. **ATTENZIONE**: secondo le specifiche più recenti ([[https://tools.ietf.org/html/rfc6409|RFC 6409]]) l'invio autenticato deve avvenire sulla porta **submission**, pertanto molti server di posta non accettano più l'autenticazione sulla porta **smtp**. Se il server che funge da relayhost è basato su Postfix, la necessità dell'autenticazione è determinata dal parametro **smtpd_sasl_auth_enable**. Esso viene impostato in **main.cf** relativamente al servizio **smtp** oppure in **master.cf** relativamente al servizio **submission** (nella apposita sezione), se il relayhost vuole rifiutare il submission ai client non autenticati, deve usare l'opzione ''smtpd_client_restrictions=permit_sasl_authenticated,reject''. Lo smarthost generico viene dichiarato con questa direttiva: relayhost = smtp.example.org Se lo smarthost richiede autenticazione con login e password, questi sono i parametri necessari a configurare Postfix come client. Gli stessi parametri sono necessari ogni qual volta Postfix deve agire come client autenticato, ad esempio quando si stabiliscono dei transport specifici per sender o per recipient. # Enable SASL authentication in the Postfix SMTP client. smtp_sasl_auth_enable = yes # Credentials for SASL authentication to remote hosts. smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd # Filter the remote SMTP server's list of offered SASL mechanisms. smtp_sasl_mechanism_filter = plain, login # We use (encrypted) plaintext passwords; the default is noplaintext, noanonymous. smtp_sasl_security_options = noanonymous # The default SMTP TLS security level for the Postfix SMTP client: may or encrypt. smtp_tls_security_level = may L'opzione **smtp_tls_security_level** definisce se deve essere usata una connessione crittografata TLS; con **may** è facoltativa, per renderela obbligatoria va impostato su **encrypt**. È possibile rendere la cifratura obbligatoria solo se siamo certi che la nostra installazione agirà da client verso server che dispongono tutti di TLS, può essere il caso se utilizziamo sempre un solo relayhost. Ad oggi (fine 2023) una buona percentuale di mail exchanger primari (MX di domini mail) non supportano alcuna crittografia. Ricordarsi che per utilizzare SSL si deve installare il pacchetto **libsasl2-modules**. L'opzione **smtp_sasl_mechanism_filter** non è strettamente necessaria in quanto abbiamo già definito la lista meccanismi supportati in **/etc/postfix/sasl/smtpd.conf**, che sono ''mech_list: PLAIN LOGIN''. L'opzione **smtp_sasl_security_options** deve essere specificata, altrimenti il valore predefinito **noplaintext, noanonymous** impedirebbe di usare il //mechanism plain// (viene effettivamente trasmessa la password, ma su canale cifrato). Le credenziali per l'autenticazione vanno messe nel file **''/etc/postfix/sasl_passwd''** che deve essere compilato con **''postmap''**: smtp.example.org login_name:password Se non si installa il pacchetto **libsasl2-modules** l'errore nei log è qualcosa di simile: warning: SASL authentication failure: No worthy mechs found SASL authentication failed; cannot authenticate to server smtp.example.org[10.11.12.13]: no mechanism available ===== Blacklist e altre restrizioni ===== Per bloccare il relaying non autorizzato e per proteggersi con la blacklist **zen.spamhaus.org** sono state aggiunte le seguenti opzioni in **''/etc/postfix/main.cf''**: # Restrictions upon recipient address. smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_rbl_client zen.spamhaus.org, reject_non_fqdn_sender, reject_non_fqdn_recipient, reject_unknown_sender_domain, reject_unauth_destination È possibile aggiungere una whitelist/blacklist locale che agisce prima della blacklist basata su DNS: smtpd_recipient_restrictions = permit_sasl_authenticated, ... check_sender_access hash:/etc/postfix/sender_access, reject_rbl_client zen.spamhaus.org, ... Il file **''sender_access''** deve essere compilato con **''postmap''** ed avere il seguente formato: myfriend@example.com OK junk@spam.com REJECT marketing@ REJECT theboss@ OK deals.marketing.com REJECT somedomain.com OK ===== Esempio di RBL zen.spamhaus.org ===== In generale le RBL (real-time blackhole list) sono in effetti delle **[[wpit>DNSBL|DNS-based Blackhole List]]** cioè utilizzano il meccanismo del DNS per scoprire se un indirizzo IP è nella blacklist o meno. Il funzionamento di **zen.spamhaus.org** è spiegato nella pagina **[[https://www.spamhaus.org/faq/section/DNSBL%20Usage#366|Frequently Asked Questions]]**, vediamo ad esempio come verificare lo stato dell'indirizzo IP **194.44.61.82**. Anzitutto si deve invertire l'ordine degli ottetti e fare una query DNS sul nome **82.61.44.194.zen.spamhaus.org**. È possibile effettuare da riga di comando Unix una richiesta per un **record di tipo A** (è la richiesta che effettua in automatico Postfix): dig +short 82.61.44.194.zen.spamhaus.org @dns.provider.tld 127.0.0.4 127.0.0.3 anzitutto notiamo che la richiesta è stata inoltrata al server DNS **dns.provider.tld**, la risposta è stata positiva, con ben due risultati. I codici 127.0.0.x sono in effetti una convenzione di ciascuna RBL per significare lo stato dell'indirizzo IP; nel nostro caso risulta elencato sia in **Spamhaus SBL CSS** che in **CBL**. Per avere un responso più descrittivo è possibile chiedere il **record di tipo TXT**: dig +short -t TXT 82.61.44.194.zen.spamhaus.org @127.0.0.1 "https://www.spamhaus.org/query/ip/194.44.61.82" "https://www.spamhaus.org/sbl/query/SBLCSS" Attenzione al server DNS utilizzato! Alcuni server DNS pubblici e gratuiti (specificatamente quello di **Google 8.8.8.8**) non rispondono a questo tipo di query. Purtroppo un risultato negativo viene interpretato da Postifix come //indirizzo IP pulito//. È opportuno installare un server DNS locale per una maggiore efficienza delle interrogazioni. ===== smtpd_sender_restrictions ===== FIXME: Unificare con il paragrafo successivo. Se si gestiscono numerosi domini locali è possibile fare un controllo sull'esistenza dell'indirizzo mittente, in pratica si rifiutano messaggi che hanno un mittente inesistente. Questo controllo è opportuno farlo **solo per i domini locali**, perché richiede un'interrogazione al server MX del mittente: host remoti potrebbero non gradire continue interrogazioni. smtpd_sender_restrictions = hash:/etc/postfix/smtpd_sender_restrictions nel file **''/etc/postfix/smtpd_sender_restrictions''** si mette: domain1.com reject_unverified_sender domain2.org reject_unverified_sender ===== Restrizioni sull'indirizzo mittente ===== Il controllo qui descritto va fatto solo sul servizio **submission** da parte di **connessioni autenticate** che chiedono il relay di un messaggio. Trattandosi di utenti con un account locale è possibile fare la verifica dell'indirizzo mittente e **rifiutare messaggi da parte di indirizzi non esistenti**. **Non è possibile** fare tale controllo sulla normale **porta SMTP** (posta in arrivo da internet), perché la verifica del mittente richiederebbe una **interrogazione sul server MX del mittente**, non sempre possibile o accettata. smtpd_sender_restrictions = hash:/etc/postfix/smtpd_sender_restrictions, check_sender_access hash:/etc/postfix/check_sender_access, reject Le regole vengono applicte in seguito al comando ''MAIL FROM'' ([[http://www.postfix.org/postconf.5.html#smtpd_sender_restrictions|smtpd_sender_restrictions]]), l'azione è determinata dal primo match. Il file **''/etc/postfix/smtpd_sender_restrictions''** elenca i domini locali con le relative azioni (vedere [[http://www.postfix.org/postconf.5.html#smtpd_sender_restrictions|reject_unverified_sender]] e [[http://www.postfix.org/postconf.5.html#generic|permit]]): domain1.tld reject_unverified_sender, permit domain2.tld reject_unverified_sender, permit domain3.tld reject_unverified_sender, permit Eventuali eccezioni (mittenti non locali, ma che vengono accettati ugualmente) sono elencati in **''/etc/postfix/check_sender_access''** utilizzando la sintassi di una [[http://www.postfix.org/access.5.html|access table]]: some.address@foreign.domain.tld OK other.address@other.domain.tld OK third.domain.tld OK ^ /etc/postfix/smtpd_sender_restrictions | Rifiuta gli indirizzi non esistenti di domini locali, accetta gli indirizzi locali validi. | ^ /etc/postfix/check_sender_access | Eccezioni: accetta i mittenti elencati (sender whitelist). | ^ reject | Rifiuta tutti gli altri mittenti. | I messaggi rifiutati saranno evidenziati nel log con i seguenti errori (rispettivamente per indirizzi non validi di domini locali oppure per mittenti non locali rifiutati): Sender address rejected: unverified address: User unknown in virtual alias table; Sender address rejected: Access denied; Con **Postfix 2.11** la verifica dell'esistenza di un mittente viene fatta con un meccanismo analogo al comando **VRFY** del protocollo **SMTP**, in realtà lo scambio dati avviene via **Unix socket** con il processo **verify** lanciato al bisogno (vedere la riga opportuna in **/etc/postfix/master.cf**). Il processo verify resta in esecuzione solo per un paio di minuti e produce una cache delle risposte memorizzata in **/var/lib/postfix/verify_cache.db**. Esiste il [[https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=578862|bug #578862]], almeno fino a Postfix 2.11 (Debian 8 Jessie). Il file con la cache viene creato **/var/lib/postfix/verify_cache.db**, ma il processo ''verify'' esegue successivamente un ''chroot'' in **/var/spool/postfix/** e pertanto produce un errore poiché tenta di chiudere l'inesistente file **/var/spool/postfix/var/lib/postfix/verify_cache.db**: postfix/verify[22229]: close database /var/lib/postfix/verify_cache.db: No such file or directory (possible Berkeley DB bug) Pare che il bug non abbia conseguenze (parola dell'autore di Postfix), per chi tuttavia preferisse non vederlo è possibile risolvere con un link simbolico: mkdir -p /var/spool/postfix/var/lib/postfix chown postfix.postfix /var/spool/postfix/var/lib/postfix cp -p /var/lib/postfix/verify_cache.db /var/spool/postfix/var/lib/postfix/ ln -sf /var/spool/postfix/var/lib/postfix/verify_cache.db /var/lib/postfix/ chown -h postfix.postfix /var/lib/postfix/verify_cache.db ===== Restrizioni per localhost (es. PHP) ===== Per consegnare la posta in uscita ad un Postfix dallo stesso localhost esistono fondamentalmente due metodi: * **Connessione TCP/IP** su porta 25. Questa modalità può essere sperimentata ad esempio con il comando **''telnet localhost 25''** utilizzando il linguaggio SMTP. Qualunque programma che giri su localhost e che possa aprire un socket TCP/IP può utilizzare questa modalità. * Apertura di un **socket Unix**. Questo è il metodo usato dai comandi ''mail'' o ''sendmail'' e l'impostazione predefinita della funzione ''mail()'' di PHP. Nel primo caso i log segnalano qualcosa del genere: postfix/smtpd[4283]: 3B544401A1: client=localhost[127.0.0.1] postfix/cleanup[4287]: 3B544401A1: message-id=<23e2c7f-ef129-b1@texnet.it> postfix/qmgr[3997]: 3B544401A1: from=, ... postfix/smtp[4290]: 3B544401A1: to=, ... postfix/qmgr[3997]: 3B544401A1: removed nel secondo caso invece si ha: postfix/pickup[5474]: 67F6A40310: uid=1006 from= postfix/cleanup[5998]: 67F6A40310: message-id=<20140915092933.67F6A40310@texnet.it> postfix/qmgr[3997]: 67F6A40310: from=, ... postfix/smtp[5758]: 67F6A40310: to=, ... postfix/qmgr[3997]: 67F6A40310: removed Nell'invio da parte della funzione ''mail()'' di PHP viene utilizzato l'utente generico del server web oppure l'utente specifico del sito web se si sta utilizzando una configurazione FastCGI e suEXEC. L'invio su connessione SMTP per impostazione predefinita è libero da 127.0.0.0/8 (parametro **''mynetworks''** di Postfix). Un modo per limitarlo (accettando solo connessioni autenticate) è il seguente smtpd_recipient_restrictions = permit_sasl_authenticated, reject ===== Relay from network ===== Per accettare la posta e farne il relay da un particolare indirizzo IP o network si usa la direttiva **mynetworks** di **''/etc/postfix/main.cf''**: mynetworks = 127.0.0.0/8 192.168.2.0/24 82.61.251.143 [2b03:3610:cb00:124::1]/64 Notare che gli indirizzip IPv6 vanno racchiusi fra parentesi quadrate. ===== Modifica degli header ===== Esempio: come nascondere uno header **''Received:''** per non mostrare che la mail passa da un IP dinamico? Si aggiunge un file **''/etc/postfix/maps/header_checks''** con l'espressione regolare e l'azione: /^Received: from mail.private.com/ IGNORE quindi si aggiunge questo in **''/etc/postfix/main.cf''**: # Filter unwanted headers. # See http://www.postfix.org/header_checks.5.html header_checks = regexp:/etc/postfix/maps/header_checks ===== Sender rewrite ===== È possibile riscrivere l'indirizzo di provenienza di una mail, utile soprattutto per le mail generate in automatico da account locale, che altrimenti potrebbero avere indirizzi brutti e poco graditi ai filtri antispam, del tipo **root@localhost** oppure **nagios@mail.mydomain.org**. Postfix dispone della direttiva **''sender_canonical_maps''**; basta aggiungere in main.cf qualcosa del genere: # Rewrite some sender addresses. sender_canonical_maps = hash:/etc/postfix/sender_canonical e predisporre il file ''/etc/postfix/sender_canonical'': root user@domain.tld root@mail.mydomain.org user@domain.tld Il file deve essere compilato con **''postmap(1)''** per creare il relativo .db. ===== Destinatari locali non qualificati ===== Ad un destinatario privo di dominio (es. **backup** o **root**) viene aggiunto il dominio specificato dall'opzione **myorigin**, in Debian questo equivale al contenuto del file **''/etc/mailname''**. Questa riscrittura avviene prima di applicare il contenuto di **/etc/aliases**. Pertanto gli alias specificati in ''/etc/aliases'' funzionano solo se il nome host specificato in ''/etc/mailname'' è uno dei domini riconosciuti come locali, cioè inclusi nell'opzione **''mydestination''**. ===== Messaggi di notifica a postmaster locale ===== I messaggi di notifica grave vengono inviati a **''postmaster''**, essendo un destinatario non qualificato viene trattato come descritto al paragrafo precedente. Un host che non riceve mail da internet ma che vuole generare messaggi di sistema con mittente valido (quindi non locale) probabilmente ha **''myorigin''** non contenuto in **''mydestination''**. In questo caso c'è il rischio che i messaggi di notifica per **''postmaster@myorigin''** non arrivino a destinazione, in quanto non locali. Conviene quindi dichiarare in **''/etc/postfix/main.cf''**: mydestination = naxos.rigacci.org, localhost # myorigin is not in mydestination and we use a smarthost: # assure that notification messages can land somewhere locally. bounce_notice_recipient = postmaster@localhost 2bounce_notice_recipient = postmaster@localhost e in **''/etc/aliases''**: postmaster: user@localhost root: user@localhost ===== Relay by recipient or domain ===== To relay mail for non-local domains (domains not in ''mydestination'' and not in local virtual domains), use the **''relay_domains''** setting: # Relay mail for non-local domains, separated by commas and/or whitespace: relay_domains = www.mydomain.org, mydomain.org **WARNING**: The receiving mail server will eventually check the SPF record and thus the relaying server should be placed into the SPF authorized hosts for the relayed domains. If you want to relay mail to a specific host - eventually not the one listed in MX records - you must provide a specific **transport map**, writing a file **''/etc/postfix/transport''** with something like this: mydomain.org smtp:real.mx.host Compile the file with **''postmap(1)''** and inform Postfix that you want to use it, in ''main.cf'' add: # Some specific transports (e.g. smtp relay) are listed in this file: transport_maps = hash:/etc/postfix/transport With the same technique we can realay a single mailbox: user@local.domain smtp:remote.realay.host If the relay host requires authentication, you may need to configure the Postfix client behaviour, see the **[[#smarthost_relayhost|relayhost paragraph]]**. ===== Relay by sender address ===== It is possibile to select a different relay path for messages based on sender address. Add the directive **sender_dependent_relayhost_maps** to **main.cf**: sender_dependent_relayhost_maps = hash:/etc/postfix/sender_dependent_relayhost_maps Each line of the file must contain an expression matching the full sender address or the entire domain (preceeded by the **@**), and the name or address of the relay host: username@rigacci.org relay2.rigacci.org @domain2.org relay3.rigacci.org Remember to recompile the file whenever you change it using **postmap** (no need to reload Postfix). All the standard requirements for a relay host are necessary: the relay host must be listed into the **SPF record** of the mail domain and the relay host should accept the original sender (e.g. via the **mynetworks** Postfix directive). If the relay host requires authentication, you may need to configure the Postfix client behaviour, see the **[[#smarthost_relayhost|relayhost paragraph]]**. ===== HELO hostname ===== Some MTAs require that the HELO or EHLO hostname is a FQDN name that resolves to an A resource record or an address literal (see [[http://www.ietf.org/rfc/rfc2821.txt|RFC2821]]). Postfix will use the [[http://www.postfix.org/postconf.5.html#myhostname|myhostname]] value for the HELO command, in a default Debian installation that is the simple hostname, without domain. You can change the **''myhostname''** in **''/etc/postfix/main.cf''** or you can force the HELO name using **''[[http://www.postfix.org/postconf.5.html#smtp_helo_name|smtp_helo_name]]''** setting, which defaults to ''myhostname'': smtp_helo_name = mail.mydomain.org # If we don't have the name registered as an A record, use an IP literal: #smtp_helo_name = [78.47.31.140] ===== Lifetime dei messaggi ===== Un messaggio che non riesca a ad arrivare a destinazione, ma che non abbia un errore fatale, resta nella coda per **maximal_queue_lifetime** (valore predefinito 5 giorni). Probabilmente 5 giorni sono troppi, perché il mittente viene notificato del problema troppo tardi. Vedere più avanti anche il parametro **delay_warning_time**. I messaggi di errore hanno un lifetime a parte, definito dal parametro **bounce_queue_lifetime**. Anche in questo caso il valore predefinito di 5 giorni potrebbe essere eccessivo. # The message is considered undeliverable if a temporary error # persists for more than "maximal_queue_lifetime" (default: 5d). maximal_queue_lifetime = 1d # A bounce message becomes undeliverable if queued for more # than "bounce_queue_lifetime" (default: 5d). bounce_queue_lifetime = 6h ===== Delay Warning ===== Per impostazione predefinita Postfix non avvisa dei ritardi di consegna dei messaggi, se si vuole attivare questa opzione si imposta il parametro seguente: delay_warning_time = 4h ===== Rimuovere messagi dalla coda ===== Per rimuovere un singolo messagio in base al sui ID: postsuper -d 75F6F10039B Per rimuovere tutti i messaggi ritardati per qualche motivo e rimasti in coda: postsuper -d ALL deferred Per forzare l'invio dei messaggi rimasti in coda, senza attendere il tempo naturale: postfix flush oppure: postqueue -f ===== Limiti ===== Questi sono alcuni parametri che si possono impostare per limitare le risorse messe a disposizione dal server: # Maximal number of Postfix child processes that provide a given service. default_process_limit = 50 # The maximal size in bytes of a message, including envelope information. message_size_limit = 20971520 # Maximum number of recipients per message. smtpd_recipient_limit = 20 smtpd_recipient_overshoot_limit = 4 local_recipient_limit = 20 relay_recipient_limit = 20 virtual_recipient_limit = 20 # Bounce headers only, not the message body (avoid to make backscatter SPAM). bounce_size_limit = 1 Il parametro **''default_process_limit''** può essere scavalcato dall'impostazione **''maxproc''** di **''master.cf''**. ===== Messaggi DSN (delivery status notifications) ===== La configurazione predefinita di Postfix prevede la possibilità di richiedere una DSN all'invio del messaggio, vedere la capability **''DSN''** annunciata all'**''EHLO''**. Alcuni clienti email fanno questa richiesta per impostazione predefinita. Nei log si trova traccia dell'invio di tale notifica: postfix/bounce[27741]: B39AE1002D1: sender delivery status notification: 69D4E1002A6 Per disattivare questa capability basta aggiungere in **''/etc/postfix/main.cf''**: # Disallow all use of DSN requests from the network. smtpd_discard_ehlo_keywords = silent-discard, dsn ===== Verifica dei messaggi di errore (Delivery Status Notifications) ===== Per generare un messaggio di notifica si può usare l'interfaccia di compatibilità ''sendmail'' di Postfix. Ad esempio per generare un messaggio di notifica senza effettivamente mandare un messaggio ad un destinatario: sendmail -bv name@domain.org Mail Delivery Status Report will be mailed to . Se invece si vuole effettivamente effettuare un invio e ricevere una notifica dell'esito: sendmail -v name@domain.org Some text message... . Mail Delivery Status Report will be mailed to . ===== SMTP over SSL su porta 465/tcp ===== Per avere una connessione cifrata è sufficiente attivare lo ''STARTTLS'' sulla porta standard 25, tuttavia può tornare utile abilitare una porta alternativa, ad esempio per quei provider che bloccano la porta 25 in uscita (notabilmente H3G dai suoi terminali mobili). In questo caso si può usare la porta 465 TCP, storicamente usata per fare **SMTP su SSL**. SMTP su SSL differisce dal ''STARTTLS'' in quanto la connessione è cifrata via SSL da subito e non viene negoziata dal client con il comando ''STARTTLS''. **ATTENZIONE** poiché SMTP su SSL viene considerato superato da STARTTLS, alcuni decidono di fare STARTTLS sulla porta 465, forse una scelta un po' azzardata che contravviene il **[[wp>Principle of least astonishment|principio di minima sorpresa]]**. Con Postfix bisogna aver preparato il certificato SSL come visto sopra e quindi si aggiunge in **''/etc/postfix/master.cf''**: smtps inet n - - - - smtpd -o syslog_name=postfix/smtps # Use the non-standard wrapper mode, i.e. direct SSL instead of STARTTLS. -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes # Allow only authenticated clients. -o smtpd_client_restrictions=permit_sasl_authenticated,reject Riavviando Postfix si vedrà che si pone in ascolto anche sulla porta 465/tcp. Nel ''mail.log'' si troveranno righe identificate da **''postfix/smtps/smtpd''**. ===== Meccanismi anti hammering ===== postfix-mx/anvil[919]: statistics: max connection rate 8/60s for (62.48.51.61:25:110.52.2.253) at Oct 15 23:26:21 postfix-mx/anvil[919]: statistics: max connection count 8 for (62.48.51.61:25:110.52.2.253) at Oct 15 23:26:21 ===== SMTP su porta 587 TCP ===== Secondo il recente [[http://tools.ietf.org/html/rfc6409|RFC 6409]], l'invio di una mail da parte di un Mail User Agent (es. un programma come Thunderbird) andrebbe indirizzato al server **SMTP sulla porta 587**, dovrebbe essere **autenticato** con login e password, e sperabilmente crittografato tramite **STARTTLS**. Con Postfix installato da pacchetto Debian si ha già una sezione predisposta in **''/etc/postfix/master.cf''**, basta togliere i commenti. La crittografia può essere obbligatoria (**''encrypt''**) oppure facoltativa (**''may''**). L'RFC la metterebbe facoltativa. submission inet n - - - - smtpd -o syslog_name=postfix/submission -o smtpd_tls_security_level=encrypt -o smtpd_sasl_auth_enable=yes -o smtpd_client_restrictions=permit_sasl_authenticated,reject ===== Debug ===== Un sistema rapido per tracciare i problemi rispetto ad **uno o più host specifici**, è quello di aggiungere la seguente direttiva in **/etc/postfix/main.cf**, che **aumenta il livello di debug** solo per quelle specifiche connessioni: debug_peer_list = 192.168.10.12 10.0.0.13 [2a01:4f8:a017:6779::1] debug_peer_level = 2 ====== Problemi SSL ====== Se un server remoto tenta di stabilire una connessione cifrata, ma incontra qualche problema, si può riscontrare questo errore nel log: postfix/smtpd[1630564]: SSL_accept error from unknown[124.132.32.203]: lost connection Se si ha l'impostazione **smtpd_tls_security_level = may**, il server remoto dovrebbe riprovare senza crittografia, ma in caso di server difettosi può essere impossibile ricevere mail da quell'host. Una soluzione temporanea può essere quella di inibire il flag STARTTLS in risposta al comando EHLO, cioè non annunciare SSL a quel particolare host. Questo comportamento si ottiene con una riga in main.cf: # Discard some EHLO features for specific servers. # E.g. disable starttls with broken servers. smtpd_discard_ehlo_keyword_address_maps = hash:/etc/postfix/smtpd_discard_ehlo_keywords E il relativo file **smtpd_discard_ehlo_keywords** che contiene effettivamente l'esclusione: 124.132.32.203 starttls Il file va compilato con postmap, ecc. ====== Postgrey ====== Postgrey è una implementazione di greylisting per Postfix: le mail da un certo sender vengono rifiutate al primo tentativo e il sender viene inserito in una greylist per un breve periodo (default 300 secondi). Ad un tentetivo successivo la mail viene accettata. Il sender quindi resta inserito nella whitelist per un periodo abbastanza lungo (default 35 giorni). Si installa il pacchetto Debain **postgrey**, il demone si pone in ascolto sulla porta 10023 dell'indirizzo localhost. In genere si aggiunge alle regole **smtpd_recipient_restrictions** in **''/etc/postfix/main.cf''**, ad esempio: smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, check_policy_service inet:127.0.0.1:10023, reject_unauth_destination Le opzioni si configurano in **''/etc/default/postgrey''**. Eventuali indirizzi whitelist si aggiungono in **''/etc/postgrey/whitelist_clients''** e **''etc/postgrey/whitelist_recipients''**. Un messaggio rifiutato temporaneamente genera questa riga in **/var/log/maio.log**: postgrey[760]: action=greylist, reason=new, client_name=server.example.org, client_address=123.123.123.123/32, sender=niccolo@domain.tld, recipient=user@example.org Quando invece il messaggio viene accettato questo è il log: postgrey[760]: action=pass, reason=triplet found, client_name=server.example.org, client_address=123.123.123.123/32, sender=niccolo@domain.tld, recipient=user@example.org Con il tool **postgreyreport** è possibile interrogare il database di postgrey (in **/var/lib/postgrey/postgrey.db**) in relazione al **mail.log** cat /var/log/mail.log | postgreyreport --show_tries