Борьба со спамом в картинках при помощи OCR

Добавил Support
Для ITDoc

1 звезда2 звезд3 звезд4 звезд5 звезд (2 голосов, средний: 5.00 из 5)
Загрузка ... Загрузка ...
1,250 Просмотров!

Издано: апреля 10, 2009

Рассмотрев на досуге статистику своего сервера я осознал, что основная
масса обычного спама осталась за бортом, но письма, содержащие рекламу в
картинках проходят.

Выбрав немного свободного времени, решил заняться  этим вопросом плотнее.

Наперед скажу, что на загруженных серверах данное решение необходимо
продумать более детально, т.к. процесс распознавания картинок - не
очень быстрый.

Ориентировочная моя суточная нагрузка выглядит так:

940   received
1476   delivered
1398   rejected (48%) - без image spam

Источники размышлений и информации

1. Большое спасибо Oles Hnatkevych, don_oles at able.com.ua за
http://able.com.ua/~gnut/fighting-spam.html
Основная конфигурация построена именно по такой схеме за исключением TLS/SSL/SASL.

2. К этому всему подключен Spamassassin
http://spamassassin.apache.org/

3. С плагином FuzzyOCR
http://fuzzyocr.own-hero.net/

4. И поправкой к нему
http://fuzzyocr.own-hero.net/ticket/201

5. SAMBA в ActiveDirectory
http://turbogaz.kharkov-ua.com/unix/www/squid.php

6. Microsoft Office Document Imaging
http://msdn2.microsoft.com/en-us/library/aa167607(office.11).aspx

Как это работает:

# Общая схема построена на FreeBSD с postfix+etc хорошо описана в able.com.ua/~gnut/fighting-spam.html , единственно к ней добавляется Spamassassin, задача которого - пометить письма с картинками непотребного содержания.
# Подключается spamassassin к postfix обычным smtp proxy (демон spampd) как и clamav. Единственно у меня получилось его подключить только перед clamav и dkfilter, а хотелось последним.
# Spamassassin использует плагин FuzzyOCR (который в свою очередь использует gocr или ocrad) в качестве распознавателя. Т.к. FuzzyOCR (с gocr) нацелен на англоязычное население, да и качество распознавания посредственное, пришлось думать над дальнейшей обработкой. FuzzyOCR готовит .pnm файл и передает его в gocr, который отдает обратно текст. Вот вместо gocr мы и будем цеплять Microsoft Office Document Imaging (MODI) Думал, про ABBY http://www.abbyy.ru/sdk/?param=60343 , но стоимость Developer лицензии моментально уничтожило всякое желание использовать FineReader.
# Perl Скрипт (вместо gocr) полученный .pnm файл конвертирует в tif и кладет на Win (через самбу)
# Заходит telnet’ом на Win и запускает там VisualBasic приложение, которое через API MODI распознает tif , а результат складывает в .txt файл.
# Perl Скрипт отдает содержимое полученного .txt файла обратно в FuzzyOCR.
Раскроем ключевые моменты

SAMBA

На рабочей станции делаем ресурс (для отладки можнос  правами Все:Change + на NTFS
тоже самое), дальше - для пользователя, прописанного в /etc/nsmb.conf

В файле /etc/nsmb.conf прописываем

[WKSTNAME]
addr=10.0.0.10
[WKSTNAME:USERNAME]
password=mypassword

Содаем /mnt/incoming с правами для демона spamd (у меня uid:spamd)

Подключаем

mount_smbfs // USERNAME@WKSTNAME/INCOMING /mnt/incoming/

Для автомаунта можно прописать в /etc/fstab

//USERNAME@WKSTNAME/INCOMING /mnt/incoming/   smbfs   rw,auto,noexec  0       0

FuzzyOCR

1. По умолчанию не понимает цифр и большие (или маленькие) буквы в
FuzzyOCR.words и соответственно не работает нормально.
Для этого воспользуемся предложением fuzzyocr.own-hero.net/ticket/201 и закомментируем строки
в FuzzyOcr.pm под номерами 1137 и 1144.

2. В конфигурационном файле FuzzyOCR.cf меняем focr_bin_gocr на наш скрипт:

focr_bin_gocr /usr/local/scripts/modi

Проверяем
[cc lang="bash" tab_size="2" lines="-1"]
focr_scansets $gocr -i $pfile

Остальные параметры - на свое усмотрение.

Perl скрипт: /usr/local/scripts/modi

[cc lang="bash" tab_size="2" lines="-1"]
#!/usr/bin/perl
use strict;
use warnings;

use Net::Telnet ();
use Getopt::Std;
use File::Basename;
my $hostname="WKSTNAME"; # имя Win рабочей станции
my $username="domain\\username"; # Имя пользователя Win
my $password="userpassword";
my $RMT_dir="/mnt/incoming/";
my $drive="Z:"; #Имя локального Win диска с tif файлами

#Имя локальной папки Win с tif файлами
my $Files="Z:\\!SPAM_imaged\\PRJ\\console\\Console OCR\\Console OCR\\INCOMING\\";
my $OCR_cmd="
\"Z:\\!SPAM_imaged\\PRJ\\console\\Console OCR\\Console  OCR\\bin\\Release\\Console OCR.exe\""; # Путь к VB программе использующей MODI
my $pnmimage="
";
my $tifimage="
";
my @lines="
";
my $textfile="
";
my $secs=120;
my $systring="
";
our($opt_i);
getopt('i:');
if ($opt_i eq "
") { exit };
$pnmimage=$opt_i;     # берем имя pnm файла
$tifimage=basename($pnmimage) . "
.tif";
# Преобразуем pnm в tif
$systring="
pnmtotiff -packbits ".$opt_i." > ".$RMT_dir.$tifimage." 2>/dev/null";
system($systring);    # Для меня - загадка,
system($systring);    # Необходимо выполнить pnmtotiff 2 раза для того, что бы MODI понял tiff, возможно из-за Кеша самбы или Win
my $image=$tifimage;

# Коннектимся телнетом на винду и логинимя
my $t =  new Net::Telnet ();
$t ->open(Host => $hostname, Timeout => $secs);
$t->waitfor('/login:/');
$t->print($username);
$t->waitfor('/password:/');
$t->print($password);
$t->waitfor ('/system32>/');

# Переходим в папку с файлами
$t->print($drive);
$t->waitfor("
/$drive/");
$t->print("
cd $Files");
$t->waitfor("
/>/");
my $cmdstring=$OCR_cmd."
".$image;

# Запускаем VB программу, параметр - имя tif файла
$t->print("
$OCR_cmd $image");
$t->waitfor(Match      => "
/OCR of $tifimage COMPLETE in seconds/",Timeout => $secs);

# Дождавшись завершения - выводим содержимое txt файла в STDOUT
$textfile=$RMT_dir.$tifimage."
.txt";
system("
cat $textfile");

# Удаляем созданные файлы
system ("
rm $textfile");
system ("
rm /mnt/incoming/$tifimage");

Программа на VB (Console OCR.exe)

Воспользовался MS Visual Basic 2005 Express Edition для создания “Console application”

Необходимо добавить reference на COM библиотеку MODI
(%ProgramFiles%\Common Files\Microsoft Shared\MODI\11.0\MDIVWCTL.DLL)

Подходит от MS Office 2003 и, возможно, дальше (В Office XP у MODI
отсутствовало API). Подробное описание в
msdn2.microsoft.com/en-us/library/aa167607(office.11).aspx.

Текст:

Module Module1
Dim MiDOC As MODI.Document = Nothing
Dim MiLayout As MODI.Layout = Nothing
Dim strLayoutInfo As String = ""
Dim Myerr As Integer = 0
Dim CMD_Args As String = ""
Dim TIFF_File As String = ""
Dim INCOMING As String = "Z:\!SPAM_imaged\PRJ\console\Console OCR\Console OCR\INCOMING\" 'Must end with \
Dim OCR_File As String = "
"
'CodePage получаемого txt файл
Dim OUT_File_ENC As String = "
windows-1251" ' koi8-r koi8-u windows-1251

Sub Main()

If (My.Application.CommandLineArgs.Count > 0) Then
TIFF_File = My.Application.CommandLineArgs(0)

Console.Write(My.Application.CommandLineArgs(0))
OCR_File = INCOMING + TIFF_File
Console.Write(OCR_File)
If (My.Computer.FileSystem.FileExists(OCR_File) = True) Then
MiDOC = New MODI.Document
' Load an existing TIFF file.
MiDOC.Create(OCR_File)
' Perform OCR на русском.
MiDOC.OCR(MODI.MiLANGUAGES.miLANG_RUSSIAN)
MiLayout = MiDOC.Images(0).Layout
Console.Write(MiLayout.Text) ' Можно опустить
TXT_File = OCR_File + "
.txt"
My.Computer.FileSystem.WriteAllText(TXT_File, MiLayout.Text, False, System.Text.Encoding.GetEncoding(OUT_File_ENC))
' Perform OCR на английском, т.к. попадаются слова типа VIAGRA, CIALIS и т.д.
MiDOC.OCR(MODI.MiLANGUAGES.miLANG_ENGLISH, True, True)
MiLayout = MiDOC.Images(0).Layout
My.Computer.FileSystem.WriteAllText(TXT_File, MiLayout.Text, True, System.Text.Encoding.GetEncoding(OUT_File_ENC))
Console.Write(MiLayout.Text) ' Можно опустить
MiLayout = Nothing
MiDOC = Nothing
End If
End If

Dim errorWriter As IO.TextWriter = Console.Error
errorWriter.WriteLine("
OCR of " + TIFF_File + " COMPLETE in seconds.")

End Sub

End Module

Заключение

Задача выполнена подручными средствами и без особого контроля над
происходящим в Perlе и VB, но даже если что-то в них не срабатывает -
почта проходит, но не помечается как спам.

В дальнейшем хочется перевести с телнета - на сокеты, вполне возможно
произвести распределение нагрузки по рабочим станциям - пусть каждый
распознает свой спам :).

Популярность: 18% [!]

Tagged with: , , , , , , , , , , , , , , ,


Спонсор



 WPSN comments




Да человек я, человек! =)

ITDoc самый Последний