Postfix как почтовый шлюз для MS Exchange 2003

Как отфильтровать спам из потока электронных писем поступающих на почтовый сервер, с одной стороны-сложная задача, с другой, есть определенные признаки по которым можно определить что хост отправитель, участвует в рассылке нежелательной корреспонденции.

Схема работы:

Рассмотрим схему подробнее:
Есть Linux сервер, который открыт для приема корреспонденции из интернет, есть сервер Windows 2003/2008- версия не важна, с установленной ролью Active Directory и почтовый сервер Exchange. Exchange может жить как на одном сервере с AD( такое обычно бывает в небольших организациях) или на выделенном сервере (тут все зависит от IT-инфраструктуры)
Значит, сама выгрузка данных о получателях, т.е. список почтовых ящиков пользователей будет происходить из AD, благо, когда в системе с AD установлен Exchange, информация об e-mail адресе пользователя, добавляется автоматически в свойства учетной записи Active Directory.

Для примера мы будим использовать имя домена example.com
Предполагается, что сервер Ubuntu уже установлен и обновлен до последней актуальной версии.

Часть первая, подготовка Postfix

Для начала, устанавливаем необходимые пакеты

sudo apt-get install postfix 

редактируем основной конфигурационный файл postfix, предварительно залогинившись как супер-пользователь

sudo su

nano /etc/postfix/main.cf

Нас интересуют следующие строки (находим их и редактируем, так как указанно ниже, адрес example.com меняем на свой)

myhostname = mail.example.com # полное имя хоста
mydomain = example.com # имя домена, от имени которого приходит почта
mydestination = mail.example.com, localhost, example.com
mynetworks = 127.0.0.0/8, 192.168.0.20 [::ffff:127.0.0.0]/104 [::1]/128 

список доверенных сетей из которых разрешена неавторизированная отправка, сервер win2k3 имеет адрес 192.168.0.20, этой директивой мы разрешаем отправку почты наружу через postfix только непосредственно серверу с Exchange на борту, даже клиенты локальной сети должны отправлять почту только через Exhcange.

virtual_mailbox_domains = example.com

transport_maps = hash:/etc/postfix/transport
virtual_transport = hash:/etc/postfix/transport

Эти пункты отвечают за то, куда будет передаваться принятая почта.

В конце конфига добавляем

bounce_queue_lifetime = 1d
maximal_queue_lifetime = 1d
minimal_backoff_time = 180s
maximal_backoff_time = 12h

strict_rfc821_envelopes = yes
disable_vrfy_command = yes
smtpd_delay_reject = yes
smtpd_helo_required = yes
anvil_rate_time_unit = 60s
smtp_always_send_ehlo = yes
smtpd_hard_error_limit = 1
smtpd_recipient_limit = 1
smtpd_sasl_security_options = noanonymous

anvil_rate_time_unit = 60s
smtpd_client_connection_count_limit = 5
smtpd_client_connection_rate_limit = 6
smtpd_client_message_rate_limit = 6
smtpd_client_recipient_rate_limit = 1

smtpd_client_restrictions =
    reject_unauth_pipelining,
    permit_sasl_authenticated,
    permit_mynetworks,
    check_helo_access regexp:/etc/postfix/helo,
    reject_unknown_client_hostname,
    check_client_access regexp:/etc/postfix/dul_checks,
    permit

smtpd_helo_restrictions =
    permit_mynetworks,
    permit_sasl_authenticated,
    reject_unknown_client,
   # проверяем IP на присутствие в спам-листах
    reject_rbl_client cbl.abuseat.org,
    reject_rbl_client sbl-xbl.spamhaus.org,
    reject_rbl_client sbl.spamhaus.org,
    reject_rbl_client dnsbl.njabl.org,
    check_helo_access regexp:/etc/postfix/helo,
    reject_invalid_helo_hostname,
    reject_non_fqdn_helo_hostname,
    reject_unknown_helo_hostname,
    check_sender_access hash:/etc/postfix/access,
    check_recipient_access hash:/etc/postfix/recipients,
    permit

smtpd_sender_restrictions =
    permit_sasl_authenticated,
    permit_mynetworks,
    reject_non_fqdn_sender,
    reject_unknown_sender_domain,
    permit

smtpd_recipient_restrictions =
    reject_unauth_pipelining,
    permit_mynetworks,
    permit_sasl_authenticated,
    reject_unauth_destination,
    reject_invalid_hostname,
    reject_non_fqdn_recipient,
    reject_unknown_recipient_domain,
    permit

сохраняем конфиг и выходим в консоль.
Подробно на всех пунктах останавливаться не буду, их назначение легко найти в гугле,
Все содержимое можно просто скопировать как есть.
Далее нам необходимо создать следующие файлы:

nano /etc/postfix/transport 

содержащий

example.com  smtp:[192.168.0.20] 

отвечает за то, куда нужно передавать принятую почту.
где: smtp:серер получатель, IP в [ ] говорит о том, что не нужно проверять его ДНС зону, а передавать почту на этот адрес как есть, а там разберутся!

nano /etc/postfix/recipients

Это наш список получателей, который экспортируется из Exchange
Содержит записи вида:

[email protected] OK

где: username-имя пользователя в AD c mailbox, example.com -домен получателя, OK –директива, как поступить с письмом, в нашем случае – пропустить.
Сведения о получателях будут содержаться именно в этом файле, можно конечно сделать опрос exchange в реальном времени и у меня даже где-то был скрипт, но все руки не доходили, тут еще появляется ненужная нагрузка на контроллер домена, а оно вам надо?! Причем если одновременно долбиться несколько сот тыс. отправителей, все эти запросы посыпятся и на AD. Это и потерянное время на ожидание ответа, от винды и нагрузка на процессор уже 2х серверов. По моему глубокому мнению, проще запустить скрипт в заданное время, выгрузинт список получателей, и перебросит их в файл, как часто его запускать-решать вам, у меня он запускается 2 раза в день 12 и 15 часов — чаще не требуется.

Едем дальше:

nano /etc/postfix/helo
/([0-9]{1,3}(\.|-)){3}[0-9]{1,3}/i      REJECT IP-able helo SPAM!
/localhost/i    REJECT you are SPAM!
/example.com/i REJECT you are not in my local networks-SPAM!

В этом файле используются регулярные выражения, для фильтрации команды helo
Если отправитель представился IP адресом-то это нарушение и почту от него, не принимают, тоже самое со вторым пунктом localhost –нормальный сервер не может представляться так, либо там админ криворукий (пускай настраивает нормально) либо на другом конце просто сильно запаршивевший компьютер, который является частью ботнета, рассылающего спам. Ну и последнее если отправитель представляется — example.com, ну не может на другом конце быть наш сервер, это на 100% спам- можно смело заворачивать письмо. Команда REJECT указывает на то, что сделать при выполнении условий.
Да к стати, после идет ответ сервера, с указанием причины отказа в принятии почты, туда можно вписать что-то обидное 😉 и это сообщение увидят на том конце. Но это дело воспитания конкретного индивидуума.

nano /etc/postfix/access

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

[email protected] REJECT user is note available
example.com  REJECT you are not in my local networks
Внешний IP нашего сервера REJECT you are not in my local networks
localhost       REJECT you are SPAM!
nano /etc/postfix/dul_checks

Проверка на принадлежность к различным сетям.
Содержит регулярные выражения различных сетей и как следствие, признаков что это не почтовые сервера, а зараженные клиентские компьютеры, а если там действительно работают нормальные сервера, то почту можно отправлять и через релей провайдера или на худой конец обратиться в тех поддержку чтобы прописали обратную DNS зону.

/([0-9]*-){3}[0-9]*(\..*){2,}/i         REJECT 553 SPAM_ip-add-rr-ess_networks
/([0-9]*\.){4}(.*\.){3,}.*/i    REJECT 553 SPAM_ip-add-rr-ess_networks
/.*\.broadband\.hu/i    REJECT 553 SPAM_broadband-hu
/client.*\..*\..*/i     REJECT 553 SPAM_CLIENT
/cable.*\..*\..*/i      REJECT 553 SPAM_CABLE
/pool.*\..*\..*/i       REJECT 553 SPAM_POOL
/dial.*\..*\..*/i       REJECT 553 SPAM_DIAL
/ppp.*\..*\..*/i        REJECT 553 SPAM_PPP
/dslam.*\..*\..*/i      REJECT 553 SPAM_DSLAM
/dhcp.*\..*\..*/i       REJECT 553 SPAM_DHCP
/[\.-]dsl.*\..*\..*/i   REJECT 553 SPAM_DSL
/[ax]dsl.*\..*\..*/i    REJECT 553 SPAM_XDSL
/.*([0-9]*\.){4}cableonline\.com\.mx/i  REJECT 553 SPAM_IP-cableonline-com-mx
/.*\.([0-9]*\.){4}ip\.holtonks\.net/i   REJECT 553 SPAM_ip-holtonks-net
/([0-9]*-){3}[0-9]*\.fibertel\.com\.ar/i        REJECT 553 SPAM_IP-fibertel-com-ar
/.*[0-9]*-[0-9]*\.fibertel\.com\.ar/i   REJECT 553 SPAM_IP-fibertel-com-ar
/[0-9]*\.user\.veloxzone\.com\.br/i     REJECT 553 SPAM_user-veloxzone-com-br
/[0-9]*\.customer\.alfanett\.no/i       REJECT 553 SPAM_customer-alfanett-no
/.*([0-9]*-){3}[0-9]*\.telecom\.net\.ar/i       REJECT 553 SPAM_host-telecom-net-ar
/.*(-[0-9]*){2}\.telpol\.net\.pl/i      REJECT 553 SPAM_host-telpol-net-pl
/(.*\.){2}maxonline\.com\.sg/i  REJECT 553 SPAM_host-maxonline-com-sg
/(.*-){2}.*\.fairgamemail\.us/i REJECT 553 SPAM_host-fairgamemail-us
/[0-9]*[0-9]*-\.wispnet\.net/i  REJECT 553 SPAM_host-wispnet-net
/.*-.*(\..*){2}\.ne\.jp/i       REJECT 553 SPAM_host-ne-jp
/[0-9]*\..*\.ne\.jp/i   REJECT 553 SPAM_h09t-ne-jp
/(.*\.){3}ad\.jp/i      REJECT 553 SPAM_host-ad-jp
/(.*\.){4}revip\.asianet\.co\.th/i      REJECT 553 SPAM_revip-asianet-co-th
/[0-9]*\..*\.virtua\.com\.br/i  REJECT 553 SPAM_host-virtua-com-br
/([0-9]*-){3}[0-9]*\.exatt\.net/i       REJECT 553 SPAM_host-exatt-net
/([0-9]*\.){4}ip\.alltel\.net/i REJECT 553 SPAM_host-ip-alltel-net
/[0-9]{6,}\.chello\.../i        REJECT 553 SPAM_host-chello
/.*[0-9]*\..*\.chello\.../i     REJECT 553 SPAM_host-chello-xx
/.*\..*\.t-dialin\.net/i        REJECT 553 SPAM_t-dialin-net
/.*\..*\.t-ipconnect\.de/i      REJECT 553 SPAM_t-ipconnect-de
/([0-9]*-){2,3}[0-9]*\..*\.cgocable\.net/i      REJECT 553 SPAM_host-cgocable-net
/.*\..*\.shawcable\.net/i       REJECT 553 SPAM_host-shawcable-net
/p[0-9]*\.mp[0-9]*\.aaanet\.ru/i        REJECT 553 SPAM_aaa_modem_pool
/([0-9]*-){2}[0-9]*\.ip\.adsl\.hu/i     REJECT 553 SPAM_ip-adsl-hu
/([0-9]{1,3}\.){2}broadband4\.iol\.cz/i REJECT 553 SPAM_broadband-iol-cz

В результате у нас должно получиться 5 файлов,
их необходимо переконвертировать в фалы базы данных используемые posfix.

postmap /etc/postfix/transport
postmap /etc/postfix/recipients
postmap /etc/postfix/helo
postmap /etc/postfix/access
postmap /etc/postfix/dul_checks

если все проходит без ошибок, двигаемся дальше.
Это что касается ubuntu…

Чась вторая: Настройка Win2k3

По моему, глубокому мнению, не имеет смысла пускать сервер с передовой, в тыл нашей обороны, по этой же причине мы не будем давать лазить в системе и опрашивать ее, а разрешим ей видеть только то, что ей необходимо для работы, не более.
Как это можно реализовать на практике?! Postfix будет видеть только тот список получателей который мы ему сами дадим -уже готовый!
На сервере Windows, через планировщик заданий, мы будем запускать скрипт который будет экспортировать список пользователей в файл recipients.

Схема работы системы Win:
В AD заводится пользователь с минимальными правами (без почтового ящика), с правом доступа, лишь в одну папку. Назовем его, для примера, postfix с паролем 1234567.
Через планировщик заданий создается новое задание с частотой выполнения нужной вам.
На просторах сети был найден скрипт, который не полностью соответствовал нашим задачам, я его слегка допилил и теперь он делает на 100% то, что нужно.
Сам скрипт написан на VBS, назовем его mail.vbs — такого содержания:
( прошу просмотреть его очень внимательно, конкретно “objOutputFileName.Writeline( objADobject.Mail & “ там есть комментарии)

Option Explicit

Dim StartTime,EndTime: StartTime = Now ' For seeing how long the script takes to run
Dim objShell
Dim objFSO
Const ScriptVersion = "1.01"
Set objShell = WScript.CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Wscript.Echo "StartTime =  " &  StartTime
' ***************************************************************** '
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Dim objRootDSE
Dim objDomain
Dim objContainer
Dim objOrganizationalUnit
Dim strOutputFileName, objOutputFileName, GarbageRC
Dim intUserObjectCountAll, intUserObjectCountSelected

strOutputFileName = "c:\путь\ к расшаренной папке\ для пользователя postfix\recipients"

Set objOutputFileName = objFSO.OpenTextFile(strOutputFileName, ForWriting, True)
intUserObjectCountAll = 0
intUserObjectCountSelected = 0

Set objRootDSE = GetObject("LDAP://RootDSE")
Set objDomain = GetObject("LDAP://" & objRootDSE.Get("DefaultNamingContext"))

Call Sub_EnumOUs(objDomain.ADsPath)

Sub Sub_EnumOUs(sADsPath)
Set objContainer = GetObject(sADsPath)
objContainer.Filter = Array("OrganizationalUnit")
For Each objOrganizationalUnit in objContainer
WScript.Echo "Checking OU: " & objOrganizationalUnit.ADsPath
Wscript.Echo " User Object Count: " & intUserObjectCountAll
Sub_EnumUsers(objOrganizationalUnit.ADsPath)
Sub_EnumOUs(objOrganizationalUnit.ADsPath)
Next
End Sub

Sub Sub_EnumUsers(sADsPath)
Dim objADobject
Set objContainer = GetObject(sADsPath)
objContainer.Filter = Array("User")
For Each objADobject in objContainer
If objADobject.Class = "user" Then
intUserObjectCountAll = intUserObjectCountAll + 1
If objADobject.Mail <> "" Then
objOutputFileName.Writeline( objADobject.Mail & "	OK" )  ' *** "[TAB]OK"- разделение с помощью табуляции **** '
intUserObjectCountSelected = intUserObjectCountSelected + 1
End If
End If
Next
End Sub

objOutputFileName.Close


' ***************************************************************** '

Чтобы создать задание в планировщике, в строку инициализации нашего скрипта пишем:

c:\windows\system32\cscript.exe c:\путь к папке со скриптом\mail.vbs

ВСЕ это одной строкой!
Ну и выставляем время, когда он будет выполнятся и как часто.
Далее создаем директорию и открываем в нее доступ по сети пользователю postfix.

Часть третья –заключительная.

Теперь задача, чтобы наш linux сервер мог увидеть содержимое сетевой папки с файлом recipients.
Я предпочел монтировать расшаренную директорию при старте системы, по этому, запихал команду монтирования в файл /etc/rc.local.
Также необходимо создать в директории media директорию win. Почему именно win- чтобы, через несколько месяцев, можно было понять, что это такое и откуда оно взялось.
Сначала ставим пакет smbfs -без него наша директория не примонтируется.

sudo apt-get install smbfs

Редактируем файл rc.local

nano /etc/rc.local

И перед строкой exit0 вписываем команду монтирования шары:

mount -t smbfs //192.168.0.20/antispam /media/win/ -o iocharset=utf8,user=postfix,pass=1234567

где: 192.168.0.20-ip сервера с exchange.
antispam-директория в которой лежит файл recipients.
/media/win/-куда должна примонтироваться виндовая шара.
iocharset=utf8-кодировака, если случайно в ней появятся папки с русскими названиями, то они будут читаемы, а не ???????????, да и хуже от этого не будет, в общем делаем сразу как надо и спим спокойно.

user=postfix,pass=1234567

–имя пользователя и пароль для доступа к шаре.

Перезагружаем Ubuntu лезем в /media/win/ видим ее содержимое виндовой шары- значит все отлично.

Далее создадим небольшой скрипт который будет переписывать файл recipients
в директорию /etc/postfix, а затем будет экспортировать его в базу данных postfix и перезагружать почтовик.

#!/bin/bash
cp /media/win/recipients /etc/postfix/
postmap /etc/postfix/recipients
/etc/init.d/postfix restart

Создаем задание в CRON которое будет выполняться через 3 мин после выполнения задания на Win2k3-на всякий случай. (например 12:03 и в 15:03)

Вот и все!

Что мы получили

Аниспам фильтр, с высокой степенью эффективности-до его установки я каждое утро разгребал по 240-260 писем сейчас наблюдаю, только нужную почту.
Единственный ящик в который спам, все таки доходит, это ящик на который приходят заявки для нашей конторы, но их число не превышает 3-4 шт.
Безопасность — в случае компрометации сервера Linux шлюз легко восстанавливается, Да и злоумышленник не получит доступа к корреспонденции, т.к ее на нем просто нет, она сразу передается Exchange-если проходит все проверки.
Кроссплатформенность-нет смысла собирать модули с поддержкой всяких экзотических функций.

Время на развертывание-1 час с условием того, что Интернет шустрый, да и если все скопировать как есть. Система протестирована в течении года-работает без сбоев.
А что еще можно прикрутить к нему- решать вам. Там можно сделать и грейлистинг и установить spamassassin в общем нет предела фантазии, но нужно соблюдать меру.
Ну и на последок, судя по комментариям настройка вызвала сложности, по этому выкладываю копию конфигов с боевого сервера, все домены в нем заменены на example.org от вас требуется- заменить только IP адреса собственно архив
Есть что добавить?! Прошу в комментарии…

Источник http://howitmake.ru/blog/ubuntu/12.html

Запись опубликована в рубрике *Mail, Postfix. Добавьте в закладки постоянную ссылку.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Я не спамер This plugin created by Alexei91