Скомпилировав рекомендации из нескольких статей и даже почитав документацию, я получил более-менее рабочее решение. Ну в том смысле, что я не до конца понимаю, как оно работает, но получаю ожидаемый результат. Вернее, не всегда получаю ожидаемый результат, что и привело меня на форум.
Итак, когда я делаю вот так: cat /tmp/test |mail test@testdomain.ru , то письмо падает в локальный каталог с почтой. А если я пробую отправить письмо с помощью telnet вот так:
Код: Выделить всё
telnet 127.0.0.1 25
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
220 SRVNAME ESMTP Postfix (Debian/GNU)
helo test@testdomain.ru
250 SRVNAME
mail from:<test@testdomain.ru>
250 2.1.0 Ok
rcpt to:<test@testdomain.ru>
250 2.1.5 Ok
data
354 End data with <CR><LF>.<CR><LF>
test
.
250 2.0.0 Ok: queued as 6B3EF23F923
То письмо уничтожается, с таким логом:
Код: Выделить всё
Jan 7 19:43:36 SRVNAME postfix/smtpd[16839]: connect from localhost[127.0.0.1]
Jan 7 19:43:52 SRVNAME postfix/smtpd[16839]: 6B3EF23F923: client=localhost[127.0.0.1]
Jan 7 19:43:57 SRVNAME postfix/cleanup[16846]: 6B3EF23F923: hold: header Received: from test?testdomain.ru (localhost [127.0.0.1])??by SRVNAME (Postfix) with SMTP id 6B3EF23F923??for <test@testdomain.ru>; Sat, 7 Jan 2017 19:43:45 +0300 (MSK) from localhost[127.0.0.1]; from=<test@testdomain.ru> to=<test@testdomain.ru> proto=SMTP helo=<test?testdomain.ru>
Jan 7 19:43:57 SRVNAME postfix/cleanup[16846]: 6B3EF23F923: message-id=<20170107164352.6B3EF23F923@SRVNAME>
Jan 7 19:43:57 SRVNAME MailScanner[13198]: New Batch: Scanning 1 messages, 954 bytes
Jan 7 19:43:57 SRVNAME MailScanner[13198]: Virus and Content Scanning: Starting
Jan 7 19:44:13 SRVNAME MailScanner[13198]: Requeue: 6B3EF23F923.AA452 to A613E24096B
Jan 7 19:44:13 SRVNAME postfix/qmgr[11496]: A613E24096B: from=<test@testdomain.ru>, size=320, nrcpt=1 (queue active)
Jan 7 19:44:13 SRVNAME postfix/qmgr[11496]: warning: connect to transport private/spamfilter: No such file or directory
Jan 7 19:44:13 SRVNAME MailScanner[13198]: Uninfected: Delivered 1 messages
Jan 7 19:44:13 SRVNAME MailScanner[13198]: Deleted 1 messages from processing-database
Jan 7 19:44:13 SRVNAME postfix/error[16868]: A613E24096B: to=<test@testdomain.ru>, relay=none, delay=28, delays=28/0.01/0/0.05, dsn=4.3.0, status=deferred (mail transport unavailable)
Jan 7 19:44:40 SRVNAME postfix/smtpd[16839]: lost connection after UNKNOWN from localhost[127.0.0.1]
Jan 7 19:44:40 SRVNAME postfix/smtpd[16839]: disconnect from localhost[127.0.0.1]
Я полагаю, проблема где-то между warning: connect to transport private/spamfilter: No such file or directory и status=deferred (mail transport unavailable) . Но понять ничего не выходит, к сожалению.
Пожалуй, покажу конфиги:
Код: Выделить всё
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no
# TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
myhostname = SRVNAME
#For mailscanner
header_checks = regexp:/etc/postfix/header_checks
#Время, в течении которого письма будут находится в очереди
maximal_queue_lifetime = 5d
#Ограничение на размер письма в байтах
message_size_limit = 10000000
#Дополнительные файлы конфигурации
additional_config_dir = /etc/postfix/config
alias_maps = hash:/etc/aliases
#Список доменов, для которых почта будет доставляться локально, а не пересылаться на другой хост.
mydestination = $myhostname, localhost, localhost.$mydomain, $myhostname.$mydomain
#Локальные сети
mynetworks = 127.0.0.0/8 192.168.251.0/24
#Карта алиасов
virtual_alias_maps = proxy:mysql:$additional_config_dir/mysql-virtual_forwardings.cf, mysql:$additional_config_dir/mysql-virtual_email2email.cf
#Карта расположения почтовых ящиков
virtual_mailbox_maps = proxy:mysql:$additional_config_dir/mysql-virtual_mailboxes.cf
#Содержит имена обслуживаемых доменов
virtual_mailbox_domains = proxy:mysql:$additional_config_dir/mysql-virtual_domains.cf
#Нужен чтобы по MAIL FROM узнать логин и затем сверить с логином, по которому прошла аутентификация.
smtpd_sender_login_maps = mysql:$additional_config_dir/mysql-virtual_email2email.cf
#Путь до каталога хранилища почты
virtual_mailbox_base = /var/spool/postfix/maildir
#Карта UID-ов виртуальных пользователей
virtual_uid_maps = static:5000
#Тоже самое для групп:
virtual_gid_maps = static:5000
#Поддержку sasl авторизации
smtpd_sasl_auth_enable = yes
#Поддержки старых версий почтовых клиентов, например Microsoft Outlook Express 4 и Microsoft Exchange 5, использующих другую форму команды AUTH
broken_sasl_auth_clients = yes
#Требуем, чтобы удаленный SMTP клиент представлял себя в начале SMTP сессии с помощью команды HELO или EHLO.
smtpd_helo_required = yes
#Всегда отправлять EHLO вначале SMTP сессии
smtp_always_send_ehlo = yes
#Отключает SMTP команду VRFY. В результате чего, невозможно определить существование определенного
#ящика. Данная техника (применение команды VRFY) используется спамерами для сбора имен почтовых ящиков.
disable_vrfy_command = yes
#Сообщать ли клиентам о возможности использования TLS (шифрования соединения)
smtpd_use_tls = yes
#Карта транспорта
transport_maps = proxy:mysql:$additional_config_dir/mysql-virtual_transports.cf
#Список таблиц, которым разрешено работать через proxymap (кэширует запросы и снижает нагрузку на БД)
proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps $virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks
#Создаем классы:
smtpd_restriction_classes = verify_sender, rbl_cbl_abuseat_org, rbl_sbl_spamhaus_org, rbl_dul_ru, rbl_spamcop, white_client_ip,
#black_client_ip,
block_dsl, helo_access, white_client, mx_access
#Описание классов:
verify_sender = reject_unverified_sender, permit
rbl_cbl_abuseat_org = reject_rbl_client cbl.abuseat.org
rbl_dul_ru = reject_rbl_client dul.ru
rbl_sbl_spamhaus_org = reject_rbl_client sbl.spamhaus.org
rbl_spamcop = reject_rbl_client bl.spamcop.net
#IP адреса, которые нужно пропускать не смотря ни на что
white_client_ip = check_client_access hash:$additional_config_dir/white_client_ip
###IP адреса, которые нужно блокировать не смотря ни на что
###black_client_ip = check_client_access hash:$additional_config_dir/black_client_ip
#Правила для блокировки dsl/модемных пулов, с которых подключаются клиенты.
block_dsl = regexp:$additional_config_dir/block_dsl
#Соблюдение документа RFC 2821
helo_access = check_helo_access pcre:$additional_config_dir/helo_checks
white_client = check_sender_access pcre:$additional_config_dir/access_vip_sender
mx_access = check_sender_mx_access cidr:$additional_config_dir/mx_access
#Далее restrictions:
#Проверки клиентского компьютера (или другого почтового сервера),
#который соединяется с сервером postfix для отправки письма
smtpd_client_restrictions =
#black_client_ip,
#Принимать письма от клиентов локальной сети
permit_mynetworks,
#Пропускать письма от авторизованный пользователей
permit_sasl_authenticated,
#Если клиент не из mynetworks оценивает reject_unauth_destination. Отклоняется попытки пересылки, если получатель
#сообщения не относится к доменам места назначения и доменам пересылки, указанным в ваших настройках
reject_unauth_destination,
white_client_ip,
#Отвергает запрос, когда клиент отправляет команды SMTP раньше времени, еще не зная о том,
#действительно ли Postfix поддерживает конвейерную обработку команд ESMTP
reject_unauth_pipelining,
helo_access,
block_dsl,
#блокируем клиентов с адресами from, домены которых не имеют A/MX записей
###reject_unknown_address,
#блокирует почту от несуществующих доменов
###reject_unknown_recipient_domain,
###Проверяем домен на записи типа A и MX в DNS — если нет, то отклоняем
###reject_unknown_sender_domain,
rbl_dul_ru,
rbl_sbl_spamhaus_org,
rbl_spamcop,
rbl_cbl_abuseat_org
#Проверки исходящей или пересылаемой через нас почты
smtpd_sender_restrictions = white_client,
white_client_ip,
#black_client_ip,
#если пользователь авторизуется как user1@domain.com и попытается передать письмо в
#котором в качестве обратного адреса указан user2@domain.com, то в ответ получит ошибку
reject_authenticated_sender_login_mismatch,
#Отклоняет сообщения в не существующие домены
reject_unknown_recipient_domain,
###Проверяем домен на записи типа A и MX в DNS — если нет, то отклоняем
###reject_unknown_sender_domain,
#Если имя получателя не соответствует FQDN то отклоняем
reject_non_fqdn_recipient,
#Если имя отправителя не соответствует FQDN - отклоняем
reject_non_fqdn_sender,
permit_sasl_authenticated,
permit_mynetworks,
#Содержит список приватных сетей, которые по всем канонам глобальной сети интернет
#не могут быть использованы в качестве IP для MX записей
mx_access,
#Отклонение писем с несуществующим адресом отправителя
reject_unlisted_sender,
#Если клиент не из mynetworks оценивает reject_unauth_destination. Отклоняется попытки пересылки, если получатель
reject_unauth_destination
#Правила приема почты нашим сервером:
smtpd_recipient_restrictions =
white_client,
#блокирует почту от несуществующих доменов
reject_unknown_recipient_domain,
###Проверяем домен на записи типа A и MX в DNS — если нет, то отклоняем
###reject_unknown_sender_domain,
#Если имя получателя не соответствует FQDN — отклоняем
reject_non_fqdn_recipient,
#Если имя отправителя не соответствует FQDN - отклоняем
reject_non_fqdn_sender,
#Отвергает запрос, когда клиент отправляет команды SMTP раньше времени, еще не зная о том,
#действительно ли Postfix поддерживает конвейерную обработку команд ESMTP
reject_unauth_pipelining,
#Пропускать письма от авторизованный пользователей
permit_sasl_authenticated,
#Принимать письма от клиентов локальной сети
permit_mynetworks,
helo_access,
#Отклонить, если адреса RCPT TO нет в допустимых получателей
reject_unlisted_recipient,
#блокируем клиентов с адресами from, домены которых не имеют A/MX записей
reject_unknown_address,
#Если клиент не из mynetworks оценивает reject_unauth_destination. Отклоняется попытки пересылки, если получатель
#сообщения не относится к доменам места назначения и доменам пересылки, указанным в ваших настройках
reject_unauth_destination,
#Для отказа в приеме сообщениям с пустым именем отправителя конверта, предназначенным нескольким получателям
reject_multi_recipient_bounce
smtpd_data_restrictions =
reject_unauth_pipelining,
reject_multi_recipient_bounce,
permit
#Пропустить серверы, которые приветствуют нас кодом состояния 5xx
smtp_skip_5xx_greeting = no
#Отклонение писем с несуществующим адресом отправителя
smtpd_reject_unlisted_sender = yes
#Отклонение писем с несуществующим адресом получателя
smtpd_reject_unlisted_recipient = yes
Всё самое интересное при этом оказалось в БД. Вот, например, config/mysql-virtual_transports.cf :
Код: Выделить всё
user = postfix
password = password
dbname = mail
query = SELECT transport FROM transport WHERE domain='%s'
hosts = 127.0.0.1
А вот содержимое таблицы:
Код: Выделить всё
SELECT * FROM transport;
domain transport
testdomain.ru :
Ну и master.cf:
Код: Выделить всё
smtp inet n - - - - smtpd
-o content_filter=spamfilter:dummy
pickup fifo n - - 60 1 pickup
cleanup unix n - - - 0 cleanup
qmgr fifo n - n 300 1 qmgr
tlsmgr unix - - - 1000? 1 tlsmgr
rewrite unix - - - - - trivial-rewrite
bounce unix - - - - 0 bounce
defer unix - - - - 0 bounce
trace unix - - - - 0 bounce
verify unix - - - - 1 verify
flush unix n - - 1000? 0 flush
proxymap unix - - n - - proxymap
proxywrite unix - - n - 1 proxymap
smtp unix - - - - - smtp
relay unix - - - - - smtp
showq unix n - - - - showq
error unix - - - - - error
retry unix - - - - - error
discard unix - - - - - discard
local unix - n n - - local
virtual unix - n n - - virtual
lmtp unix - - - - - lmtp
anvil unix - - - - 1 anvil
scache unix - - - - 1 scache
maildrop unix - n n - - pipe
flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient}
uucp unix - n n - - pipe
flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
ifmail unix - n n - - pipe
flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
bsmtp unix - n n - - pipe
flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient
scalemail-backend unix - n n - 2 pipe
flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension}
mailman unix - n n - - pipe
flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py
${nexthop} ${user}
spamfilter unix - n n - - pipe
flags=Rq user=spamfilter argv=/usr/local/bin/spamfilter -f ${sender} -- ${recipient}
А вот так выглядит скрипт /usr/local/bin/spamfilter :
Код: Выделить всё
#!/bin/bash
echo $1 > /tmp/spamc
echo $2 >> /tmp/spamc
echo $3 >> /tmp/spamc
echo $4 >> /tmp/spamc
echo $5 >> /tmp/spamc
/usr/bin/spamc | /usr/sbin/sendmail -i "$@"
exit $?
Файлик /tmp/spamc при этом не создаётся.
В общем, вот так вот всё оно. Буду рад помощи в понимании проблемы.