Автоответчики · 13 min read · Jan 04, 2026

Автоответчики для виртуальных пользователей и доменов с Postfix, Courier и MySQL

Автоответчики для виртуальных пользователей и доменов с Postfix, Courier и MySQL

Этот гид сосредоточен на том, чтобы заставить Yaa! (Yet Another Autoresponder!) работать с Debian Sarge и виртуальными пользователями в учебнике по Postfix (см. https://www.howtoforge.com/virtual_postfix_mysql_quota_courier).

Первое, что нужно понять о руководстве, это то, что оно использует Virtual Delivery Agent (VDA), и в результате любые автоответчики, которые вы могли бы использовать, передавая их в трубу через файл .forward, просто не будут работать, так как VDA не поддерживает расширения .forward. Это ограничение можно преодолеть с помощью доставки Procmail/Maildrop, но это неаккуратно и медленно, особенно для почтовых систем, которые активно используются. Простое решение — Yaa!

Давайте загрузим Yaa и начнем вечеринку:

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

Следующим шагом нам нужно получить необходимые модули Perl, чтобы Yaa работал. Yaa работает в обоих режимах демона, однако в этом руководстве я буду беспокоиться только о недемонизированном режиме программы.

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

Давайте настроим структуру базы данных, чтобы Yaa работал:

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;

Следующим шагом мы хотим настроить Postfix для вызова Yaa! через транспорт, поэтому нам нужно отредактировать /etc/postfix/master.cf, чтобы добавить следующее:

 # yaa автоответчик  
yaa     unix    -       n       n       -       -       pipe  
                                                        user=vmail  
                                                        argv=/usr/local/postfix-tools/yaa-0.3/bin/yaa.pl

Давайте перезапустим Postfix, чтобы применить изменения:

/etc/init.d/postfix restart

Наконец, нам нужно настроить Yaa! Чтобы упростить задачу, я предоставил свой yaa.conf

######################################################  
#                 !!!!WARNING!!!!                    #  
#  DO NOT REMOVE OR COMMENT OUT THE FOLLOWING LINE   #  
use strict;                                          #  
######################################################  
  
# УВЕДОМЛЕНИЕ:  
# Если у вас возникли проблемы с запуском yaa.pl и вы  
# не уверены, что идет не так, установите переменную окружения  
#  
#                   YAA_DEBUG  
#  
# и запустите yaa.pl снова с теми же аргументами/файлом конфигурации.  
#  
# Вывод отладки Yaa будет записан в stderr, если запущен в одиночном  
# режиме обработки сообщений или в режиме демона с $daemon_background = 0.  
#   
# Если вы работаете в режиме демона с $daemon_background = 1, сообщения отладки  
# будут отправлены в подсистему журнала, если она включена.  
#  
# пример для csh:  
# setenv YAA_DEBUG 1  
#  
# пример для sh/ksh/bash:  
# export YAA_DEBUG=1  
#  
  
# ОБЩИЕ ЗАМЕТКИ  
#   
# отрывок взят из файла конфигурации отличного проекта с открытым исходным кодом  
# под названием amavisd-new   
# от Марка Мартинеца .  
#   
#  Этот файл является обычным кодом Perl, интерпретируемым самим Perl.  
#  - убедитесь, что этот файл (или каталог, в котором он находится) НЕ ДОЛЖЕН БЫТЬ ЗАПИСЫВАЕМЫМ  
#    простыми смертными, иначе это представляет собой серьезный риск безопасности!  
#  - для значений, которые интерпретируются как логические, рекомендуется  
#    использовать 1 для истинного, и 0 или undef или '' для ложного.  
#  - применяется синтаксис Perl. В частности: строки в "" могут включать переменные  
#    (которые начинаются с $ или @); чтобы включить символы @ и $ в двойные  
#    кавычки, предшествуйте им обратным слэшем; в строках в одинарных кавычках  
#    $ и @ теряют свое особое значение, поэтому обычно проще использовать  
#    строки в одинарных кавычках. Тем не менее, в обоих случаях обратный слэш должен быть удвоен.  
  
######################################################  
#           НАСТРОЙКИ ПОДСИСТЕМЫ ЖУРНАЛИРОВАНИЯ               #  
######################################################  
  
# включить журналирование?  
# тип: логическое  
# по умолчанию: 1  
# $logging = 1;  
  
# включить журналирование в syslog?  
# тип: логическое  
# по умолчанию: 1  
$log_syslog = 1;  
  
# подсистема журналирования syslog  
# тип: строка  
# по умолчанию: "mail"  
# эта настройка применяется только при включенном журналировании в syslog  
# $log_syslog_facility = "mail";  
  
# приоритет журналирования syslog  
# тип: строка  
# по умолчанию: "info"  
# эта настройка применяется только при включенном журналировании в syslog  
# $log_syslog_priority = "info";  
  
# журналировать в текстовый файл?  
# тип: логическое  
# по умолчанию: 0  
#$log_file = 1;  
  
# имя файла журнала  
# тип: строка  
# по умолчанию: undef  
# эта настройка применяется только при включенном журналировании в файл  
#$log_file_filename = "/var/log/yaa.log";  
  
# журналировать в stderr?  
# тип: логическое  
# по умолчанию: 0  
# !!!! ПРЕДУПРЕЖДЕНИЕ !!!!  
# когда отладка yaa включена (переменная окружения YAA_DEBUG установлена),  
# вывод STDERR сопоставляется с подсистемой журнала, и ничего на самом деле не отображается  
# на реальном stderr, поэтому убедитесь, что настроено журналирование на основе syslog или файла.  
# !!!! ПРЕДУПРЕЖДЕНИЕ !!!!  
# $log_stderr = 0;  
  
# формат времени журнала при журналировании в файл  
# тип: строка  
# по умолчанию: "[%a, %b %e %T %Y]: "  
# см. strftime(3) для получения дополнительной информации  
# $log_time_format = undef;  
  
######################################################  
#               НАСТРОЙКИ РЕЖИМА ДЕМОНА                 #  
######################################################  
  
# запускать как демон?  
# тип: логическое  
# по умолчанию: 0, не запускать как демон  
# эта настройка включает работу в режиме демона.  
# $daemon = 1;  
  
$daemon = 0;  
$daemon_lockfile = "/tmp/yaa.lock";  
$daemon_pidfile = "/tmp/yaa.pid";  
$daemon_tcpserver_loglevel = 4;  
  
# форк в фоновый режим при запуске как демон?  
# по умолчанию: 1  
# эта настройка применяется только при работе в режиме демона  
# $daemon_background = 1;  
  
# файл блокировки демона  
# тип: строка  
# по умолчанию: "/var/lock/yaa.lock"  
# эта настройка применяется только при работе в режиме демона  
# ПРЕДУПРЕЖДЕНИЕ: если работаете в chroot тюрьме, эту опцию следует  
# установить относительно каталога chroot  
# $daemon_lockfile = "/tmp/yaa.lock";  
  
# файл pid демона  
# тип: строка  
# по умолчанию: "/var/run/yaa.lock"  
# эта настройка применяется только при работе в режиме демона  
# $daemon_pidfile = "/tmp/yaa.pid";  
  
# минимальное количество дочерних процессов yaa  
# тип: целое число  
# по умолчанию: 2  
# эта настройка применяется только при работе в режиме демона  
# $daemon_min_servers = 2;  
  
# максимальное количество дочерних процессов yaa  
# тип: целое число  
# по умолчанию: 3  
# эта настройка применяется только при работе в режиме демона  
# $daemon_max_servers = 3;  
  
# минимальное количество запасных дочерних процессов yaa  
# тип: целое число  
# по умолчанию: 1  
# эта настройка применяется только при работе в режиме демона  
# $daemon_min_spare_servers = 0;  
  
# максимальное количество запасных дочерних процессов yaa  
# тип: целое число  
# по умолчанию: 1  
# эта настройка применяется только при работе в режиме демона  
#$daemon_max_spare_servers = 1;  
  
# протокол связи демона  
# тип: строка  
# протокол, который ваш MTA использует для связи с yaa  
#  
# УВЕДОМЛЕНИЕ: для возможных значений этого параметра конфигурации выполните  
# yaa.pl --list-transport-protocols  
#  
# по умолчанию: "SMTP"  
# эта настройка применяется только при работе в режиме демона  
# $daemon_protocol = "LMTP";  
  
# tcp порт прослушивания или сокет домена unix, на котором yaa должен слушать  
# тип: целое число/строка  
# по умолчанию: 40000  
# чтобы указать сокет домена unix, установите значение: '/path/to/socket|unix'  
#  
# см. также: perldoc Net::Server::Proto  
#  
# эта настройка применяется только при работе в режиме демона  
# $daemon_listen_port = 40000;  
  
# имя хоста, к которому yaa должен привязываться.  
# тип: строка  
# по умолчанию: "localhost"  
# эта настройка применяется только при работе в режиме демона  
# $daemon_listen_host = "127.0.0.1";  
  
# уровень журнала tcpserver (Net::Server) демона  
# тип: целое число  
# по умолчанию: 0  
# 'O' => отключить журналирование  
# 0 => 'err'  
# 1 => 'warning'  
# 2 => 'notice'  
# 3 => 'info'  
# 4 => 'debug'  
$daemon_tcpserver_loglevel = 4;  
  
######################################################  
#               НАСТРОЙКИ ОБЪЕКТА YAA                  #  
######################################################  
  
# каталог, используемый для хранения базы данных времени отправки автоответного сообщения.  
# тип: строка  
# по умолчанию: "/tmp"  
# !!!! ПРЕДУПРЕЖДЕНИЕ !!!!  
#   -  если вы запускаете yaa в chroot (см. переменную конфигурации $chroot),  
#      тогда вам нужно установить эту переменную на значение, ОТНОСИТЕЛЬНО к каталогу chroot  
#   - каталог должен быть записываемым для uid/gid, которые yaa использует для обработки сообщений  
#     см. также переменные $user и $group  
#  
# !!!! ПРЕДУПРЕЖДЕНИЕ !!!!  
$db_dir = "/db";  
  
# время в секундах между отправкой автоответов одному и тому же отправителю сообщения от получателя сообщения, у которого автоответчик  
# включен.  
#   
# !!!! ПРЕДУПРЕЖДЕНИЕ !!!!  
#  
# Для тестирования установите -1 (выключите проверку времени),   
# НО НЕ УСТАНАВЛИВАЙТЕ ЭТО ЗНАЧЕНИЕ НИЖЕ 3600 (1 час) НА  
# ПРОДАКШН СИСТЕМЕ !!!!  
#  
# !!!! ПРЕДУПРЕЖДЕНИЕ !!!!  
# тип: целое число  
# по умолчанию: 7200  
# $duration_interval = 24 * 60 * 60;  
$duration_interval = "-1";  
  
######################################################  
#             НАСТРОЙКИ АВТООТВЕТА                  #  
######################################################  
  
# метод, используемый для отправки автоответов и пересылки сообщений  
# тип: строка  
# возможные значения: "smtp", "sendmail"  
# - "smtp" использует smtp сервер для отправки почты  
# - "sendmail" вызывает бинарный файл sendmail для отправки почты  
#  
# !!!!ПРЕДУПРЕЖДЕНИЕ!!!!: странные вещи происходят при использовании метода отправки sendmail  
# и запуске в режиме демона!  
#  
# по умолчанию: "smtp"  
# $mail_sending_method = "smtp";  
  
# путь к программе sendmail  
# тип строка  
# по умолчанию: автоматически ищется в переменной окружения $PATH;  
# undef, если не найден в $PATH.  
#$sendmail_path = undef;  
  
# Настройка SMTP сервера  
# тип: строка  
#  
# см. также perldoc Net::SMTP  
#  
# по умолчанию: localhost  
# $smtp_server = "localhost";  
  
# Использовать SMTP аутентификацию?  
# тип: логическое  
# по умолчанию: 0  
# $smtp_auth = 0;  
  
# Имя пользователя SMTP аутентификации  
# тип: строка  
# по умолчанию: undef  
# $smtp_username = undef;  
  
# Пароль SMTP аутентификации  
# тип: строка  
# по умолчанию: undef  
# $smtp_password = undef;  
  
######################################################  
#              НАСТРОЙКИ КАРТЫ ПОИСКА                   #  
######################################################  
  
# Список ВСЕХ карт поиска  
# Вам нужно определить карты поиска здесь и  
# затем установить порядок запроса lookup_map_query_order, где вы ссылаетесь на  
# имя поиска  
#   
# УВЕДОМЛЕНИЕ:  
# Все карты поиска инициализируются ДО того, как Yaa! войдет в chroot тюрьму (если такая есть)  
# и ДО начала обработки электронной почты.  
#   
# УВЕДОМЛЕНИЕ: Чтобы получить список всех драйверов поиска, выполните  
# yaa.pl --list-lookup-map-drivers  
#   
# тип: хэш хэшей  
# по умолчанию: пустой хэш (карты поиска не определены)  
$lookup_maps = {  
    #  
    # !!!ПРЕДУПРЕЖДЕНИЕ!!!!  
    #  
    # ДЛЯ ПОЛНОГО СПИСКА АРГУМЕНТОВ КОНФИГУРАЦИИ ДРАЙВЕРА  
    # ВЫПОЛНИТЕ yaa.pl --show-lookup-map-doc   
    #  
    # Формат конфигурации карты поиска  
    #   
    # 'map_name' => {  
    #    'driver' => 'DRIVER_NAME',  
    #    'driver_param1' => 'value1'.  
    #    'driver_param2' => 'value2',  
    #    'driver_param3' => 'value3',  
    # },  
    #  
    # Пример карты поиска SQL  
    #  
    # (используемая sql база данных: mysql)  
    # (для других типов см. 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'",  
    },  
      
    # Пример карты поиска PCRE  
    #  
    # 'my_pcre_map' => {  
    #    'driver' => 'PCRE',  
    #    'file' => "file.pcre",  
    #    'replacement_num' => 0  
    #},  
      
    # Пример статической карты поиска  
    # 'my_static_map' => {  
    #    'driver' => 'STATIC',  
    #    'result_key1' => 'result_value1',  
    #    'result_key2' => 'result_value2',  
    #    'result' => 'sth'  
    #},  
      
    # Пример карты поиска 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'],  
    #},  
      
    # Пример карты поиска DB_File  
    # 'my_dbf_map' => {  
    #    'driver' => 'DB_File',  
    #    'file' => "/path/to/mydb",  
    #},  
      
    # Пример карты поиска BerkeleyDB  
    #'my_dbd_map' => {  
    #    'driver' => 'BerkeleyDB',  
    #    'type' => 'Btree',  
    #    'file' => "/path/to/mydb"  
    #},  
};  
  
# порядок запроса карты поиска по атрибуту  
# для каждого автоответа, кроме 'rewrite_recipient' и 'rewrite_sender', должен  
# быть определен порядок запроса поиска  
#   
# Каждый элемент может быть указан как:  
# + строка   (пример: 'domain.tld')  
#   
# ИЛИ  
#   
# lookup_map_name:result_value (пример: 'my_pcre_map:result')  
#  
# Карта поиска распознается по символу ':' в строке.  
#  
# Карта поиска 'lookup_map_name' ДОЛЖНА БЫТЬ указана в параметре конфигурации $lookup_maps  
# в yaa.conf  
#   
# тип: хэш хэшей  
# по умолчанию: пустой хэш (списки порядков поиска не определены)  
#   
$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'  
        ],  
};  
  
######################################################  
#                 ДРУГИЕ НАСТРОЙКИ                     #  
######################################################  
  
# chroot в какой-то каталог?  
# тип: строка  
# по умолчанию: undef, не chroot  
# Предупреждение: yaa должен быть запущен от имени суперпользователя, чтобы включить эту функцию.  
# это относится как к режиму демона, так и к режиму обработки одного сообщения  
# $chroot = undef;  
  
# изменить uid/gid перед обработкой?  
# тип: строка  
# по умолчанию: undef, не изменять uid/gid  
# Предупреждение: yaa должен быть запущен от имени суперпользователя, чтобы включить эту функцию.  
# это относится как к режиму демона, так и к режиму обработки одного сообщения  
# $user = undef;  
# $group = undef;  
  
# Загружать дополнительные модули perl перед обработкой любого сообщения  
# Модули из этого списка будут загружены перед тем, как Yaa! обработает любое  
# сообщение в режиме одиночного процесса или станет демоном, когда работает  
# в режиме демона.  
#   
# Этот параметр конфигурации очень удобен, когда  
# работаете в chroot тюрьме  
#   
# тип: массив  
# по умолчанию: пустой массив (не загружать дополнительные модули)  
@extra_modules = (  
    # !!!!ПРЕДУПРЕЖДЕНИЕ!!!!  
    # когда как chrooted демон, раскомментируйте следующую строку  
    # 'Net::Server::Mail::ESMTP::PIPELINING',  
      
    # если работаете в chrooted, и используете mysql версию  
    # карты поиска SQL, раскомментируйте следующую строку  
    #'DBD::mysql',  
      
    # если работаете в chrooted, и используете postgres версию  
    # карты поиска SQL, раскомментируйте следующую строку  
    #'DBD::Pg',  
);  
  
######################################################  
#                 !!!!ПРЕДУПРЕЖДЕНИЕ!!!!                    #  
#  ЗАКОММЕНТИРУЙТЕ СЛЕДУЮЩУЮ СТРОКУ, ЧТОБЫ YAA РАБОТАЛ!  #  
#                 !!!!ПРЕДУПРЕЖДЕНИЕ!!!!                    #  
######################################################  
#die "Вы не редактировали файл конфигурации, не так ли?:))";  
  
######################################################  
#                 !!!!ПРЕДУПРЕЖДЕНИЕ!!!!                    #  
#  НЕ УДАЛЯЙТЕ И НЕ КОММЕНТИРУЙТЕ СЛЕДУЮЩУЮ СТРОКУ   #  
1;                                                   #  
######################################################  

Вам нужно найти

 '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'", 

и отредактировать для вашего собственного имени пользователя и пароля.

Следующим шагом нам нужно добавить несколько дополнительных записей в базу данных.

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', 'Текст сообщения', 'Тема сообщения', '', '', '[email protected]', 'autoreply.domain.com', '0', '0');

Кроме того, вы можете заполнить значения tstart/tfinish, они задаются в метке времени Unix и позволяют вам включить автоответчик на определенный период времени — отлично подходит для людей, которые всегда забывают отключить их после возвращения в офис, например!

INSERT INTO `autoresponder` ( `active` , `message` , `subject` , `charset` , `forward` , `address` , `local_domains` , `tstart` , `tfinish` ) VALUES ('1', 'Текст сообщения', 'Тема сообщения', '', '', '[email protected]', 'autoreply.domain.com', UNIX_TIMESTAMP(), UNIX_TIMESTAMP() + 14400);

В Thunderbird я заметил некоторые очень странные поведения относительно темы ответа, поэтому я погуглил и нашел небольшой патч, чтобы исправить проблему.

Создайте файл с именем 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");  
  
        # Тема  
-       push(@headers, "Subject: =?" . (($self->{charset}) ? $self->{charset} : $self->{default_charset}) . "?Q?" . encode_qp($subject) . "?=");  
+       #  
+       # Исправляет странные темы, которые почтовые клиенты не понимают  
+       # (второй аргумент на encode_qp должен быть "")  
+       push(@headers, "Subject: =?" . (($self->{charset}) ? $self->{charset} : $self->{default_charset}) . "?Q?" . encode_qp($subject,"") . "?=");  
  
        push(@headers, "MIME-Version: 1.0"); 

Следующим шагом мы применяем патч:

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

Этот гид не касается демонизированной версии Yaa!, которая, вероятно, будет более эффективной при очень высоких объемах почты, но это должно быть лишь вопросом настройки файла yaa.conf, если требуется версия демона.

Yaa имеет некоторые отличные функции, такие как отсутствие ответа одному и тому же человеку в течение определенного времени, поэтому он может быть очень умным, особенно поскольку вы можете получить две программы автоответчиков, отвечающие друг другу и создающие цикл. Это не происходит с Yaa!

Share: X/Twitter LinkedIn

Get new posts in your inbox

No spam. Unsubscribe anytime.