강좌
클라우드/리눅스에 관한 강좌입니다.
해킹&보안 분류

Spamassassin을 이용한 스팸메일 필터링 3부

작성자 정보

  • 관리자 작성
  • 작성일

컨텐츠 정보

본문

Spamassassin을 이용한 스팸메일 필터링 3

 

3.6.5 스팸어세신 룰 설정 방법

 

실제로 스팸어세신을 운영하여 메일을 수신하다보면 스팸으로 잘 걸러지고는 있지만 스팸의 기법도 워낙 복잡하고 다양하기 때문에 무언가 부족함을 느끼게 된다.

 

따라서 스팸어세신을 설치하였을 때 기본적으로 설치되는 룰 외에 추가적으로 다른 룰을 사용 할 수 있는데, 이에 대해서는 메일링리스트를 참고하거나 스팸어세신 홈페이지에서 많은 룰 파일을 제공하고 있으므로, 각각의 룰 파일을 다운로드 받아 /etc/mail/spamassassin/ 디렉토리에 저장해도 되고, 기존의 파일에 추가해도 된다.

 

이는 앞에서도 언급하였지만 확장자가 .cf이기만 하면 모두 설정 파일로 인식하기 때문이다.

물론 각 유저별로 설정하려면 유저의 user_prefs 파일에 지정하면 될 것이다.

 

그러나 기존의 룰 외에 각자의 환경에 따라 각 룰별로 다른 점수를 주는 것은 물론이고, 특정한 규칙을 가지고 있는 메일에 대해서는 별도로 룰을 직접 생성할 필요가 있을 때가 있다.

 

이를테면, 메일 메시지에 하이퍼링크로 "click here"로 되어 있는 메일의 경우 룰의 이름이 “HTML_LINK_CLICK_HERE”이고 점수(score)0.01로 매우 낮은데, 이 수치를 높이고자 한다면 간단히 설정 파일에

"score HTML_LINK_CLICK_HERE 3.5"와 같이 지정해 주면 된다.

 

반대로 수치가 너무 높다면 수치를 낮추거나 아예 -10과 같이 낮은 점수를 부여할 수도 있다.

 

이는 스팸어세신을 구동 후 일정정도 전송되는 메일의 헤더를 분석하여 각각의 환경에 맞게 적당히 설정하여 사용하면 될 것이다.

 

룰에는 몇 가지 규칙이 있는데, 예를 들어서 간단히 살펴보자.

header L_s_casino Subject =~ /c[a\@]sin[o0]/i

score L_s_casino 0.3

describe L_s_casino Subject mentions a casino

 

룰은 위와 같이 3가지로 이루어져 있는데, 순서대로

 

타입과 정규식 -- 룰을 수행하는 코드

점수(score) -- 룰에 매칭 되었을 때 부여되는 스팸 점수

설명 -- 룰의 의미 등 간략한 설명으로 이루어져 있다.

 

 

위는 L_s_casino라는 이름의 룰인데, 메일의 헤더를 보아 제목(Subject)casino 또는 c@sin0등과 같이 casino와 유사할 경우 0.3점이 부여된다.

 

여기에서 i는 대소문자에 관계없이 처리하겠다는 의미이므로 제목에 casinoCaSiNo 모두 이 룰에 적용될 것이다.

Subject 외에도 헤더에는 To, From, Received, X-Mailer등이 올 수 있는데, 여기에서 주의할 점은 대소문자가 정확히 일치하여야 한다는 것이다.

 

그리고 그 다음에는 “=~”“!~”이 올 수 있는데, 이는 perl의 정규식(regural expression)을 따른다. 그리고 타입에는 header외에 메일의 메시지를 뜻하는 body가 올 수도 있는데, 이를테면 아래의 경우 메일의 메시지에 v.i.@.g.r.a와 같이 보이면 3.0점이 주어지게 된다.

 

body RM_bw_VIAGRA /V.?[i1].?[a\@].?g.?[\@a]?.?r.?[\@a]/i

describe RM_bw_VIAGRA mentions viagra

score RM_bw_VIAGRA 3.0

 

일부 스팸에서는 헤더의 Date 다음에 added by라는 단어가 붙는데, 정상적인 메일에서는 없는 것이다.

아래 룰에서는 이러한 메일에 1.8을 부여하였다.

 

header RM_hd_DateAdded Date =~ /\(added by/

describe RM_hd_DateAdded Original email had no date; added by later system

score RM_hd_DateAdded 1.800

 

그리고 Message-ID로도 구분할 수 있는데, 일반적으로는 Message-ID에 시스템이름이 부여되는데, 스팸 메일에서는 IP 주소 형식인 경우가 가끔 있다.

 

아래 룰은 이러한 메일에 점수를 부여한 예이다.

header RM_hm_midip essage-ID =~ /\@\w{1,3}\.\w{1,3}\.\w{1,3}\.\w{1,3}/

describe RM_hm_midip Message ID seems to be from IP address

score RM_hm_midip 1.209

 

rawbody를 이용하면 body와 달리 html 코드도 인식하는데, 아래의 경우 메시지에 너무 많은 <br> 태그가 있을 경우 1.0이 주어진다.

rawbody MY_MANY_BR /<br><br><br><br><br>/i

describe MY_MANY_BR Tooo many <br>'s!

score MY_MANY_BR 1.000

또한 메일을 받다 보면 메시지가 없는 메일도 자주 받게 되는데, 이러한 메일을 스팸으로 처리하려면 아래와 같은 룰을 사용하면 된다.

 

아래 룰에서 \S, 화이트스페이스가 아닌 다른 어떤 것의 의미이므로 위 룰의 의미를 각자 생각해 보기 바란다.

 

rawbody __SOMETHING /\S/

meta BODY_EMPTY !__SOMETHING

score BODY_EMPTY 2.606

 

또한 URI의 경우 메시지 본문에 있는 URL 주소에 매칭 하는 것인데, 아래의 경우

http://xxx.xxx.com:8080와 같이 http 주소 뒤에 포트번호가 있을 경우 스팸일 가능성이 높으므로 2.0이 주어진 것을 알 수 있다.

 

uri MY_HTTP_ODD_PORT /\w+\.(com|net|info|biz):\d+/i

describe MY_HTTP_ODD_PORT Link to a server on nonstandard port

score MY_HTTP_ODD_PORT 2.0

 

또한 아래의 경우 본문의 메시지 내 URL 주소(도메인 이름)가 숫자로만 이루어진 경우 역시 스팸일 가능성이 높으므로 2.0점이 주어지는 것을 알 수 있다.

 

uri MY_DOMAIN_NUMBERS_ONLY /[.\/@]+\d+\.(com|net|biz|info)/i

describe MY_DOMAIN_NUMBERS_ONLY Domain names has numbers only

score MY_DOMAIN_NUMBERS_ONLY 2.0

 

이외 정규식에 대해서는 아래의 URL을 참고하기 바란다.

 

 

 

http://www.perldoc.com/perl5.8.0/pod/perlrequick.html

 

만약 정기적으로 뉴스레터를 발송하고 있다면 자신이 보낸 메일이 스팸으로 분류되지 않도록 하는 것이 좋다. 이를 위해서는 다음과 같은 규칙을 따르도록 하면 된다.

 

 

 

- 스팸 메일에서 자주 사용되는 단어를 사용하지 않는다. 이를테면 광고, 홍보, 무료, 대출등이 가장 대표적인 예일 것이다.

 

- 알파벳을 사용할 때는 가급적 대문자나 큰 font의 단어는 사용하지 않는다.

- 스패머들이 대량 메일 발송 시 사용하는 메일발송 프로그램을 사용하지 않는다.

- 메일 발송 시에는 From 주소에 유명한 도메인이나 본인의 도메인을 사용하는 것이 좋다. 무료로 이용이 가능한 메일 주소는 가급적 사용하지 않는 것이 좋다.

- 회원들에게 메일 발송전에 일단 본인에게 메일을 발송해 보고 스팸어세신에 매칭되는 항목과 점수(score)를 살펴본 후 적절히 수정하도록 하는 것이 좋다.

 

진보된 여러 가지 anti-스팸 기법 중 가장 효율적인 방법중 하나인 URIBL(SURBL)에 대해 살펴보자. URIBL은 스팸어세신뿐만 아니라 대부분의 상용솔루션에서도 적극 활용하고 있는 방법인데, 이는 일종의 RBL(Realtime Blackhole List)이기는 하지만 메일발송 ip위주여서 오탐이 많았던 이전의 RBL과 달리 전송된 메일의 본문에 있는 http 주소를 기반으로 운영하는 RBL이어서 오탐이 매우 적고 단순한 영문 텍스트 메일도 스팸으로 걸러낼 수 있을 정도로 효율적이다.

왜냐하면 스팸메일은 프록시나 해킹, 바이러스가 감염된pc등 여러 ip를 통해 발송할 수는 있지만 홍보하고자 하는 사이트의 주소인 URL은 쉽게 바꿀 수 없기 때문이다.

SURBL에 대해서는 http://www.surbl.org/ 또는 http://uribl.com/를 참고하기 바라며 surbl 관련 룰은 기본적으로 정의되어 있지만 점수(score)가 좀 낮게 설정되어 있으므로 일정 기간 모니터링 후 4 이상으로 높게 설정하는 것이 좋다. 아울러 위 사이트에서 자신의 도메인을 검색해 보아 혹 블랙리스트로 등록되어 있지는 않은지 확인해 보기 바란다.

 

아래는 한 스팸메일의 헤더를 보여주고 있는데, 베이시안필터링(BAYES_99)외에 URIBL을 통해서 많은 점수가 할당된 것을 알 수 있다.

 

01279ae25ef9d844ae0866fb55254f26_1670565937_0257.png
 

[그림] URIBL로 스팸으로 필터링된 메일의 헤더 예

 

마지막으로 직접 룰을 생성해 보는 예를 살펴보자. 일부 포탈사이트에서 무료로 제공되는 메일의 경우 수신 확인 기능이나 메일에 첨부되는 광고 설정 등으로 인하여 실제 수치를 보면 수치가 높아 스팸으로 분류되는 경우가 많다. 실제로, 포털 사이트 등에는 한 번에 발송 가능한 메일의 수 등이 제한되어 있어 포탈사이트에서 직접 스팸 메일을 발송하는 것은 거의 불가능하도록 되어 있다.

 

따라서 해당 포탈사이트에서 오는 메일은 별도의 룰을 만들어 score(수치)를 재조정함으로써 스팸으로 분류되지 않도록 하는 것이 좋다. 이를 위해 몇 가지 예를 들어보도록 하자.

 

먼저, daum.net에서 전송되는 메일을 예로 들어보자.

 

아래는 발신자의 메일 주소가 모두 xxx@hanmail.net이지만 정상적으로 daum.net에 로그인하여 전송된 메일과 발신자의 메일 주소만 hanmail.net이고 실제로는 스팸 프로그램을 이용하여 발송된 메일의 헤더이다.

두 메일의 차이점을 확인해 보기 바란다.

 

 

정상적인 hanmail

Received: from smail-110.hanmail.net (smail-110.hanmail.net [211.43.197.39])

by tt.co.kr (8.13.8/8.13.8) with ESMTP id m1RBvbGE006314

for <antihong@tt.co.kr>; Wed, 27 Feb 2008 20:57:37 +0900

Received: from wwl417.hanmail.net ([222.231.34.62])

by smail-110.hanmail.net (8.12.1/8.9.1) with ESMTP id m1RBvab1026186;

Wed, 27 Feb 2008 20:57:36 +0900

Received: (from hanadmin@localhost)

by wwl417.hanmail.net (8.12.9/8.9.1) id m1RBvXTP009173

for <antihong@tt.co.kr>; Wed, 27 Feb 2008 20:57:33 +0900

Content-Type: text/html; charset="EUC-KR"

Content-Transfer-Encoding: 8bit

X-Originating-IP: [192.168.69.32]

From: "=?EUC-KR?B?yKu8rrn8?=" <kkkhst2@hanmail.net>

 

 

 

위조된 hanmail

Received: from vwall.tt.co.kr (localhost.localdomain [127.0.0.1])

by vwall.tt.co.kr (8.13.1/8.13.1) with ESMTP id m0U9W6vk001227;

Wed, 30 Jan 2008 18:32:06 +0900

Received: from ([221.201.217.93])

by vwall.tt.co.kr Wed, 30 Jan 2008 18:31:59 +0900 (KST)

Received: from [98.104.195.234] by 211.47.66.51 with SMTP; Wed, 30 Jan 2008 06:25:03 -0300

Message-ID: <jm8zclg02a9vg2gf55zmyx-bx8-5@kek2y>

From: "오주미" <im99jd2fsfe88hoifsd@daum.net>

Reply-To: "오주미" <im99jd2fsfe88hoifsd@daum.net>

To: security@tt.co.kr

Subject: [SPAM] ########## 멋쟁이 남친 . vwkkz k kpsjftca

Date: Wed, 30 Jan 2008 06:25:03 -0300

X-Mailer: MIME-tools 5.503 (Entity 5.501)

 

차이점을 쉽게 알 수 있을 것이다.

바로 Received: 부분에 차이가 있음을 알 수 있는데, 이의 특성을 이용하여 다음과 같은 룰을 생성할 수 있을 것이다.

 

header LOCAL_DAUM_RULE Received =~ /(from hanadmin\@localhost)/

score LOCAL_DAUM_RULE -5.5

describe LOCAL_DAUM_RULE This is a normal daum rule

 

, 헤더 내 Received 부분에 (from hanadmin@localhost)가 있으면 정상적으로 daum.net 에 로그인하여 발송된 메일로 인식하여 -5.5를 부여한다는 의미이다.

같은 방법으로 다른 포탈에서 오는 메일도 각자 만들 수 있을 것이다.

이를테면 아래의 경우 dreamwiz.com에서 보내는 메일인데, 정상적으로 dreamwiz에서 발송한 메일은 헤더 중간에 localhost.dreamwiz.com이 있다는 특성을 이용하면 된다.

 

 

 

Return-Path: <ksclinu@dreamwiz.com>

Received: from mx-s1.dreamwiz.com ([211.39.128.136])

by panmail02.tt.co.kr (8.11.6/8.11.6) with ESMTP id i755wMP20347

for <testmerong@server.com>; Thu, 5 Aug 2007 14:58:22 +0900

X-DreamWiz-Peer-IP: [10.0.0.38]

Received: from mail18.dreamwiz.com (mail18.dreamwiz.com [10.0.0.38])

by mx-s1.dreamwiz.com (8.13.0/8.13.0) with ESMTP id i755vcTx006777

for <testmerong@server.com>; Thu, 5 Aug 2007 14:57:38 +0900 (KST)

Received: from [127.0.0.1] (localhost.dreamwiz.com [127.0.0.1])

by mail18.dreamwiz.com (8.13.0/8.13.0) with ESMTP id i755vbgA097668

for <testmerong@server.com>; Thu, 5 Aug 2007 14:57:37 +0900 (KST)

Received: from [211.219.171.33] by mail18.dreamwiz.com with HTTP;

Thu, 5 Aug 2007 14:57:37 +0900 (KST)

 

이때의 룰은 아래와 같을 것이다.

 

 

header LOCAL_DREAMWIZ_RULE Received =~ /localhost\.dreamwiz\.com/

score LOCAL_DREAMWIZ_RULE -8

describe LOCAL_DREAMWIZ_RULE This is a normal DREAMWIZ rule

 

아래는 paran.com이라는 포탈에서 발송한 메일이다.

아래 헤더에서는 ParanMail Web이라는 부분이 보이는데, 이 부분을 가지고 설정하면 될 것이다.

Return-Path: <antianti@paran.com>

Received: from system.tt.co.kr ([211.47.65.83])

by www10.tt.co.kr (8.11.6/8.11.6) with ESMTP id i87BLqH05009

for <antihong@tt.co.kr>; Tue, 7 Sep 2007 20:21:52 +0900

Received: from mail12.paran.com ([211.41.82.117])

by system.tt.co.kr (8.11.6/8.10.1) with SMTP id i87BLsR26079

for <antihong@tt.co.kr>; Tue, 7 Sep 2007 20:21:54 +0900

Message-Id: <200409071121.i87BLsR26079@system.tt.co.kr>

Received: from 211.219.171.33 ([211.219.171.33]) by mail12.paran.com (ParanMail Web 0.1) with ESMTP

for <antihong@tt.co.kr>; Tue, 7 Sep 2007 20:22:07 +0900

 

이때의 룰은 아래와 같을 것이다.

 

 

header LOCAL_PARAN_RULE Received =~ /ParanMail Web/

score LOCAL_PARAN_RULE -10

describe LOCAL_PARAN_RULE This is a normal PARAN rule

 

같은 원리로 다음과 같이 응용할 수도 있다.

 

먼저 아래의 헤더를 잘 살펴보기 바란다.

 

 

 

Return-Path: <antihong@msn.com>

Received: from hotmail.com ([64.4.37.51])

by www10.tt.co.kr (8.11.6/8.11.6) with ESMTP id i87BeZH07609

for <antihong@www10.tt.co.kr>; Tue, 7 Sep 2007 20:40:35 +0900

Received: from mail pickup service by hotmail.com with Microsoft SMTPSVC;

Tue, 7 Sep 2007 04:40:50 -0700

Received: from 211.219.171.33 by by10fd.bay10.hotmail.msn.com with HTTP;

Tue, 07 Sep 2007 11:40:50 GMT

 

위의 hotmail.com에서 발송한 메일의 헤더를 보면 헤더 부분에 반드시 hotmail.msn.com 부분이 보여야 하므로 이를 이용하면 아래와 같은 룰을 만들 수 있다.

 

, 아래의 룰은 id@msn.com에서 발송한 메일 중 Received 부분에 hotmail.msn.com이 포함되지 않은 것은 스팸일 가능성이 높으므로 이러한 메일에 대해 5점을 할당했다는 의미이다.

여기에서는 각각의 룰을 정의한 후 meta라는 것을 이용하여 두 룰의 관계를 정의한 것인데, &&그리고의 의미이고, !~이 아니라는 의미이다.

 

header __RCVD_MSN_ANTI Received =~ /hotmail\.msn\.com/i

header __FROM_MSN_ANTI From =~ /msn\.com/i

meta SARE_FORGED_MSN (__FROM_MSN_ANTI && !__RCVD_MSN_ANTI)

score SARE_FORGED_MSN 5

 

참고로 룰의 양이 많으면 많을수록, 그리고 복잡하면 복잡할수록 스팸어세신의 성능은 저하될 수 있으므로 가급적 룰은 작고 단순하게 정규식을 이용하여 설정하는 것이 좋다.

 

* 스팸어세신 운영 팁

스팸어세신 운영 시 몇 가지 팁에 대해 살펴보도록 하자.

 

스팸으로 분류된 메일의 헤더를 보면 아래와 같이 각 항목에 대한 내용과 점수가 보이게 된다.

 

 

X-Spam-Report:

* 5.0 LOCAL_ANTI2_CHANGE_CHR13 BODY: Subject has illegal character

* 0.3 MIME_HTML_ONLY BODY: Message only has text/html MIME parts

* 5.4 BAYES_99 BODY: Bayesian spam probability is 99 to 100%

* [score: 0.9999]

하지만, 스팸으로 분류되지 않은 메일의 경우 아래와 같이 항목만 보이고 구체적인 점수가 보이지 않아 일일이 점수를 찾아보아야 할 때가 있다.

 

 

 

tests=BAYES_44,SARE_HTML_URI_PARTID,unsub48 autolearn=no version=3.02

 

이러한 경우 아래의 내용을 local.cf등의 설정 파일에 한 줄로 추가하면 스팸으로 분류되지 않은 메일도 각 항목에 대해 간략하게 점수가 보이게 된다.

 

 

add_header all Status "_YESNO_, hits=_HITS_ required=_REQD_

tests=_TESTSSCORES_ autolearn=_AUTOLEARN_ version=_VERSION_"

 

만약 메일 수신이 많은 대형 사이트에서 사용하고자 할 경우에는 다음의 사항을 고려하여야 한다.

 

먼저 메일 송수신시에는 많은 DNS 질의를 하므로 가급적 원격지의 DNS 서버를 사용하는 것보다 로컬에 DNS를 구축하여 캐싱서버로 운영하는 것이 좋다. 두 번째는 룰을 간소화하는 것이 좋다. 불필요하게 많은 룰을 설정하면 할수록 속도는 느려질 것이다.

그리고 body*와 같은 형식을 사용하지 말고, 가급적 정규식을 사용하여 룰을 통합하는 것이 좋다.

아울러, 시스템 구성시에는 “3.2 큐잉(Queueing)서버를 이용한 메일서비스 가용성강화에서 설명한 것처럼 메일 박스는 스토리지와 같이 NFS로 공유하고 sendmail과 같은 서버에 스팸어세신을 설치하여 운영하면 된다.

 

 

 

스팸 발송의 기술은 하루가 다르게 진보하고 있다.

 

초기에 스패머들은 정직하게도 전용 메일러를 헤더에 명시하였지만 이를 이용하여 스팸을 인식하자 이후에는 마치 Outlook Express와 같이 정상적인 메일러로 가장하였으며, 동일한 제목이나 내용의 대량 메일 발송시 이를 스팸으로 인식하자 제목이나 메시지에 “ki g j bzxhg st”와 같은 의미없는 random한 문자열을 생성하여 이를 우회하였다. 이후에는 From에 보이는 메일 주소도 수시로 random하게 변경하였으며 received 부분의 정보도 위조하기에 이르렀다. 따라서 스팸어세신도 지속적으로 새로운 버전으로 업그레이드되면서 새로운 방식의 룰을 계속적으로 적용되고 있다.

 

따라서 설치 시에는 가급적 최신 버전의 프로그램을 설치하는 것이 좋다.

 

룰을 추가하거나 수정하여 설정한 다음에는 문법상 에러가 없는지 확인하기 위해 프로세스를 재가동하기 전에 아래와 같이 실행해 보도록 한다.

 

만약 에러가 있으면 에러가 있는 줄의 내용을 출력하게 된다.

 

 

# spamassassin --lint --prefs-file=./add.cf

 

스팸어세신을 가동하면 기본적으로 /var/log/maillog 파일에 많은 로그 메시지가 쌓이게 되어 이 때문에 부하를 유발하거나 용량을 차지하게 된다.

 

굳이 로그를 남기지 않으려면 /etc/rc.d/init.d/spam 파일을 열어 SPAMDOPTIONS 부분에 아래와 같이 -s null을 추가한후 프로세스를 restart해 주면 된다.

 

만약 -s /var/log/spamd.log와 같이 하면 /var/log/maillog 대신 /var/log/spamd.log 파일에 별도의 로그가 남게 할 수도 있다.

 

SPAMDOPTIONS="-d -c -m5 -H --user-config -s null "

 

스팸어세신을 설치하면 서버 내 모든 유저에게 적용된다.

 

만약 스팸어세신을 원하지 않는 유저가 있을 경우에는 local.cf

whitelist_to *@abc.com

와 같이 해당 메일 주소로 오는 메일은 모두 whitelist로 인식하도록 설정하면 된다.

 

 

만약 mailog에 아래와 같은 메시지가 보이면 spamd child 프로세스가 수신되는 메일을 제대로 처리하지 못하였다는 의미이므로 /etc/rc.d/init.d/spam 파일에서 -m 의 수치를 높인 후 재가동하기 바란다.

 

그리고 가능하면 CPU 및 메모리의 HW사양을 올리는 것이 좋다.

 

mail spamc[18837]: connect(AF_INET) to spamd at 127.0.0.1 failed, retrying (#1 of 3): Connection timed out

mail spamc[18273]: connect(AF_INET) to spamd at 127.0.0.1 failed, retrying (#2 of 3): Connection timed out

 

만약 스팸어세신이 제대로 작동하지 않는다면 /etc/procmailrc 의 설정 여부, spamd127.0.0.1:783에 리슨하고 있는지 여부 등을 체크하여야 한다.

 

초기에 스팸어세신을 설치한 후에는 스팸 매칭이 잘 되는 것 같지만 한 두 달 후에는 스팸룰을 통과하는 스팸 메일들이 점차로 증가하게 될 것이다.

따라서 수시로 이러한 메일들을 분석하여 룰을 업데이트 하여야만 스팸과의 전쟁에서 이길 수 있을 것이다.

물론 이러한 정보는 아래의 홈페이지나 메일링리스트를 통해 얻을 수 있다.

 

 

홈페이지 : http://www.spamassassin.org/

http://johnbokma.com/spam/spamassassin-cookbook.html

http://www.rulesemporium.com/

메일링리스트 : http://news.gmane.org/gmane.mail.spam.spamassassin.general

 

 

3.6.6 서버에서 발송되는 메일에 대한 필터링

 

지금까지 스팸어세신을 통해 외부에서 inbound 되는 메일에 대한 스팸 필터링 기법에 대해 살펴보았다. 그렇다면 반대로 서버에서 외부로 발송되는 메일에 대해서도 별도의 정책을 통한 스팸필터링이 가능할까?’ 라는 생각을 가질 수 있다.

 

왜냐하면 최근에는 웹해킹 등을 통해 대량의 스팸메일을 발송하거나 아예 스팸발송 프로그램 등을 업로드 후 발송하는 경우도 많기 때문이다.

또한 여러 대의 서버가 있을 경우 각각의 서버에서 발송되는 메일을 관리하는 것이 쉽지 않기 때문에 각 서버에서 메일을 직접 발송하지 않고 발송 전용 메일 서버인 메일허브 서버를 구축하여 이를 거쳐서 발송되도록 한다면 보다 통합적인 관리가 가능할 것이다.

여기에서는 이러한 요구를 구현할 수 있도록 시스템을 디자인해 보도록 하자.

이때 사용될 수 있는 프로그램으로 sendmail과 함께 스팸어세신 기반에서 메일에 대한 필터를 제공하는 spamass-milter이라는 별도의 MILTER(mail filter)를 이용하여 쉽게 사용할 수 있는 방법에 대해 살펴보도록 하자.

 

- MailHub 서버

메일허브는 아래 그림과 같이 외부로 전송될 메일을 대신 받아 처리해 주는 일종의 중계서버라고 생각하면 된다.

 

 

01279ae25ef9d844ae0866fb55254f26_1670565964_4018.png
 

[그림] 메일허브 구성도

 

이렇게 구성을 할 경우 다음과 같은 장점이 있다.

 

- 여러 대의 서버가 있을 경우 외부로 전송되는 메일을 중앙(메일허브서버)에서 일괄 관리할 수 있다.

 

- 바로 전송되지 못한 메일은 서버의 큐에 저장되어 있다가 수시로 재전송 시도되므로 이로 인한 dns 및 프로세싱 처리에 대한 부하가 유발될 수 있으나 메일허브가 구성되면 이 역할을 메일허브가 대신 하므로 각 서버의 큐는 비어있게 되어 부하가 없다.

 

 

- 메일허브에 anti 스팸/바이러스 프로그램 등을 설치할 경우 외부로 발송되는 메일에 대한 필터링이 가능하다.

 

그럼, 이제 메일허브를 먼저 구축해 보자.

# 각 서버

sendmail.cf를 보면 아래와 같은 DS라는 부분이 있는데, 이는 외부로 전송되는 메일에 대한 정책을 정의하는 것으로 기본적으로 비어있다.

 

이를 아래와 같이 메일허브 서버의 IP 또는 호스트명을 입력한 후 sendmail을 재가동하면 이후부터는 모든 outbound 메일을 메일허브로 보내게 된다.

 

만약 메일허브를 여러 대로 구성하고자 할 경우에는 ip 대신 도메인명으로 지정하고 도메인에 ip를 여러 개 부여하면 될 것이다.

 

기존)

# "Smart" relay host (may be null)

DS

 

변경)

# "Smart" relay host (may be null)

DS192.168.3.5

 

# 메일허브 서버

메일 허브에서는 자신의 서버로 들어오는 메일에 대해 relay를 허용해 주어야 하므로 /etc/mail/access를 열어 아래와 같이 각 메일 서버의 ip에 대해 relay를 허용해 주어야 한다.

 

또는 지정된 도메인을 통해서만 메일이 발송된다면 도메인에 대해 relay를 허용해도 된다.

 

 

192.168.2 RELAY

192.168.3.4 RELAY

192.168.3.5 RELAY

 

이후, 아래와 같이 실행하여 access.db를 생성하면 모든 설정이 완료되었다.

# makemap hash /etc/mail/access < /etc/mail/access

 

실제 정상적으로 메일허브를 거쳐 메일이 전송되는지 해당 서버에서 메일을 발송해 보아 수신된 메일의 헤더를 살펴보기 바란다.

 

아래 헤더에서 아래부터 윗부분으로 살펴보면 r01에서 보낸 메일이 메일허브서버인 mailhub2-23 서버를 통해 전송된 것을 알 수 있다.

 

Received: from mailhub2-23.tt.co.kr (mailhub2-23.tt.co.kr [211.47.72.223])

by www10.tt.co.kr (8.13.8/8.13.8) with ESMTP id m1S28jgD010600

for <antihong@www10.tt.co.kr>; Thu, 28 Feb 2008 11:08:45 +0900

Received: from r01.tt.co.kr ([211.47.69.46])

mailhub2-23.tt.co.kr (8.12.11.20060308/8.12.11) with ESMTP id m1S28fOq026868 for <antihong@www10.tt.co.kr>; Thu, 28 Feb 2008 11:08:41

Received: from r01.tt.co.kr (localhost.localdomain [127.0.0.1])

by r01.tt.co.kr (8.12.8/8.12.8) with ESMTP id m1S28cnI015923

for <antihong@www10.tt.co.kr>; Thu, 28 Feb 2008 11:08:38 +0900

Received: (from root@localhost)

by r01.tt.co.kr (8.12.8/8.12.8/Submit) id m1S28bYx015922

for antihong@www10.tt.co.kr; Thu, 28 Feb 2008 11:08:38 +0900

Date: Thu, 28 Feb 2008 11:08:38 +0900

 

이제는 메일허브에 spamass-milter라는 스팸필터링 프로그램을 설치하여 메일허브에서 스팸을 필터링하도록 구성해 보자.

spamass-milter 홈페이지 : http://savannah.nongnu.org/projects/spamass-milt/

 

01279ae25ef9d844ae0866fb55254f26_1670565991_7613.png
 

[그림] spamass-milter 홈페이지



 

spamass-milter는 앞에서 살펴본 바와 같이 역시 milter를 이용하므로 sendmail에서 sendmail-dev디 및 sendmail-cf 패키지를 추가 설치하고 MILTER가 지원되는지 먼저 확인 후 sendmail.mc 에 아래와 같이 설정 후 sendmail.cf를 재생성하면 된다.

 

 

INPUT_MAIL_FILTER(`spamassassin', `S=local:/var/run/spammilter/spamass.sock, F=, T=C:15m;S:4m;R:4m;E:10m')dnl

define(`confMILTER_MACROS_CONNECT',`t, b, j, _, {daemon_name}, {if_name}, {if_addr}')dnl

define(`confMILTER_MACROS_HELO',`s, {tls_version}, {cipher}, {cipher_bits}, {cert_subject}, {cert_issuer}')dnl

 

이제 spamass-milter 홈페이지에서 소스 파일을 다운로드하여 설치해 보도록 하자.

 

# wget http://download.savannah.nongnu.org/releases/spamass-milt/

spamass-milter-0.3.1.tar.gz

# tar zxfp spamass-milter-0.3.1.tar.gz

# cd spamass-milter-0.3.1

# ./configure ; make ; make install

 

위와 같이 실행하여 설치를 하면 /usr/local/sbin/spamass-milter 실행 파일이 정상적으로

설치된다.

 

이제 구동에 필요한 관련 디렉토리를 생성해 주도록 하자.

 

# mkdir /var/run/spammilter

# chown nobody.nobody /var/run/spammilter

# chmod 755 /var/run/spammilter

 

그리고 다음과 같은 구동스크립트를 생성한 후 실행하도록 한다.

 

 

 

#!/bin/sh

#

# $Id: spamass-milter-redhat.rc,v 1.1 2002/07/24 16:19:53 dnelson Exp $

#

# spamass-milter This script starts and stops the spamass-milter daemon

#

# chkconfig: 2345 80 30

#

# description: spamass-milter is a daemon which hooks into sendmail and routes

# email messages to spamassassin

# processname: spamass-milter

 

 

# Source function library.

. /etc/rc.d/init.d/functions

 

# Source networking configuration.

. /etc/sysconfig/network

# For some reason perl5.8.0 really doesn't like UTF-8.

# Fix courtesy of Mark Cohen mcohen@looksmart.net

unset LANG

export LANG=C

 

# Local spamass-milter config

SM_SOCKET=/var/run/spammilter/spamass.sock

SM_EXTRA_FLAGS="-b spam-mail"

 

[ -x /etc/sysconfig/spamassmilter ] && . /etc/sysconfig/spamassmilter

 

# Check that networking is up.

[ ${NETWORKING} = "no" ] && exit 0

 

[ -x /usr/local/sbin/spamass-milter ] || exit 0

PATH=$PATH:/usr/bin:/usr/local/sbin:/usr/local/bin

 

# See how we were called.

case "$1" in

start)

# Start daemon.

echo -n "Starting spamass-milter: "

daemon --user=nobody /usr/local/sbin/spamass-milter -p ${SM_SOCKET} -f ${SM_EXTRA_FLAGS}

RETVAL=$?

touch /var/lock/subsys/spamass-milter

echo

;;

stop)

# Stop daemons.

echo -n "Shutting down spamass-milter: "

killproc spamass-milter

RETVAL=$?

rm -f /var/lock/subsys/spamass-milter

echo

;;

restart)

$0 stop

$0 start

;;

status)

status spamass-milter

;;

*)

echo "Usage: $0 {start|stop|restart|status}"

exit 1

esac

 

exit 0

 

# /etc/rc.d/init.d/milter start

Starting spamass-milter: [ $OK ]

 

이후 sendmail도 재가동하면 바로 적용된다.

 

물론 사전에 spamassassin은 설치되어 작동하고 있어야 하므로 spamed도 가동한다.

 

이제 메일허브서버에서는 해당 서버에서 발송되는 메일에 대해서도 스팸여부를 체크하게 되는데 maillog를 살펴보면 필터여부를 확인할 수 있을 것이다.

 

 

Feb 28 10:52:00 mailhub2-28 sendmail[26221]: m1S1psWx026221: Milter delete: rcpt <knowgloria@hotmail.com>

 

Feb 28 10:52:00 mailhub2-28 sendmail[26221]: m1S1psWx026221: Milter add: header: X-Spam-Level: ****************

 

Feb 28 10:52:00 mailhub2-28 sendmail[26221]: m1S1psWx026221: Milter add: header: X-Spam-Checker-Version: SpamAssassin 3.2.1 (2007-05-02) on mailhub2-25.tt.co.kr

 

Feb 28 10:52:00 mailhub2-28 sendmail[26221]: m1S1psWx026221: Milter change: header Subject: from May your get its full-$!ze! to [SPAM] May your get its full-$!ze!

 

Feb 28 10:52:00 mailhub2-28 sendmail[26221]: m1S1psWx026221: Milter message: body replaced

 

Feb 28 10:52:04 mailhub2-28 sendmail[26227]: m1S1psWx026221: to=spam-mail, delay=00:00:10, xdelay=00:00:04, mailer=local, pri=61893, dsn=2.0.0, stat=Sent

 

 

spamass-milter는 여러 가지 옵션을 제공하여 환경에 따라 원하는 설정을 할 수 있는데,

스크립트 파일 내 SM_EXTRA_FLAGS에 설정할 수 있는 몇 가지 옵션을 살펴보도록

하자.

 

-b spamaddress

: 이는 스팸수치가 required_score에 지정한 값보다 높을 경우 해당 메일을 수신자에게 발

송하지 않고 지정된 유저의 메일박스로 전송하는 옵션이다.

따라서 -b spam과 같이 지정하

였을 경우 스팸수치가 높은 스팸메일은 실제 수신자에게 전송되지 않고 spam이라는 계정에

게 전달된다.

 

 

 

-B spamaddress

:이는 스팸 메일이 원래의 수신자에게도 전송되고, 지정한 유저에게도 전송된다는 의미이다.

 

 

-f : 백그라운드에서 fork하도록 하는 옵션이다.

 

 

-i networks

: 특정한 IP대역에서의 메일은 스팸어세신에서 검사하지 않고 바로 통과시키도록 하는 것이

. 10.0.0.0/24또는 10.0.0.0/255.255.255.0과 같은 형식의 사용이 가능하다.

 

-r nn

: 이는 특정 수치이상의 메일은 SMTP 레벨에서 아예 받아들이지 않고 REJECT하도록 하

는 옵션이다.

만약 nn-1의 경우라면 [SPAM]으로 찍히는 메일은 전송하지 않고 서버에

서 거부하게 된다.

 

 

아래는 메일 발송 시 스팸메일에 대해서 SMTP 레벨에서 reject하는 것을 확인할 수 있다.

 

 

>>> DATA

250 2.1.5 <root@test.tt.co.kr>... Recipient ok

354 Enter mail, end with "." on a line by itself

>>> .

550 5.7.1 Blocked by SpamAssassin

>>> RSET

250 2.0.0 Reset state

 

이때 maillog에 찍히는 로그는 다음과 같다.

15:33:19 r06 sendmail[3061]: kBS6XFSq003061: Milter: data, reject=550 5.7.1

Blocked by SpamAssassin

15:33:19 r06 sendmail[3061]: kBS6XFSq003061: to=<root@test.tt.co.kr>,

delay=00:00:04, pri=30332, stat=Blocked by SpamAssassin

 

지금까지 살펴본 spamass-milter를 각자의 환경에 따라 적절히 이용하면 수신되는 메일 뿐

만 아니라 자신의 서버에서 발송되는 메일에 대한 스팸 여부의 제어가 가능하므로 자신의

서버가 스팸서버로 악용되는 것을 상당 부분 막을 수 있을 것이다.

 

 

 

최근에는 각 서버에서 /usr/sbin/sendmail 등과 같은 파일을 호출하지 않고 발송하고자 하는 메일서버의 25/tcp에 소켓으로 직접 연결한 후 스팸을 발송하는 경우가 있다.

 

이러한 경우 sendmail을 실행한 것이 아니기 때문에 maillog에도 찍히지 않아 추후 로그분석도 불가능하게 된다.

 

이를테면 다음과 같이 gmail.comMX 질의후 해당 서버로 직접 연결하여 메일을 보낸다고 가정해 보자.

 

# telnet gmail-smtp-in.l.google.com. 25

Trying 209.85.147.27...

Connected to gmail-smtp-in.l.google.com (209.85.147.27).

Escape character is '^]'.

220 mx.google.com ESMTP m24si16179543waf.57

EHLO SPAM

250-mx.google.com at your service, [211.47.72.223]

250-SIZE 28311552

250-8BITMIME

250 ENHANCEDSTATUSCODES

MAIL FROM:<spam@antihong.com>

250 2.1.0 OK

RCPT TO:<antihong@gmail.com>

250 2.1.5 OK

DATA

354 Go ahead

I will send lots of spams by socket to gmail server ....

.

250 2.0.0 OK 1204165791 m24si16179543waf.57

quit

221 2.0.0 mx.google.com closing connection m24si16179543waf.57

Connection closed by foreign host.

따라서, 이러한 발송을 차단하기 위해 각 메일서버에서는 outbound 되는 25/tcp에 대해 접근 통제 설정을 할 수 있다.

 

즉 아래와 같이 설정하였을 경우 정상적으로 메일 프로그램을 호출하여 발송되는 메일은 모두 메일허브 서버로만 전송되므로 해당 프로세스만 허용하고 나머지는 모두 차단하는 것이다.

이와 같이 설정 시에는 앞에서 본 바와 같이 직접 특정 메일서버에 25/tcp로의 소켓 연결 자체는 차단되게 된다.

 

물론 공격자가 메일허브 서버의 존재를 알고 메일허브 서버의 ip를 안다면 메일 허브의 25/tcp로 소켓 연결하여 메일 발송을 할 수도 있을 것이다.

 

iptables -A OUTPUT -p TCP --sport 1024: -d 192.168.3.5 --dport 25 -m state --state NEW -j ACCEPT

iptables -A OUTPUT -p TCP --sport 1024: -d 0/0 --dport 25 -m state --state NEW -j DROP

 

 

 

 

 

관련자료

댓글 0
등록된 댓글이 없습니다.

공지사항


뉴스광장


  • 현재 회원수 :  60,035 명
  • 현재 강좌수 :  35,795 개
  • 현재 접속자 :  181 명