Email Management · 14 min read · Jan 04, 2026

Autoresponder per accompagnare Utenti Virtuali e Domini con Postfix, Courier e MySQL

Autoresponder per accompagnare Utenti Virtuali e Domini con Postfix, Courier e MySQL

Questa guida si concentra su come far funzionare Yaa! (Yet Another Autoresponder!) con Debian Sarge e il tutorial sugli utenti virtuali su Postfix (vedi https://www.howtoforge.com/virtual_postfix_mysql_quota_courier).

La prima cosa da capire riguardo alla guida è che utilizza il Virtual Delivery Agent (VDA) e, di conseguenza, nessuno degli autoresponder che potresti utilizzare passando loro a un pipe tramite un file .forward funzionerà semplicemente perché il VDA non supporta le espansioni .forward. Questa limitazione può essere superata tramite la consegna Procmail/Maildrop, ma è disordinata e più lenta, specialmente per i sistemi di posta che sono molto utilizzati. La risposta semplice è Yaa!

Scarichiamo Yaa e iniziamo la festa:

mkdir -p /usr/local/postfix-tools 
cd  /usr/local/postfix-tools
wget http://frost.ath.cx/software/yaa/dist/yaa-0.3.tar.bz2
tar jxvf yaa-0.3.tar.bz2

Successivamente dobbiamo ottenere i moduli Perl richiesti per far funzionare Yaa. Yaa funziona in entrambe le modalità daemon, tuttavia in questa guida mi preoccuperò solo della modalità non daemonizzata del programma.

apt-get install libmldbm-perl libio-lockedfile-perl  libnet-perl libcarp-clan-perl libdbi-perl libdbd-mysql-perl libnet-server-perl libio-stringy-perl

Configuriamo la struttura del database affinché Yaa funzioni:

mysql -uroot -p
use mail;
CREATE TABLE `autoresponder` (  
`active` tinyint(1) NOT NULL default '0',  
`message` mediumtext NOT NULL,  
`subject` varchar(250) NOT NULL default '',  
`charset` varchar(250) NOT NULL default '',  
`forward` varchar(250) NOT NULL default '',  
`address` varchar(250) NOT NULL default '',  
`local_domains` varchar(250) NOT NULL default '',  
`tstart` int(32) NOT NULL default '0',  
`tfinish` int(32) NOT NULL default '0',  
PRIMARY KEY (`address`),  
KEY `active` (`active`),  
KEY `tstart` (`tstart`,`tfinish`)  
)
quit;

Successivamente vogliamo configurare Postfix per invocare Yaa! tramite un trasporto, quindi dobbiamo modificare /etc/postfix/master.cf per aggiungere quanto segue:

  # yaa autoresponder  
yaa     unix    -       n       n       -       -       pipe  
                                                        user=vmail  
                                                        argv=/usr/local/postfix-tools/yaa-0.3/bin/yaa.pl

Riavviamo Postfix per abilitare le modifiche:

/etc/init.d/postfix restart

Infine, dobbiamo configurare Yaa! Per semplificare le cose, ho fornito il mio yaa.conf

######################################################  
#                 !!!!WARNING!!!!                    #  
#  NON RIMUOVERE O COMMENTARE LA SEGUENTE LINEA      #  
use strict;                                          #  
######################################################  
  
# AVVISO:  
# Se hai problemi nell'eseguire yaa.pl e non sei  
# sicuro di cosa stia andando storto, imposta la variabile di ambiente  
#   
#                   YAA_DEBUG  
#   
# e esegui di nuovo yaa.pl con gli stessi argomenti/file di configurazione.  
#   
# L'output di debug di Yaa verrà scritto su stderr se eseguito in modalità di  
# elaborazione di messaggi singoli o in modalità daemon con $daemon_background = 0.  
#   
# Se stai eseguendo in modalità daemon con $daemon_background = 1, i messaggi di debug  
# verranno inviati al sottosistema di registrazione se è abilitato.  
#   
# esempio per csh:  
# setenv YAA_DEBUG 1  
#   
# esempio per sh/ksh/bash:  
# export YAA_DEBUG=1  
#   
  
  
# NOTE GENERALI  
#   
# estratto dal file di configurazione di un eccellente progetto open source  
# chiamato amavisd-new   
# da Mark Martinec .  
#   
#  Questo file è un normale codice Perl, interpretato da Perl stesso.  
#  - assicurati che questo file (o la directory in cui risiede) NON SIA SCRIVIBILE  
#    da semplici mortali, altrimenti rappresenta un grave rischio per la sicurezza!  
#  - per i valori che vengono interpretati come booleani, è consigliabile  
#    utilizzare 1 per vero e 0 o undef o '' per falso.  
#  - si applica la sintassi Perl. In particolare: le stringhe in "" possono includere variabili  
#    (che iniziano con $ o @); per includere i caratteri @ e $ nelle stringhe tra virgolette doppie, precedili con una barra rovesciata; nelle stringhe tra virgolette singole  
#    il $ e l'@ perdono il loro significato speciale, quindi è solitamente più facile utilizzare  
#    stringhe tra virgolette singole. Tuttavia, in entrambi i casi la barra rovesciata deve essere raddoppiata.  
  
  
######################################################  
#           IMPOSTAZIONI DEL SOTTOSISTEMA DI REGISTRAZIONE               #  
######################################################  
  
# abilitare la registrazione?  
# tipo: booleano  
# predefinito: 1  
# $logging = 1;  
  
# abilitare la registrazione su syslog?  
# tipo: booleano  
# predefinito: 1  
$log_syslog = 1;  
  
# struttura di registrazione syslog  
# tipo: stringa  
# predefinito: "mail"  
# questa impostazione si applica solo quando la registrazione su syslog è abilitata  
# $log_syslog_facility = "mail";  
  
# priorità di registrazione syslog  
# tipo: stringa  
# predefinito: "info"  
# questa impostazione si applica solo quando la registrazione su syslog è abilitata  
# $log_syslog_priority = "info";  
  
# registrare su file di testo?  
# tipo: booleano  
# predefinito: 0  
#$log_file = 1;  
  
# nome file di registrazione  
# tipo: stringa  
# predefinito: undef  
# questa impostazione si applica solo quando la registrazione su file è abilitata  
#$log_file_filename = "/var/log/yaa.log";  
  
# registrare su stderr?  
# tipo: booleano  
# predefinito: 0  
# !!!! AVVERTENZA !!!!  
# quando il debug di yaa è attivato (la variabile di ambiente YAA_DEBUG è impostata),  
# l'output STDERR è mappato al sottosistema di registrazione e nulla appare effettivamente  
# su real stderr, quindi assicurati di impostare la registrazione basata su syslog o su file.  
# !!!! AVVERTENZA !!!!  
# $log_stderr = 0;  
  
# formato ora di registrazione quando si registra su file  
# tipo: stringa  
# predefinito: "[%a, %b %e %T %Y]: "  
# vedere strftime(3) per ulteriori dettagli  
# $log_time_format = undef;  
  
  
######################################################  
#               IMPOSTAZIONI DELLA MODALITÀ DAEMON                 #  
######################################################  
  
# eseguire come daemon?  
# tipo: booleano  
# predefinito: 0, non eseguire come daemon  
# questa impostazione abilita il funzionamento in modalità daemon.  
# $daemon = 1;  
  
$daemon = 0;  
$daemon_lockfile = "/tmp/yaa.lock";  
$daemon_pidfile = "/tmp/yaa.pid";  
$daemon_tcpserver_loglevel = 4;  
  
# fork nel background quando si esegue come daemon?  
# predefinito: 1  
# questa impostazione si applica solo quando si opera in modalità daemon  
# $daemon_background = 1;  
  
# file di blocco di accettazione del daemon  
# tipo: stringa  
# predefinito: "/var/lock/yaa.lock"  
# questa impostazione si applica solo quando si opera in modalità daemon  
# AVVERTENZA: se si esegue in chroot jail, questa opzione deve essere  
# impostata rispetto alla directory chroot  
# $daemon_lockfile = "/tmp/yaa.lock";  
  
# file pid del daemon  
# tipo: stringa  
# predefinito: "/var/run/yaa.lock"  
# questa impostazione si applica solo quando si opera in modalità daemon  
# $daemon_pidfile = "/tmp/yaa.pid";  
  
# numero minimo di processi figlio yaa  
# tipo: intero  
# predefinito: 2  
# questa impostazione si applica solo quando si opera in modalità daemon  
# $daemon_min_servers = 2;  
  
# numero massimo di processi figlio yaa  
# tipo: intero  
# predefinito: 3  
# questa impostazione si applica solo quando si opera in modalità daemon  
# $daemon_max_servers = 3;  
  
# numero minimo di processi figlio yaa di riserva  
# tipo: intero  
# predefinito: 1  
# questa impostazione si applica solo quando si opera in modalità daemon  
# $daemon_min_spare_servers = 0;  
  
# numero massimo di processi figlio yaa di riserva  
# tipo: intero  
# predefinito: 1  
# questa impostazione si applica solo quando si opera in modalità daemon  
#$daemon_max_spare_servers = 1;  
  
# protocollo di comunicazione del daemon  
# tipo: stringa  
# protocollo che il tuo MTA utilizza per comunicare con yaa  
#   
# AVVISO: per i valori possibili per questo parametro di configurazione, ESEGUI  
# yaa.pl --list-transport-protocols  
#   
# predefinito: "SMTP"  
# questa impostazione si applica solo quando si opera in modalità daemon  
# $daemon_protocol = "LMTP";  
  
# porta tcp di ascolto o socket di dominio unix su cui yaa dovrebbe ascoltare  
# tipo: intero/stringa  
# predefinito: 40000  
# per specificare il socket di dominio unix impostare il valore a: '/path/to/socket|unix'  
#   
# vedere anche: perldoc Net::Server::Proto  
#   
# questa impostazione si applica solo quando si opera in modalità daemon  
# $daemon_listen_port = 40000;  
  
# hostname a cui yaa dovrebbe legarsi.  
# tipo: stringa  
# predefinito: "localhost"  
# questa impostazione si applica solo quando si opera in modalità daemon  
# $daemon_listen_host = "127.0.0.1";  
  
# livello di registrazione del tcpserver del daemon (Net::Server)  
# tipo: intero  
# predefinito: 0  
# 'O' => disabilita la registrazione  
# 0 => 'err'  
# 1 => 'warning'  
# 2 => 'notice'  
# 3 => 'info'  
# 4 => 'debug'  
$daemon_tcpserver_loglevel = 4;  
  
  
######################################################  
#               IMPOSTAZIONI DELL'OGGETTO YAA                  #  
######################################################  
  
# directory utilizzata per memorizzare il database del tempo di invio del messaggio di risposta automatica.  
# tipo: stringa  
# predefinito: "/tmp"  
# !!!! AVVERTENZA !!!!  
#   
#   -  se stai eseguendo yaa chrooted (vedi la variabile di configurazione $chroot),  
#      allora devi impostare questa variabile a un valore RELATIVO alla directory chroot  
#   
#   - la directory deve essere scrivibile per uid/gid che yaa utilizza per l'elaborazione dei messaggi  
#     vedere anche le variabili $user e $group  
#   
# !!!! AVVERTENZA !!!!  
# $db_dir = "/db";  
  
# tempo in secondi tra le risposte automatiche inviate allo  
# stesso mittente di messaggi da parte del destinatario che ha l'autoresponder  
# attivato.  
#   
# !!!! AVVERTENZA !!!!  
#   
# Per scopi di test, impostare a -1 (disattivare il controllo del tempo),   
# MA NON IMPOSTARE QUESTO VALORE INFERIORE A 3600 (1 ora) SU  
# SISTEMI DI PRODUZIONE !!!!  
#   
# !!!! AVVERTENZA !!!!  
# tipo: intero  
# predefinito: 7200  
# $duration_interval = 24 * 60 * 60;  
$duration_interval = "-1";  
  
######################################################  
#             IMPOSTAZIONI DELLA RISPOSTA AUTOMATICA                  #  
######################################################  
  
# metodo utilizzato per inviare risposte automatiche e inoltrare messaggi  
# tipo: stringa  
# valori possibili: "smtp", "sendmail"  
# - "smtp" utilizza il server smtp per inviare la posta  
# - "sendmail" invoca il binario sendmail per inviare la posta  
#   
# !!!!AVVERTENZA!!!!: cose strane accadono quando si utilizza il metodo di invio sendmail  
# e si esegue in modalità daemon!  
#   
# predefinito: "smtp"  
# $mail_sending_method = "smtp";  
  
# percorso del programma sendmail  
# tipo stringa  
# predefinito: cercato automaticamente nella variabile ambientale $PATH;  
# undef se non trovato in $PATH.  
#$sendmail_path = undef;  
  
# impostazione del server SMTP  
# tipo: stringa  
#   
# vedere anche perldoc Net::SMTP  
#   
# predefinito: localhost  
# $smtp_server = "localhost";  
  
# Utilizzare l'autenticazione SMTP?  
# tipo: booleano  
# predefinito: 0  
# $smtp_auth = 0;  
  
# nome utente di autenticazione SMTP  
# tipo: stringa  
# predefinito: undef  
# $smtp_username = undef;  
  
# password di autenticazione SMTP  
# tipo: stringa  
# predefinito: undef  
# $smtp_password = undef;  
  
######################################################  
#              IMPOSTAZIONI DELLA MAPPA DI RICERCA                   #  
######################################################  
  
# Elenco di TUTTE le mappe di ricerca  
# Devi definire le mappe di ricerca qui e  
# quindi impostare lookup_map_query_order, dove fai riferimento a  
# il nome della ricerca  
#   
# AVVISO:  
# Tutte le mappe di ricerca vengono inizializzate PRIMA che Yaa! entri in chroot jail (se presente)  
# e PRIMA di iniziare a elaborare le email.  
#   
# AVVISO: Per ottenere l'elenco di tutti i driver di ricerca, ESEGUI  
# yaa.pl --list-lookup-map-drivers  
#   
# tipo: hash di hash  
# predefinito: hash vuoto (nessuna mappa di ricerca definita)  
$lookup_maps = {  
    #  
    # !!!AVVERTENZA!!!!  
    #  
    # PER L'ELENCO COMPLETO DEGLI ARGOMENTI DI CONFIGURAZIONE DEL DRIVER  
    # ESEGUI yaa.pl --show-lookup-map-doc   
    #   
    # Formato di configurazione della mappa di ricerca  
    #   
    # 'map_name' => {  
    #    'driver' => 'DRIVER_NAME',  
    #    'driver_param1' => 'value1'.  
    #    'driver_param2' => 'value2',  
    #    'driver_param3' => 'value3',  
    # },  
    # Esempio di mappa di ricerca SQL  
    #   
    # (database sql utilizzato: mysql)  
    # (per altri tipi vedere perldoc DBD::)  
    #   
     'my_sql_map' => {  
        'driver' => 'SQL',  
        'sql_dsn' => 'dbi:mysql:database=mail;host=localhost',  
        'sql_username' => "mail_admin",  
        'sql_password' => "mail_admin_password",  
        'sql_select' => "select active,message,subject,charset,forward from autoresponder where address = %m and active='1'",  
    },  
      
    # Esempio di mappa di ricerca PCRE  
    #  
    # 'my_pcre_map' => {  
    #    'driver' => 'PCRE',  
    #    'file' => "file.pcre",  
    #    'replacement_num' => 0  
    #},  
      
    # Esempio di mappa di ricerca STATIC  
    # 'my_static_map' => {  
    #    'driver' => 'STATIC',  
    #    'result_key1' => 'result_value1',  
    #    'result_key2' => 'result_value2',  
    #    'result' => 'sth'  
    #},  
      
    # Esempio di mappa di ricerca LDAP  
    # 'my_ldap_map' => {  
    #    'driver' => 'LDAP',  
    #    'ldap_host' => 'ldap.example.org',  
    #   
    #    'ldap_bind' => 1,  
    #    'ldap_bind_dn' => "cn=Manager,dc=example,dc=org",  
    #    'ldap_bind_pw' => "secret",  
    #   
    #    'ldap_search_base' => "ou=MyOU,dc=example,dc=org",  
    #    'ldap_search_filter' => "(&(objectClass=rfc822Recipient)(mail=%m)(accountActive=1)",  
    #    'ldap_search_attrs' => ['autoResponseActive', 'autoResponseSubject', 'autoresponseMessage', 'autoResponseCharset', 'autoresponseForward'],  
    #},  
      
    # Esempio di mappa di ricerca DB_File  
    # 'my_dbf_map' => {  
    #    'driver' => 'DB_File',  
    #    'file' => "/path/to/mydb",  
    #},  
      
    # Esempio di mappa di ricerca BerkeleyDB  
    #'my_dbd_map' => {  
    #    'driver' => 'BerkeleyDB',  
    #    'type' => 'Btree',  
    #    'file' => "/path/to/mydb"  
    #},  
};  
  
# ordine di query della mappa di ricerca per attributo  
# per ogni risposta automatica eccetto 'rewrite_recipient' e 'rewrite_sender' deve  
# essere definito l'ordine di query di ricerca  
#   
# Ogni elemento può essere specificato come:  
# + stringa   (esempio: 'domain.tld')  
#   
# O  
#   
# lookup_map_name:result_value (esempio: 'my_pcre_map:result')  
#  
# La mappa di ricerca è riconosciuta dal carattere ':' nella stringa.  
#   
# La mappa di ricerca 'lookup_map_name' DEVE ESSERE specificata nel parametro di configurazione $lookup_maps  
# in yaa.conf  
#   
# tipo: hash di hash  
# predefinito: hash vuoto (nessun elenco di ordini di ricerca definito)  
#   
#   
$lookup_map_query_order = {  
        active => [  
                'my_sql_map:active'  
        ],  
        subject => [  
                'my_sql_map:subject'  
        ],  
        message => [  
                'my_sql_map:message'  
        ],  
        charset => [  
               # 'my_sql_map:charset'  
        ],  
        forward => [  
                'my_sql_map:forward'  
        ],  
        rewrite_sender => [  
                #vuoto  
        ],  
        rewrite_recipient => [  
                #vuoto  
        ],  
        'local_domains' => [  
                'my_sql_map:local_domains'  
        ],  
};  
  
######################################################  
#                 ALTRE IMPOSTAZIONI                     #  
######################################################  
  
# chroot in qualche directory?  
# tipo: stringa  
# predefinito: undef, non chroot  
# Attenzione: yaa deve essere avviato come superutente per abilitare questa funzione.  
# questo si applica alla modalità daemon e alla modalità di elaborazione di messaggi singoli  
# $chroot = undef;  
  
# cambiare uid/gid prima dell'elaborazione?  
# tipo: stringa  
# predefinito: undef, non cambiare uid/gid  
# Attenzione: yaa deve essere avviato come superutente per abilitare questa funzione.  
# questo si applica alla modalità daemon e alla modalità di elaborazione di messaggi singoli  
# $user = undef;  
# $group = undef;  
  
# Carica moduli perl aggiuntivi prima di elaborare qualsiasi messaggio  
# I moduli in questo elenco verranno caricati prima che Yaa! elabori qualsiasi  
# messaggio in modalità di processo singolo o diventi daemon, quando eseguito  
# in modalità daemon.  
#   
# Questo parametro di configurazione è molto utile quando  
# si esegue in chroot jail  
#   
# tipo: array  
# predefinito: array vuoto (non caricare moduli aggiuntivi)  
@extra_modules = (  
    # !!!!AVVERTENZA!!!!  
    # quando come daemon chrooted, decommenta la seguente riga  
    # 'Net::Server::Mail::ESMTP::PIPELINING',  
      
    # se eseguito chrooted, e utilizzando la versione mysql  
    # della mappa di ricerca SQL, decommenta la seguente riga  
    #'DBD::mysql',  
      
    # se eseguito chrooted, e utilizzando la versione postgres  
    # della mappa di ricerca SQL, decommenta la seguente riga  
    #'DBD::Pg',  
);  
  
######################################################  
#                 !!!!AVVERTENZA!!!!                    #  
#  COMMENTA LA SEGUENTE LINEA PER FAR FUNZIONARE YAA!  #  
#                 !!!!AVVERTENZA!!!!                    #  
######################################################  
#die "Non hai modificato il file di configurazione, vero?:))";  
  
######################################################  
#                 !!!!AVVERTENZA!!!!                    #  
#  NON RIMUOVERE O COMMENTARE LA SEGUENTE LINEA      #  
1;                                                   #  
######################################################  

Dovrai trovare

 'my_sql_map' => {  
        'driver' => 'SQL',  
        'sql_dsn' => 'dbi:mysql:database=mail;host=localhost',  
        'sql_username' => "mail_admin",  
        'sql_password' => "mail_admin_password",  
        'sql_select' => "select active,message,subject,charset,forward from autoresponder where address = %m and active='1'",  

e modificare per il tuo nome utente e password.

Successivamente dobbiamo aggiungere alcune voci aggiuntive al database.

INSERT INTO `forwardings` ( `source` , `destination` ) VALUES ('[email protected]', '[email protected], [email protected]');
INSERT INTO `transport` ( `domain` , `transport` ) VALUES ('autoreply.domain.com', 'yaa');
INSERT INTO `autoresponder` ( `active` , `message` , `subject` , `charset` , `forward` , `address` , `local_domains` , `tstart` , `tfinish` ) VALUES ('1', 'Message Body', 'Message Subject', '', '', '[email protected]', 'autoreply.domain.com', '0', '0');

Inoltre puoi popolare i valori tstart/tfinish, questi sono fatti in timestamp Unix e ti permettono di abilitare l’autoresponder per un determinato periodo di tempo - ottimo per le persone che dimenticano sempre di disattivarli dopo essere tornate in ufficio, per esempio!

INSERT INTO `autoresponder` ( `active` , `message` , `subject` , `charset` , `forward` , `address` , `local_domains` , `tstart` , `tfinish` ) VALUES ('1', 'Message Body', 'Message Subject', '', '', '[email protected]', 'autoreply.domain.com', UNIX_TIMESTAMP(), UNIX_TIMESTAMP() + 14400);

Sotto Thunderbird ho notato un comportamento molto strano riguardo all’oggetto della risposta, quindi ho cercato su Google e trovato una piccola patch per risolvere il problema.

Crea un file chiamato email_subject.patch:

--- Autoresponse.pm     2004-08-19 20:35:28.000000000 +0200  
+++ Autoresponse.pm     2005-07-14 13:16:03.000000000 +0200  
@@ -182,7 +182,11 @@  
        push(@headers, "Precedence: bulk");  
  
        # Oggetto  
-       push(@headers, "Subject: =?" . (($self->{charset}) ? $self->{charset} : $self->{default_charset}) . "?Q?" . encode_qp($subject) . "?=");  
+       #  
+       # Risolve i soggetti strani che i client email non capiscono  
+       # (il secondo argomento su encode_qp dovrebbe essere "")  
+       push(@headers, "Subject: =?" . (($self->{charset}) ? $self->{charset} : $self->{default_charset}) . "?Q?" . encode_qp($subject,"") . "?=");  
  
        push(@headers, "MIME-Version: 1.0"); 

Successivamente applichiamo la patch:

cd /usr/local/postfix-tools/yaa-0.3/lib/
patch -p0 

Questa guida non si occupa della versione daemonizzata di Yaa! che probabilmente sarebbe più efficiente su volumi estremamente elevati di posta, ma dovrebbe essere solo una questione di modificare il file yaa.conf se è necessaria la versione daemon.

Yaa ha alcune ottime funzionalità, come non rispondere alla stessa persona entro un certo periodo di tempo, quindi può essere molto intelligente, specialmente poiché puoi avere due programmi di autoresponder che rispondono a se stessi e creano un loop. Questo non accade con Yaa!

Share: X/Twitter LinkedIn

Ricevi i nuovi post nella tua casella di posta.

Nessuno spam. Disiscriviti in qualsiasi momento.