Pull to refresh

Защита от спама при помощи капчи

Reading time 4 min
Views 992
После недолгих исследований методов борьбы со спамом, я решил сделать свой.

Все дело в том, что найденные методы не удовлетворяют одному простому условию — защита должна экономить траффик, т.е. желательно, чтобы текст письма не загружался на сервер, а принятие решения о том, нужно или нет принимать письмо основывалось исключительно на анализе заголовков.
Так как у нас есть веб сервер, который находится на том же компьютере, где и почтовый сервер, был реализован следующий алгоритм:
— Созадем белый список отправителей, от которых письма принимаются без ограничений
— Если отправитель не содержится в белом списке — ему отправляется ошибка с указанием, как внести свой адрес в белый список
— На веб сервере делаем страничку с капчей для внесения адреса в белый список

И так, по-порядку (у нас используюется ubuntu, поэтому инструкции приводятся для этого типа дистрибутива):
1. Для хранения белого списка будем использовать postgresql:
sudo apt-get install apache2 postgresql-8.3 postfix php

в файл /etc/postgresql/8.3/main/pg_hba.conf вставляем строку
local whitelist whitelist password

далее создаем базу данных whitelist с единственной таблицей whitelist

sudo su - postgres
psql -c "create user whitelist password '1'" (указать нормальный пароль)
psql -c "create database whitelist owner whitelist"
psql -d whitelist -c "create table whitelist(email varchar, primary key(email))"


2. база данных готова, создаем страничку для добавления адреса эл. почты в белый список.
скачиваем kcaptcha http://www.captcha.ru/kcaptcha/
создаем whitelist.php:
<?
session_start();
?>
<html><head><title>добавление</title>
</head>
<body>
<div align="center">
<table width="80%"><tr><td>
<h1>Добавление адреса в белый список</h1>
Чтобы довавить ваш адрес в белый список, пожалуйста,
заполните приведенную ниже форму.
</td></tr>
<tr><td align="center" class="formbg">
<form action="/whitelist_add.php" method="post">
<table><tr>
<td>введите ваш e-mail адрес:</td>
<td><input type="text" name="email" class="inp"/></td></tr>
<tr><td> </td></tr>
<tr>
<td valign="bottom">кривыми буквами написано:</td>
<td><img src="/kcaptcha/index.php?<?=session_name()?>=<?=session_id()?>"><br/><input type="text" name="keystring" class="inp"></td></tr>
<tr><td> </td></tr>
<tr><td colspan="2" align="center"><input type="submit" value=" добавьте меня в белый список"></td>
</tr></table>
</form>
</td></tr>
</table>
</body>
</html>



и файл whitelist_add.php
<?
session_start();
$correct = false;
if(count($_POST)>0){
        if(isset($_SESSION['captcha_keystring']) && $_SESSION['captcha_keystring'] ==  $_POST['keystring']){
                $correct = true;
        }
}
unset($_SESSION['captcha_keystring']);
?>
<html><head><title>результат добавления</title>
</head>
<body>
<div align="center">
<table width="80%"><tr><td>
<h1><?
if($correct) {
$dbconn = pg_connect("host=localhost dbname=whitelist user=whielist password=1") // укажите тот же пароль, что и в п.1
    or die('Could not connect: ' . pg_last_error());

// Performing SQL query
$result = pg_prepare($dbconn, "check_query", 'select email from white_list where email = $1');
$result = pg_execute($dbconn, "check_query", array($_POST['email']));
if(pg_fetch_array($result)) {
?>ваш адрес уже находится в белом списке<?
} else {
$result = pg_prepare($dbconn, "insert_query", 'insert into white_list(email) values($1)');
$result = pg_execute($dbconn, "insert_query", array($_POST['email']));
?>
ваш адрес был добавлен!<?
}
if($result) {
    pg_free_result($result);
}
pg_close($dbconn);
} else { ?>неверный код на картинке<?
}?>
</h1><?
if($correct) {
?>теперь вы можете без ограничений отправлять нам почтовые сообщения<?
} else {
?>
попробуйте <a href="whitelist.php">ещё раз</a>
<?
}
?>
</td></tr>
<tr><td><br/><br/><a href="/whitelist.php">добавить еще один адрес</a></td></tr>
</table>
</body>
</html>


3. теперь настраиваем postfix на фильтрацию заголовков

в каталое /etc/postfix создаем файл block
/.*/ REJECT \n\n******** your e-mail should be in our whitelist ******** \n Visit http://[адрес вашего сайта]/whitelist.php \n\n *******************************************\n\n

в этом же каталоге создаем файл pg_whitelist.cf
hosts = localhost
user = whitelist
password = 1 #не забываем поменять на пароль из п. 1
dbname = whitelist
query = select 'permit' from white_list where email = '%s'


в файле /etc/postfix/main.conf добавляем
smtpd_sender_restrictions = check_sender_access pgsql:/etc/postfix/pg_whitelist.cf, check_sender_access regexp:/etc/postfix/block

4. перегружаем postfix:
sudo /etc/init.d/postfix reload

Мы используем такой механизм примерно год. С первого дня использования спам как отрезало. Конечно, время от времени приходится самостоятельно вносить адреса клиентов, но в основном они разбираются самостоятельно. Спам бывает прорывается, по 2 причинам: обратный адрес либо не заполнен, либо совпадает с получателем — так как все получатели внесены в белый список, фильтр их пропускает. К сожалению, быстрого способа проверки что From = To не нашел, долго разбираться не было времени.
Tags:
Hubs:
-16
Comments 11
Comments Comments 11

Articles