Tag Archives: 스팸어쎄신

Spam Assassin + ClamAV 바이러스 필터 연동하기

기존에 SpamAssassin과 ClamAV를 연동하는 방법은 많이 있어왔지만 사실상 연동이라기 보다는 Sendmail에서 둘다 따로 호출하거나 Procmail 스크립트를 사용하는 방법등이었습니다.

다음은 ClamAV를 아예 SpamAssassin으로 합쳐 바이러스 발견시 SpamAssassin의 점수계산에 포함되도록 하는 방법입니다.

무선 ClamAV를 설치하고 시작해 보도록 하겠습니다. [이곳]에서 ClamAV 소스를 다운받아 설치합니다. 패키지 모음은 [이곳]에 있습니다.

ClamAV를 설치하기 전에 우선 사용자 계정을 추가합니다.
[code]# groupadd clamav
# useradd -g clamav -s /bin/false -c “Clam AntiVirus” -d /var/lib/clamav clamav[/code]
다운받은 소스를 설치합니다.
[code]# ./configure –sysconfdir=/etc/clamav
# make
# make install[/code]
추가로 필요한 디렉토리를 생성합니다.
[code]# mkdir /var/lib/clamav
# mkdir /var/log/clamav
# mkdir /var/run/clamav
# chown clamav.clamav /var/lib/clamav
# chown clamav.clamav /var/log/clamav
# chown clamav.clamav /var/run/clamav[/code]
/etc/clamav/clamd.conf 파일에 다음의 내용을 수정합니다.
[code]LogFile /var/log/clamav/clamd.log
LogFileMaxSize 2M
LogTime yes
PidFile /var/run/clamav/clamd.pid
TemporaryDirectory /tmp
LocalSocket /var/lib/clamav/clamd.sock
FixStaleSocket yes
ScanMail yes[/code]
다음으로는 /etc/clamav/freshclam.conf 파일을 수정합니다.
[code]UpdateLogFile /var/log/clamav/freshclam.log
PidFile /var/run/clamav/freshclam.pid
DatabaseOwner clamav
DNSDatabaseInfo current.cvd.clamav.net
DatabaseMirror db.kr.clamav.net
DatabaseMirror database.clamav.net[/code]
다음의 스크립트 파일을 /etc/rc.d/init.d 안에 추가합니다.


1066105557.xxx이제 스크립트를 실행해 봅시다.
[code]# /etc/rc.d/init.d/freshclam start
# /etc/rc.d/init.d/clamd start[/code]
/etc/cron.daily/freshclam이 생성되었다면 freshclam은 따로 데몬으로 돌리실 필요는 없습니다.
SpamAssassin이 설치된 설정 디렉토리 /etc/mail/spamassassin 안에 다음의 파일을 추가합니다.

clamav.cf
[code]loadplugin ClamAV clamav.pm
full CLAMAV eval:check_clamav()
describe CLAMAV Clam AntiVirus detected a virus
score CLAMAV 10
add_header all Virus _CLAMAVRESULT_[/code]

clamav.pm
[code]package ClamAV;
use strict;


# version 2.0, 2010-01-07
#   – use SA public interface set_tag() and add_header, instead of
#     pushing a header field directly into $conf->{headers_spam}


# our $CLAMD_SOCK = 3310;               # for TCP-based usage
our $CLAMD_SOCK = “/var/run/clamd.basic/clamd.sock”;   # change me


use Mail::SpamAssassin;
use Mail::SpamAssassin::Plugin;
use Mail::SpamAssassin::Logger;
use File::Scan::ClamAV;
our @ISA = qw(Mail::SpamAssassin::Plugin);


sub new {
  my ($class, $mailsa) = @_;
  $class = ref($class) || $class;
  my $self = $class->SUPER::new($mailsa);
  bless($self, $class);
  $self->register_eval_rule(“check_clamav”);
  return $self;
}


sub check_clamav {
  my($self, $pms, $fulltext) = @_;
  dbg(“ClamAV: invoking File::Scan::ClamAV, port/socket: %s”, $CLAMD_SOCK);
  my $clamav = new File::Scan::ClamAV(port => $CLAMD_SOCK);
  my($code, $virus) = $clamav->streamscan(${$fulltext});
  my $isspam = 0;
  my $header = “”;
  if (!$code) {
    my $errstr = $clamav->errstr();
    $header = “Error ($errstr)”;
  } elsif ($code eq ‘OK’) {
    $header = “No”;
  } elsif ($code eq ‘FOUND’) {
    $header = “Yes ($virus)”;
    $isspam = 1;
    # include the virus name in SpamAssassin’s report
    $pms->test_log($virus);
  } else {
    $header = “Error (Unknown return code from ClamAV: $code)”;
  }
  dbg(“ClamAV: result – $header”);
  $pms->set_tag(‘CLAMAVRESULT’, $header);
  # add a metadatum so that rules can match against the result too
  $pms->{msg}->put_metadata(‘X-Spam-Virus’,$header);
  return $isspam;
}


1;[/code]
이후에 File::Scan::ClamAV 를 설치하여야 합니다.

[code]# cpan File::Scan::ClamAV[/code]
이제 SpamAssassin에서 메일을 처리할때 ClamAV를 호출하여 바이러스 검사까지 하게 되며 바이러스가 존재할시 스코어 10점을 부여하고 X-Spam-Virus: Yes 헤더를 붙이게 됩니다.

세세한 점수를 확인하고 싶다면 [이곳]에서 확인해 보시면 됩니다.

SpamAssassin을 데몬형태로 사용하고 계신다면 재시작 해주시면 됩니다. 그외의 경우에는 바로 적용됩니다.

참고 : http://wiki.apache.org/spamassassin/ClamAVPlugin

한국에 맞는 스팸어쎄신 설정하여 스팸 95% 줄여보기

사용자 삽입 이미지개인적으로 운영하는 투명아이의 서버는 오랫동안 스팸메일과의 전쟁을 벌여오고 있었다.  용하다는 온갖 필터를 다 사용해 보았지만 특별히 효과를 본 것이 없었다.

그러던중 단순하면서도 매우 괜찮은 조합을 발견해 내었다. 그 조합을 가지고 3달을 테스트 해보고 6달에 걸쳐 스팸어쎄신의 베이시안 필터를 학습 시켰다.

결국 나의 노력을 하늘도 알아준 것일까? 거짓말같이 스팸이 줄기 시작했다. 투명아이 서버의 경우 하루평균 2000통 이상의 스팸메일이 도착하는데 현재 이 모든 필터들을 통과하는 스팸이 서버 내 통틀어 5개 이내로 줄었다.

이 5개도 스팸으로 분류되어 도착한다. 그 조합은 다음과 같다.

Sendmail MTA → 3 DNSBL → SPF-Milter → Clamav-Milter → SpamAssassin → Procmailrc


오늘은 스팸어쎄신에 대해서만 이야기를 해보자. 보통의 서버에서 스팸어쎄신을 별다른 옵션없이 디폴트로 설정해 놓고 베이시안 필터도 사용하지 않고 있을것이다. 그런 절반의 스팸어쎄신을 사용하며 만족하고 있었던적이 있었다.

확실히 스팸 어쎄신은 학습전과 학습 후의 작동 모습이 확연하게 차이나는 녀석이다. 다만 Perl기반이라 그런지 처리에 엄청난 무리가 온다. 확실히 베이시안 필터로서의 스팸어쎄신은 대규모 메일 서버에서는 사용하기 힘들듯 하다. Bogofilter등을 사용하는것을 추천해 본다.

우선 스팸어쎄신을 설치해보자. cpan을 이용하면 옵션 모듈까지 손쉽게 설치할 수 있다.

[code]# cpan

cpan> install Digest::SHA1 HTML::Parser DB_File Net::DNS Mail::SPF::Query IP::Country Mail::Audit::Razor Net::Ident IO::Socket::INET6 IO::Socket::SSL Time::HiRes DBI LWP::UserAgent HTTP::Date Archive::Tar IO::Zlib Encode::Detect Net::SSLeay Mail::DKIM Mail::DomainKeys Compress::Zlib
cpan> install Mail::SpamAssassin[/code]

위와 같은 방법만으로도 스팸어쎄신을 손쉽게 설치할 수 있다. 옵션 모듈중에 설치 안되는 것들에 대해서는 너무 목숨걸지 말자. 다음같은 모듈은 굳이 필요없다.

Encode::Detect, IO::Socket::INET6, IO::Socket::SSL, Net::SSLeay, Razor2

이제 스팸어쎄신의 로컬 설정을 한다. 디폴트로 /etc/mail/spamassassin/local.cf 파일이다.

[code]# This is the right place to customize your installation of SpamAssassin.
#
# See ‘perldoc Mail::SpamAssassin::Conf’ for details of what can be
# tweaked.
#
# Only a small subset of options are listed below
#
###########################################################################

#   Save spam messages as a message/rfc822 MIME attachment instead of
#   modifying the original message (0: off, 2: use text/plain instead)
#
report_safe 0

#   Set the threshold at which a message is considered spam (default: 5.0)
#
required_score 5.0

#   Use Bayesian classifier (default: 1)
#
use_bayes 1

#   Bayesian classifier auto-learning (default: 1)
#
bayes_auto_learn    1
bayes_path          /etc/mail/spamassassin/bayes/bayes
bayes_file_mode     0666

# Enable or disable network checks
skip_rbl_checks         0
use_razor2              0
use_dcc                 0
use_pyzor               0

# Mail using languages used in these country codes will not be marked
# as being possibly spam in a foreign language.
ok_languages            ko

# Mail using locales used in these country codes will not be marked
# as being possibly spam in a foreign language.
ok_locales              ko

# Add your own customised scores for some tests below.  The default scores are
# read from the installed spamassassin rules files, but you can override them
# here.  To see the list of tests and their default scores, go to
# http://spamassassin.apache.org/tests.html .
score SPF_PASS -2.0
score SPF_HELO_PASS -2.0
score SPF_NEUTRAL -1.0
score SPF_HELO_NEUTRAL -1.0

# For Daum Communications
score WEIRD_PORT 0.0

# For Korean Fonts
score HTML_FONT_FACE_BAD 0.0

# Whitelist important senders
whitelist_from          *@theeye.pe.kr[/code]


report_safe : 스팸으로 판단될 경우 원본글을 감출지 여부이다. 메일을 읽는 순간 당할수 있는 그 어떤 공격이 두렵다면 1로 해야 한다. 하지만 0으로 설정한다.


required_score : 몇점 이상을 스팸메일로 의심할것인지에 대한 설정이다. 이것은 서버관리자의 주관적인 부분이다. 그냥 5로 해도 무관하다고 본다.


use_bayes : 학습된 Bayesian Classifier를 사용할것인지에 대한 여부이다. 당연히 1로 한다.


bayes_auto_learn : 자동학습에 대한 설정이다. 정말로 확실한 스팸의 경우 분석하여 나누어진 토큰을 지속적으로 학습 시킨다. 물론 자동으로.


bayes_path : 학습된 토큰 파일을 저장할 위치이다. 기본적으로 사용자 별로 개별 저장되나 이런식으로 하여 중앙 관리가 가능하다. 저 값은 접두어다. 저 뒤로 _toks와 _seen이 붙는 파일 두개가 생긴다.


bayes_file_mode : 파일의 권한이다. 666정도면 되겠다.


skip_rbl_checks : RBL체크값을 점수에 활용한다. 나름 맹활약을 하게 된다.


use_razor2 : Vipul’s Razor라는 곳에서 운영하는 블랙리스트 공유 시스템을 활용할지 여부이다. 난 사용안했다. 설치할것이 별도로 존재한다.


use_dcc : Distributed Checksum Clearinghouse의 약자이다. 실제 홈페이지에서는 스팸을 줄이는데 특출난 효과가 있다고 설명하고 있다. 필요하다 판단되면 사용하자


use_pyzor : Razor2와 비슷한 역할을 하는것 같다. 자세한건 사용해 보지 않아서 모르겠다. 홈페이지는 여기


ok_languages : 중요하게 사용되는 언어를 설정해 주면 된다. 한국의 경우 ko를 적어주면 된다. 영어권과 메일을 주고 받을일이 많다면 en도 추가해 주자.


ok_locales : 위와 같은 역할을 한다.


score : 별도로 특정 룰에 대한 점수를 강제로 지정할 수 있다.


whitelist_from : 믿을 수 있는 메일주소를 지정해주자. 매우 중요한 거래처의 메일이나 같은 서버의 메일은 굳이 점수를 매길필요가 없다.


다음의 SPF설정은 SPF의 신뢰도를 믿고 점수를 -해주겠다는 뜻을 가지게 된다.
[code]score SPF_PASS -2.0
score SPF_HELO_PASS -2.0
score SPF_NEUTRAL -1.0
score SPF_HELO_NEUTRAL -1.0[/code]

다음의 한메일의 경우 메일을 보내는데 기본 포트가 아닌 특이한 포트를 사용하는것 같다. 다음메일이 무조건 스팸메일화 되는것을 막을려면 설정해 주자.
[code]score WEIRD_PORT 0.0[/code]

다음의 설정은 한글 폰트 설정때문에 스팸메일의 의심을 받게 되는것을 막기 위한 설정이다. 보통은 font-face가 영문으로 설정되기 마련이지만 국내의 메일 시스템은 “font-face:돋음”과 같이 한글로 표기하는 경우가 많다. 무시하도록 하자.
[code]score HTML_FONT_FACE_BAD 0.0[/code]

위와 같이 설정을 하였으면 procmailrc스크립트에 스팸어쎄신을 등록하자. 보통은 spamd로 데몬으로 띄우기 마련이지만 이렇게 하는 편이 더 간단하다. procmailrc스크립트의 제일 상단에 추가해 주자.

[code]# Pipe the mail through spamassassin (replace ‘spamassassin’ with ‘spamc’
# if you use the spamc/spamd combination)
#
# The condition line ensures that only messages smaller than 250 kB
# (250 * 1024 = 256000 bytes) are processed by SpamAssassin. Most spam
# isn’t bigger than a few k and working with big messages can bring
# SpamAssassin to its knees.
#
# The lock file ensures that only 1 spamassassin invocation happens
# at 1 time, to keep the load down.

:0fw: spamassassin.lock
* < 256000
| spamassassin

# Mails with a score of 15 or higher are almost certainly spam (with 0.05%
# false positives according to rules/STATISTICS.txt). Let’s put them in a
# different mbox. (This one is optional.)
:0:
* ^X-Spam-Level: \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
/var/spool/mail/spam[/code]

여기서 주목할 점은 X-Spam-Level 체크 구문인데 *한개가 1점을 뜻한다. 위의 경우 15개이므로 15점 이상이면 spam으로 포워딩 해버리겠다는 뜻을 가지게 된다. 주관적인 판단아래 조정하길 바란다.

여기서 *의 수는 이정도 점수면 스팸이 확실하다라는 확신이 서는 기준을 점수로 하면 되겠다.

그리고 스팸메일을 spam 파일에 1달정도 모으자. 그리고 학습을 시켜보도록 하자.

[code]# sa-learn –spam –mbox /var/spool/mail/spam
# sa-learn –ham –mbox /var/spool/mail/ham[/code]

위와 같은 방법으로 스팸메일을 모은 파일을 –spam옵션을 주고 분석하여 학습 시키면 된다. 반대로 스팸메일이 아닐경우에는 –ham으로 등록하면 된다. 정확히 스팸메일만 분류되어있다면 ham은 학습을 시키지 않아도 정확성이 높다.

위에서 설정한 대로라면 학습한 데이터는 /etc/mail/spamassassin/bayes/ 안에 존재하게 된다.

현재 내가 수집하여 만든 학습 데이터를 공개하겠다. 6개월에 걸쳐 스팸메일을 모았으며 15,000개의 스팸메일이 사용되었으며 8만개 이상의 단어가 누적 학습되었다.

1155977043.tgz


필요하다면 1주일마다 spam학습을 시키는 스크립트를 만들어 cron에 등록하여 작동시킬수도 있을것이다.
하지만 학습시마다 데이터를 백업하자. 학습이 과하면 미치기 시작한다. 일반 메일까지 분류하게 될지도 모른다.
적당한 시점을 찾아보자.