Документация по ОС FreeBSD Вторник, 07.05.2024, 03:59
Приветствую Вас Гость | RSS
Меню сайта

Категории каталога
Apache [58]
DNS [25]
FTP [27]
Mail [74]
Samba [24]
Squid [46]
SSH [23]
VPN [35]
РРР [20]
Net [173]

Главная » Статьи » Сеть » Mail

Хороший почтовый сервер
  ·  Введение.

Что такое хороший почтовый сервер? Это такой почтовик, который можно один раз настроить, запустить и забыть про его существование. Забыть, потому что он никогда более не потребует внимания к себе, будет исправно гонять почту, удалять спам и вирусы.
На удивление построить такой сервер очень просто, тем более под ALT Linux Master 2.4. Надо только забыть про то, что когда-то программы собирались вручную из исходников, засоряли файловую систему и были совершенно неподконтрольны администратору системы.
Итак, для создания хорошего почтового сервера потребуются:
* Postfix с поддержкой SASL и TLS,
* Cyrus-SASL
* OpenLDAP,
* Courier-imap,
* Amavisd-new,
* Clamav,
* Spamassassin.

По традиции, описание начнём с openldap. В директории будут хранится почтовые учётные записи.

1. Opendlap

$ sudo apt-get install openldap openldap-servers openldap-clients

* Конфигурация /etc/openldap/slapd.conf

Для простоты приведу только отличия от дефолтной конфигурации

# Добавим эти две схемы
include         /etc/openldap/schema/courier.schema
include         /etc/openldap/schema/qmail.schema


с qmail.schema вас ждёт засада, поскольку по недосмотру майнтейнера в пакет попала устаревшая схема, которую openldap не поймёт. Простой workaround - вытащить последнюю версию схемы из qmail-ldap patch и уложить её в /etc/openldap/schema/.

Далее описание самой базы:

database bdb
suffix "dc=gorodmasterov,dc=com"
rootdn "cn=admin,dc=gorodmasterov,dc=com"
rootpw {SSHA}*****************************
directory /var/lib/ldap/bases/gm
index objectClass eq
index uid pres,eq,sub
index cn pres,eq,sub,subany
access to attrs=userPassword
       by self write
       by anonymous auth
       by dn="cn=courier,ou=Daemons,dc=gorodmasterov,dc=com" read
       by * none
access to *
       by * read


Здесь и далее, указание {SSHA}*******.. означает пароль в формате SSHA. Сгенерировать такой пароль можно при помощи утилиты slappasswd.

Создадим базу. Сформируем ldif-файл с описанием:
#
# base.ldif
#
dn: dc=gorodmasterov,dc=com
objectClass: dcObject
objectClass: organization
o: Gorod Masterov
dc: gorodmasterov

dn: cn=admin,dc=gorodmasterov,dc=com
objectClass: organizationalRole
cn: admin

dn: ou=Users,dc=gorodmasterov,dc=com
objectClass: organizationalUnit
objectClass: top
ou: Users

dn: ou=Groups,dc=gorodmasterov,dc=com
objectClass: organizationalUnit
objectClass: top
ou: Groups

dn: ou=Daemons,dc=gorodmasterov,dc=com
objectClass: organizationalUnit
objectClass: top
ou: Daemons

dn: cn=postfix,ou=Daemons,dc=gorodmasterov,dc=com
objectClass: simpleSecurityObject
objectClass: organizationalRole
objectClass: top
cn: postfix
userPassword: {SSHA}****************************

dn: cn=courier,ou=Daemons,dc=gorodmasterov,dc=com
objectClass: simpleSecurityObject
objectClass: organizationalRole
objectClass: top
cn: courier
userPassword: {SSHA}****************************

dn: cn=Lettiev V.V.,ou=Users,dc=gorodmasterov,dc=com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: qmailUser
cn: Lettiev V.V.
uid: admin
accountStatus: active
mailMessageStore: admin/Maildir/
userPassword: {SSHA} ***********************************
displayName: Vladimir Lettiev
sn: Lettiev
givenName: Vladimir
initials: V
o: Gorod Masterov
mail: admin@gorodmasterov.com
mailAlternateAddress: crux@gorodmasterov.com
mailAlternateAddress: Vladimir.Lettiev@gorodmasterov.com

Следующей командой внесём данные из файла в базу:
$ ldapadd -x -W -D 'cn=admin,dc=gorodmasterov,dc=com' -f base.ldif

Итак мы получим базовый набор - организация, в ней три контейнера: Users - там будут учётки пользователей, Groups - группы пользователей, Daemons - учётки программ, которые будут подключаться к ldap.
Создаются также три пользователя:
courier - учётная запись, под которой будет подключаться courier-imap к ldap. Если вы обратили внимание, то для этого пользователя в настройках LDAP даётся право заглядывать в аттрибут userPassword пользователей.
postfix - учётная запись, под которой будет подключаться postfix к ldap.
Lettiev V.V. - это собственно первая учётная запись почтового пользователя.


2. Postfix

Postfix, идущий в поставке ALM24 не имеет патча, дающего поддержку TLS, также не собирается и поддержка SASL. Объясняется это просто - данные компоненты ухудшают безопасность почтового сервера, поскольку являются сторонними с большой историей security проблем в прошлом, а postfix разрабатывался с упором на безопасность (иначе чем он лучше sendmail, не так ли?).
Но поскольку функционал востребован, сборка postfix с необходимыми патчами есть в Daedalus (репозиторий Altlinux для нестабильных пакетов или альтернативных сборок пакетов). Наша задача пересобрать данный пакет в окружении ALM24.

$ wget ftp://ftp.altlinux.ru/pub/distributions/ALTLin…
$ rpmbuild --rebuild postfix-2.0.20-alt2.1.src.rpm


Тут возможно сообщение о ненайденом rpmbuild. Это значит, что вам надо сказать sudo apt-get install rpm-build. Также может (и наверняка) сказать, что для сборки требуются установить те или иные пакеты. Опять же apt-get install вам в помощь.

После сборки:

$ cd ~/RPM/RPMS/i686/
$ sudo apt-get install postfix-2.0.20-alt2.1.i686.rpm postfix-ldap-2.0.20-alt2.1.i686.rpm postfix-pcre-2.0.20-alt2.1.i686.rpm


Создадим системного пользователя vmail:vmail (uid=499, gid=499) - этот пользователь будет владеть всей почтой. Все же пользователи у нас будут виртуальными.

# grouadd -g 499 vmail
# useradd -g vmail -u 499 -s /bin/false -d /home/vmail -m -k /dev/null
# passwd -l vmail


  · Конфигурация:

#/etc/postfix/main.cf
#-------------------------------------------------------------#

# имя хоста
myhostname = mail.gorodmasterov.com
# имя домена
mydomain = gorodmasterov.com
# это то, что идёт после собачки в email-адресах
myorigin = $mydomain

# слушаем на всех интерфейсах
inet_interfaces = all
# доставка локальным юзерам отсутствует. всё делаем через виртуальный транспорт
mydestination =
unknown_local_recipient_reject_code = 550
# адреса локальной сети, для которых мы разрешаем релеить почту
mynetworks = 192.168.1.0/24, 127.0.0.0/8

# почтовый ящик в формате Maildir
home_mailbox = Maildir/
smtpd_etrn_restrictions = permit_mynetworks, reject
smtpd_helo_required = yes
# примаем отправляемую почту для тех, кто прошёл smtp_auth или в локальной сети. Остальных посылаем.
smtpd_recipient_restrictions=permit_sasl_authenticated permit_mynetworks reject_unauth_destination
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain =
broken_sasl_auth_clients = yes

smtp_use_tls = yes

# Здесь указан путь к сертификату, который мы сгенерируем позже.
smtp_tls_key_file = /var/lib/ssl/certs/imapd.pem
smtp_tls_cert_file = $smtp_tls_key_file
smtp_tls_CAfile = $smtp_tls_key_file
smtp_tls_note_starttls_offer = yes

# включать возможность авторизации только в режиме tls
smtpd_tls_auth_only = yes

# использовать tls для приема почты
smtpd_use_tls = yes
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom

# теже ключи
smtpd_tls_key_file = /var/lib/ssl/certs/imapd.pem
smtpd_tls_cert_file = $smtpd_tls_key_file
smtpd_tls_CAfile = $smtpd_tls_key_file

# почтовый фильтр amavis-new
content_filter=smtp-amavis:[127.0.0.1]:10024

# LDAP
# транспорт виртуальный
virtual_transport = virtual
virtual_mailbox_domains = $myhostname $mydomain
# путь к корневой папке, где будут находится почта всех юзеров (/home/vmail)
virtual_mailbox_base = /home/vmail
virtual_mailbox_maps = ldap:ldapvirtual
# uid и gid пользователя vmail, которому будет принадлежать вся почта.
virtual_uid_maps = static:499
virtual_gid_maps = static:499
virtual_minimum_uid = 498
virtual_mailbox_limit = 0
ldapvirtual_server_host = localhost
ldapvirtual_server_port = 389
ldapvirtual_bind = yes
ldapvirtual_bind_dn = cn=postfix,ou=Daemons,dc=gorodmasterov,dc=com
# пароль учётки postfix'а в ldap
ldapvirtual_bind_pw = **********
ldapvirtual_search_base = ou=Users,dc=gorodmasterov,dc=com
ldapvirtual_query_filter = (&(mail=%s)(|(AccountStatus=active)(accountStatus=shared)))
# аттрибут пользователя, по которому postfix определит куда ложить почту (путь относительно virtual_mailbox_base)
ldapvirtual_result_attribute = mailMessageStore

# Алиазы берём из /etc/postfix/aliases и/или из ldap.
virtual_alias_maps = hash:/etc/postfix/aliases, ldap:ldapalias
ldapalias_server_host = localhost
ldapalias_server_port = 389
ldapalias_bind = yes
ldapalias_bind_dn = cn=postfix,ou=Daemons,dc=gorodmasterov,dc=com
# пароль учётки postfix'а в ldap
ldapalias_bind_pw = **********
ldapalias_search_base = ou=Users,dc=gorodmasterov,dc=com
ldapalias_query_filter = (&(|(mail=%s)(mailAlternateAddress=%s))(|(AccountStatus=active)(AccountStatus=shared)))
ldapalias_result_attribute = mail
#-------------------------------------------------------------#


Отличия в master.cf значительные (от дефолтных).
Создаётся дополнительный pre-cleanup, в котором не происходит разрешения алиасов, чтобы избежать дублирования почты из-за двойного лукапа (создаваемый вследствии наличия фильтра amavis).
Указываются настройки для фильтра почты - amavis.

# /etc/postfix/master.cf
#-------------------------------------------------------------#
smtp    inet    n       -       -       -       -       smtpd
       -o cleanup_service_name=pre-cleanup
pickup  fifo    n       -       -       60      1       pickup
       -o cleanup_service_name=pre-cleanup
pre-cleanup         unix  n      -      -      -       0      cleanup
       -o canonical_maps=
       -o sender_canonical_maps=
       -o recipient_canonical_maps=
       -o masquerade_domains=
       -o virtual_alias_maps=
cleanup unix    n       -       -       -       0       cleanup
qmgr    fifo    n       -       -       300     1       qmgr
rewrite unix    -       -       -       -       -       trivial-rewrite
bounce  unix    -       -       -       -       0       bounce
defer   unix    -       -       -       -       0       bounce
flush   unix    n       -       -       1000?   0       flush
proxymap  unix  -       -       n       -       -       proxymap
smtp    unix    -       -       -       -       -       smtp
relay   unix    -       -       -       -       -       smtp
showq   unix    n       -       -       -       -       showq
error   unix    -       -       -       -       -       error
local     unix  -       n       n       -       -       local
virtual   unix  -       n       n       -       -       virtual
lmtp    unix    -       -       -       -       -       lmtp

# Added for amavisd
smtp-amavis unix -      -       n     -       2  lmtp
   -o smtp_data_done_timeout=1200
   -o smtp_send_xforward_command=yes

127.0.0.1:10025 inet n  -       n     -       -  smtpd
   -o content_filter=
   -o local_recipient_maps=
   -o relay_recipient_maps=
   -o smtpd_restriction_classes=
   -o smtpd_client_restrictions=
   -o smtpd_helo_restrictions=
   -o smtpd_sender_restrictions=
   -o smtpd_recipient_restrictions=permit_mynetworks,reject
   -o mynetworks=127.0.0.0/8
   -o strict_rfc821_envelopes=yes
   -o smtpd_error_sleep_time=0
   -o smtpd_soft_error_limit=1001
   -o smtpd_hard_error_limit=1000
#-------------------------------------------------------------#


3. Cyrus-SASL

SASL потребуется для того, чтобы авторизовать пользователей при smtp-авторизации.

$ sudo apt-get install cyrus-sasl2

  · Конфигурация:

#/etc/sasl2/saslauthd.conf
#
ldap_servers: ldap://127.0.0.1/
ldap_bind_dn: cn=courier,ou=Daemons,dc=gorodmasterov,dc=com
ldap_bind_pw: **********
ldap_version: 3
ldap_timeout: 5
ldap_search_base: ou=Users,dc=gorodmasterov,dc=com
ldap_filter: uid=%u
#------------------------------------


Как видно используется учётная запись courier в ldap, чтобы иметь доступ к атрибуту userPassword.

Файл /etc/sysconfig/saslauthd должен содержать такую строку:
OPTIONS="-a ldap -m /var/spool/postfix/var/run/saslauthd -O /etc/sasl2/saslauthd.conf"

Демон saslauthd должен помещать свой сокет в /var/spool/postfix/var/run/saslauthd, поскольку postfix сидит в чруте.

И последнее: создаётся файл /usr/lib/sasl2/smtpd.conf с таким содержимым:
pwcheck_method: saslauthd
mech_list: PLAIN LOGIN


Т.е. используются основные методы авторизации PLAIN (мозилка, фандербёрд), LOGIN (аутглюк).

4. Courier-imap

Courier-imap - превосходный IMAP, POP3 сервер.

Установка проста:
$ sudo apt-get install courier-imap courier-authdaemon courier-authdaemon-ldap

И конфигурация тривиальна:

#/etc/courier-imap/authdaemon-ldap.conf

LDAP_SERVER             localhost
LDAP_PORT               389
LDAP_PROTOCOL_VERSION   3
LDAP_BASEDN             ou=Users,dc=gorodmasterov,dc=com
LDAP_BINDDN             cn=courier,ou=Daemons,dc=gorodmasterov,dc=com
LDAP_BINDPW             **********
LDAP_TIMEOUT            5
LDAP_AUTHBIND           1
LDAP_MAIL               uid
LDAP_GLOB_UID           vmail
LDAP_GLOB_GID           vmail
LDAP_HOMEDIR            uid
LDAP_MAILROOT           /home/vmail
LDAP_DEFAULTDELIVERY    defaultDelivery
LDAP_FULLNAME           cn
LDAP_CLEARPW            clearPassword
LDAP_CRYPTPW            userPassword
LDAP_DEREF              never
LDAP_TLS                0


В /etc/courier-imap/authdaemon.conf сокращается список модулей до одного:
authmodulelist="authldap"

В файлах /etc/courier-imap/{imapd,pop3d} указывается параметр
ADDRESS=0.0.0.0
чтобы сервис сидел на всех интерфейсах (а не только на lo).

Чтобы сгенерировать сертификаты для возможности запуска imapds и pop3ds (которые также будут использоваться и для TLS в postfix), надо отредактировать файлы:
/etc/courier-imap/{imapd.cnf,pop3s.cnf}
Здесь собственно требуется привести в порядок секцию [ req_dn ], где указать корректную информацию о организации и главное FQDN (имя хоста, аттрибут CN) почтового сервера.
После этого запуск скриптов mkpop3dcert, mkimapdcert (/usr/share/courier-imap), создаст корректные сертификаты.

Думаете всё? Нет. Специфика АЛьТа:
в файле /etc/sysconfig/courier-imap указать параметр DEFAULT_AUTHD=ldap , иначе он не будет подгружать ldap-модуль аутентификации.

5. Amavisd-new + (clamav, spamassassin) - Анти{спам|вирус} - в одном флаконе.

Что произойдёт, если вы сделаете
$ sudo apt-get amavisd-new

Правильно, в вашу систему доустановится куча пакетов, включая clamav и spamassassin. Если скажет, что такого пакета нет, значит вы забыли подключить contrib'ы в настройках apt (sources.list).

Amavisd-new - служит посредником между MTA и антивирусом|антиспамом. Настраивается практически со всеми известными антивирусами и в частности clamav - опенсоурс антвирус, подающий большие надежды. Разочаровавшись в drweb и kav (из-за их тупой лицензионной политики и стоимости), я выбрал clamav и не пожалел. Spamassassin - единственный спам-фильтр, который мне удалось найти.

Настройка:

Файл настройки /etc/amavis/amavisd.conf, есть по сути perl-скрипт с настройками. Изменить пришлось всего один параметр:
$mydomain = 'gorodmasterov.com'

После долгого боя с юзерами, подправил и переменную $banned_filename_re , чтобы могли отсылать файлы "*.exe".

Все остальные параметры, касаемые clamav и spamassassin уже настроены. Т.о. по уже расписанным выше настройкам postfix'а всё будет работать сразу и без промедления.

Запускаем почтовый сервер.

Теперь необходимо убедиться, что все сервисы описанные выше: postfix, amavisd, saslauthd, clamav, courier-*, slapd прописаны на запуск при старте системы (chkconfig --list). Теперь стартуем их в порядке, в котором они стартуют в /etc/rc3.d/. Если всё нормально, то мы получим работающую почтовую систему, но пока со всего одним пользователем.
Чтобы пользователей стало побольше, можно использовать в качестве примера ldif-файл, приведённый выше для openldap.
Стоит помнить, что атрибут mail - это основной адрес пользователя. Если вы хотите навесить ему алиасы, используйте атрибут mailAlternateAddress, которых может быть сколько угодно. Также можно незаметно читать чужую почту, навесив себе в алиас email какого-либо существующего пользователя ;)

Или вот такой простой скрипт на перле для добавления почтовых пользователей (для его работы надо установить пакет perl-ldap):

#!/usr/bin/perl
#
# addmailuser - adding new mail user
#

#### LDAP ####
use Net::LDAP;

my $ldapsrv = "localhost";
my $ldapadmin = "cn=admin,dc=gorodmasterov,dc=com";
my $ldappw = "****************";

my $ldap = Net::LDAP->new($ldapsrv, version=>3);

$user = $ARGV[0];

unless ($user) {
       print "usage: addmailuser <username>\n";
       exit(1);
}

$ldap->bind($ldapadmin,password=>$ldappw);

print "adding user $user ...\n";
$result = $ldap->search(base=>'ou=Users,dc=gorodmasterov,dc=com',scope=>'one',
                               filter=>"uid=$user");
@entries = $result->entries;
foreach $entry (@entries) {

       if ($entry->get_value('mail')) {
               print " oops, $user already exist: ".$entry->dn()." . Exiting\n";
               exit(1);
       } else {
               print " $user exist: ".$entry->dn().", but dont have mail attributes. Adding\n";
               $flag = 1;
               last;
       }

}

print "New password : ";
system "stty -echo" if (-t STDIN);
chomp($pass=<STDIN>);
system "stty echo" if (-t STDIN);
print "\n";

print "Retype new password : ";
system "stty -echo" if (-t STDIN);
chomp($pass2=<STDIN>);
system "stty echo" if (-t STDIN);
print "\n";

if ($pass ne $pass2) {
       print "New passwords don't match!\n";
       exit (1);
}

$pass = quotemeta($pass);

open(PA, "/usr/sbin/slappasswd -h {SSHA} -s $pass |") || die "cant open slappaswd\n";
chomp($pass = <PA>);
close(PA);

if ($flag) {

       $entries[0]->add(
               'objectClass' => ['person','organizationalPerson','qmailUser'],
               'mail' => "$user\@gorodmasterov.com",
               'mailMessageStore' => $user."/Maildir/",
               'accountStatus' => "active"
               );
       $entries[0]->replace(
               'userPassword' => $pass
               );
       $entries[0]->update($ldap);

} else {

       $result = $ldap->add("uid=$user,ou=Users,dc=gorodmasterov,dc=com",
               attr => [
                               'objectClass' => ['top', 'person', 'organizationalPerson', 'inetOrgPerson',
                                                 'qmailUser'],
                               'sn' => $user,
                               'cn' => $user,
                               'userPassword' => $pass,
                               'mail' => "$user\@gorodmasterov.com",
                               'uid' => $user,
                               'mailMessageStore' => $user."/Maildir/",
                               'accountStatus'=>"active"
                       ]
               );
}

print "Ok\n";

$ldap->unbind();

exit;


Скрипт обрабатывает ситуацию, когда в ldap уже есть пользователь (posixAccount), но он не имеет атрибута mail (адрес почты).

Заключение.
Пожалуй это всё. Если есть вопросы или вы обнаружили ошибки, пишите на ..., хотя моё мыло уже фигурировало тут в примерах ;)

Использованные источники

1. LDAP for Postfix with Courier IMAP / T. Knab, http://annapolislinux.org/docs/plc/postfix-cour… /
2. ldap, postfix and courier-imap howto / J.Vriesman, http://jeroen.protheus.com/postfix-courier-ldap… /
3. LDAP_README, VIRTUAL_README (документация по Postfix) / http://www.postfix.org /
4. LDAP+postfix+courier-imap HOWTO /crux/ http://unix.nordcomp.ru/articles.html?id=12&pag…
5. postfix-how-to /Valery Inozemtsev aka Shrek/ ftp://ftp.altlinux.ru/pub/people/shrek/doc/pos…
Категория: Mail | Добавил: oleg (27.10.2007)
Просмотров: 1335 | Рейтинг: 0.0/0 |
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Форма входа

Beastie

Друзья сайта

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
links

Copyright MyCorp © 2024