Linux cкрипт для обучения spamassassin

Основные возможности

Внимание, данные скрипты используются для упрощения процесса конвертации писем утилитой mapitool и обучения spamassassin.

  • Помогает конвертировать письма из формата msg в eml;
  • Помогает обучать spamassassin.

Описание cкриптов для обучения spamassassin

Зависимости

Для работы скриптов, должны быть установлены:

Для обучения spamassassin используется группа скриптов в каталоге salearnsh

Структура каталогов:

  • ham
  • hamloaded
  • hammsg
  • hammsgloaded
  • spam
  • spamloaded
  • spammsg
  • spammsgloaded

Список скриптов:

  • emltoeml.sh
  • msgtoeml.sh
  • reneml.sh
  • renmsg.sh
  • salearnham.sh
  • salearnspam.sh

здесь:
ren*.sh — скрипт для переименования файлов (заменяет символы «!», «$», » «, «+», «%», «(«, «)» и «,» на _ );
emltoeml.sh — обрабатывает письмо формата eml (удаляет некоторые блоки);
msgtoeml.sh — конвертирует письмо из формата msg в eml;
salearn*.sh — обучает spamassassin.

Два варианта обучения

  1. исходные письма в формате msg (из Outlook):
    • спам положить в spammsg, неспам — в hammsg;
    • выполнить пункты Обучение 1a, 2a (для спама c ключом spammsg, для неспама с ключом hammsg) и 3;
  2. исходные письма в формате eml (тело письма — обычный текст):
    • спам положить в spam, неспам — в ham;
    • выполнить пункты Обучение 1b, 2b (для спама c ключом spam, для неспама с ключом ham) и 3.

Обучение

  1. Переименовать файлы:
    • Запустить renmsg.sh с ключом spammsg или hammsg;
    • Запустить reneml.sh с ключом spam или ham;
  2. Конвертировать/обработать файлы:
    • Запустить msgtoeml.sh с ключом spammsg или hammsg (только для писем в формате msg);
    • Запустить emltoeml.sh с ключом spam или ham (только для писем в формате eml);
  3. Запустить salearnspam.sh или salearnham.sh без ключей (запуск производится root`ом от имени vscan).

После обучения, письма перемещаются в каталоги {spam|ham|spammsg|hammsg}loaded соответственно.

Известные баги

  1. После конвертации, блок «Content-Type: text/plain» перекодируется в UTF-8, а «Content-Type: text/html» остается в прежней кодировке.
  2. После конвертации, отсутствует упоминание о кодировке блоков, «charset» — не указан.
  3. Следствием этого является некорректное распознавание русского языка модулем TextCat.

Вероятно в стабильной версии ruby-msg будет реализована возможность сохранять кодировку письма, а пока оптимальным вариантом вижу использование вместо Outlook другого почтового клиента с поддержкой IMAP4 (например Thunderbird, Kmail, Evolution и т.д.) и возможностью сохранения писем прямо в формат eml. Обучать spamassassin напрямую, а скрипт msgtoeml.sh использовать только для получения общей информации о письме.

Пример комплекта скриптов salearnsh

Скачать архив можно по ссылке salearnsh-1.1.tgz

Текст файл emltoeml.sh:

#!/bin/sh
if [ "$1" = "" ]; then
    echo "# Directory not set!"
    echo "# Use: $0 Directory(spam|ham)"
exit
fi
pattern="Received: {1,2}from (mail\.example\.ru .{2}10\.1\.1\.1.{2} by mail\.example\.local|localhost .{1}localhost .{1}127\.0\.0\.1.{2} by mail\.example\.ru)"
pattern1="X-(Virus-Scanned: amavisd-new at example\.ru|Spam-(Flag|Score|Level|Status):)"
patternx="\*{3}SPAM\*{3}"
 
if [ "$1" = "spam" ]; then
    if [ ! -d ./$1 ]; then
        echo "# Directory $1 not exist!"
	exit
    fi
    files=`ls -1 ./$1/*.eml | sed -e 's/\.eml$//' -e 's/^\.\/'$1'\///'`
    for i in $files
    do
	echo "# Converting mail ./$1/$i.eml to ./spam/$i.eml"
	sed -r -e "/^$pattern/ d" -e "/^$pattern1/ d" -e "s/$patternx//" ./spam/$i.eml > ./spam/$i.eml.tmp
	rm -f ./spam/$i.eml
	rename ".eml.tmp" ".eml" ./spam/$i.eml.tmp
    done
elif [ "$1" = "ham" ]; then
    if [ ! -d ./$1 ]; then
	echo "# Directory $1 not exist!"
        exit
    fi
    files=`ls -1 ./$1/*.eml | sed -e 's/\.eml$//' -e 's/^\.\/'$1'\///'`
    for i in $files
    do
	echo "# Converting mail ./$1/$i.eml to ./ham/$i.eml"
	sed -r -e "/^$pattern/ d" -e "/^$pattern1/ d" -e "s/$patternx//" ./ham/$i.eml > ./ham/$i.eml.tmp
	rm -f ./ham/$i.eml
	rename ".eml.tmp" ".eml" ./ham/$i.eml.tmp
    done
else
    echo "# Directory incorrect! Use spam or ham"
fi

Текст файл msgtoeml.sh:

#!/bin/sh
if [ "$1" = "" ]; then
    echo "# Directory not set!"
    echo "# Use: $0 Directory(spammsg|hammsg)"
exit
fi
pattern="Received: {1,2}from (mail\.example\.ru .{2}10\.1\.1\.1.{2} by mail\.example\.local|localhost .{1}localhost .{1}127\.0\.0\.1.{2} by mail\.example\.ru)"
pattern1="X-(Virus-Scanned: amavisd-new at example\.ru|Spam-(Flag|Score|Level|Status):)"
patternx="\*{3}SPAM\*{3}"
 
if [ "$1" = "spammsg" ]; then
    if [ ! -d ./$1 ]; then
        echo "# Directory $1 not exist!"
	exit
    fi
    files=`ls -1 ./$1/*.msg | sed -e 's/\.msg$//' -e 's/^\.\/'$1'\///'`
    for i in $files
    do
	echo "# Converting mail ./$1/$i.msg to ./spam/$i.eml"
        mapitool -siv ./$1/$i.msg > ./spam/$i.eml.tmp
	sed -r -e "/^$pattern/ d" -e "/^$pattern1/ d" -e "s/$patternx//" -e "s/\x0d$//" ./spam/$i.eml.tmp > ./spam/$i.eml
	rm -f ./spam/$i.eml.tmp
    done
elif [ "$1" = "hammsg" ]; then
    if [ ! -d ./$1 ]; then
	echo "# Directory $1 not exist!"
        exit
    fi
    files=`ls -1 ./$1/*.msg | sed -e 's/\.msg$//' -e 's/^\.\/'$1'\///'`
    for i in $files
    do
	echo "# Converting mail ./$1/$i.msg to ./ham/$i.eml"
        mapitool -siv ./$1/$i.msg > ./ham/$i.eml.tmp
	sed -r -e "/^$pattern/ d" -e "/^$pattern1/ d" -e "s/$patternx//" -e "s/\x0d$//" ./ham/$i.eml.tmp > ./ham/$i.eml
	rm -f ./ham/$i.eml.tmp
    done
else
    echo "# Directory incorrect! Use spammsg or hammsg"
fi

здесь используются дополнительные pattern`ы для удаления и замены некоторых заголовков письма, а также замена окончания строки CR/LF на LF: sed -e «s/\x0d$//».

Текст файл renmsg.sh:

#!/bin/sh
if [ "$1" = "" ]; then
    echo "# Directory not set!"
    echo "# Use: $0 Directory(spammsg|hammsg)"
exit
fi
echo "Starting find!"
check=`find ./$1 -regex '.* .*\.msg$'`
while [ "$check" != "" ];
do
    rename " " _ ./$1/*.msg
    check=`find ./$1 -regex '.* .*\.msg$'`
    echo "#"
done
for rnm in \! "\$" "%" "(" ")" ",";
do
    check2=`find ./$1 -regex ".*$rnm.*\.msg$"`
    while [ "$check2" != "" ];
    do
	rename $rnm _ ./$1/*.msg
        check2=`find ./$1 -regex ".*$rnm.*\.msg$"`
        echo "#2"
    done
done
check3=`find ./$1 -regex '.*\+.*\.msg$'`
while [ "$check3" != "" ];
do
    rename \+ _ ./$1/*.msg
    check3=`find ./$1 -regex '.*\+.*\.msg$'`
    echo "#3"
done
echo \n "End!"

в файле reneml.sh заменено msg на eml и spammsg|hammsg на spam|ham.

Текст файл salearnspam.sh:

#!/bin/sh
echo "Запуск от имени vscan:"
sudo -u vscan sa-learn --spam ./spam
mv ./spam/* ./spamloaded/
mv ./spammsg/* ./spammsgloaded/

в файле salearnham.sh заменено все начинающееся с spam на ham соответственно.

Здесь запуск обучения проводится от имени vscan для того чтобы spamassassin, вызываемый фильтром amavisd-new, смог работать с базой в каталоге {vscan_home_dir}/.spamassassin/. Владелец базы: vscan:vscan, права доступа: 600.

Обсуждение закрыто.