Как отфильтровать спам из потока электронных писем поступающих на почтовый сервер, с одной стороны-сложная задача, с другой, есть определенные признаки по которым можно определить что хост отправитель, участвует в рассылке нежелательной корреспонденции.
Схема работы:
Рассмотрим схему подробнее:
Есть 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