Борьба со спамом

Материал из poiuty wiki
Перейти к: навигация, поиск

На PHP хостингах, чаще всего, отправляют спам через функцию mail()
С помощью maillog (PHP >= 5.3) можно быстро определить какой именно скрипт делает рассылку.

; The path to a log file that will log all mail() calls. Log entries include
; the full path of the script, line number, To address and headers.
mail.log = /home/spam/mail.log

Сделаем скрипт, который будет отправлять письмо на наш адрес.

<? mail("poiuty@lepus.su", "My Subject", "Line 1\nLine 2\nLine 3");

Запустим его и проверим логи. Письмо ушло.

2015-03-20 15:45:56 1YYwJI-00041B-SP <= info@seolo.ru U=seolo P=local S=370 from <info@seolo.ru> for poiuty@lepus.su
2015-03-20 15:45:57 1YYwJI-00041B-SP => poiuty@lepus.su R=dnslookup T=remote_smtp H=aspmx.l.google.com [74.125.136.26] X=TLS1.2:RSA_ARCFOUR_SHA1:128 DN="C=US,ST=California,L=Mountain View,O=Google Inc,CN=mx.google.com" C="250 2.0.0 OK 1426855589 gg9si3139613wib.13 - gsmtp"
2015-03-20 15:45:57 1YYwJI-00041B-SP Completed

Проверим что попало в /home/spam/mail.log

mail() on [/var/www/seolo/data/www/seolo.ru/test.php:2]: To: poiuty@lepus.su -- Headers:

Чтобы остановить рассылку, мы можем заблокировать функцию php mail()

disable_functions = "mail"

Но это не поможет если отправляют через сокет. Обычно в настройках почтового сервера оставляют открытый relay для 127.0.0.1

<?
$smtp = fsockopen('127.0.0.1', 25);
$result = array();
stream_set_timeout($smtp, 1);
$result[0] = fgets($smtp);
$result[0] = substr($result[0], 0, 3); // 220
 
fwrite($smtp, "HELO localhost\n");
$result[1] = fgets($smtp);
 
fwrite($smtp, "MAIL FROM:noreply@seolo.ru\r\n");
$result[2] = fgets($smtp);
 
fwrite($smtp, "RCPT TO:poiuty@lepus.su\r\n");
$result[3] = fgets($smtp);
 
fwrite($smtp, "DATA\r\n");
$result[4] = fgets($smtp);
 
fwrite($smtp, "From: Test User <noreply@seolo.ru> 
Subject: SPAM!\r\n
How are you?\r\n
.\r\n");
$result[5] = fgets($smtp);
 
fwrite($smtp, "QUIT\r\n");
$result[6] = fgets($smtp);

Закрыть relay можно так, редактируем файл /etc/exim4/exim4.conf.template

#hostlist relay_from_hosts = 127.0.0.1
hostlist relay_from_hosts =

Не всегда можно просто взять и закрыть relay. Но выход есть, например запретить коннекты для всех пользователей кроме некоторых.

iptables -N ALLOWED
iptables -A OUTPUT -j ALLOWED
iptables -A OUTPUT -s 127.0.0.1 -p tcp --dport 25 -j DROP

Пробуем отправить. Смотрим статистику iptables => видим, что уходит в DROP.

# iptables -L -v -n
Chain OUTPUT (policy ACCEPT 91626 packets, 115M bytes)
 pkts bytes target     prot opt in     out     source               destination
1456M 1976G ISPMGR     all  --  *      *       0.0.0.0/0            0.0.0.0/0
 803K 1011M ALLOWED    all  --  *      *       0.0.0.0/0            0.0.0.0/0
    6   360 DROP       tcp  --  *      *       127.0.0.1            0.0.0.0/0            tcp dpt:25

Теперь разрешим пользователю отправлять письма.

iptables -A ALLOWED -s 127.0.0.1 -p tcp -m tcp --dport 25 -m owner --uid-owner seolo -j ACCEPT

Снова смотрим статистику => письмо ушло.

Chain ALLOWED (1 references)
 pkts bytes target     prot opt in     out     source               destination
   10   679 ACCEPT     tcp  --  *      *       127.0.0.1            0.0.0.0/0            tcp dpt:25 owner UID match 532

Кстати, это работает только для TCP соединений. Если пользователь отправит через php mail() -> то блокировка через iptables не сработает.