Autoresponders · 14 min read · Jan 04, 2026
Autoresponders para acompanhar Usuários Virtuais e Domínios com Postfix, Courier e MySQL
Autoresponders para acompanhar Usuários Virtuais e Domínios com Postfix, Courier e MySQL
Este guia foca em fazer o Yaa! (Yet Another Autoresponder!) funcionar com Debian Sarge e o tutorial de usuários virtuais no Postfix (veja https://www.howtoforge.com/virtual_postfix_mysql_quota_courier).
A primeira coisa a entender sobre o guia é que ele usa o Agente de Entrega Virtual (VDA) e, como resultado, qualquer um dos autoresponders que você poderia usar passando-os para um pipe via um arquivo .forward simplesmente não funcionará, pois o VDA não suporta expansões .forward. Essa limitação pode ser superada via entrega Procmail/Maildrop, mas isso é bagunçado e mais lento, especialmente para sistemas de e-mail que são muito utilizados. A resposta simples é Yaa!
Vamos baixar o Yaa e começar a festa:
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.bz2Em seguida, precisamos obter os módulos Perl necessários para fazer o Yaa funcionar. O Yaa funciona em ambos os modos de daemon, no entanto, neste guia, eu só vou me preocupar com o modo não daemonizado do 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 configurar a estrutura do banco de dados para que o 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;Em seguida, queremos configurar o Postfix para invocar o Yaa! via um transporte, então precisamos editar /etc/postfix/master.cf para adicionar o seguinte:
# yaa autoresponder
yaa unix - n n - - pipe
user=vmail
argv=/usr/local/postfix-tools/yaa-0.3/bin/yaa.plVamos reiniciar o Postfix para habilitar as mudanças:
/etc/init.d/postfix restartFinalmente, precisamos configurar o Yaa! Para facilitar as coisas, eu forneci meu yaa.conf
######################################################
# !!!!WARNING!!!! #
# NÃO REMOVA OU COMENTE A LINHA SEGUINTE #
use strict; #
######################################################
# AVISO:
# Se você está tendo problemas para executar yaa.pl e não
# tem certeza do que está errado, defina a variável de ambiente
#
# YAA_DEBUG
#
# e execute yaa.pl novamente com os mesmos argumentos/arquivo de configuração.
#
# A saída de depuração do Yaa será escrita no stderr se executado em modo de
# processamento de mensagem única ou em modo daemon com $daemon_background = 0.
#
# Se você estiver executando em modo daemon com $daemon_background = 1, mensagens de depuração
# serão enviadas para o subsistema de logger se estiver habilitado.
#
# exemplo para csh:
# setenv YAA_DEBUG 1
#
# exemplo para sh/ksh/bash:
# export YAA_DEBUG=1
#
# NOTAS GERAIS
#
# trecho retirado do arquivo de configuração do excelente projeto opensource
# chamado amavisd-new
# por Mark Martinec .
#
# Este arquivo é um código Perl normal, interpretado pelo próprio Perl.
# - certifique-se de que este arquivo (ou diretório onde reside) NÃO É GRAVÁVEL
# por meros mortais, caso contrário, representa um grave risco de segurança!
# - para valores que são interpretados como booleanos, é recomendado
# usar 1 para verdadeiro, e 0 ou undef ou '' para falso.
# - A sintaxe Perl se aplica. Notavelmente: strings em "" podem incluir variáveis
# (que começam com $ ou @); para incluir caracteres @ e $ em strings entre aspas duplas,
# preceda-os com uma barra invertida; em strings entre aspas simples
# o $ e @ perdem seu significado especial, então geralmente é mais fácil usar
# strings entre aspas simples. Ainda assim, em ambos os casos a barra invertida precisa ser duplicada.
######################################################
# CONFIGURAÇÕES DO SUBSISTEMA DE LOGGING #
######################################################
# habilitar logging?
# tipo: booleano
# padrão: 1
# $logging = 1;
# habilitar logging para syslog?
# tipo: booleano
# padrão: 1
$log_syslog = 1;
# instalação de logging syslog
# tipo: string
# padrão: "mail"
# esta configuração se aplica apenas quando o logging para syslog está habilitado
# $log_syslog_facility = "mail";
# prioridade de logging syslog
# tipo: string
# padrão: "info"
# esta configuração se aplica apenas quando o logging para syslog está habilitado
# $log_syslog_priority = "info";
# log para arquivo de texto?
# tipo: booleano
# padrão: 0
#$log_file = 1;
# nome do arquivo de log
# tipo: string
# padrão: undef
# esta configuração se aplica apenas quando o logging para arquivo está habilitado
#$log_file_filename = "/var/log/yaa.log";
# log para stderr?
# tipo: booleano
# padrão: 0
# !!!! AVISO !!!!
# quando a depuração do yaa está ativada (variável de ambiente YAA_DEBUG está definida),
# a saída STDERR é mapeada para o subsistema de logger e nada aparece
# no verdadeiro stderr, então certifique-se de configurar o logging baseado em syslog ou arquivo.
# !!!! AVISO !!!!
# $log_stderr = 0;
# formato de tempo do log ao registrar em arquivo
# tipo: string
# padrão: "[%a, %b %e %T %Y]: "
# veja strftime(3) para mais detalhes
# $log_time_format = undef;
######################################################
# CONFIGURAÇÕES DO MODO DAEMON #
######################################################
# executar como daemon?
# tipo: booleano
# padrão: 0, não executar como daemon
# esta configuração habilita a operação em modo daemon.
# $daemon = 1;
$daemon = 0;
$daemon_lockfile = "/tmp/yaa.lock";
$daemon_pidfile = "/tmp/yaa.pid";
$daemon_tcpserver_loglevel = 4;
# fork para o background ao executar como daemon?
# padrão: 1
# esta configuração se aplica apenas quando operando em modo daemon
# $daemon_background = 1;
# arquivo de bloqueio do daemon
# tipo: string
# padrão: "/var/lock/yaa.lock"
# esta configuração se aplica apenas quando operando em modo daemon
# AVISO: se executando em chroot jail, esta opção deve ser
# definida em relação ao diretório chroot
# $daemon_lockfile = "/tmp/yaa.lock";
# arquivo pid do daemon
# tipo: string
# padrão: "/var/run/yaa.lock"
# esta configuração se aplica apenas quando operando em modo daemon
# $daemon_pidfile = "/tmp/yaa.pid";
# número mínimo de processos filhos do yaa
# tipo: inteiro
# padrão: 2
# esta configuração se aplica apenas quando operando em modo daemon
# $daemon_min_servers = 2;
# número máximo de processos filhos do yaa
# tipo: inteiro
# padrão: 3
# esta configuração se aplica apenas quando operando em modo daemon
# $daemon_max_servers = 3;
# número mínimo de processos filhos do yaa em espera
# tipo: inteiro
# padrão: 1
# esta configuração se aplica apenas quando operando em modo daemon
# $daemon_min_spare_servers = 0;
# número máximo de processos filhos do yaa em espera
# tipo: inteiro
# padrão: 1
# esta configuração se aplica apenas quando operando em modo daemon
#$daemon_max_spare_servers = 1;
# protocolo de comunicação do daemon
# tipo: string
# protocolo que seu MTA usa para comunicação com yaa
#
# AVISO: para possíveis valores para este parâmetro de configuração, EXECUTE
# yaa.pl --list-transport-protocols
#
# padrão: "SMTP"
# esta configuração se aplica apenas quando operando em modo daemon
# $daemon_protocol = "LMTP";
# porta de escuta tcp ou socket de domínio unix no qual o yaa deve escutar
# tipo: inteiro/string
# padrão: 40000
# para especificar socket de domínio unix, defina o valor como: '/path/to/socket|unix'
#
# veja também: perldoc Net::Server::Proto
#
# esta configuração se aplica apenas quando operando em modo daemon
# $daemon_listen_port = 40000;
# nome do host ao qual o yaa deve se vincular.
# tipo: string
# padrão: "localhost"
# esta configuração se aplica apenas quando operando em modo daemon
# $daemon_listen_host = "127.0.0.1";
# nível de log do tcpserver do daemon (Net::Server)
# tipo: inteiro
# padrão: 0
# 'O' => desabilitar logging
# 0 => 'err'
# 1 => 'warning'
# 2 => 'notice'
# 3 => 'info'
# 4 => 'debug'
$daemon_tcpserver_loglevel = 4;
######################################################
# CONFIGURAÇÕES DO OBJETO YAA #
######################################################
# diretório usado para armazenar o banco de dados de tempo de envio da mensagem de resposta automática.
# tipo: string
# padrão: "/tmp"
# !!!! AVISO !!!!
#
# - se você estiver executando yaa em chroot (veja a variável de configuração $chroot),
# então você precisa definir esta variável para um valor RELATIVO ao diretório chroot
#
# - o diretório deve ser gravável para uid/gid que o yaa usa para processamento de mensagens
# veja também as variáveis $user e $group
#
# !!!! AVISO !!!!
# $db_dir = "/db";
# tempo em segundos entre duas respostas automáticas que serão enviadas para o
# mesmo remetente de mensagem do destinatário que tem o autoresponder
# ativado.
#
# !!!! AVISO !!!!
#
# Para fins de teste, defina como -1 (desativar verificação de tempo),
# MAS NÃO DEFINA ESTE VALOR MENOR QUE 3600 (1 hora) NO
# SISTEMA DE PRODUÇÃO !!!!
#
# !!!! AVISO !!!!
# tipo: inteiro
# padrão: 7200
# $duration_interval = 24 * 60 * 60;
$duration_interval = "-1";
######################################################
# CONFIGURAÇÕES DE RESPOSTA AUTOMÁTICA #
######################################################
# método usado para enviar respostas automáticas e encaminhar mensagens
# tipo: string
# valores possíveis: "smtp", "sendmail"
# - "smtp" usa servidor smtp para enviar e-mail
# - "sendmail" invoca o binário sendmail para enviar e-mail
#
# !!!!AVISO!!!!: coisas estranhas acontecem ao usar o método de envio sendmail
# e executando em modo daemon!
#
# padrão: "smtp"
# $mail_sending_method = "smtp";
# caminho do programa sendmail
# tipo string
# padrão: pesquisado automaticamente na variável de ambiente $PATH;
# undef se não encontrado no $PATH.
#$sendmail_path = undef;
# configuração do servidor SMTP
# tipo: string
#
# veja também perldoc Net::SMTP
#
# padrão: localhost
# $smtp_server = "localhost";
# Usar autenticação SMTP?
# tipo: booleano
# padrão: 0
# $smtp_auth = 0;
# nome de usuário de autenticação SMTP
# tipo: string
# padrão: undef
# $smtp_username = undef;
# senha de autenticação SMTP
# tipo: string
# padrão: undef
# $smtp_password = undef;
######################################################
# CONFIGURAÇÕES DO MAPA DE BUSCA #
######################################################
# Lista de TODOS os mapas de busca
# Você precisa definir mapas de busca aqui e
# então definir lookup_map_query_order, onde você faz referência ao
# nome da busca
#
# AVISO:
# Todos os mapas de busca são inicializados ANTES do Yaa! entrar na jaula chroot (se houver)
# e ANTES de começar a processar e-mails.
#
# AVISO: Para obter a lista de todos os drivers de busca, EXECUTE
# yaa.pl --list-lookup-map-drivers
#
# tipo: hash de hashes
# padrão: hash vazio (nenhum mapa de busca definido)
$lookup_maps = {
#
# !!!AVISO!!!!
#
# PARA LISTA COMPLETA DOS ARGUMENTOS DE CONFIGURAÇÃO DO DRIVER
# EXECUTE yaa.pl --show-lookup-map-doc
#
# Formato de configuração do mapa de busca
#
# 'map_name' => {
# 'driver' => 'DRIVER_NAME',
# 'driver_param1' => 'value1'.
# 'driver_param2' => 'value2',
# 'driver_param3' => 'value3',
# },
# Exemplo de mapa de busca SQL
#
# (banco de dados usado: mysql)
# (para outros tipos veja 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'",
},
# Exemplo de mapa de busca PCRE
#
# 'my_pcre_map' => {
# 'driver' => 'PCRE',
# 'file' => "file.pcre",
# 'replacement_num' => 0
#},
# Exemplo de mapa de busca ESTÁTICO
# 'my_static_map' => {
# 'driver' => 'STATIC',
# 'result_key1' => 'result_value1',
# 'result_key2' => 'result_value2',
# 'result' => 'sth'
#},
# Exemplo de mapa de busca 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'],
#},
# Exemplo de mapa de busca DB_File
# 'my_dbf_map' => {
# 'driver' => 'DB_File',
# 'file' => "/path/to/mydb",
#},
# Exemplo de mapa de busca BerkeleyDB
#'my_dbd_map' => {
# 'driver' => 'BerkeleyDB',
# 'type' => 'Btree',
# 'file' => "/path/to/mydb"
#},
};
# ordem da consulta do mapa de busca por atributo
# para cada resposta automática, exceto 'rewrite_recipient' e 'rewrite_sender' deve
# ser definida a ordem da consulta de busca
#
# Cada item pode ser especificado como:
# + string (exemplo: 'domain.tld')
#
# OU
#
# lookup_map_name:result_value (exemplo: 'my_pcre_map:result')
#
# O mapa de busca é reconhecido pelo caractere ':' na string.
#
# O 'lookup_map_name' DEVE SER especificado na configuração $lookup_maps
# no parâmetro de configuração yaa.conf
#
# tipo: hash de hashes
# padrão: hash vazio (nenhuma lista de ordem de busca definida)
#
#
$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 => [
#empty
],
rewrite_recipient => [
#empty
],
'local_domains' => [
'my_sql_map:local_domains'
],
};
######################################################
# OUTRAS CONFIGURAÇÕES #
######################################################
# chroot para algum diretório?
# tipo: string
# padrão: undef, não fazer chroot
# Aviso: yaa deve ser iniciado como superusuário para habilitar este recurso.
# isso se aplica ao modo daemon e ao modo de processamento de mensagem única
# $chroot = undef;
# mudar uid/gid antes do processamento?
# tipo: string
# padrão: undef, não mudar uid/gid
# Aviso: yaa deve ser iniciado como superusuário para habilitar este recurso.
# isso se aplica ao modo daemon e ao modo de processamento de mensagem única
# $user = undef;
# $group = undef;
# Carregar módulos Perl adicionais antes de processar qualquer mensagem
# Os módulos nesta lista serão carregados antes que o Yaa! processe qualquer
# mensagem em modo de processo único ou se torne um daemon, ao executar
# em modo daemon.
#
# Este parâmetro de configuração é muito útil quando
# ao executar em chroot jail
#
# tipo: array
# padrão: array vazio (não carregar módulos adicionais)
@extra_modules = (
# !!!!AVISO!!!!
# quando como daemon chrooted, descomente a linha a seguir
# 'Net::Server::Mail::ESMTP::PIPELINING',
# se executando chrooted, e usando a versão mysql
# do mapa de busca SQL, descomente a linha a seguir
#'DBD::mysql',
# se executando chrooted, e usando a versão postgres
# do mapa de busca SQL, descomente a linha a seguir
#'DBD::Pg',
);
######################################################
# !!!!AVISO!!!! #
# COMENTE A LINHA SEGUINTE PARA FAZER O YAA FUNCIONAR! #
# !!!!AVISO!!!! #
######################################################
#die "Você não editou o arquivo de configuração, não é?:))";
######################################################
# !!!!AVISO!!!! #
# NÃO REMOVA OU COMENTE A LINHA SEGUINTE #
1; #
###################################################### Você precisará 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'", e editar para seu próprio nome de usuário e senha.
Em seguida, precisamos adicionar algumas entradas adicionais ao banco de dados.
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', 'Mensagem Corpo', 'Mensagem Assunto', '', '', '[email protected]', 'autoreply.domain.com', '0', '0');Além disso, você pode preencher os valores tstart/tfinish, que são feitos em timestamp Unix e permitem que você ative o autoresponder por um período de tempo específico - ótimo para pessoas que sempre esquecem de desligá-los depois que retornam ao escritório, por exemplo!
INSERT INTO `autoresponder` ( `active` , `message` , `subject` , `charset` , `forward` , `address` , `local_domains` , `tstart` , `tfinish` ) VALUES ('1', 'Mensagem Corpo', 'Mensagem Assunto', '', '', '[email protected]', 'autoreply.domain.com', UNIX_TIMESTAMP(), UNIX_TIMESTAMP() + 14400);Sob o Thunderbird, notei um comportamento muito peculiar em relação ao Assunto da resposta, então eu pesquisei e encontrei um pequeno patch para corrigir o problema.
Crie um arquivo chamado 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");
# Assunto
- push(@headers, "Subject: =?" . (($self->{charset}) ? $self->{charset} : $self->{default_charset}) . "?Q?" . encode_qp($subject) . "?=");
+ #
+ # Corrige os assuntos estranhos que os clientes de e-mail não entendem
+ # (o segundo argumento em encode_qp deve ser "")
+ push(@headers, "Subject: =?" . (($self->{charset}) ? $self->{charset} : $self->{default_charset}) . "?Q?" . encode_qp($subject,"") . "?=");
push(@headers, "MIME-Version: 1.0"); Em seguida, aplicamos o patch:
cd /usr/local/postfix-tools/yaa-0.3/lib/patch -p0 Este guia não se preocupa com a versão daemonizada do Yaa! que provavelmente seria mais eficiente em volumes extremamente altos de e-mail, mas deve ser apenas uma questão de ajustar o arquivo yaa.conf se a versão daemon for necessária.
O Yaa tem alguns ótimos recursos, como não responder a mesma pessoa dentro de um determinado período de tempo, então pode ser muito inteligente, especialmente porque você pode ter dois programas de resposta automática respondendo um ao outro e criando um loop. Isso não acontece com o Yaa!
Receba novas postagens na sua caixa de entrada
Sem spam. Cancele a assinatura a qualquer momento.