Почтовый сервер на Gentoo

Мы будем ставить почтовый сервер, основанный на qmail и vpopmail с dovecot для доступа по POP3/IMAP, базой данных mysql для хранения учетных данных пользователей, веб интерфейсом администратора qmailadmin, почтовым веб клиентом squirrelmail. Сервер будет поддерживать SMTP авторизацию (PLAIN LOGIN CRAM-MD5), POP3/IMAP авторизацию (PLAIN LOGIN CRAM-MD5 APOP), а также работу через SSL для отправки и получения почты. Борьба со спамом осуществляется с помощью smtp-плагинов, контекстные фильтры не используются. Эффективно это или нет – решать вам. Вот статистика почтового сервера с более чем 5000 почтовыми ящиками за неделю работы:

Всего попыток соединений: 858557, из них прекращено плагинами:
dynamic-ip: 268953
mf-dns-check: 1853
helo-dns-check: 474175
rblchecks: 80214
В результате доставлено сообщений: 33362 (3% от всех попыток соединений)

ВАЖНО! Данная статья подразумевает, что Вы владеете навыками работы с Gentoo, принципами работы qmail, vpopmail, dovecot, mysql, apache, squirrelmail и других программ. Здесь приведены действия, которые сработали для меня, возможно они не сработают в Вашей системе, особенно если система была установлена не по моей статье «Установка Gentoo«. Обязательно прочитайте всю статью до конца прежде, чем начать копипастить.

Итак, начнем. Для начала неплохо взять сервер и установить на него Gentoo, как описано в статье «Установка Gentoo» . После этого необходимо убедиться, что hostname и hostname -d указывают на правильные имя хоста и домен соответственно. В моем случае

#hostname
mail

#hostname -d
spnet.ru

Поэтому не забываем далее по тексту поменять spnet.ru на свой домен :) Крайне желательно изменить названия баз данных и дефолтные пароли!

Определим необходимые USE флаги для устанавливаемых пакетов и сделаем возможной установку MASKED пакетов, которые нам нужны (не забудьте заменить x86 на Вашу архитектуру в случае необходимости)

cat >> /etc/portage/package.use << end-of-text
dev-lang/php cli cgi apache2 pcre mysql iconv session unicode ctype bcmath bzip2 curl discard-path force-cgi-redirect ftp gd mhash posix sharedext sockets spell tidy tokenizer truetype xml xmlreader xmlwriter xmlrpc xpm zip xsl imap simplexml
media-libs/gd jpeg png truetype xpm
sys-apps/grep pcre
www-servers/apache auth_digest
sys-process/daemontools doc
sys-apps/ucspi-tcp doc
mail-mta/netqmail highvolume qmail-spp
net-mail/vpopmail clearpasswd mysql
net-mail/dovecot pop3d vpopmail
dev-db/mysql latin1
sys-kernel/hardened-sources symlink
end-of-text
cat >> /etc/portage/package.keywords << end-of-text
app-text/txt2man ~x86
end-of-text

Удаляем ssmtp и metalog, устанавливаем mysql и netqmail

emerge -C ssmtp metalog && emerge mysql netqmail && emerge --config dev-db/mysql && rc-update add mysql default && sed -i -e 's#^log-bin##log-bin#g' /etc/mysql/my.cnf && /etc/init.d/mysql start

Правим файл конфигурации самоподписанного SSL сертификата, добавляем службы netqmail автозагрузку, создаем его начальную конфигурацию и генерим сертификат

cat > /var/qmail/control/servercert.cnf <<end-of-text
[ req ]
default_bits = 1024
encrypt_key = yes
distinguished_name = req_dn
x509_extensions = cert_type
prompt = no
[ req_dn ]
C=RU
ST=Moscow region
L=Sergiev Posad
O=CSIT
OU=CSIT SSL key
CN=mail.spnet.ru
emailAddress=sadm@spnet.ru
[ cert_type ]
nsCertType = server
end-of-text
ln -s /var/qmail/supervise/qmail-send /service/qmail-send && ln -s /var/qmail/supervise/qmail-smtpd /service/qmail-smtpd && rc-update add svscan default && emerge --config mail-mta/netqmail

Конфигурим qmail: убираем задержку при соединении по SMTP, храним 100 файлов логов, SMTP авторизация через vpopmail, максимальный размер обрабатываемого письма – 50мб, удаляем двойные bounce

sed -i -e 's#^TCPSERVER_OPTS=".*"#TCPSERVER_OPTS="-v -l 0"#g' -e "s#^LOG_MAXCOUNT=.*#LOG_MAXCOUNT=100#g" /var/qmail/control/conf-common
sed -i -e 's#^#QMAIL_SMTP_CHECKPASSWORD="/bin/cmd5checkpw"#QMAIL_SMTP_CHECKPASSWORD="/var/vpopmail/bin/vchkpw"#g' /var/qmail/control/conf-smtpd
echo 52428800 >/var/qmail/control/databytes
echo "#" > /var/qmail/control/doublebounceto

Наш netqmail собран с поддержкой qmail SMTP plugins, что позволяет использовать плагины на разных этапах соединения. Я написал пару своих плагинов, первый дает защиту от подмены адреса отправителя авторизованным пользователем, второй и третий проверяют DNS посылающего нам почту хоста и HELO/EHLO на предмет соответствия регулярным выражениям в /var/qmail/control/dynamic_ip. Если соответствие есть – хосту выдается требование использовать SMTP своего провайдера для отправки почты на наш сервер. Эти плагины рубят 90% спама!

Пара слов относительно greylisting – это серые списки, работают следующим образом: до приёма сообщения сервером проверяется триада хост отправителя-отправитель-получатель. Если она есть в сером списке – письмо принимается для дальнейшей обработки. Если пары нет в сером списке, то посылающему нам почту хосту выдается сообщение 451 (не могу временно принять почту) и соединение прекращается. Если в течение 15 последующих минут будут повторные попытки отправить почту (что обычно и происходит, если это не спамер) с этого же хоста, то ему будет выдаваться все та же ошибка 451, через 15 минут письмо принимается и триада хост отправителя-отправитель-получатель заносится в серый список. Это очень эффективно, так как спамерам нужно разослать как можно больше писем и они в большинстве случаев не пытаются повторно перепослать письмо этому же адресату. Более того, по имеющейся в базе информации легко определять спамеров, например, в нормальных условиях даже одноклассники.сру не посылают более 20 писем за минуту на почтовый сервер с >5000 ящиками (это из практики). Я написал небольшой скрипт (/var/qmail/plugins/greylisting-0.2.2/greylisting_hardening.sh), который находит такие аномальные спамхосты и удаляет их из серого списка.

Устанавливаем smtp плагины (для удобства я собрал их в одном архиве)

cd /var/qmail ; wget http://klyaznik.ru/files/qmail-plugins.tgz && tar zxvf qmail-plugins.tgz && cd plugins && gcc -o helodnscheck helodnscheck.c -lresolv && gcc -o ifauthskip ifauthskip.c && gcc -o mfdnscheck mfdnscheck.c -lresolv && gcc -o tarpit tarpit.c && cd greylisting-0.2.2 && gcc -o greylisting greylisting.c -I/usr/include -I/usr/include/mysql -I/usr/local/include/mysql -L/usr/lib/mysql -L/usr/local/lib/mysql -lmysqlclient && strip greylisting
mysql -e "create database greylisting; grant select, insert, update, delete, create, drop on greylisting.* to greylisting@localhost identified by 'qmailgrey'; flush privileges;" -p
mysql -p greylisting <greylisting.sql
emerge cmake txt2man
cd ../ra-plugins-read-only/build ; cmake .. && make check && make rblchecks
cat > /var/qmail/control/greylisting << end-of-text
mysql_host=localhost
mysql_port=3306
mysql_user=greylisting
mysql_pass=qmailgrey
mysql_db=greylisting
block_expire=15
record_expire=500
record_expire_good=7
loglevel=4
end-of-text

Добавляем задания в крон

crontab -u root -e

Нужно добавить два задания:

1 * * * * /var/qmail/plugins/greylisting-0.2.2/greylisting_cleanup.sh
* * * * * /var/qmail/plugins/greylisting-0.2.2/greylisting_hardening.sh

Создаем файл настроек SMTP плагинов

cat > /var/qmail/control/smtpplugins << end-of-text
[connection]
[helo]
[mail]
:if [ "$SMTPAUTHUSER" != "" ] ; then if [ "$SMTPMAILFROM" != "$SMTPAUTHUSER" -a "$SMTPMAILFROM" != "$SMTPAUTHUSER@spnet.ru" ] ; then echo "E553 Sender address $SMTPMAILFROM rejected - you must authorize as $SMTPMAILFROM, not as $SMTPAUTHUSER" ; echo "check_auth_mailfrom: Sender address $SMTPMAILFROM rejected - you must authorize as $SMTPMAILFROM, not as $SMTPAUTHUSER" >&2 ; fi ; fi
plugins/ifauthskip
:echo $TCPREMOTEHOST | egrep -f /var/qmail/control/dynamic_ip >/dev/null && echo "E553 Dynamic IP's are not allowed. Please use your provider mail server to send mail for us." && echo "check_dynamic_ip: $TCPREMOTEHOST - Dynamic IP's are not allowed. Please use your provider mail server to send mail for us." >&2
:echo $SMTPHELOHOST | egrep -f /var/qmail/control/dynamic_ip >/dev/null && echo "E553 Dynamic IP's are not allowed. Please use your provider mail server to send mail for us." && echo "check_dynamic_helo: $SMTPHELOHOST - Dynamic IP's are not allowed. Please use your provider mail server to send mail for us." >&2
plugins/mfdnscheck
plugins/helodnscheck
plugins/ra-plugins-read-only/build/rblchecks
 
[rcpt]
plugins/tarpit
plugins/ifauthskip
[data]
plugins/greylisting-0.2.2/greylisting
end-of-text

Создаем файл регулярных выражений для проверки коннектящихся по smtp хостов на принадлежность к dynamic-ip

cat > /var/qmail/control/dynamic_ip << end-of-text
([[:print:]]{4,30})(.)+(ppp|pppoe|dsl|adsl|dialup|dial-up|dhcp|dyn|dynamic|dynamicip)2([[:print:]])+.
([[:print:]]{4,30})(-|_)+(ppp|pppoe|dsl|adsl|dialup|dial-up|dhcp|dyn|dynamic|dynamicip)2(([[:print:]])+.){2}
([[:print:]])*(([[:digit:]]{1,3}(-|_)){3}([[:digit:]]{1,3})).([[:print:]]+){2,}
end-of-text

Устанавливаем почтовый ящик администратора системы, которому будет приходить почта рута, постмастера и почтовых демонов

echo "sadm@spnet.ru" > /var/qmail/alias/.qmail-mailer-daemon ; echo "sadm@spnet.ru" > /var/qmail/alias/.qmail-postmaster ; echo "sadm@spnet.ru" > /var/qmail/alias/.qmail-root 

Устанавливаем vpopmail

emerge vpopmail

Создаем базу данных для vpopmail

mysql -e "create database vpopmail; grant select, insert, update, delete, create, drop on vpopmail.* to vpopmail@localhost identified by 'secret'; flush privileges;" -p

Конфигурируем квоту по умолчанию 100 мб. на создаваемые почтовые ящики

sed -i -e 's#^#quota.*#quota 104857600#g' ~vpopmail/etc/vlimits.default

Конфигурируем домен по умолчанию (это дает возможность использовать только vasya вместо vasya@spnet.ru при авторизации, возможно послать письмо просто на vasya)

hostname -d > ~vpopmail/etc/defaultdomain

Создаем письмо, которое будет посылаться пользователю, у которого заканчивается квота

cat > ~vpopmail/domains/quotawarnmsg << end-of-text
From: Почтовый сервер <postmaster@spnet.ru>
To: Пользователь
Subject: Внимание! Ваш почтовый ящик заполнен более, чем на 90%!
Mime-Version: 1.0
Content-Type: text/plain; charset=koi8-r
Content-Transfer-Encoding: 8bit
-------------------------------------------------------------------------------
-   Внимание! Это соообщение создано сервером и на него не нужно отвечать!    -
-------------------------------------------------------------------------------
Ваш почтовый ящик заполнен более, чем на 90%! Вам необходимо удалить ненужные
сообщения из почтового ящика, иначе скоро Вы не сможете получать электронную
почту. Вы можете удалить ненужные сообщения через веб клиент почтового
сервера: https://mail.spnet.ru. Удалите ненужные сообщения из всех папок, затем
нажмите кнопку "Очистить" рядом с папкой "Корзина", чтобы полностью
удалить сообщения из Вашего почтового ящика.
end-of-text

Устанавливаем dovecot и добавляем его в автозагрузку

emerge dovecot && rc-update add dovecot default
cat > /etc/dovecot/dovecot.conf << end-of-text
protocols = imap imaps pop3 pop3s
disable_plaintext_auth = no
log_timestamp = "%b %d %H:%M:%S "
syslog_facility = mail
ssl_cert_file = /var/qmail/control/servercert.pem
ssl_key_file = /var/qmail/control/servercert.pem
mail_location = maildir:%h/.maildir
first_valid_uid = 89
last_valid_uid = 89
protocol imap {
mail_plugins = quota imap_quota
}
protocol pop3 {
pop3_uidl_format = %v-%u
mail_plugins = quota
}
auth default {
mechanisms = plain login digest-md5 cram-md5 apop
passdb vpopmail {
}
userdb vpopmail {
}
user = vpopmail
}
dict {
}
plugin {
quota = maildir
}
end-of-text

Устанавливаем веб сервер apache, почтовый веб интерфейс squirrelmail и веб интерфейс администратора почты qmailadmin. Они потянут за собой около 50 пакетов, так что придется запастись терпением :)

emerge apache squirrelmail qmailadmin && rc-update add apache2 default && emerge --config apache && mkdir -p /var/local/squirrelmail/attach && chown apache:apache /var/local/squirrelmail/attach && chmod go-rwx /var/local/squirrelmail/attach

Немного донастраиваем apache

sed -i -e 's#ServerSignature On#ServerSignature Off#g' -e 's##EnableMMAP off#EnableMMAP on#g' -e 's##EnableSendfile off#EnableSendfile on#g' /etc/apache2/modules.d/00_default_settings.conf
sed -i -e 's#<IfModule negotiation_module>#<IfModule negotiation_module>\nDefaultLanguage ru\nAddDefaultCharset koi8-r#' /etc/apache2/modules.d/00_languages.conf
sed -i -e 's#DocumentRoot "/var/www/localhost/htdocs"#DocumentRoot "/var/www/localhost/htdocs"\n\nRewriteEngine   on\n\nRewriteCond     %{REQUEST_METHOD}       ^(TRACE|TRACK)\nRewriteRule     .*                      - [F]\n\nRewriteCond     %{SERVER_PORT}          !^443$\nRewriteRule     ^/(.*)                  https://%{SERVER_NAME}/$1                               [L,R]#g' /etc/apache2/vhosts.d/default_vhost.include
sed -i -e "s#SSLCertificateFile /etc/apache2/ssl/server.crt#SSLCertificateFile /var/qmail/control/servercert.pem#g" -e "s#SSLCertificateKeyFile /etc/apache2/ssl/server.key#SSLCertificateKeyFile /var/qmail/control/servercert.pem#g" /etc/apache2/vhosts.d/00_default_ssl_vhost.conf

Делаем редирект на веб интерфейс squirrelmail

echo '<html><head><meta http-equiv="Refresh" content="0; url=/squirrelmail/src/login.php"></head></html>' > /var/www/localhost/htdocs/index.html

Обновляем профиль и добавляем наши домены

env-update ; source /etc/profile
vadddomain spnet.ru
vadddomain domain2.tld
...

Одной из технологий спамеров является отправка спама через bounce. Как это работает: на Ваш сервер приходит письмо на несуществующий ящик, адресом отправителя которого спамеры ставят е-мейл, на который нужно послать спам. Настроенный по умолчанию vpopmail такие письма bounce-ит, то есть отсылает отправителю обратно с ошибкой что такого ящика не существует. Таким образом хитрый спамер может посылать письма через Ваш сервер. Возможно что на нашем сервере такой номер не пройдет (у нас используются плагины для проверки отправителей), однако я не проверял. Чтобы защититься от данного метода рассылки спама, поставим удаление всех писем, получателей для которых не существует на нашем сервере:

for i in `vdominfo | grep /var/vpopmail/domains | awk '{print $2;}'` ; do echo "| /var/vpopmail/bin/vdelivermail '' delete" > $i/.qmail-default ; done

В дальнейшем при добавлении нового домена всегда помещайте «| /var/vpopmail/bin/vdelivermail » delete» в .qmail-default для этого домена.

Создаем файл правил для обработки входящих SMTP сессий

cat > /etc/tcprules.d/tcp.qmail-smtp << end-of-text
# localhost
127.0.0.1:allow,NOSPP="",TARPITCOUNT="5",TARPITDELAY="NORMAL"
# drop spam networks
89.111.164.:deny
89.111.165.:deny
# default
:allow,TARPITCOUNT="5",TARPITDELAY="NORMAL",GREYLISTING="",RBLSERVERS="bl.spamcop.net:zen.spamhaus.org"
end-of-text
cd /etc/tcprules.d ; make

Можно использовать следующие параметры (здесь кратко, читайте на http://qmail-spp.sourceforge.net/plugins/):

NOHELODNSCHECK=»" – отключить плагин helodnscheck

SMTP_ACCEPT_BOUNCE=»1″ – принимать bouces

TARPITCOUNT=»5″ – количество сообщений в одной сессии, после которых включать задержку
TARPITDELAY=»MEDIUM» – задержка, может быть NORMAL, MEDIUM, HARD

GREYLISTING=»" – включить грейлистинг
RELAYCLIENT=»" – разрешить пересылку почты (релеинг)

RBLSERVERS=»bl.spamcop.net:zen.spamhaus.org» – использовать указанные черные списки

NOSPP=»" – полностью отключить плагины

Устанавливаем плагин quota_usage для squirrelmail

cd /var/www/localhost/htdocs/squirrelmail/plugins && wget http://www.squirrelmail.org/countdl.php?fileurl=http%3A%2F%2Fwww.squirrelmail.org%2Fplugins%2Fquota_usage-1.3.1-1.2.7.tar.gz && tar zxvf quota_usage-1.3.1-1.2.7.tar.gz && cp /var/www/localhost/htdocs/squirrelmail/plugins/quota_usage/config.php.sample /var/www/localhost/htdocs/squirrelmail/plugins/quota_usage/config.php

Конфигурируем squirrelmail

cd /var/www/localhost/htdocs/squirrelmail/config && wget http://klyaznik.ru/files/squirrelmail-config.tgz && tar zxvf squirrelmail-config.tgz && /var/www/localhost/htdocs/squirrelmail/config/conf.pl
cat > /var/www/localhost/htdocs/squirrelmail/data/default_pref << end-of-text
show_html_default=1
left_refresh=300
javascript_on=1
hililist=a:0:{}
notes_count=0
language=ru_RU
delete_move_next_t=on
delete_move_next_formATtop=on
delete_move_next_b=on
delete_move_next_formATbottom=on
mailbox_select_style=1
collapse_folder_INBOX=0
hour_format=1
reply_citation_style=date_time_author
prefix_sig=0
order1=1
order2=2
order3=3
order4=5
order5=4
order6=6
order7=6
attachment_common_show_images=1
pf_cleandisplay=1
reply_focus=focus
abook_take_verify=1
unseen_notify=3
unseen_cum=1
newmail_enable=on
newmail_popup=on
newmail_allbox=on
newmail_recent=on
newmail_changetitle=on
newmail_media=https://mail.spnet.ru/squirrelmail/plugins/newmail/sounds/Notify.wav
end-of-text
cp /var/www/localhost/htdocs/squirrelmail/data/default_pref /var/www/localhost/htdocs/squirrelmail/data/.pref

Добавляем правила iptables, разрешающие коннекты на порты почтовых служб и веб сервера и правило, запрещающее апачу соединения с внешними хостами. Можно использовать iptables расширение multiport, однако я считаю, что так более наглядно

sed -i -e 's#-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT#-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT\n-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT#g' -e 's#-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT#-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT\n-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT#g' -e 's#-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT#-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT\n-A INPUT -p tcp -m tcp --dport 25 -j ACCEPT#g' -e 's#-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT#-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT\n-A INPUT -p tcp -m tcp --dport 110 -j ACCEPT#g' -e 's#-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT#-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT\n-A INPUT -p tcp -m tcp --dport 143 -j ACCEPT#g' -e 's#-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT#-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT\n-A INPUT -p tcp -m tcp --dport 993 -j ACCEPT#g' -e 's#-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT#-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT\n-A INPUT -p tcp -m tcp --dport 995 -j ACCEPT#g' -e 's#-A OUTPUT -j ACCEPT#-A OUTPUT -m owner --uid-owner apache -m state --state NEW,INVALID -j DROP\n-A OUTPUT -j ACCEPT#g' /var/lib/iptables/rules-save

Делаем наш сервер более безопасным убирая права на доступ к мало-мальски интересным файлам

chgrp mysql /etc/mysql ; chmod o-rwx /boot /home/* /etc/apache2 /etc/conf.d /etc/config-archive /etc/cron.* /etc/kernels /etc/logcheck /etc/logrotate.* /etc/modules.* /etc/mysql /etc/portage /etc/skel /etc/sysctl.conf /etc/syslog-ng /etc/tripwire /usr/src /var/log/genkernel.log

Можно запустить mysql_secure_installation для удаления тестового пользователя и базы

Даем пользователю sadm@spnet.ru возможность управлять почтовыми ящиками через админский веб интерфейс (postmaster изначально имеет доступ)

vmoduser -a sadm@spnet.ru

Запускаем службы

for i in `rc-status | grep stopped | awk '{print $1}'` ; do /etc/init.d/$i start ; done

Идем на http://mail.spnet.ru/cgi-bin/qmailadmin и создаем почтовые ящики. Для просмотра почты идем на https://mail.spnet.ru

Ну вот и все, поздравляю, настройка почтового сервера на этом окончена.

Комментарии запрещены.