Своя почта для ubuntu.ru

Предлагаю сделать свою почту для ubuntu.ru.

Что нужно:

  1. Правильно настроить DNS
  2. Поставить postfix

Самым разумным, на мой взгляд, является организация ящиков в виде редиректов на основной ящик пользователя из профиля SMF. То есть члены определённой группы SMF автоматически получают адрес login@ubuntu.ru, который является редиректом на их основной почтовый адрес из профиля. Плюс можно будет добавить несколько адресов вручную, естественно тоже редиректами.

Проще говоря мы предоставляем пользователям адрес, но не предоставляем почтовый ящик. Ящики и так уже у всех есть, накой плодить сущности?

Преимущества: безопасность сервера (нет ни авторизации, ни фильтров спама, ни вообще какого-либо доступа пользователей к SMTP) и идеальная простота для конечного пользователя. Ибо ящики и так уже у всех есть и пытаться стать ещё одним почтовым провайдером просто бесполезно.

Конфиг Postfix примерно такой:

# See /usr/share/postfix/main.cf.dist for a commented, more complete version
 
########################################################
## Основные параметры
 
smtpd_banner = $myhostname ESMTP server
biff = no
 
# Максимальный размер письма. По умолчанию всего 10Mb
message_size_limit = 204800000
 
# Основные параметры хоста
myhostname = mail.ubuntu.ru
mydestination =
 $myhostname
myorigin = $mydomain
mynetworks =
 127.0.0.0/8
 
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all
append_dot_mydomain = no
readme_directory = no
 
# Параметры оповещений и очереди (актуальны только для отправки через SMTP)
delay_warning_time = 2h
maximal_queue_lifetime = 1d
bounce_queue_lifetime = 1d
 
# Оповещения на ящик администратора (включать только для отладки!)
#notify_classes = delay, resource, software
 
bounce_notice_recipient = postmaster@$mydomain
2bounce_notice_recipient = postmaster@$mydomain
delay_notice_recipient = postmaster@$mydomain
error_notice_recipient = postmaster@$mydomain
 
##########################################################
## Настройки адресов и доставки
 
# Используем только виртуальных пользователей
local_recipient_maps =
relay_domains =
relay_recipient_maps =
 
# Настройки виртуальных ящиков
virtual_mailbox_domains =
 $mydomain
# Локальных пользователей нет (если нужны - нужно ставить Dovecot)
virtual_mailbox_maps =
# Собственно карты перенаправлений
virtual_alias_maps =
 hash:/etc/postfix/mailboxes/smf-aliases
 hash:/etc/postfix/mailboxes/local-aliases
# Параметры локальной доставки. Если она нужна, то надо ставить Dovecot
virtual_mailbox_base = /var/mail
virtual_uid_maps = static:900
virtual_gid_maps = static:900
 
# Карты транспортов (могут пригодится для добавления перенаправлений)
transport_maps =
 
# LDA - Dovecot (только для локальной доставки)
#dovecot_destination_recipient_limit = 1
#virtual_transport = dovecot
 
###########################################################
## Авторизация и шифрование - отключены
 
# SASL авторизация отключена
smtpd_sasl_auth_enable = no
 
# TLS отключён
smtpd_use_tls = no
 
###########################################################
## Ограничения и запреты
 
# Запретить ETRN команду
smtpd_etrn_restrictions = reject
 
# Запретить VRFY команду
disable_vrfy_command = yes
 
# Требовать наличие EHLO (HELO) команды
smtpd_helo_required = yes
 
# Всегда отклонять письма для всех неизвестных ящиков
smtpd_reject_unlisted_recipient = yes
 
# Ограничения на клиента - принимаем только если есть PTR (не жёсткий запрет)
smtpd_client_restrictions =
 permit_mynetworks
 reject_unknown_reverse_client_hostname
 permit
 
# Ограничения на HELO. Отклоняем письма от всех хостов, которые даже представиться не могут
smtpd_helo_restrictions =
 permit_mynetworks
 reject_invalid_helo_hostname
 reject_non_fqdn_helo_hostname
 reject_unknown_helo_hostname
 permit
 
# Ограничения на MAIL FROM. Отклоняем все письма, отправитель которых предоставил невалидный адрес
smtpd_sender_restrictions =
 reject_non_fqdn_sender
 reject_unknown_sender_domain
 permit
 
# Ограничения на RCPT TO. Принимаем только для известных нам адресов
smtpd_recipient_restrictions =
 reject_non_fqdn_recipient
 reject_unlisted_recipient
 permit_mynetworks
 reject_unauth_destination
 permit
 
# Ограничения на данные. Не принимаем в случае некорректной передачи
smtpd_data_restrictions =
 reject_unauth_pipelining

Как видно, postfix для определения валидных получателей использует одну стандартную карту - /etc/postfix/mailboxes/smf-aliases. Её мы будем генерить раз в сутки на основе БД SMF таким вот скриптом:

#!/usr/bin/perl
 
use 5.010;
use DBI;
 
#############################################################
 
# Настройки базы данных
$MYSQL_host = 'localhost';
$MYSQL_port = '3306';
$MYSQL_user = 'mail';
$MYSQL_pass = 'Passw0rd';
$MYSQL_db = 'smf';
 
# Параметры SMF - группа пользователей почты и префикс таблиц
$SMF_GID = '9';
$SMF_prefix = 'smf_';
 
# Обслуживаемый домен
$domain = "ubuntu.ru";
 
# Файл псевдонимов
$postfix_file = "/etc/postfix/mailboxes/smf-aliases";
 
#############################################################
 
$dbh = DBI->connect("DBI:mysql:$MYSQL_db:$MYSQL_host:$MYSQL_port",$MYSQL_user,$MYSQL_pass) or die "Hey guys! We've got a big error here...";
 
# Выполняем запрос
my $sth = $dbh->prepare("SELECT memberName, realName, emailAddress
	FROM ${SMF_prefix}members
	WHERE (ID_GROUP = $SMF_GID OR FIND_IN_SET($SMF_GID, additionalGroups))");
$sth->execute() or die "Hey guys! We've got a big error here...";
 
# Открываем файл псевдонимов для Postfix
open ALIASES, ">$postfix_file" or die "Can't open $postfix_file\n";
 
# Анализируем ответ
foreach my $row ($sth->fetchrow_hashref()) {
	my $user = $row->{realName};
	# Если имя пользователя содержит неразрешённые символы - пропускаем его
	# Разрешены любые буквы, цифры и символы ".", "-" и "_"
	next if $user =~ /[^\w.-_]/;
	# Пишем псевдоним в файл
	say ALIASES "$user\@$domain\t$row->{emailAddress}";
}
 
# Закрываем файл псевдонимов и создаём хеш для postfix'а
close ALIASES;
`/usr/sbin/postmap hash:$postfix_file`;

Добавляем скрипт в cron и радуемся жизни. Итого поставленная цель достигнута. Кроме того, можно вручную добавлять алиасы, чтобы не создавать лишние аккаунты в SMF. Для этого служит вторая карта - local-aliases, которая заполняется по необходимости вручную.

В качестве дополнения к этому:

В дальнейшем при необходимости эту схему можно расширить путём добавления реальных почтовых ящиков со всеми причиндалами в виде авторизации, IMAP и прочих прелестей. Сделать это просто и не потребуется изменения уже работающей системы, предложенной выше, только её надстройка.