Autorespondedores · 14 min read · Jan 04, 2026
Autoresponders para acompañar Usuarios Virtuales y Dominios con Postfix, Courier y MySQL
Autoresponders para acompañar Usuarios Virtuales y Dominios con Postfix, Courier y MySQL
Esta guía se centra en hacer que Yaa! (¡Yet Another Autoresponder!) funcione con Debian Sarge y el tutorial de usuarios virtuales en Postfix (ver https://www.howtoforge.com/virtual_postfix_mysql_quota_courier).
Lo primero que hay que entender sobre la guía es que utiliza el Agente de Entrega Virtual (VDA) y, como resultado, cualquiera de los autorespondedores que podrías usar pasándolos a un pipe a través de un archivo .forward simplemente no funcionará, ya que el VDA no admite expansiones de .forward. Esta limitación se puede superar a través de la entrega de Procmail/Maildrop, pero eso es desordenado y más lento, especialmente para sistemas de correo que se utilizan mucho. La respuesta simple es ¡Yaa!
Vamos a descargar Yaa y comenzar la fiesta:
mkdir -p /usr/local/postfix-tools cd /usr/local/postfix-toolswget http://frost.ath.cx/software/yaa/dist/yaa-0.3.tar.bz2tar jxvf yaa-0.3.tar.bz2A continuación, tenemos que obtener los módulos de Perl requeridos para hacer que Yaa funcione. Yaa funciona en ambos modos de demonio, sin embargo, en esta guía solo me voy a preocupar por el modo no demonizado del programa.
apt-get install libmldbm-perl libio-lockedfile-perl libnet-perl libcarp-clan-perl libdbi-perl libdbd-mysql-perl libnet-server-perl libio-stringy-perlVamos a configurar la estructura de la base de datos para que Yaa funcione:
mysql -uroot -puse 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;A continuación, queremos configurar Postfix para invocar Yaa! a través de un transporte, por lo que necesitamos editar /etc/postfix/master.cf para agregar lo siguiente:
# yaa autoresponder
yaa unix - n n - - pipe
user=vmail
argv=/usr/local/postfix-tools/yaa-0.3/bin/yaa.plVamos a reiniciar Postfix para habilitar los cambios:
/etc/init.d/postfix restartFinalmente, necesitamos configurar Yaa! Para facilitar las cosas, he proporcionado mi yaa.conf
######################################################
# !!!!ADVERTENCIA!!!! #
# NO ELIMINE NI COMENTE LA SIGUIENTE LÍNEA #
use strict; #
######################################################
# AVISO:
# Si tienes problemas para ejecutar yaa.pl y no estás
# seguro de qué está mal, establece la variable de entorno
#
# YAA_DEBUG
#
# y ejecuta yaa.pl nuevamente con los mismos argumentos/configuración.
#
# La salida de depuración de Yaa se escribirá en stderr si se ejecuta en modo de procesamiento de
# mensaje único o en modo demonio con $daemon_background = 0.
#
# Si estás ejecutando en modo demonio con $daemon_background = 1, los mensajes de depuración
# se enviarán al subsistema de registro si está habilitado.
#
# ejemplo para csh:
# setenv YAA_DEBUG 1
#
# ejemplo para sh/ksh/bash:
# export YAA_DEBUG=1
#
# NOTAS GENERALES
#
# extracto tomado del archivo de configuración de un excelente proyecto de código abierto
# llamado amavisd-new
# por Mark Martinec .
#
# Este archivo es un código Perl normal, interpretado por el propio Perl.
# - asegúrate de que este archivo (o el directorio donde reside) NO SEA ESCRIBIBLE
# por simples mortales, de lo contrario representa un grave riesgo de seguridad!
# - para valores que se interpretan como booleanos, se recomienda
# usar 1 para verdadero, y 0 o undef o '' para falso.
# - se aplica la sintaxis de Perl. Más notablemente: las cadenas en "" pueden incluir variables
# (que comienzan con $ o @); para incluir caracteres @ y $ en cadenas entre comillas dobles,
# precede a ellos con una barra invertida; en cadenas entre comillas simples
# el $ y @ pierden su significado especial, por lo que generalmente es más fácil usar
# cadenas entre comillas simples. Aún así, en ambos casos la barra invertida necesita ser duplicada.
######################################################
# CONFIGURACIONES DEL SUBSISTEMA DE REGISTRO #
######################################################
# ¿habilitar registro?
# tipo: booleano
# predeterminado: 1
# $logging = 1;
# ¿habilitar registro en syslog?
# tipo: booleano
# predeterminado: 1
$log_syslog = 1;
# instalación de registro de syslog
# tipo: cadena
# predeterminado: "mail"
# esta configuración se aplica solo cuando el registro en syslog está habilitado
# $log_syslog_facility = "mail";
# prioridad de registro de syslog
# tipo: cadena
# predeterminado: "info"
# esta configuración se aplica solo cuando el registro en syslog está habilitado
# $log_syslog_priority = "info";
# registrar en archivo de texto plano?
# tipo: booleano
# predeterminado: 0
#$log_file = 1;
# nombre del archivo de registro
# tipo: cadena
# predeterminado: indefinido
# esta configuración se aplica solo cuando el registro en archivo está habilitado
#$log_file_filename = "/var/log/yaa.log";
# registrar en stderr?
# tipo: booleano
# predeterminado: 0
# !!!! ADVERTENCIA !!!!
# cuando la depuración de yaa está activada (la variable de entorno YAA_DEBUG está establecida),
# la salida STDERR se asigna al subsistema de registro y nada realmente aparece
# en el verdadero stderr, así que asegúrate de configurar el registro basado en syslog o en archivo.
# !!!! ADVERTENCIA !!!!
# $log_stderr = 0;
# formato de tiempo de registro al registrar en archivo
# tipo: cadena
# predeterminado: "[%a, %b %e %T %Y]: "
# ver strftime(3) para más detalles
# $log_time_format = undef;
######################################################
# CONFIGURACIONES DEL MODO DEMONIO #
######################################################
# ¿ejecutar como demonio?
# tipo: booleano
# predeterminado: 0, no ejecutar como demonio
# esta configuración habilita la operación en modo demonio.
# $daemon = 1;
$daemon = 0;
$daemon_lockfile = "/tmp/yaa.lock";
$daemon_pidfile = "/tmp/yaa.pid";
$daemon_tcpserver_loglevel = 4;
# ¿fork en segundo plano al ejecutarse como demonio?
# predeterminado: 1
# esta configuración se aplica solo cuando se opera en modo demonio
# $daemon_background = 1;
# archivo de bloqueo de aceptación del demonio
# tipo: cadena
# predeterminado: "/var/lock/yaa.lock"
# esta configuración se aplica solo cuando se opera en modo demonio
# ADVERTENCIA: si se ejecuta en una cárcel chroot, esta opción debe ser
# establecida en relación con el directorio chroot
# $daemon_lockfile = "/tmp/yaa.lock";
# archivo pid del demonio
# tipo: cadena
# predeterminado: "/var/run/yaa.lock"
# esta configuración se aplica solo cuando se opera en modo demonio
# $daemon_pidfile = "/tmp/yaa.pid";
# número mínimo de procesos hijo de yaa
# tipo: entero
# predeterminado: 2
# esta configuración se aplica solo cuando se opera en modo demonio
# $daemon_min_servers = 2;
# número máximo de procesos hijo de yaa
# tipo: entero
# predeterminado: 3
# esta configuración se aplica solo cuando se opera en modo demonio
# $daemon_max_servers = 3;
# número mínimo de procesos hijo de yaa en espera
# tipo: entero
# predeterminado: 1
# esta configuración se aplica solo cuando se opera en modo demonio
# $daemon_min_spare_servers = 0;
# número máximo de procesos hijo de yaa en espera
# tipo: entero
# predeterminado: 1
# esta configuración se aplica solo cuando se opera en modo demonio
#$daemon_max_spare_servers = 1;
# protocolo de comunicación del demonio
# tipo: cadena
# protocolo que tu MTA utiliza para comunicarse con yaa
#
# AVISO: para posibles valores para este parámetro de configuración, EJECUTA
# yaa.pl --list-transport-protocols
#
# predeterminado: "SMTP"
# esta configuración se aplica solo cuando se opera en modo demonio
# $daemon_protocol = "LMTP";
# puerto de escucha tcp o socket de dominio unix en el que yaa debe escuchar
# tipo: entero/cadena
# predeterminado: 40000
# para especificar un socket de dominio unix establece el valor en: '/path/to/socket|unix'
#
# ver también: perldoc Net::Server::Proto
#
# esta configuración se aplica solo cuando se opera en modo demonio
# $daemon_listen_port = 40000;
# nombre de host al que yaa debe vincularse.
# tipo: cadena
# predeterminado: "localhost"
# esta configuración se aplica solo cuando se opera en modo demonio
# $daemon_listen_host = "127.0.0.1";
# nivel de registro del servidor tcp del demonio (Net::Server)
# tipo: entero
# predeterminado: 0
# 'O' => deshabilitar registro
# 0 => 'err'
# 1 => 'advertencia'
# 2 => 'aviso'
# 3 => 'info'
# 4 => 'depuración'
$daemon_tcpserver_loglevel = 4;
######################################################
# CONFIGURACIONES DEL OBJETO YAA #
######################################################
# directorio utilizado para almacenar la base de datos de tiempo de envío de mensajes de respuesta automática.
# tipo: cadena
# predeterminado: "/tmp"
# !!!! ADVERTENCIA !!!!
# - si estás ejecutando yaa en chroot (ver variable de configuración $chroot),
# entonces necesitas establecer esta variable en un valor RELATIVO al directorio chroot
# - el directorio debe ser escribible para uid/gid que yaa utiliza para el procesamiento de mensajes
# ver también las variables $user y $group
#
# !!!! ADVERTENCIA !!!!
# $db_dir = "/db";
# tiempo en segundos entre las respuestas automáticas que se enviarán al
# mismo remitente de mensajes desde el destinatario que tiene el autorespondedor
# activado.
#
# !!!! ADVERTENCIA !!!!
#
# Para fines de prueba, establece en -1 (desactivar la verificación de tiempo),
# PERO NO ESTABLEZCAS ESTE VALOR MENOR QUE 3600 (1 hora) EN
# EL SISTEMA DE PRODUCCIÓN !!!!
#
# !!!! ADVERTENCIA !!!!
# tipo: entero
# predeterminado: 7200
# $duration_interval = 24 * 60 * 60;
$duration_interval = "-1";
######################################################
# CONFIGURACIONES DE RESPUESTA AUTOMÁTICA #
######################################################
# método utilizado para enviar respuestas automáticas y reenviar mensajes
# tipo: cadena
# valores posibles: "smtp", "sendmail"
# - "smtp" utiliza el servidor smtp para enviar correo
# - "sendmail" invoca el binario sendmail para enviar correo
#
# !!!!ADVERTENCIA!!!!: cosas extrañas suceden al usar el método de envío sendmail
# y ejecutarse en modo demonio!
#
# predeterminado: "smtp"
# $mail_sending_method = "smtp";
# ruta del programa sendmail
# tipo cadena
# predeterminado: buscado automáticamente en la variable ambiental $PATH;
# indefinido si no se encuentra en $PATH.
#$sendmail_path = undef;
# configuración del servidor SMTP
# tipo: cadena
#
# ver también perldoc Net::SMTP
#
# predeterminado: localhost
# $smtp_server = "localhost";
# ¿Usar autenticación SMTP?
# tipo: booleano
# predeterminado: 0
# $smtp_auth = 0;
# nombre de usuario de autenticación SMTP
# tipo: cadena
# predeterminado: indefinido
# $smtp_username = undef;
# contraseña de autenticación SMTP
# tipo: cadena
# predeterminado: indefinido
# $smtp_password = undef;
######################################################
# CONFIGURACIONES DEL MAPA DE BÚSQUEDA #
######################################################
# Lista de TODOS los mapas de búsqueda
# Necesitas definir mapas de búsqueda aquí y
# luego establecer lookup_map_query_order, donde haces referencia a
# el nombre de búsqueda
#
# AVISO:
# Todos los mapas de búsqueda se inicializan ANTES de que Yaa! entre en la cárcel chroot (si la hay)
# y ANTES de comenzar a procesar correos electrónicos.
#
# AVISO: Para obtener la lista de todos los controladores de búsqueda, EJECUTA
# yaa.pl --list-lookup-map-drivers
#
# tipo: hash de hashes
# predeterminado: hash vacío (sin mapas de búsqueda definidos)
$lookup_maps = {
#
# !!!ADVERTENCIA!!!!
#
# PARA LA LISTA COMPLETA DE ARGUMENTOS DE CONFIGURACIÓN DEL CONTROLADOR
# EJECUTA yaa.pl --show-lookup-map-doc
#
# Formato de configuración del mapa de búsqueda
#
# 'map_name' => {
# 'driver' => 'DRIVER_NAME',
# 'driver_param1' => 'value1'.
# 'driver_param2' => 'value2',
# 'driver_param3' => 'value3',
# },
# Ejemplo de mapa de búsqueda SQL
#
# (base de datos sql utilizada: mysql)
# (para otros tipos ver 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'",
},
# Ejemplo de mapa de búsqueda PCRE
#
# 'my_pcre_map' => {
# 'driver' => 'PCRE',
# 'file' => "file.pcre",
# 'replacement_num' => 0
#},
# Ejemplo de mapa de búsqueda ESTÁTICO
# 'my_static_map' => {
# 'driver' => 'STATIC',
# 'result_key1' => 'result_value1',
# 'result_key2' => 'result_value2',
# 'result' => 'sth'
#},
# Ejemplo de mapa de búsqueda 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'],
#},
# Ejemplo de mapa de búsqueda DB_File
# 'my_dbf_map' => {
# 'driver' => 'DB_File',
# 'file' => "/path/to/mydb",
#},
# Ejemplo de mapa de búsqueda BerkeleyDB
#'my_dbd_map' => {
# 'driver' => 'BerkeleyDB',
# 'type' => 'Btree',
# 'file' => "/path/to/mydb"
#},
};
# orden de consulta del mapa de búsqueda por atributo
# para cada respuesta automática excepto 'rewrite_recipient' y 'rewrite_sender' debe
# definirse el orden de consulta de búsqueda
#
# Cada elemento puede especificarse como:
# + cadena (ejemplo: 'domain.tld')
#
# O
#
# lookup_map_name:result_value (ejemplo: 'my_pcre_map:result')
#
# El mapa de búsqueda es reconocido por el carácter ':' en la cadena.
#
# El 'lookup_map_name' DEL MAPA DE BÚSQUEDA DEBE SER especificado en el parámetro de configuración $lookup_maps
# en yaa.conf
#
# tipo: hash de hashes
# predeterminado: hash vacío (sin listas de orden de búsqueda definidas)
#
#
$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 => [
#vacío
],
rewrite_recipient => [
#vacío
],
'local_domains' => [
'my_sql_map:local_domains'
],
};
######################################################
# OTRAS CONFIGURACIONES #
######################################################
# ¿chroot a algún directorio?
# tipo: cadena
# predeterminado: indefinido, no chroot
# Advertencia: yaa debe iniciarse como superusuario para habilitar esta función.
# esto se aplica al modo demonio y al modo de procesamiento de un solo mensaje
# $chroot = undef;
# cambiar uid/gid antes de procesar?
# tipo: cadena
# predeterminado: indefinido, no cambiar uid/gid
# Advertencia: yaa debe iniciarse como superusuario para habilitar esta función.
# esto se aplica al modo demonio y al modo de procesamiento de un solo mensaje
# $user = undef;
# $group = undef;
# Cargar módulos perl adicionales antes de procesar cualquier mensaje
# Los módulos en esta lista se cargarán antes de que Yaa! procese cualquier
# mensaje en modo de proceso único o se convierta en demonio, al ejecutarse
# en modo demonio.
#
# Este parámetro de configuración es muy útil cuando
# se ejecuta en una cárcel chroot
#
# tipo: array
# predeterminado: array vacío (no cargar ningún módulo adicional)
@extra_modules = (
# !!!!ADVERTENCIA!!!!
# cuando se ejecuta como demonio chrooted, descomenta la siguiente línea
# 'Net::Server::Mail::ESMTP::PIPELINING',
# si se ejecuta en chrooted, y se utiliza la versión mysql
# del mapa de búsqueda SQL, descomenta la siguiente línea
#'DBD::mysql',
# si se ejecuta en chrooted, y se utiliza la versión postgres
# del mapa de búsqueda SQL, descomenta la siguiente línea
#'DBD::Pg',
);
######################################################
# !!!!ADVERTENCIA!!!! #
# ¡COMENTE LA SIGUIENTE LÍNEA PARA HACER QUE YAA FUNCIONE! #
# !!!!ADVERTENCIA!!!! #
######################################################
#die "No has editado el archivo de configuración, ¿verdad?:))";
######################################################
# !!!!ADVERTENCIA!!!! #
# NO ELIMINE NI COMENTE LA SIGUIENTE LÍNEA #
1; #
###################################################### Necesitarás encontrar
'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'", y editar para tu propio nombre de usuario y contraseña.
A continuación, necesitamos agregar algunas entradas adicionales a la base de datos.
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', 'Cuerpo del Mensaje', 'Asunto del Mensaje', '', '', '[email protected]', 'autoreply.domain.com', '0', '0');Además, puedes poblar los valores de tstart/tfinish, estos se hacen en timestamp de Unix y te permiten habilitar el autorespondedor por un período de tiempo particular - ¡genial para las personas que siempre olvidan apagarlos después de regresar a la oficina, por ejemplo!
INSERT INTO `autoresponder` ( `active` , `message` , `subject` , `charset` , `forward` , `address` , `local_domains` , `tstart` , `tfinish` ) VALUES ('1', 'Cuerpo del Mensaje', 'Asunto del Mensaje', '', '', '[email protected]', 'autoreply.domain.com', UNIX_TIMESTAMP(), UNIX_TIMESTAMP() + 14400);Bajo Thunderbird noté un comportamiento muy peculiar respecto al Asunto de la respuesta, así que busqué en Google y encontré un pequeño parche para solucionar el problema.
Crea un archivo llamado 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");
# Asunto
- push(@headers, "Subject: =?" . (($self->{charset}) ? $self->{charset} : $self->{default_charset}) . "?Q?" . encode_qp($subject) . "?=");
+ #
+ # Soluciona los extraños asuntos que los clientes de correo no entienden
+ # (el segundo argumento en encode_qp debería ser "")
+ push(@headers, "Subject: =?" . (($self->{charset}) ? $self->{charset} : $self->{default_charset}) . "?Q?" . encode_qp($subject,"") . "?=");
push(@headers, "MIME-Version: 1.0"); A continuación, aplicamos el parche:
cd /usr/local/postfix-tools/yaa-0.3/lib/patch -p0 Esta guía no se ocupa de la versión demonizada de Yaa! que probablemente sería más eficiente en volúmenes extremadamente altos de correo, pero debería ser solo cuestión de ajustar el archivo yaa.conf si se requiere la versión demonio.
Yaa tiene algunas características geniales, como no responder a la misma persona dentro de un cierto período de tiempo, por lo que puede ser muy inteligente, especialmente porque puedes tener dos programas de autorespondedor respondiéndose entre sí y creando un bucle. Esto no sucede con Yaa!
Recibe nuevas publicaciones en tu bandeja de entrada.
No spam. Cancela la suscripción en cualquier momento.