Простий greylisting в opensmtpd

Дана стаття є логічним продовженням статті "Інтеграція поштового анти-спаму rspamd з opensmtpd" з-за деякого виклику, який мені кинули, сказавши, що складно реалізувати greylisting у зв'язці opensmtpd+rspamd.
"Історій успіху" інтеграції greylisting в opensmtpd я не зустрічав (якщо вони існують, то прохання написати в коментарях).
Що реалізувати greylisting в моєму випадку складно — я не заперечував і не збирався робити даний функціонал до того, як у opensmtpd реалізують фільтри, хоча і розумів, що greylisting — одна з непоганих методик боротьби зі спамом. Але кинутий виклик і бажання ще трохи знизити кількість спаму і спати спокійно — не дали спати спокійно і змусили зробити це.
Мені вдалося реалізувати простий спосіб greylisting'а.

Кілька уточнень:
  1. простий Спосіб тільки для того випадку, якщо реалізація зв'язки opensmtpd+rspamd зроблена через скрипт-прошарок mda.
  2. Реалізація greylisting'а для opensmtpd існує через фільтр. Але, як знають, зацікавлені в opensmtpd особи, стабільної реалізації фільтрів в opensmtpd немає. Крім того, не хотілося додавати ще один демон при наявності вбудованого грейлистинга в rspamd.
  3. Реалізація грейлистинга для opensmtpd існує для freebsd і spamd. Подробицями реалізації не цікавився, т. к. демона spamd під linux немає.
  4. Реалізація є милицею і використанням недокументованих можливостей, але куди ми без них в IT?
Теорія
Greylisting — методика покидька спаму, заснована на тому, що спам-програми хочуть розіслати як можна більше спаму тут і в цю секунду.
Спрощена логіка грейлистинга: якщо до нас приходить лист, то ми відповідаємо відправнику тимчасовою помилкою, самі запам'ятовуємо відправника (наприклад, на добу) для того, щоб прийняти від нього лист через деякий час (наприклад, через 5 хвилин).
"Правильний" відправник (згідно стандартам) повинен спробувати відправити нам листа ще раз через деякий час. "Неправильний" відправник цього або не робить або робить, але за минулий час відправник встигає потрапити в різні зовнішні спам-списки і ми його отфильтровываем вже на підставі цих спам-списків.
Після того, як ми відправника запам'ятали, то протягом доби (як приклад), перевірка на грейлисты не робиться повторно. Це дозволяє скоротити час доставки повторного листа (якщо це правильний відправник).
У postfix+amavis+spamasassin greylisting робився, якщо не помиляюся, за доменним іменам. У rspamd ключем для greylisting'а зроблений IP адреса відправника з маскою /19 (конфигурируемо). З боку загальної кластеризації та гео-розподілених сервісів — це виглядає як більш правильне рішення, але і обговорюване, з іншого боку.
На жаль, все вищесказане в теорії виглядає добре, але на практиці, коли на чайниках, мікрохвильових печах і звичайних комп'ютерах користувачів існує безліч ботнетів, які розсилають спам через звичайний Outlook (як він там, існує ще досі на Windows?) — все не так чудово. Але як-то методика працює і відмовлятися від неї не варто.
Практика
redis в rpsamd
Включаємо підтримку редиски в rpsamd. Модуль грейлистинга зберігає в редисці свої дані.
# /etc/rspamd/local.d/redis.conf
servers = "redis.example.com";
password = "example_password";

Запускаємо редис (в докері, наприклад, це робиться однією командою).
greylisting в rspamd
Включаємо модуль грейлистинга (за замовчуванням, він вимкнений. expire — час, на який відправник стає довіреною, після проходження перевірки. Я спеціально підкрутив побільше. За замовчуванням — 86400 секунд.
# /etc/rspamd/modules.d/greylist.conf
greylist {
expire = 864000;

.include(try=true,priority=5) "${DBDIR}/dynamic/greylist.conf"
.include(try=true,priority=1,duplicate=merge) "$LOCAL_CONFDIR/local.d/greylist.conf"
.include(try=true,priority=10) "$LOCAL_CONFDIR/override.d/greylist.conf"
}

Приклад контейнера з rspamd
greylisting в opensmtpd
Сама неоднозначна частину рішення.
Після того, як ми відправили лист демону rspamd через клієнт rspamc (див. попередню статтю) — демон нам на STDOUT відповідає текстом листа з доданими заголовками.
У випадку, якщо потрібно greylisting, то в заголовках буде присутній "X-Spam-Action: soft reject". По хорошому, mta або фільтри розпізнають цей заголовок і відповідають відправнику тимчасовою помилкою.
Але у нас немає підтримки mta або фільтрів. Тому, ми просто робимо exit 1!
# див. скрипт з попередній статті
greylisted=$( cat $mail_file | fgrep 'X-Spam-Action: soft reject' )
if [ -n "$greylisted" ]; then
exit 1
fi

opensmtpd, отримавши код повернення 1, розуміє, що щось пішло не так і за нас відповідає відправнику тимчасовою помилкою.
Особливості запуску docker контейнера з opensmtpd: його потрібно запускати в режимі мережі "host", щоб демон бачив коректні IP адреси відправників.
Приклад контейнера з opensmtpd
Разом
Ще менше спаму.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.