스팸 필터링은 어디까지가 적당할까요?

eunjea의 이미지

qmail (http://qmail.kldp.org/) 을 운영하면서 꽤 오래동안 고민(?)하던 문제입니다.
즉, 서버 수준에서 스팸 거르기는 어느 수준까지가 적당한 걸까요?
각 이메일 계정 사용자가 직접 사용하는 스팸 필터링이 아니라 그에 앞서 배달을 맏고 있는 smtp 수준에서의 필터링을 말합니다.

서버단에서의 필터링은 일반적인 우편물로 비교하자면 우체국에서 쓸데 없는 광고물이라 판단하고 배달을 아예 안 해주는거나 마찬가지겠죠.
그렇다면 명백한 100% 스팸(이라고 판단이 가능할 지언정) 이라도 각 사용자에게 배달하는것이 가장 좋을까요?

사실 제 개인적으로는 이메일(편지)는 그 내용과는 상관없이 무조건 배달되어야 하는것이 smtp의 올바른 임무라고 생각하고 있습니다.
하지만 스팸이 너무 많이 쏟아져 들어가면 그에 대한 불만을 가지는 사용자역시 많다는 것이 문제입니다.

어디까지가 적정한 수준일까요? 아니면 각 사용자들에게 그 책임을 가지도록 하는것이 좋을까요?

* 오타 수정했습니다.

netskate의 이미지

참 애매하고, 어려운 문젠데요..

제 생각엔 스팸의 기준이란 개개인에게 달린 거 같네요..

무엇이 스팸이고, 무엇이 스팸이 아닌지 통합된 기준은 존재할 수 없다고 봅니다..

Let it Be 가 최선 아닐지..
===================================================
Make it Simple, Easy, Compact !!!!

===================================================
Make it Simple, Easy, Compact !!!!

김정균의 이미지

좀 암담한 것은 spam 을 받기를 원하는 사용자도 있더군요 ^^;

warpdory의 이미지

일단 저에게 오는 게 스팸이든 정상메일이든 ...

제가 받아야 합니다. 그리고 그걸 제가 나눠놓은 기준으로 스팸인지 여부를 결정해서 지울 건 지우고 .. 뭐 이래야 한다고 생각하는 사람입니다.

그런 이유 중 하나가, OS/2 사용자 메일링 리스트가 대개 동구권 국가나 러시아에서 도는 게 많은데, 이게 국내에서는 스팸처리 되는 경우가 대부분입니다. 그러다보니, 일반적으로 쓰는 스팸필터 또는 메일 서버들은 그냥 막아버리더군요.

그 외에도 이러저러한 이유로, 일단 수신자가 저로 된 건 제가 다 받습니다. 중간에 어디선가 사라진다면 .. 좀 짜증날 것 같습니다.

---------
귓가에 햇살을 받으며 석양까지 행복한 여행을...
웃으며 떠나갔던 것처럼 미소를 띠고 돌아와 마침내 평안하기를...
- 엘프의 인사, 드래곤 라자, 이영도

즐겁게 놀아보자.
http://akpil.egloos.com


---------
귓가에 햇살을 받으며 석양까지 행복한 여행을...
웃으며 떠나갔던 것처럼 미소를 띠고 돌아와 마침내 평안하기를...
- 엘프의 인사, 드래곤 라자, 이영도

즐겁게 놀아보자.

김정균의 이미지

제가 겪은 경우는.. 정말 스팸 메일을 받고 싶어 하더군요. 그 중에 건질 것이 있다나 머래나 ^^;

warpdory의 이미지

가끔 (19) 사이트 광고가 오면서 동영상을 링크해서 보여주게 해보는데, 그럴 때 html 코드를 보면 avi 또는 wmv 등의 파일이 그대로 박혀 있는 경우도 있거든요. wget 등으로 쓸쩍 건질 수 있습니다. ^^;

물론 .. 이건 제 경우고 =3=3=3=3=3=3

---------
귓가에 햇살을 받으며 석양까지 행복한 여행을...
웃으며 떠나갔던 것처럼 미소를 띠고 돌아와 마침내 평안하기를...
- 엘프의 인사, 드래곤 라자, 이영도

즐겁게 놀아보자.
http://akpil.egloos.com


---------
귓가에 햇살을 받으며 석양까지 행복한 여행을...
웃으며 떠나갔던 것처럼 미소를 띠고 돌아와 마침내 평안하기를...
- 엘프의 인사, 드래곤 라자, 이영도

즐겁게 놀아보자.

다콘의 이미지

저희 회사는 2가지만 smtp단에서 차단합니다.
1. surbl로 차단
2. spf는 fail만 차단

나머지는 사용자 선택입니다.

은재님께 말씀드릴게 한가지 있는데 knetqmail-1.06 20080402에서
newline 패치가 좀 이상한거 같습니다.

아래 스크립트로 테스트 했는데 테스트 메일 발송이 안되더군요.
물론 http://cr.yp.to/docs/smtplf.html 이 URL을 보라는 에러도 안나옵니다.
빌 아저씨 토스터에 있는 패치는 테스트 메일 발송이 잘 됩니다. ;)

# cat send-test-via-smtp.sh
#! /bin/bash
#
# -- shove a message through an SMTP server; Martin A. Brown
 
case "$#" in
 
   1)  SERVER=$1 ;;
   2)  SERVER=$1 && RECIP=$2 ;;
 
esac
 
ME="${USER}@${HOSTNAME}"
SERVER=${SERVER:-localhost}
RECIP=${RECIP:-${ME}}
 
echo $RECIP
 
{
cat <<-EOSMTP
HELO $( hostname )
MAIL FROM:<$RECIP>
RCPT TO:<$RECIP>
DATA
From: <$RECIP>
To: $RECIP
Subject: test message at $( date )
 
Test message at $( date )
 
.
EOSMTP
} | nc -w 9 $SERVER 25
eunjea의 이미지

지금 보니 좀 문제가 있네요.
그런데 그 스크립트로 테스트해보니 토스터 패치로 해도 "http://cr.yp.to/docs/smtplf.html" 만 나오는데요?

--
/~eunjea

다콘의 이미지

아 착각했습니다.
빌 아저씨 패치가 아니라 http://www.qmailtoaster.org 에 있는 RPM에
포함된 패치였습니다.

diff -urN knetqmail-1.06-20080402.orig/qmail-smtpd.c knetqmail-1.06-20080402/qmail-smtpd.c
--- knetqmail-1.06-20080402.orig/qmail-smtpd.c  2008-04-02 17:31:02.000000000 +0900
+++ knetqmail-1.06-20080402/qmail-smtpd.c       2008-08-09 07:15:23.000000000 +0900
@@ -103,7 +103,6 @@
 void die_nomem() { out("421 out of memory (#4.3.0)\r\n"); flush(); _exit(1); }
 void die_control() { out("421 unable to read controls (#4.3.0)\r\n"); flush(); _exit(1); }
 void die_ipme() { out("421 unable to figure out my IP addresses (#4.3.0)\r\n"); flush(); _exit(1); }
-void straynewline() { out("451 See <a href="http://pobox.com/~djb/docs/smtplf.html.\r\n"" rel="nofollow">http://pobox.com/~djb/docs/smtplf.html.\r\n"</a>); flush(); _exit(1); }
 
 void err_size() { out("552 sorry, that message size exceeds my databytes limit (#5.3.4)\r\n"); }
 void err_bmf() { out("553 sorry, your envelope sender has been denied (#5.7.1)\r\n"); }
@@ -763,23 +762,14 @@
   int flagmaybex; /* 1 if this line might match RECEIVED, if fih */
   int flagmaybey; /* 1 if this line might match \r\n, if fih */
   int flagmaybez; /* 1 if this line might match DELIVERED, if fih */
-  int seencr;
 
-  state = 1;
+  /* NEWLINE: We start in state 2 now, instead of state 1. */
+  state = 2;
   *hops = 0;
   flaginheader = 1;
   pos = 0; flagmaybex = flagmaybey = flagmaybez = 1;
   for (;;) {
     substdio_get(&ssin,&ch,1);
-    if (ch == '\n')
-     {
-      if (seencr == 0)
-       {
-        substdio_seek(ssin,-1);
-        ch = '\r';
-       }
-     }
-    if (ch == '\r') seencr = 1; else seencr = 0;
     if (flaginheader) {
       if (pos < 9) {
         if (ch != "delivered"[pos]) if (ch != "DELIVERED"[pos]) flagmaybez = 0;
@@ -789,36 +779,42 @@
         if (flagmaybex) if (pos == 7) ++*hops;
         if (pos < 2) if (ch != "\r\n"[pos]) flagmaybey = 0;
         if (flagmaybey) if (pos == 1) flaginheader = 0;
+       /* NEWLINE: Header may end on \n now, too. */
+        if (pos == 0) if (ch == '\n') flaginheader = 0;
        ++pos;
       }
       if (ch == '\n') { pos = 0; flagmaybex = flagmaybey = flagmaybez = 1; }
     }
     switch(state) {
+      /* NEWLINE: New state machine to allow both \n and \r\n */
       case 0:
-        if (ch == '\n') straynewline();
-        if (ch == '\r') { state = 4; continue; }
+        if (ch == '\n') state = 2;
+        if (ch == '\r') { state = 1; continue; }
         break;
-      case 1: /* \r\n */
-        if (ch == '\n') straynewline();
-        if (ch == '.') { state = 2; continue; }
-        if (ch == '\r') { state = 4; continue; }
+     case 1: /* \r */
+        if (ch == '\n') { state = 2; break; }
+        if (ch == '\r') break;
         state = 0;
+       put ("\r");
         break;
-      case 2: /* \r\n + . */
-        if (ch == '\n') straynewline();
-        if (ch == '\r') { state = 3; continue; }
+      case 2: /* \n or \r\n */
+        if (ch == '.') { state = 3; continue; }
+        if (ch == '\r') { state = 1; continue; }
+        if (ch == '\n') break;
         state = 0;
         break;
-      case 3: /* \r\n + .\r */
+      case 3: /* \n or \r\n   . */
         if (ch == '\n') return;
-        put(".");
-        put("\r");
         if (ch == '\r') { state = 4; continue; }
         state = 0;
         break;
-      case 4: /* + \r */
-        if (ch == '\n') { state = 1; break; }
-        if (ch != '\r') { put("\r"); state = 0; }
+      case 4: /* \n or \r\n  . \r */
+        if (ch == '\n') return;
+        put (".");
+        put ("\r");
+        if (ch == '\r') { state = 1; continue; }
+        state = 0;
+        break;
     }
     put(&ch);
   }
eunjea의 이미지

수정해서 knetqmail-1.06-20080815 로 올렸습니다.
감사합니다.

http://qmail.kldp.org/phpbb/viewtopic.php?t=7694

원래 주제와는 완전히 다르게 버그 패치가 되었네요. ;-)

--
/~eunjea

웃는 남자의 이미지

회사에서 A사 스팸필터링 장비를 쓰고 있는데요
이 솔루션이 사용하는 메카니즘과 운용방식이 합리적인 것 같습니다
대충 작동방식을 훑어보면

1. 제일 먼저 악성코드/바이러스/고의적인 대량메일(DoS메일)들은 서버단에서 사전방역으로 최우선 차단

2. 수신자 메일주소에 따라 각 사용자별로 설정된 whitelist / blacklist 를 적용합니다.

3. 2번에 해당하지 않는 메일은 다시 복합적인 스팸필터링을 통해 스팸으로 분류합니다.
SPF (Sender Policy Framework)
SDR (Sender Domain Resolve)
DKIM (Domainkeys Identified Mail)
RBL (Realtime Blackhole List)

4. 이후 최종적으로 걸러지고 남은 메일은 사용자에게 배달됨

5. 각 사용자별로 자신에게 온 스팸메일리스트를 하루에 한번씩 각 사용자들에게 알림메일을 배달.
사용자는 자신에게 온 스팸메일리스트를 보고 재배달처리 여부 결정, ip/이메일주소/ 키워드별로 white/black list 를 적용하는 것이 가능
1번에서 걸러진 메일은 여기에서는 사용자에게 보여주지는 않습니다
이 단계에서 사용자에게 서버단에 오탐으로 잘못 걸러진 메일을 재처리할수 있는 기능이 제공되므로
개인화된 스팸필터적용이 가능합니다.

위와 같은 방식으로 운용된다면 서버단/사용자단에 어디에서 스팸필터를 할 것이냐라는 고민은 덜 수 있죠
1. 사용자단에서 별도로 스팸필터를 사용할 필요가 없어지구요
2. 서버단에서 걸러지더라도 사용자에게 스팸메일을 선택적으로 재처리할 수 있는 기능을 제공해주는것

Nothing left after Nirvana.

----------------------------------------
Nothing left after Nirvana.

brucewang의 이미지

추천~
-------------------------------------------------
$yes 4 8 15 16 23 42

-------------------------------------------------
$yes 4 8 15 16 23 42

ptmono의 이미지

최소한 이런 메일은 걸렀으면 좋겠어요.

오늘본 메일을 내일 또 본다.
5일간 꾸준히 본 뒤 필터링을 결정한다.

메일 발신자는 메번 바뀐다.
광고하는 홈페이지 주소도 매번 바뀐다.
광고하는 용어도 매번 바뀐다.
(바키라, 바.키라, 바키.라, 바~키라,바/.키라)

나는 매번 똑같은 내용의 광고를
"[RE]급함"
"어제는 왜 그랬니?"
등의 제목으로 열어본다.

나로서는 어쩔 수가 없다... 저주스런 스팸...
혹시 물건을 사면 보내지 않으려나...

------------------------------------------
emacs user

------------------------------------------
emacs user

bh의 이미지

스팸 판단은 최종사용자(end-user)에게 맡겨야 한다는데에 한표입니다..

--
이 아이디는 이제 쓰이지 않습니다.

oldbell의 이미지

하루에 수십만통이상을 받는 메일서버 관리자 입장에서는 필터링이 선택사항이 아닐겁니다.
(더구나 흑자도 가끔나는 직원수 100여명의 회사에서 여러대의 메일서버는 기대하기 어렵습니다.)
스팸으로 인한 메일서버의 부하뿐 아니라 바이러스의 유통으로 인한 유지보수 또한 만만치 않습니다.
그래서 강력한 스팸처리를 선호하게 됩니다.

더우기 그 많은 스팸에 대한 적절한 대처(POP3 이용, Client 에서 스팸처리등)법을 잘 모르는 직원들이
대부분인 곳에서는 더욱 그렇습니다. (대부분 웹메일을 그대로 씁니다. ㅠ.ㅠ)

인생의 무게를 느껴라. 아는 만큼 보이는게다.

pcharley의 이미지

이 역시 정책이 우선 확립이 되야겠지만, 회사라면 smtp 단에서 강력한 필터링 정책 필요하다고 생각합니다.
모두를 만족할 수 없다면 다수에 피해자가 생기지 않는 방향으로 가는게 옳다고 봅니다.
그리고 회사라면 회사 자원 낭비 및 보안, 기타 불필요한 인력 낭비등도 고려되야 하겠죠...

frenzy의 이미지

개인에게 메일에 대한 모든권한을 줘야 하는 것이 맞다고 생각합니다.
프로그램은 이러한 권한을 쉽게 행사할 수 있도록 도와줘야 되고요~~~

메일시스템은 베이시안, spf, rblsmtpd 등등의 다양한 기능들을 개인의 통제하에 두도록 하고,
쉽게 작동시킬 수 있도록 하는 것이 가장 좋은 방법인것 같습니다.
+
++++++++++++++++++++++++++++++++++++++++++++++
혼자놀기의 도사가 되리라... http://geeklife.co.kr

.
++++++++++++++++++++++++++++++++++++++++++++++
혼자놀기의 도사가 되리라... http://geeklife.co.kr

이은태의 이미지

자신이 받은 메일은 받은 사람에게 선택할 수 있게 권한을 줘야 하는게 맞다고 봅니다.

IRONP??? 사용인데,
일단 걸러주고; 걸러진 스팸중에서 1시간에 한번 정도 받아보고 싶은 것을 선택할 수 있게 따로 email 로 알려줍니다.

:-)

:-)

playhop의 이미지

사용자가 모든 걸 핸들링 하게 해야 하는게 맞지만,

이것이 사내 메일 이라면. (제조업체 내지...) 서비스 제공자(전산실에서) 관리 해야 한다고 봅니다.

업무적인 메일 데이타라면 당연히 관리가 되어야 하지만 (메일 데이타를 보고 있노라면 동영상 및 개인적인 놀이 데이타가 넘 많네요).

이것 저것 서비스 유지 비용에 데이타 공간, 그리고 백업 공간의 비용 따지자면... 이것도 만만치 않은것 같습니다..

또 밀어야 하나 아니 이제 인생 자체를 밀어야 한다..... IT 관두는 젖비린내 SE (/ㅡ_-)/~

sblade의 이미지

악의적 공격이 분명한 스팸들을 제외하면 어떤 형태로든 사용자에게 배달해 주는 게 옳은 것 같습니다. 대신 Inbox 에 저장하지 않고 각 사용자의 spam 디렉토리에 저장되게 하면 spam 도 보고 싶은 사람은 그 디렉토리를 뒤적거리면 되죠. 그리고 오래 된 spam들은 정기적으로 제거해주면 되구요.

만약 Bayesian filtering 을 사용한다면, MissedSpam 과 NotSpam 디렉토리를 만드는 것도 고려할 만 합니다. Inbox 에 있는 메일 중 스팸인데 스팸필터가 놓쳤다고 판단한 애들을 MissedSpam 으로 사용자가 직접 넣어 주거나, spam 디렉토리에 있지만 spam 이 아닌 애들을 NotSpam 디렉토리에 넣어 주면 training set 을 사용자별로 관리하는 것도 가능하고, 스팸 필터의 품질을 점진적으로 높일 수 있겠죠.

제 학교의 메일 시스템이 이런 식인데 매우 만족하고 있습니다.

dcmru의 이미지

글과는 상관없는 질문이 될 수 있을것 같지만, 메일서버를 운영중인데, smtp 하나로만 운영중입니다.

스팸은 거의 막지못하고 있는데요. sendmail conf 파일에서 제목만 몇개 막고 있습니다.

그리고 access 에 메일주소로 reject 로 등록을 하는데요. 주소가 계속 바뀌기 때문에 별소용이 없는것 같습니다.

스팸은 주로 freeware 툴로 쓸만한 것이 무엇인가요? qmail 을 써서 다른툴과 병행하여 쓴다는데, 아직 잘 모르겠습니다.

다행이 qmail.kldp.org 를 한 번 훑어 봐야겠네요.

그리고 몇백통이나 되는 메일이 한꺼번에 보내지는 경우가 있습니다. DoS 공격 비슷한데요.

제목은 주로 return 메일로 들어오구요...

이러한 경우도 어떤툴을 써야할까요?
-------------------------------------------------------
노력만이 살길이다.

노력만이 살길이다.

taesachi의 이미지

클라이언트가 광고기획사라면...
광고라는 문구가 포함된 메일이 주로 수신될겁니다.
또한 주 거래처들로부터 해당 메일이 많이 수신될텐데요...
이 경우... 기계적판단... 예컨데 spam assassin 같은 것들의 로직으로 판단하면 100% 스팸처리가 됩니다.
클라이언트에게는 대단히 중요한 메일임에도 불구하고 말이죠...
이러한 예들은 많습니다.
광고기획사... 성인물품 판매회사... 룸or나이트클럽... 등등등 말이죠...
그나마 다행인것은 이러한 업체에서 메일을 사용하는 사용자들은 자신들이 뭘 해야하는지 알고 있다는겁니다.
따라서 사용자들의 접근성을 열어줘야합니다.
사용자가 100% 수신을 원할경우 MTA단이건... MDA단이건 간에 100% 메일박스에 넣어줘야 한다고 생각합니다.

그래서 저는 기계적 판단은 보조도구이고... 사용자 단에서 이 기계적 판단을 컨트롤 할 수 있게 해 줘야한다고 생각합니다.
스팸에 대한 판단은 인위적 판단에 의한 처리를 하는게 낫지 않을까요? ^^

록타오가~
"호드에게 영광을~~"
인형처럼 생긴 얼라이언스보다 못생겼지만... 나름대로 어려운 환경속에서 잡초처럼 자라나 새로운 문명을 꽃피운 호드에게 정이 가는건 비단 나 하나뿐일까?

록타오가~
"호드에게 영광을~~"
인형처럼 생긴 얼라이언스보다 못생겼지만... 나름대로 어려운 환경속에서 잡초처럼 자라나 새로운 문명을 꽃피운 호드에게 정이 가는건 비단 나 하나뿐일까?