DirectAdmin — ограничение количества писем в час
Итак, вы пользуетесь DirectAdmin для предоставления услуг хостинга или в личных целях. Вам нужно, чтобы в случае закачки на сервер через дырявые скрипты или при взломе аккаунта скриптов для рассылки спама, чтобы весь этот спам не ушел моментом с вашего сервера. По этому вам требуется сделать ограничение на количество писем отправляемых с одного аккаунта.
Факты: DirectAdmin умеет ограничивать количество отправляемых писем в сутки с доменов пользователя, ограничение можно выставить общие для всех. С новой версией exim.pl, которая еще не идет со стабильным релизом DirectAdmin, можно задавать ограничения для определенного пользователя.
Мысли: например мы выставили ограничение в 500 писем в сутки, тогда эти 500 писем можно отправить все сразу, так и периодически. Из этого следует, что это не вариант предотвращения спама, потому что:
- все письма можно отослать сразу (спамеру этого вполне достаточно);
- так же есть веб ресурсы, которым требуется большое количество отправок корреспонденции и данное ограничение для них не подойдет.
Вывод: Хороший вариант – это ограничение количества писем в час, настраиваемое как для всех аккаунтов сервера, так и для определенного пользователя.
Решение: Все не только просто, а очень просто. DirectAdmin использует для подсчета количества писем и ограничение скрипт написанный на perl. Посмотрев содержимое /etc/exim.pl можно сразу найти функцию check_limits, где все и считается. Итак, открываем этот файл на редактирование и заменяем эту функцию с ее содержимым на:
sub check_limits
{
my $count = 0;
my $last_send = 0;
my $cur_time = 0;
my $diff_time = 0;
if (open (LIMIT, "/etc/virtual/limit_$name"))
{
$email_limit = int(LIMIT);
close(LIMIT);
}
else
{
open (LIMIT, "/etc/virtual/limit");
$email_limit = int(LIMIT);
close(LIMIT);
}
#find the curent user
$uid = find_uid();
#log_str("Found uid: $uid\n");
if (uid_exempt($uid)) { return "yes"; }
my $name="";
#check this users limit
$name = getpwuid($uid);
if (!defined($name))
{
$name = "unknown";
}
if ($email_limit > 0)
{
$last_send = (stat("/etc/virtual/usage/$name"))[9];
if ($last_send eq "")
{
open(USAGE, ">/etc/virtual/usage/$name");
close(USAGE);
chmod (0660, "/etc/virtual/usage/$name");
}
$time_lock = (stat("/etc/virtual/usage/$name.time"))[9];
if ($time_lock eq "")
{
open(TIMELOCK, ">/etc/virtual/usage/$name.time");
close(TIMELOCK);
$time_lock = (stat("/etc/virtual/usage/$name.time"))[9];
}
$cur_time = time;
$diff_time = $cur_time - $time_lock;
if ($diff_time >= 3600)
{
open(USAGE, ">/etc/virtual/usage/$name");
close(USAGE);
chmod (0660, "/etc/virtual/usage/$name");
open(TIMELOCK, ">/etc/virtual/usage/$name.time");
close(TIMELOCK);
}
$count = (stat("/etc/virtual/usage/$name"))[7];
if ($count eq "")
{
$count = 0;
}
if ($count > $email_limit)
{
die("You ($name) have reach your daily email limit of $email_limit emails\n");
}
open(USAGE, ">>/etc/virtual/usage/$name");
print USAGE "1";
close(USAGE);
chmod (0660, "/etc/virtual/usage/$name");
}
my $sender_address = Exim::expand_string('$sender_address');
my $mid = Exim::expand_string('$message_id');
log_bandwidth($uid,"type=email&email=$sender_address&method=outgoing&id=$mid");
return "yes"
}
Сохраняем файл и перезапускаем exim. Заходим в директорию /etc/virtual/ , создаем файл с названием limit_имяпользователя и вписуем в него цифрами количество писем в час, например 200. Далее идем в директорию /etc/virtual/usage/ и ищем файлы с именем пользователя. При отправке сообщения пользователем, например user, с домена, в директории появятся файлы:
user – в файле калькулируются количество писем, одно письмо = 1 в файле
user.bytes – логируются данные писем (пользователь, исходящее письмо или входящее и т.д.)
user.time – файл является точкой отсчета для проверки ограничения писем в час
Вот и все. Cтавьте, проверяйте и пользуйтеcь на здоровье.
Архив файла exim.pl можно скачать тут — ссылка












В ограничениях есть одна уязвимость, когда стоит квота на 50 писем в час, посылается миллион писем, спул переполняется и падает мускуль, днс, почта и прочие сервисы.
уменьшите количество запускаемых процессов exim, чтобы не отъедал всю память.
Там банально заканчивается дисковое пространство.
/dev/ad0s1d 2.9G 1.5G 1.1G 57% /var
нужно что то, что формирует квоту на прием к отправке писем, еще круче, если будет анализировать количество адресов для отправки
а как вы себе это представляете ? запущен скрипт который отправляет спам, письма не уходят по рассылке а отбрасываются назад, так как проверка идет уже когда письмо упало в очередь (для примера рассылка идет через sendmail, локальный мейлер).
Тут как вариант мониторить кучу на количество писем + свободное место на диске.
Я не могу вычислить кто забивает очередь,
потому как вся статистика собирается с от правленых писем.
А мониторить можно на уровне сокета,
по какому логину/паролю поднят сокет.
ведь, очередь отправки как то разбирается по пользователям, не зависимо от того какой адрес поставлен отправителем.
>Я не могу вычислить кто забивает очередь, потому как вся статистика собирается с от правленых писем.
exim -bp — покажет письма в очереди и их id
exim -Mvb id — покажет содержимое письма, если оно уже отброшено, то и заголовки
exim -Mvh id — покажет заголовки письма, от кого оно и как попало в очередь
exim -Mvl id — покажет статус доставки сообщения
>А мониторить можно на уровне сокета, по какому логину/паролю поднят сокет.
это если через сокет отправлено с авторизацией, а если через локальный мейлер, то покажет только пользователя. А если еще через localhost разрешено отправлять письма без авторизации, то можно подставить все что угодно и найти будет практически не возможно.
>ведь, очередь отправки как то разбирается по пользователям, не зависимо от того какой адрес поставлен отправителем.
не факт, пример смотрите выше
Эта инфа для меня доступна
# exim -bp
24h 1.9K 1RVRFT-000Gy4-FV *** frozen ***
fraternizez@unisonprojects.com
24h 2.0K 1RVRIW-000Gzl-GC *** frozen ***
fleckedl@everspring.com
Только по ней я не пойму, кто конекится у почтовику и отправляет почту.
Хотя после отправки, письмо будет посчитано и к конкретному логину привязано.
Значит есть еще гдето связка.
1RVRFT-000Gy4-FV и 1RVRIW-000Gzl-GC и есть id писем, используйте остальные комманды для получения информации
В том то и прикол, что немогу по id,
узнать логин/пароль отправителя.
Значить как я уже и писал рассылка идет через localhost без авторизации. Нужно исправить это в конфиге exim, правда после этого некоторые web почтовые клиенты, которые идут в поставке с DirectAdmin, перестанут работать.
Хех, за эту дырку, забыл вообще!