simscan

목적
Qmail-scanner(perl)에 비해 c로 작성된 simscan 의 성능 테스트 및 장단점
perl scanner 사용시 서버의 로드가 많이 높아지는 부분을 해소해 보고자 함

다운로드 위치
http://sourceforge.net/projects/simscan/
필요한 것들
Ripmime(첨부파일을 필터링 하고자 한다면 필요하다)
Qmail-queue패치
Clamav(바이러스메일 체크)
Spamassassin
Trophie(or sophie)-옵션으로 설치 가능

– 설치 –
위의 다운로드 위치에서 소스를 다운로드 받는다.
먼저 clamav와 spamassassin을 설치하도록 한다.
simscan소스를 풀고 소스 디렉토리로 이동

 

Shell# groupadd simscan
Shell# adduser –g simscan –r –d /var/qmail/simscan –M –s /sbin/nologin simscan

Shell# ./configure 필요 옵션
Shell# make
Shell# make install-strip

 

 

옵션 설명
–enable-user=유저명 (simscan을 유저를 셋팅한다. 기본값으로 simscan)
–enable-clamav=y|n (clamav 를 이용한 스캐닝. 기본값으로 y 이다.)
–enable-clamdscan=clamdscan의 PTAH
–enable-custom-smtp-reject=y|n (바이러스 이름을 포함하여 리턴 메시지를 보내도록한다)
주의 – 위의 옵션을 사용하기 위해서는 소스디렉토리/contrib/qmail-queue-custom-error.patch 의 패치를
Qmail에 해주어야 한다. 또한 나중에 설명되는 옵션중에 하나인 –enable-dropmsg 의 값이 y이면 안된다.)
–enable-per-domain=y|n ( 많은 도메인에 대해서 메일서비스를 하고 있으며 각각에 대한 simscan 의 설정을
하고자 한다면 y를 택하도록 한다.)
–enable-attach=y|n ( 첨부파일에 대해서 체크를 할 것인지의 여부를 정한다. /var/qmail/control/ssattach 파일안에 필터링할 파일명이나 확장자를 넣어주면 된다.)
–enable-spam=y|n (스팸메일에 대한 필터링을 할 것인지에 대한 옵션이다. 스팸어세신에 의해서 status 가 YES인 메일에 대해서는 반송을 하게 될것이다.)
–enable-spam-passthru=y|n ( 스팸 어세신에서 붙은 status값을 무시하고 그냥 통과시키고자 할 경우에 사용한다. 이는 나중에 procmail 이나 maildrop으로 스팸 편지함이나 별도의 디렉토리에 스팸 메일을 저장하고자 한다면 유용하게 사용될 수 있을 것이다.)
–enable-spam-hits=점수 (기본값으로 10 이 셋팅되며 스팸 어세신에서 정한 값을 넣으면 될 것이다.)
–enable-spamc=PTAH (spamc 바이너리파일의 위치를 잡아준다. 자동으로 잡을것이다…^^)
–enable-spamc-args (spamc 에 필요한 옵션을 지정할 수 있다. 필자의 경우에 퍼포먼스를 위해 spamd 를 소켓을 사용하게 하였으며 소켓의 위치는 /tmp/spamd 였다, 쌍따옴표로 지정한다는 점에 주의 하라)
Ex) –enable-spamc-args=”-U /tmp/spamd”
–enable-dropmsg=y|n (스팸 메일에 대한 메시지를 sender 에게 보내지 않겠다는 옵션이다.)
–enable-quarantinedir=디렉토리위치( 스팸,바이러스 메일을 따로 저장해둘 디렉토리를 지정한다)
–enable-received=y|n ( 메일헤더에 received를 추가할 것인지에 대한 옵션이다. 버전정보 및 처리시간이 기록되어진다.)

-필자의 경우의 configure
./configure –enable-spam –enable-per-domain –enable-attach –enable-received=y –enable-spamassassin-path=/usr/bin/spamassassin –enable-spam-hits=5.1 –enable-spamc-args=”-U /tmp/spamd”

컴파일 및 설치가 완료 되었다면 이제 큐메일의 run 파일을 고치도록 한다.
필자의 run 파일의 내용이다.

#!/bin/sh
QMAILQUEUE="/var/qmail/bin/simscan"
#QMAILQUEUE="/var/qmail/bin/qmail-scanner-queue.pl"
export QMAILQUEUE
Q_UID=`id -u qmaild`
Q_GID=`id -g qmaild`
exec /usr/local/bin/softlimit -m 55000000 /usr/local/bin/tcpserver -vHRl 0 -x /etc/tcp.smtp.cdb -u $Q_UID -g $Q_GID 0 25 /var/qmail/bin/qmail-smtpd spamgw.linuxstudy.pe.kr /bin/checkpassword /bin/true 2>&1

 

 

메일서버 재시작

메일 테스트
메일을 보내보고 도착한 메일을 열었을 때 헤더에 다음과 같은 라인이 존재하는지 확인해 보자
필자의 경우에 –enable-received=y 를 주었기 때문에
Received: by simscan 1.1.0 ppid: 18392, pid: 18393, t: 0.0957s
scanners: clamav: 0.84rc1/m:30/d:813 spam: 3.0.2
가 있으며 스팸어세신의 점수를 5.1로 주었기 때문에 아래와 같이 헤더가 추가되어 있다.
X-Spam-Checker-Version: SpamAssassin 3.0.2 (2004-11-16) on test
X-Spam-Level:
X-Spam-Status: No, score=0.4 required=5.1 tests=AWL,NO_REAL_NAME autolearn=no
version=3.0.2

메일이 위의 헤더를 가지고 있다면 정상적으로 simscan이 작동한다.

-간단Tip-
Clamav 와의 연동시 퍼미션 문제가 나올 경우에 아래와 같이 clamav 유저를 simscan 의 그룹으로 추가해 준다.
Shell# usermod –G simscan clamav

각 도메인 별 설정(simcontrol)
*enable-per-domain옵션을 주고 설치했을 경우에만 적용된다.

Shell# cat /var/qmail/control/simcontrol
postmaster@example.com:clam=yes,spam=no,attach=.txt:.com
example.com:clam=no,spam=yes,attach=.mp3
:clam=yes,spam=yes,spam_hits=20.1
Shell#/var/qmail/bin/simscanmk

첨부파일 필터링

Shell# cat /var/qmail/control/ssattach
.exe
.jpeg
.pif
.scr
.vbs

 

 

Qmail-scanner 와 simscan 의 장단점 비교
비교는 어디까지나 필자의 경험상으로 작성된 것이면 상황에 따라 또는 설정에 따라 얼마든지 달라질 수 있다.
-테스트 방법-
A 호스트에서 웹 프로그램으로 첨부파일 100k 짜리와 함께 간단한 메시지를 100통 발송
스캐너가 설치된 B 서버의 메일 메시지에 남은 시간을 계산하여 평균값을 냈다.
로컬 전송의 수치를 기본값과 100을 주었을 때를 비교해 보았다.

Simscan Qmail-scanner 비고
메시지 처리시간 평균 1.6665 5.42134148 concurrencylocal의 기본값 사용
메시지 처리시간 평균 1.8093 5.25143428 Concurrencylocal값 100사용
로그 파일 별도 로그가 없음
smtp로그에 같이 남음 별도 로그 남기기 쉬움 Simscan의 경우에 별도로 sender 의 아이피 정보나 기타 필요한 정보를 따로 저장하지 않기 때문에 소스를 수정하던지 다른 방법으로 자동 필터링 시스템을 생각해야 할 것 같다.

전체적으로 c 로 작성된 simscan이 메시지 처리 능력에서는 다소 앞선 듯 보이기는 한다.
하지만 qmail-scanner 의 경우에는 perl로 작성되어 있어서 원하는 대로 쉽게 수정이 가능하다는 장점이 있을것이다.

Mysql 튜닝정보

mysql 관련하여 가장 간단하게 튜닝할 수 있는 버퍼관련 정보와 튜닝 관련된 내용을 적어봅니다.

내용중에 잘못된 부분이 있으면 의견 바랍니다.

먼저 mysql의 경우에 두가지의 메모리 설정이 있다는 점을 먼저 알아둬야 합니다.
mysql의 경우 global 변수와 session 변수(또는 thread 변수) 두 가지 변수로 메모리를 컨트롤 합니다.
척 보면 아시겠지만 global 변수의 경우 mysql 데몬이 구동이 되면서 설정하는 변수들이며
session변수(per thread변수)는 client 가 접속할 때 마다 부여가 되는 변수 입니다.
따라서 메모리를 적절하게 부여하지 않으면 동시 접속시 과다한 메모리 할당으로 시스템에 문제가 발생할 수 있습니다.
자세한 변수들은 아래 페이지에서 확인할 수 있습니다.
변수 적용 범위가 both 인 경우에는 global로 설정하면 per thread변수와 같이 적용이 됩니다.
따라서 가급적으로 both인 변수들은 global 에 설정하지 말고  따로 mysql 서버에 접속하여 set 명령으로 할당하기를 권장합니다.
즉 /etc/my.cnf 에 both인 변수가 설정이 되는 경우를 주의 깊게 보시는게 좋을 것 같습니다.
1. mysql server 에 할당할 메모리 계산
global memory+(동시접속자수(max_connections* session buffers) ): 시스템에 장착된 물리 메모리의 60%~80% 이하로 설정하는것이 좋다고 합니다.
예를 들면 DB 데이터 사이즈가 5G 라고 가정하면 디스크IO 를 줄이기 위해서 DB 전체를 global 버퍼에 넣고 약 300개의 동시처리를 하겠다면 대략 global buffer(6G정도)+(300* session버퍼들의 합)을 보고 서버에 적정한 메모리도 알수 있습니다.
일단 모든 OS는 메모리가 빵빵한게 최고입니다.^^
2.  변수 및 적정값
innodb 를 위주로 설명드리겠습니다.
값들을 설정할때는 mysql서버에 접속후 show variable 과 show status(show global status,show session status) 명령으로 서버 상태를 확인하면서 적절한 값을 찾아내시면 됩니다.
가급적 mysql서버가 구동이 된지 1~2일 지나서 status들이 갱신이 되어 있는 상태에서 확인을 하시는게 좋습니다.
max_connections – mysql서버에 접속할수 있는 최대 client갯수입니다. 1번 메모리를 할당량을 참고 해서 적절한 숫자로 설정하시면 됩니다. show global status like ‘Threads_created%’; 하시면 mysql server에 최대로 생성됐던 클라이언트 수를 확인할 수 있습니다.
show status 결과중에서 Com_XXX 로 시작하는 값들은 모두 mysql 쿼리와 관련된 값이라고 보시면 됩니다.
create table,delete,insert,replace,select,show tables,show triggers,update 등등을 확인할 수 있으며
DB 서버가 읽기가 많은지 쓰기가 많은지 확인하면 됩니다.
그리고 다음으로 Handler_XXX 로 시작되는 값들은 튜닝에 중요한 정보를 제공해 주므로 반드시 한번씩 확인해보시기 바랍니다.
특히 아래의 값들은 잘 확인해 보시기 바랍니다.
* Handler_read_prev,Handler_read_rnd,Handler_read_rnd_next
위의 값들의 값이 시간에 따라서 계속 증가한다면 DB 테이블들이 설계가 잘못되어 있다고 보시면 됩니다.
특히 read_rnd 나 read_rnd_next의 경우에는 index 를 사용하지 않는 테이블들을 조인할 경우나 index key 없이 select 하는 경우등
이므로 테이블들 구조와 DB프로그램의 쿼리문들을 잘 살펴보시기 바랍니다.
* Key_xx 은 MyISAM DB와 관계 되는 값으로(Innodb에도 영향을 주는지는 확인하지 못했으니 확인부탁드립니다.)
Key_reads/Key_read_requests 를 계산해서 캐시 hit rate를 계산 할수 있습니다.
값이 높을수록 캐시가 잘되고 있다는 이야기 입니다.
Key_reads 값이 높다면 Key_buffer_size가 작다는 이야기 이므로 적당히 늘려주시면 됩니다.
* Qcache_XXX 값들은 query cache와 관계되는 값들로 아래의 값들을 유심히 확인해보시면 됩니다.
반복되는 쿼리에 대해서는 캐시에 저장했다가 응답하므로써 반응 속도도 높아집니다.
쿼리캐시 hir rate = Qcache_hits/(Qcache_hits+Com_select) 를 계산해서 100%에 근접한지 확인해보시면 됩니다.
mysql 서버를 막 시작하고 나서는 서버에 쿼리들이 실행이 안된 상태이므로 캐시히트률은 아주 작다는 점을 알아두시기 바랍니다.
서버에 DB프로그램에서 사용하는 쿼리를 계속 날려보시면 히트률이 증가하는것을 볼 수 있습니다.
* sort_buffer_size – status 값중에서 Sort_merge_passes값을 확인해서 이 값들이 계속 증가한다면 sort_buffer_size가 작다는 이야기 이므로 늘려주시면 됩니다. 제가 직 접확인해 본 결과 sort_buffer_size 가 커지면 디비 서버 성능이 상당히 감소 합니다.
따라서 가급적이면 global 변수보다는 session 변수로 할당을 해주시는것이 좋습니다.
Sort_merge_passes 값이 안늘어나는 상태까지 메모리를 줄여서 다른 곳에 할당해 주시면 됩니다.
ex) SET SESSION sort_buffer_size=값(my-innodb-heavy-4G.cnf 기본값이 8M입니다.)
벤치마크 테스트 결과입니다. 처리속도가 상당히 차이가 많이 납니다. QPS(query per sec)는 초당 처리한 쿼리갯수 입니다.
8M : QPS – 7506.51
32M; QPS – 4001.56
* Select_full_join, Select_range_check – show staus 결과 값이 0  이상인 경우에는 쿼리상 index 가 없이 table을 scan 하고 있다는 이야기 입니다.
따라서 이런 경우에는 반드시 테이블들이 index가 정상적으로 되어 있는지  및 DB프로그램에서 잘못된 join을 하고 있는지 확인해야 합니다.
* innodb_buffer_pool_size(global) – innodb를 위한 메모리 사이즈 입니다. DB전용 서버로 사용한다면 물리적인 메모리의 80%정도까지
잡아서 사용하시면 됩니다. 메모리에 모든 DB가 올라가 있는 경우 DB 데이터에 엑세스 할때 disk I/O를 최대한 줄일 수 있습니다.
아래는 테이블 레코드 1000만건에 대한 select,insert,update 시의 io 입니다. read가 0 인것을 보실 수 있습니다.
io.jpg
* innodb_log_file_size(global) – innodb는 기본적으로 buffer에서 동작을 하며 모든 입출력의 관한 내용은 log 파일에 남기고
로그 파일이 모두 차면 실제 DB데이터 파일인 ibdataX 에 기록을 합니다. 따라서 로그 파일이 작으면 ibdata파일에 기록하는 횟수가 증가하게 됩니다. 사이즈를 키우면 IO를 줄일 수 있으나 사이즈가 커지면 디비가 크래시 됐을때 복구하는 시간이 길어집니다.
적당한 계산법은 사이트들 마다 조금씩 다릅니다만  innodb_buffer_full_size 의 25% 정도 설정하라고들 합니다.
* key_buffer_size(global) – MyISAM 테이블의 index 블럭 사이즈 입니다. MYISAM 만 사용한다면 서버의 물리적인 메모리에서 25%정도 할당하시면 됩니다. 이 값은 너무 크게 설정하시면 디비가 시작할때 디비를 읽으면서 페이징을 하게 되어 시간이 오래 걸리면서 시작이 됩니다.
* table_cache(global) – 모든 스레드에서 열린 테이블의 갯수 입니다. show status 결과중에서 opened_tables 값이 계속 증가하거나  flush tables 명령을 가끔 내리는 경우라면 table_cache 변수를 늘려주시면 성능 향상에 도움이 됩니다.
* thread_cache_size(global) – 쓰레드를 재사용하기 위한 값입니다. 클라이언트가 DB접속을 종료하더라도 쓰레드를 종료하지 않고 캐시에 저장하여 재사용하게 됩니다. 쓰레드생성비용을 줄일 수 있습니다. 접속이 많은 경우라면 아래와 같이 계산해서 캐시 효과를 누릴 수 있습니다.
쓰레드 캐시 히트률 계산 = 100-((Threads_created/Connections)*100)
* query_cache_size(global) – 쿼리 결과를 캐싱하기 위한 메모리양 입니다. 기본값으로 0  으로 잡혀 있으며 query_cache_type 이 0(캐시를 하지 않음)으로 되어 있어도 메모리는 할당됩니다.
* max_heap_table_size(session) – heap테이블 사이즈를 지정합니다.
* tmp_table_size(session)  –  임시테이블 사이즈를 지정합니다.
위의 두 값은 disk IO와도 밀접한 관계가 있습니다. 기본적으로 heap,temp 테이블은 메모리에 생성하지만 사이즈가 초과되면 디스크에 생성하게 됩니다. created_tmp_disk_tables 와 created_tmp_tables 값으로 설정이 가능합니다.
* read_buffer_size(session) – 쓰레드당 full tables scan 을 하는 경우에 사용함.
큰 테이블이 많거나 범위에 대해서 scan 하는 경우 적당한 값으로 늘려줌
* join_buffer_size(session) – index 를 타지 않는 join할 경우에 사용함. 기본적으로 index없이 join하는 경우는 자제해야 하므로
쿼리를 수정하는 것이 나을듯 합니다.

Suricata를 이용한 IDS/IPS 구축하기

Suricata란?

Suricata is a high performance Network IDS, IPS and Network Security Monitoring engine. Open Source and owned by a community run non-profit foundation, the Open Information Security Foundation (OISF). Suricata is developed by the OISF and its supporting vendors.

대충 요약하자면 OISF에서 개발되어진 고성능의 네트워크IDS,IPS,NSM 엔진이라는 이야기다.
정말 고성능인지는 각자 테스트 해보기를 바란다.
10Gbps트래픽에서 9000개의 룰로 운영되는 suricata IDS 시스템에서 약 4%의 packet drop 만 생기도록 구성한 사례들도 있다.

 

용어정리
*IDS – Intrusion detection system(침입탐지 시스템)
*IPS – Intrusion prevention systems(침입방지 시스템)

사전준비

suricata는 다양한 OS를 지원한다. 필자의 경우 CentOS6 Linux 시스템에 설치하였다.
리눅스를 이용해서 쓸만한 IDS/IPS시스템을 구축해 보도록 하자.
  • OS: CentOS6.6
  • Network Card:2EA 이상(단독 서버에서만 구동한다면 1개여도 상관은 없다)
  •  적절한 사양의 PC 또는 서버(실제 운영해 보면 알겠지만 트래픽에 따라 메모리나 CPU사용이 제법 많이 필요한 경우가 많다)

설치

  1. EPEL repository추가
    rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
    
  2. 소스빌드를 위한 기본 패키지 설치
    yum -y install libpcap libpcap-devel libnet libnet-devel pcre \ pcre-devel gcc gcc-c++ automake autoconf libtool make libyaml \ libyaml-devel zlib zlib-devel file-devel
    

     

     

  3. IPS mode(NFQUEUE) 지원을 위한 패키지 설치
    나중에 다시 설명하겠지만 suricata 를 IPS모드로 동작하는 방법은 리눅스에서는 2가지 방법이 있다.
    Netfilter queue를 이용하는 방식(iptables)과 AF_PACKET를 이용하는 방식이 있다.

    yum -y install libnetfilter_queue libnetfilter_queue-devel \
    libnfnetlink libnfnetlink-devel
  4. Suricata build & install

    wget http://www.openinfosecfoundation.org/download/suricata-2.0.8.tar.gz
    tar -xvzf suricata-2.0.8.tar.gz
    cd suricata-2.0.8
    ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var 
    make 
    make install-full
  5. 기본환경설정 확인 및 수정
    suricata 환경설정 파일은 기본적으로 /etc/suricata/suricata.yaml에 위치하고 있다.
    몇 가지 중요한 부분들을 수정하여 사용하도록 하자

    • host-mode:auto(suricata가 설치된 호스트를 IDS 모드 또는 IPS 모드로 사용할 것인지 지정한다)

      침입탐지용으로만 사용한다면 sniffer-only, 침입방지용으로 사용한다면 router로 지정해주면 된다.보통은 그냥 auto모드로 두고 데몬을 구동할 때 옵션으로 설정하는 경우가 많다.

    • pid-file: /var/run/suricata.pid(suricata 데몬의 pid 위치를 지정한다)
    • default-log-dir: /var/log/suricata/ (로그 디렉토리 설정)
    • ouputs: (로그 저장에 관련된 설정들이 들어있다.특히 나중에 mysql같은 데이터베이스에 로그를 남기고자 한다면 barnyard2 를 이용하여 남길 수 있다.이런 경우 unified2 형태로 로그를 남겨야 한다.)
    • drop: (IPS모드로 구동할때 룰에 의해서 drop된 로그를 저장하게 한다.)
    • af-packet: (IPS모드 중 하나인 af-packet 모드로 사용하고자 하는 경우 옵션들이다.)
    • cuda: (nvidia GPU을 이용해서 패킷 처리를 가속하기 위한 옵션이다.)
    • default-rule-path: (룰 파일의 위치를 지정한다.)
    • vars: (suricata 엔진에서 사용할 환경변수들이다. 이 변수들을 이용해서 룰파일에서도 사용한다.)
  6. 테스트 룰 삽입
    vi /etc/suricata/rules/drop.rules
    alert icmp 핑을 날릴호스트의 IP주소 any -> any any (msg:"ALERT test ICMP ping";
     icode:0; itype:8; classtype:trojan-activity; sid:99999998; rev:1;)
    192.168.2.126호스트에서 suricata로 ping 을 날리면 로그에 남는다
    alert icmp 192.168.2.126 any -> any any (msg:"ALERT test ICMP ping";
     icode:0; itype:8; classtype:trojan-activity; sid:99999998; rev:1;)

     

  7. suricata 실행 및 확인
    일단 기본적으로 IDS 모드로 구동해 본다.
    -i 다음에는 패킷들을 처리할 인터페이스를 넣어주도록 한다.

    suricata -c /etc/suricata/suricata.yaml -i eth0

    아래의 init파일을 /etc/init.d/suricata로 복사해두고 데몬 제어를 하는것이 편할 것 이다.
    suricata_init

리눅스 배워보기

필자가 리눅스를 배우고 다루면서 느낀 몇 가지 조언을 해보고자 한다.

흔히들 처음 리눅스 하면 배우기 어렵고 난해하다고 생각할지도 모르겠지만 필자가 보기에는 리눅스 만큼
쉽고 매력적인 OS는 아마 없지 않나 싶다.
리눅스를 한번도 다뤄본적이 없는가? 아니다 이미 당신은 리눅스를 사용하고 있을지도 모른다.
휴대폰,PDA,인터넷 공유기,방화벽,라우터 등등 수많은 시스템에 리눅스가 적재가 되어 있다.^^;

* 무작정 일단 해봐라.
실제로 경험만큼 좋은 스승은 없다고 하지 않았는가!
예전에 컴퓨터는 깡통이다라는 책이 기억이 난다. 그렇다 컴퓨터는 단순한 기계다. 그 기계는 우리에 의해서 동작한다. 일단 마음껏 이것저것 시도해 보도록 하자.
잘못된 명령으로 컴퓨터가 폭발하는 일은 절대로 없다..^^;
* 메뉴얼을 반드시 읽어보자.
유닉스 계열의 혹은 기타 모든 시스템은 각자의 매뉴얼들이 준비가 되어있다.
메뉴얼을 읽어보는 습관을 무조건 갖자. 우리 인간의 머리는 한계가 있다.
자주 쓰는 명령어도 가끔을 헷갈릴 경우가 많다.
항상 메뉴얼을 뒤적거려보는 습관을 들이도록 하자.
* 에러 메시지를 두려워 하지 말자.
리눅스를 공부하면서 수많은 에러들을 보게 될 것이다.
미리 겁부터 먹지 말자. 컴퓨터는 정확하고 인간은 실수를 하는 법이다.
잘못된 명령만이 오류를 발생시킨다.^^;
command not found – 간단하다. 명령을 찾을수 없단다. 정확히 명령을 내리던지 명령이 수행될 수있도록만 해주자. 더이상 에러는 없을 것이다.
No such file or directory – 파일이나 디렉토리를 못찾는 단다. 왜 못찾는지 한번 확인해보자.
이처럼 유닉스 계열의 시스템은 사용자와 대화를 나누려고 한다.
겁먹지 말고 시스템과 대화를 나눠보자..^^;

왜 리눅스를 사용하는가?

* 리눅스는 자유롭다
당신은 리눅스를 사용함에 있어서 어떠한 제약이 없다.
로열티를 지불하지도 라이센스 비용을 지불하지 않아도 된다.
* 다양한 플랫폼에서 동작한다
i386 기반에서만 동작하는 windows 계열들 sparc에서만 동작하는 solaris 등
특정 플랫폼에서만 동작하는 OS와는 달리 리눅스는 아주 다양한 플랫폼을 지원한다.
아래는 리눅스 커널소스에서 살펴본 arch 디렉토리다.
[root@server arch]# pwd /usr/src/linux/arch
[root@server arch]# ls
alpha avr32 cris h8300 m32r m68knommu parisc ppc sh sparc um x86 arm
blackfin frv ia64 m68k mips powerpc s390 sh64 sparc64 v850 xtensa
[root@server arch]#
생소한 cpu 들이 보이지 않는가?
이처럼 리눅스는 아주 다양한 플랫폼에서도 동작을 함으로써 많은 용도로 사용이 가능하다.

* 진정한 멀티 태스킹 시스템이다.
리눅스에서 동작하는 모든 프로그램은 개별적으로 동작을 한다.
시스템에 문제가 되는 프로세서만 간단히 제거하면 시스템은 아무 문제없는 상태로 되돌아 갈것이다. Windows xp를 사용하면서 잘쓰고 있던 워드 프로세서가 인터넷 익스플로러 때문에 먹통이 된 경험을 한적이 있는가? 안심해라 리눅스는 그럴 일이 거의 없다.

* 저사양의 시스템에서도 동작한다.
요즘은 배포판의 크기들이 커져서 꽤 많은 메모리를 요구를 하며 꽤많은 하드 디스크를 요구하지만
실제로는 여러분이 원한다면 구닥다리 486 PC 에서도 리눅스를 설치해서 사용할 있다.
심지어는 1M도 안되는 플로피 디스켓으로도 리눅스를 운영할 수 있다.
집에 쓸데없이 뒹굴고 있는 구닥다리 PC가 있다면 리눅스로 훌륭한 공유기를 만들수도 있다.^^;

어떤 배포판을 사용 할 것인가

현재 우리는 수많은 배포판을 사용할 수 있으며 당신은 당신이 마음에 드는 배포판을 선택해서 리눅스를 설치할 수 있다.
래드햇,수세,맨드레이크,칼데라,데비안,슬렉웨어,젠투,CentOS,우분투,안녕리눅스 등등 당신의 입맛에 맞는 OS를 선택할 수 있다.
배포판 별로 약간씩의 차이는 있지만 기본적인 구조들은 모두 같다고 봐도 된다.

Anti Spam for Qmail

1 Anti spam 시스템 구축하기
2 머릿말
3 어디서 부터 막을 것인가?
3.1 메일 시스템에 접근하는 단계에서의 필터링
3.1.1 rblsmtpd 를 이용
3.1.2 tcp.smtp(cdb) 이용
3.1.3 시스템의 자체 방화벽을 이용(리눅스의 경우에는 iptables)
3.1.4 qmail control파일 이용
3.2 qmail 의 Queue 에 저장되는 단계에서의 필터링
3.3 MDA 단계(사용자의 메일박스에 메시지가 도달하기전)에서의 필터링
4 유용한 Spam filtering 도구
4.1 메일 서버 접근 단계의 필터링 도구
4.1.1 rblsmtpd
4.1.2 spamdyke
4.2 qmail-smtpd or qmail-queue 단계에서의 필터링 도구
4.2.1 [http]qmail-scanner
4.2.2 [http]simscan
4.2.3 Qmail 패치를 통한 스팸 방지 기능 추가
4.3 MDA 단에서의 필터링
5 스팸 필터링의 새로운 패러다임
5.1 SPF (Sender Policy Framework)
5.1.1 qmail 에 spf 패치를 하여 필터링를 하는 방법
5.1.2 spamassassin 을 이용하여 필터링을 하는 방법.
5.2 DKIM(Domain keys identified mail)
6 맺으며

 

1 Anti spam 시스템 구축하기

  • 이글은 qmail을 이용한 메일서버를 운영중인 시스템 관리자를 위한 문서이며
    본문의 내용중에 다소 틀린 내용이 있을 수 있습니다.
  • 글에 문제가 있다면 언제라도 고쳐서 업데이트를 해주시길 바라겠습니다.^^;
  • 좋은 의견은 stone@nuxinfo.net 로 주시면 감사하겠습니다.
  • 존칭은 생략하도록 하겠습니다. 널리 이해해 주시기 바랍니다.

2 머릿말

  1. 스팸을 막을 수는 없지만 최소한 아침에 메일 정리하는 시간을 줄여보고자 이 글을 적는다.
  2. 100% 막으려 하지 말라. 머리도 아프고 당신은 원하던 메일도 못받는 경우가 생길 수 있다.
  3. 완벽히 스팸을 막고 싶은가? 당장 메일 서버의 랜선을 뽑아라!! :-)

3 어디서 부터 막을 것인가?

qmail 시스템에서 스팸 필터링 하는 과정은 크게 세 가지 정도로 구분지어 본다.(이건 어디까지나 필자의 의견이다..^^)
이번 장 에서는 전체적으로 스팸 필터링하는 과정에 대한 설명을 하고 실제 스팸필터링 도구를 이용하는것은 나중에 살펴보도록 하자.

3.1 메일 시스템에 접근하는 단계에서의 필터링

이 단계에서는 불 필요한 메일에 대한 처리 과정이 없이 smtp 서버에 접속을 막기 때문에 서버의 불필요한 자원의 낭비를 막아주는 효과가 있다.

3.1.1 rblsmtpd 를 이용

rblsmtpd 프로그램은 [http]ucspi-tcp 패키지에 포함되어 있는 프로그램으로
rbldns서버에 쿼리를 던져서 그 결과에 따라 접속 허가를 해주는 프로그램이다.
rblsmtpd 설정 예제

vi /var/qmail/supervise/qmail-smtpd/run #!/bin/sh QMAILDUID=`id -u qmaild` NOFILESGID=`id -g qmaild`rbldns=-r bl.spamcop.net -r rbl.nuxinfo.net exec /usr/local/bin/softlimit -m 100000000 \/usr/local/bin/tcpserver -vRHl0 -x/etc/tcp.smtp.cdb \ -u $QMAILDUID -g $NOFILESGID 0 smtp /usr/local/bin/rblsmtpd -t 30 -b $rbldns \ /var/qmail/bin/qmail-smtpd mail.nuxinfo.net \/bin/checkpassword /bin/true 2>&1

 

3.1.2 tcp.smtp(cdb) 이용

qmail.kldp.org 에서 열심히 활동해주시고 계시는 ironiris 님이 업데이트 하셨던 [http] 스팸서버 발송지 주소리스트 를 참조해보자.
tcp.smtp 파일을 변경하였다면 tcprules 명령으로 cdb 파일을 업데이트 하도록 한다.

  • 참고) qmail과 vpopmail을 연동한다면 ~vpopmail/etc/tcp.smtp

 

1.2.3.4(spam sender ip):deny
5.6.7.8(spam sender ip):deny
tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtp

 

3.1.3 시스템의 자체 방화벽을 이용(리눅스의 경우에는 iptables)

iptables -A INPUT -p tcp -s 스팸아이피주소 -dport 25 -j DROP

 

3.1.4 qmail control파일 이용

badmailfrom 이나 기타 스팸 필터관련 패치 이후 환경 설정 파일을 이용하는 방법.
(실제로는 qmail-smtpd 단에서 호출해서 사용하지만 일단 tcpserver 와 qmail-smtpd 중간의 과정이라 이곳에 기록한다.)

3.2 qmail 의 Queue 에 저장되는 단계에서의 필터링

먼저 큐메일의 전체적인 구조를 살펴보도록 하자.

외부에서 우리의 메일서버로 메시지가 전송되는 과정은 다음과 같다.

 tcpserver->qmail-smtpd->qmail-queue->qmail-send->qmail-lspawn->qmail-local->메일박스

큐메일 서버의 전달 과정을 보면 알겠지만 모든 메일 메시지는 qmail-queue에 의해서 메시지가 처리된다.

queue_patch 이후에 메시지 전달 과정
tcpserver->qmail-smtpd->임의의 필터링 프로그램(or qmail-queue)->qmail-send->qmail-lspawn->qmail-local->메일박스

 

3.3 MDA 단계(사용자의 메일박스에 메시지가 도달하기전)에서의 필터링

.qmail 을 이용한 메시지 처리
procmail 예제.

cat .qmail 
|/var/qmail/bin/qmail-quota
|/var/qmail/bin/preline /usr/bin/procmail -p -m /home/webmail/nuxinfo.net/stone/.procmailrc

 

cat .procmailrc PATH=/bin:/usr/bin:/usr/local/bin DEFAULT=/home/webmail/nuxinfo.net/tttt/Maildir/MAILDIR=/home/webmail/nuxinfo.net/tttt/Maildir/ LOGFILE=/var/log/qmail/procmail VERBOSE=no SHELL=/bin/sh:0 Efhw *^(Subject|From|Cc):.*=\?EUC-KR\?(B|Q)\? |formail -c | hcode -dk -m :0 Efhw*^(Subject|From|Cc):.*=\?ks_c_5601-1987\?(B|Q)\? |formail -c | hcode -dk -m

 

4 유용한 Spam filtering 도구

여기서 소개하는 스팸 필터링 도구는 일반적으로 많이 사용된다고 생각되는 것으로
각각의 취향에 맞게 구축해볼것을 권유한다.

4.1 메일 서버 접근 단계의 필터링 도구

4.1.1 rblsmtpd

메일서버에 접속하는 클라이언트 아이피가 rbldns 서버에 등록되어 있는 IP 인지 여부를 판단하여
등록되어 있을 경우에는 rbldns서버에 기록되어진 반송 메시지와 함께 반송을 한다.
rblsmtpd에 대한 자세한 내용은 [http]rblsmtpd한글 메뉴얼을 살펴보도록 하자.

rblsmtpd 를 설정했을때의 qmail-smtp로그 파일의 내용이다.(필자는 현재 spamcop.net 과 필자가 직접 구축한 rbldns 를 이용하고 있다.)

@4000000046c8b4dc2e44d74c rblsmtpd: 61.183.0.8 pid 1601: 553 Blocked - see http://www.spamcop.net/bl.shtml?61.183.0.8
@4000000046ca90a91a7ab984 rblsmtpd: 72.237.208.57 pid 23522: 553 Your IP is Blocked, see http://spamlist.nuxinfo.net/lookup?72.237.208.57

 

rblsmtp 설정하기
/var/qmail/bin/qmail-smtpd/run 파일에 아래와 같이 rbldns 서버의 주소를 추가해 준다.

  • 참고 -r 은 블럭리스트 -a는 white 리스트임.

안타깝게도 rbldns서버들이 예전에는 많았지만 지금은 많이 유료화 되었다.
우리나라에서는 [http]kisa에서 무료로 rbldns서버를 운영하고 있다.

exec /usr/bin/softlimit -m 66000000 \
/usr/bin/tcpserver -vRHl0 -x/etc/tcp.smtp.cdb \
-u "$QMAILDUID" -g "$NOFILESGID" 0 smtp /usr/bin/rblsmtpd \
-t 30 -b -a white.nuxinfo.net \
-r bl.spamcop.net \
-r rbl.nuxinfo.net \
/var/qmail/bin/qmail-smtpd nuxinfo.net  /bin/true 2>&1

참고) 이운억님께서 작성하신[http]local rbldns구축하기

4.1.2 spamdyke

– rblsmtp 처럼 tcpserver 와 qmail-smtp 사이에서 IP레벨의 다양한 필터 설정을 할 수 있는 통합(?)툴이다. 또한 패키지에 들어있는 몇몇 유틸리티들은 다양한 기능들을 제공해주고 있다.

– 먼저 소스를 [http]spamdyke다운로드 한다.

받은 소스를 압축을 해제하고 소스디렉토리에서 make 명령을 실행하여 spamdyke 실행파일 생성
적당한 위치에 파일을 복사(/var/qmail/bin/spamdyke)
qmail-smtpd/run 파일 수정

wget http://www.spamdyke.org/releases/spamdyke-2.6.3.tgz
tar xvfz spamdyke-2.6.3.tgz
cd spamdyke-2.6.3/spamdyke
make
cp spamdyke /var/qmail/bin/
vi /var/qmail/supervise/qmail-smtpd/run

 

예제)spamdyke 를 포한한 smtpd run파일 내용

exec /usr/bin/softlimit -m 66000000 \ /usr/bin/tcpserver -vRHl0 -x/etc/tcp.smtp.cdb \ -u $QMAILDUID -g$NOFILESGID 0 smtp \ /var/qmail/bin/spamdyke -a 30 /var/qmail/bin/qmail-smtpd nuxinfo.net /bin/true2>&1

위의 예제는 spamdyke 의 많은 옵션 중 에서 한번 접속당 recipients 수를 지정한 경우다.
이외에도 아주 많은 기능을 제공하니 [http]www.spamdyke.org를 참고하도록 한다.

4.2 qmail-smtpd or qmail-queue 단계에서의 필터링 도구

qmail 의 queue 단계에서의 필터링은 반드시 qmail의 queue 패치를 해주는게 좋다. 물론 queue 패치없이도 필터링이 불가능 한것은 아니다.
약간의 꼼수겠지만 qmail-queue 바이너리 파일의 이름을 변경하고 다른 프로그램으로 대체하는것이다.
먼저 [http]netqmail-1.05를 사용중이라면 별도의 패치가 필요없을 것이다. 이미 queue 패치가 이루어진 버전이다.
qmail-1.03 버전을 사용한다면 반드시 패치를 해주도록 하자.

Qmail-queue 단계에서의 필터링을 위한 기본 구성.
먼저 qmail-smtpd 에 QMAILQUEUE라는 환경변수를 통해서 기본 큐 프로그램인 qmail-queue 를 다른 프로그램으로 전환한다.
둘중에 편한 방법을 선택하도록 한다.

  • run 파일에서 환경 변수 지정.

 

QMAILQUEUE=qmail-queue 를 대신할 다른 프로그램(ex. /var/qmail/bin/qmail-scanner-queue) export QMAILQUEUE exec/usr/bin/softlimit -m 66000000 \ /usr/bin/tcpserver -vRHl0 -x/etc/tcp.smtp.cdb \ -u $QMAILDUID -g$NOFILESGID 0 smtp /usr/bin/rblsmtpd -t 30 \ -b $rbl /var/qmail/bin/qmail-smtpd nuxinfo.net /bin/true2>&1

 

  • tcp.smtp파일을 변경하는 방법.

 

cat /etc/tcp.smtp
127.0.0.1:allow,RELAYCLIENT="",QMAILQUEUE="/var/qmail/bin/qmail-scanner-queue"
:allow,QMAILQUEUE="/var/qmail/bin/simscan" 

 

4.2.1 [http]qmail-scanner

perl 로 제작된 대표적인 content 필터링 도구임. 다양한 다른 필터링 모듈(ex. clamav,spamassassin,etc)들을 추가할 수 있는 장점과 perl 로 제작되어 있기 때문에
시스템 관리자의 입맛대로 고쳐서 사용할수 있는 장점이 있다.
참고.)qmail-scanner-1.x 버전과 2.x 버전에서는 기본 설치 디렉토리가 /var/spool/qmailscan 에서 /var/spool/qscan 으로 변경이 되었다.
필터링 정의 파일의 이름도 변경이 되었으니 참고 하기 바란다.

  • 설치 및 사용 방법
    소스 다운로드 후 압축해제
    qmail-scanner 를 위한 사용자 추가
    컴파일 및 설치
    환경 설정

     

    $ groupadd qscand
    $ useradd -c "Qmail-Scanner Account" -g qscand  -s /bin/false qscand
    $ configure --install yes
    

    설치가 마무리 되었다면 /var/qmail/bin/qmail-scanner-queue.pl -g 명령으로 DB를 생성해 주면 된다.

* qmail-scanner 환경 파일 설정하기 및 적용
앞에서도 이야기 했지만 qmail-scanner 1.x 버전과 qmail-scanner 2.x 버전은
스팸 필터링 정의 파일도 변화가 생겼으니 참고하기 바란다.
(quarantine-attachments.txt -> quarantine-events.txt)
필자는 2.x 버전을 기준으로 설명하겠다.
필터링 정의 파일 만들기
이제 우리는 qmail-scanner 만을 가지고 바이러스 메일과 스팸 메일을 필터링 해 볼 것이다.
qmail-scanner 는 quarantine-events.txt 에 스팸에 대한 규정을 적고 DB 형태로 만든 다음
메일서버에 들어오는 메시지와 비교를 해서 룰에 맞으면 걸러주는 형태로 동작을 한다.
따라서 스팸 필터링 정의에 대한 규칙을 이해하는 것이 중요하다.
quarantine-events.txt 을 열어보면 예제에 대한 상세한 내용들이 있으니 좀 더 살펴보도록 하자.
기본적으로 Qmail-scanner의 스팸 필터링 정의 파일은 탭으로 구분된 3개의 필드로 이루어져 있다.
파일명(또는 문자열)<TAB>파일사이즈(또는 메일헤더)<TAB>설명

예제)quarantine-event.txt

# 첨부 파일에 mp3가 첨부되어 있다면 필터링 하겠다는 룰이다. SIZE에 -1 되어 있다면 사이즈에 관계없이 필터링 하라는 룰이 된다.
.mp3 SIZE=-1 mp3 disallowed

# 첨부파일에 .doc 가 첨부되어 있고 사이즈가 0 인 경우에 필터링 하라는 룰이다.
.doc  SIZE=0   Zero-length corrupt viruses - ignore

# 첨부파일에 Happy99.exe 가 첨부되어 있고 첨부파일 사이즈가 10Kbyte 라면 필터링 하라는 룰이다.
Happy99.exe             SIZE=10000      Happy99 Trojan virus

# 메일헤더의 제목에 viagra 라는 문자열이 있을 경우에 필터링 하라는 룰이다.
.*viagra.*              Policy-Subject:       Spam Viagra

# 메일 헤더의 from  주소가 duma.gov.ru 가 포함된 경우에는 필터링 하라는 룰이다.
.*duma.gov.ru   Policy-MAILFROM:      Virus Dumaru

# 메일 보낸 주소가 127.0.0.5 일 경우에 필터링 하라는 룰이다.
127.0.0.5      Policy-REMOTEIPADDR:   Blocked IP from 127.0.0.5 blocked

# 스팸 메일 발송기 중에서 Bat이 들어가 있는 경우에 필터링 하라는 룰이다. 스팸 메일 발송기가 업그레이드가 늦다면 꽤 유용하게도 쓸수 있을듯 하다.
.*Bat.*            Policy-X-Mailer:             Spammailer sender

이런 형대로 정책 파일을 만든 다음에는 /var/qmail/bin/qmail-scanner.pl -g 명령으로 반드시 DB를 갱신해 줘야 적용이 된다.
그리고 메일 헤더를 가지고 필터링을 할때는 반드시 Policy- 으로 시작해야 되며 1.x 버전을 사용중이라면 반드시 Virus- 으로 시작해야 된다.

4.2.2 [http]simscan

Simscan은 C로 작성된 스팸 필터링 도구로 qmail-scanner 와 마찬가지로 다른 스팸/바이러스 필터링 프로그램(ex. spamassassin,Clamav,Dspam)과 결합이 가능하다.
C로 작성된 만큼 빠른 속도를 자랑한다. simscan과 qmail-scanner 의 장단점은 개인적으로 simscan 에 기록을 남겨두었으니 참고하기 바란다.
  • simscan 설치
    $ adduser -c "simscan user" -s /dev/null simscan
    $ wget  http://www.inter7.com/simscan/simscan-1.1.tar.gz
    $ tar xvfz simscan-1.1.tar.gz
    $ cd simscan-1.1
    $ ./configure && make && make install

     

  • simscan configure 옵션 설명
--enable-user=유저명 //simscan을 유저를 셋팅한다. 기본값으로 simscan
--enable-clamav=y|n //clamav 를 이용한 스캐닝. 기본값으로 y 이다.
--enable-clamdscan=clamdscan의 PTAH
--enable-custom-smtp-reject=y|n //바이러스 이름을 포함하여 리턴 메시지를 보내도록한다
주의. 위의 옵션을 사용하기 위해서는 소스디렉토리/contrib/qmail-queue-custom-error.patch 의 패치를 Qmail에 해주어야 한다.
또한 나중에 설명되는 옵션중에 하나인 enable-dropmsg 의 값이 y이면 안된다.
--enable-per-domain=y|n //많은 도메인에 대해서 메일서비스를 하고 있으며 
각각에 대한 simscan 의 설정을 다르게 하고자 한다면 y를 택하도록 한다.
--enable-attach=y|n //첨부파일에 대해서 체크를 할 것인지의 여부를 정한다. /var/qmail/control/ssattach 파일안에 필터링할 파일명이나 확장자를 넣어주면 된다.
--enable-spam=y|n //스팸메일에 대한 필터링을 할 것인지에 대한 옵션이다. 
스팸어세신에 의해서 status 가 YES인 메일에 대해서는 반송을 하게 될것이다.
--enable-spam-passthru=y|n //스팸 어세신에서 붙은 status값을 무시하고 그냥 통과시키고자 할 경우에 사용한다. 
이는 나중에 procmail 이나 maildrop으로 스팸 편지함이나 별도의 디렉토리에 스팸 메일을 저장하고자 한다면 유용하게 사용될 수 있을 것이다.
--enable-spam-hits=점수 //기본값으로 10 이 셋팅되며 스팸 어세신에서 정한 값을 넣으면 될 것이다.
--enable-spamc=PTAH //spamc 바이너리파일의 위치를 설정한다.
--enable-spamc-args //spamc 에 필요한 옵션을 지정할 수 있다. 필자의 경우에 퍼포먼스를 위해 spamd 를 소켓을 사용하게 하였으며 소켓의 위치는 /tmp/spamd 였다. 
Ex) --enable-spamc-args=”-U /tmp/spamd” 
--enable-dropmsg=y|n //스팸 메일에 대해서는 반송을 하지않고 삭제하겠다는 옵션이다.
--enable-quarantinedir=디렉토리위치 //스팸,바이러스 메일을 따로 저장해둘 디렉토리를 지정한다. 보통 /var/qmail/quarantine 으로 설정될 것이다. 
--enable-received=y|n //메일헤더에 received를 추가할 것인지에 대한 옵션이다. 버전정보 및 처리시간이 기록되어진다.

 

 

  • simscan 설정

먼저 QMAILQUEUE 환경 변수에 simscan을 사용하도록 변경을 한다.(물론 qmail에 queue 패치가 되어 있어야 한다.)

둘 중에 한가지를 선택해서 사용하면 되겠다.
/var/qmail/supervise/qmail-smtpd/run 파일에서 설정하는 방법

#!/bin/sh QMAILDUID=`id -u qmaild` NOFILESGID=`id -g qmaild` QMAILQUEUE=/var/qmail/bin/simscan exportQMAILQUEUE rbl=-r bl.spamcop.net -r rbl.nuxinfo.net exec /usr/local/bin/softlimit -m 100000000 \/usr/local/bin/tcpserver -vRHl0 -x/etc/tcp.smtp.cdb \ -u $QMAILDUID -g $NOFILESGID 0 smtp /usr/local/bin/rblsmtpd -t 30 -b $rbl \ /var/qmail/bin/qmail-smtpd mail.nuxinfo.net \ /bin/checkpassword /bin/true 2>&1

 

tcp.smtp 를 이용하는 방법

vi  /etc/tcp.smtp
127.0.0.1:allow,RELAYCLIENT="",QMAILQUEUE="/var/qmail/bin/simscan"
:allow,QMAILQUEUE="/var/qmail/bin/simscan"

 

첨부파일 필터링( –enable-attach 옵션을 주고 설치했을 경우이다.)

$ cat /var/qmail/control/ssattach
    .jpg
    .mp3
    .scr
    .bat

 

simscan 에서 각 도메인별로 필터링룰 설정하는 방법( –enable-per-domain 옵션을 주고 설치했을 경우이다.)

  $ cat /var/qmail/control/simcontrol
  postmaster@example.com:clam=yes,spam=no,attach=.txt:.com
  example.com:clam=no,spam=yes,attach=.mp3
  :clam=yes,spam=yes,trophie=yes,spam_hits=20.1

각 룰의 의미는 다음과 같다.
– postmaster@example.com 으로 오는 메일에 대해서는 clamav로 바이러스 메일을 필터링하고 첨부파일이 .txt 또는.com에 대해 필터링 한다
– example.com 으로 오는 메일은 spamassassin로 스팸 필터링을 하고 mp3 확장자가 있는 첨부파일에 대해서 호출한다.
– 기본값으로 clamav 로 바이러스 메일을 필터링 하고 spamassassin 과 trophie로 스팸 필터링을 하며 spamassassin에서 부여한 점수가 20.1이 넘는 경우에는 reject한다.

4.2.3 Qmail 패치를 통한 스팸 방지 기능 추가

qmail 패치를 통한 스팸방지 기능의 추가는 거의 대부분 소스 패치를 통해서 이루어지고 있어서 상세한 과정은 생략하고 주로 패치들에 대한 소개로 진행할까 한다.
주로 qmail 의 control 파일이 추가 되거나 qmail-smtpd 에 환경변수가 추가되어 동작하는 경우가 많다.
자세한 내용은 아래 사이트를 참고하기 바랍니다.
[http]http://qmail.psshee.com/top.html#spam

몇몇 쓸만한 패치들을 소개를 해본다.

이 패치는 Qmail에 패턴 매칭을 통해서 다양한 필터링을 제공한다.
/var/qmail/control 하위에 아래와 같은 control 파일들을 이용해서 접근을 막는다.
badhalo,badmailfrom,mailmailfromnorelay,badmailto,badmailtonorelay

이 패치는 RCPT TO 명령어에 대한 카운트를 제한을 하고 그 제한이 걸리면 일정 시간동안 delay를 줘서 한꺼번에 다량의 메일 전송하는것을 방지한다.
/var/qmail/control 하위에 tarpitdelay,tarpitcount 로 제어를 할 수 있게된다.

4.3 MDA 단에서의 필터링

보통 메일 박스 이전에 .qmail 또는 .qmail-default를 이용해서 다른 프로그램을 호출하여 사용한다.
다른 방법으로는 qmail 의 run 파일을 이용해서도 가능하다.
먼저 간단한 .qmail 의 예제를 보도록 하자.
필자는 개인적으로 procmail 보다는 maildrop을 선호하는 편이다.
$ cat>.qmail
|spamc -U /tmp/spamd | maildrop .mailfilter

 

위의 내용은 메시지를 먼저 spamassassin 에 전달하여 메시지에 스팸 점수를 체크한 다음에 maildrop 으로 원하는 메일박스로 전달을 하는 형태이다.

cat> .mailfilter

DEFAULT=/home/webmail/nuxinfo.net/tttt/Maildir/
SPAMDIR=/home/webmail/nuxinfo.net/tttt/SPAMDIR/
if (/^X-Spam-Flag: *YES/)
{
to "$SPAMDIR"
}  


위는 maildrop 에서 호출하는 .mailfilter 의 내용이다. 메일 메시지에서 X-Spam-Flag 가 YES인 경우에는 스팸 디렉토리로 메일을 저장하라는 내용이다.
필자가 maildrop을 선호하는 이유는 아주 다양한 설정을 편하게 설정할수 있기 때문이다.
[http]maildrop홈페이지에서 다양한 예제를 볼 수 있다. 참고하기 바란다.

5 스팸 필터링의 새로운 패러다임

5.1 SPF (Sender Policy Framework)

SPF 는 DNS 기반의 스팸 필터링 기술이다. 메일 발송의 도메인에 대하여 실제로 정상적인 도메인에서 발송이 되었는지 query를 통해서 처리를 하는것이다.
즉 메일 발송지의 DNS 서버에 특정레코드(TXT)에 대한 쿼리를 해서 그 결과에 따라서 정상적인 메일인지 아닌지를 구분하는 것이다.
아래는 간단한 spf를 이용한 메일 필터링의 구조이다.

메일 송신->메일 수신->발송지(도메인,IP,e-mail address)에 대한 Query->Query 값 리턴받음->메일서버 정책에 따라 처리 

 

자세한 정보는 [http]http://www.openspf.org/에서 확인해 보도록 하자.
만약 우리의 메일 서버에서 외부로 메일을 발송을 한다면 그리고 메일을 수신하는 메일서버가 SPF 체크를 해서 필터링을 한다면 먼저 우리는 발송 서버에 대한 SPF 설정을 해줘야만
필터링을 무사히 통과할 수 있을 것이다.

spf설정은 네임서버에서 설정을 해주는 것으로 일단 아래의 예제를 보도록 하자

nuxinfo.net.  IN   TXT   "v=spf1 ip4:211.189.119.187 ip4:211.189.119.186 -all" 

위의 설정은 다음과 같은 의미를 가지고 있다.
메일을 보내는 서버의 도메인이 nuxinfo.net 이면 발송지 주소는 211.189.119.187,211.189.119.186 이며 이외의 ip에 대해서는 fail 결과를 리턴하라는 이야기이다.

Zone파일 설명

도메인 IN TXT "v=spf1 조건(a,mx,prt,ip4,ip6) 조건 외 정책(-all(fail),~all(softfail),+all(pass),?all(neutral))

 

몇 가지 Zone 파일의 예제를 보면서 이해를 해보도록 하자.( 조건외 정책은 최소한 -all 또는 ~all 정도 셋업해주는게 좋다.)

nuxinfo.net.               IN      A       211.189.119.186
                IN      MX 0    mail0.nuxinfo.net.
                IN      MX 1    mail1.nuxinfo.net.
                IN      MX 2    mail2.nuxinfo.net.

mail0            IN      A       211.189.119.187
mail1            IN      A       211.189.119.188
mail2            IN      A       211.189.119.189

# 메일을 보낸쪽 도메인이 nuxinfo.net 이고 ip address 가 211.189.119.187 이라면  pass 하고 그 나머지에 대해서는 fail 값을 리턴한다.
nuxinfo.net.  IN   TXT   "v=spf1 ip4:211.189.119.187-all" 

# 메일 수신서버에서 spf레코드에 대한 query 를 했을때 mx값에 설정되어 있는 Host의 IP(아래 예제를 보자면 211.189.119.187~189)에 대한 인증을 하고
# 그 이외의 ip에 대해서는 softfail 값을 리턴하라는 이야기다. 마지막이 -all 이라면 fail값을 리턴한다)
nuxinfo.net.  IN   TXT   "v=spf1 mx ~all"

# a레코드 값에 설정되어 있는 Host의 IP(즉 211.189.119.186) 일 경우에는 pass 값을 보내주고 그 이외의 값은 fail값을 리턴 하라는 이야기 이다.
nuxinfo.net.  IN   TXT   "v=spf1 a:nuxinfo.net -all"

쉽게 설명하자면 네임서버에 우리가 메일을 발송할때는 아래와 같은 서버(or IP)를 사용하니
혹시 우리 도메인을 사용하면서 다른 IP라면 그건 가짜 입니다 라는 정보를 다른 메일서버에
알려주는 형태이다.

지금까지는 메일을 송신했을때 spf 체크를 하는 메일서버에 메일이 잘 들어갈 수 있도록 하는 설정이었으며
이제는 우리가 메일을 받을 경우에 spf 를 가지고 체크를 해서 필터링을 해보는 방법을 알아보도록 하자.

참고로 아래는 필자가 확인해 본 몇몇 포탈 사이트의 spf 설정 상황이다.

dig TXT 도메인
nownuri.net.  21476   IN      TXT     "v=spf1 ip4:203.238.128.90 ip4:203.238.128.56 ip4:203.238.128.57 ~all"
hanmail.net.  20568   IN      TXT     "v=spf1 ip4:211.43.197.0/24 ptr ~all"
naver.com.    600     IN      TXT     "v=spf1 ip4:220.95.234.208 ip4:61.74.70.0/23 ip4:222.122.16.0/24 ip4:220.73.156.0/24 ip4:211.218.150.0/24 ~all"
chol.com.     3600    IN      TXT     "v=spf1 ip4:203.252.1.0/24 ip4:203.252.3.0/24 ip4:164.124.191.0/24 ip4:210.120.128.23 ~all"
empas.com.    3600    IN      TXT     "v=spf1 ip4:61.97.66.0/24 ip4:61.97.67.0/24 ip4:61.97.70.0/24 ip4:61.97.72.0/24 ptr -all"

 

먼저 spf 레코드 체크를 위한 몇가지 방법을 알아보도록 하자.
편하게 할 수 있는 방법 몇가지를 소개해 본다.

5.1.1 qmail 에 spf 패치를 하여 필터링를 하는 방법

[http]http://www.saout.de/misc/spf/에서 qmail-spf 패치를 받아서 spf 패치 이후 Qmail을 재설치 한다.

$ tar xvfz qmail-1.03.tar.gz
$ cd qmail-1.03
$ patch -p1<qmail-spf-rc5.patch
$ make && make setup check

참고로 spf패치를 하게 되면 spfquery 라는 바이너리 파일이 생성이 되고 간단하게 테스트 spf 테스트를 해볼 수 있다.
기본 사용법: spfquery 메일쪽IP 메일도메인 메일주소

$ spfquery 211.189.119.186 nuxinfo.net root@nuxinfo.net
result=pass
Received-SPF: pass (localhost: SPF record at nuxinfo.net designates 211.189.119.186 as permitted sender)
필자는 네임서버에 spf설정을 해두었기 때문에 return 값이 pass 로 나온다.

$ spfquery 211.189.119.190 nuxinfo.net root@nuxinfo.net                 
result=fail: See http://spf.pobox.com/why.html?sender=root%40nuxinfo.net&ip=211.189.119.190&receiver=localhost
Received-SPF: fail (localhost: SPF record at nuxinfo.net does not designate 211.189.119.190 as permitted sender)

메일 보낸쪽 IP address를 약간 변조를 해서 query 를 날려보았다.
결과를 보면 알겠지만 fail 값이 리턴이 되었다. 왜냐면 필자의 네임서버에서는 186,187번 IP에 대해서만 spf 설정을 해두었기 때문이다.

위의 원리로 변조되어 들어오는 메일을 필터링 할수 있는 것이다.

이제 spf 패치가 된 qmail의 설정을 살펴보도록 하자.
다른 패치와 비슷하게 control 파일을 이용하도록 되어 있다.

$ cat>/var/qmail/control/spfbehavior<<EOF
3
EOF

값은 0~6까지 줄수 있으며 아래와 같은 레벨로 필터링을 할 수 있다.
0: spf 설정에 대한 쿼리를 하지 않으며 spf 결과에 대한 헤더를 생성하지 않는다.
1: 단지 spf 쿼리에 대한 헤더만 생성하되 블럭은 하지 않는다.
2: spf쿼리에 문제가 있을경우 dns 에러와 함게 reject한다.
3: spf 쿼리 결과가 fail 일 경우에 deny한다.
4: spf 쿼리 결과가 softfail 일 경우에 deny한다.
5: spf 쿼리 결과가 neutral 일 경우에 deny한다.
6: spf 쿼리 결과가 pass가 아닐 경우에 deny한다.

나머지 몇개의 control파일이 더 있는데 생략한다.

5.1.2 spamassassin 을 이용하여 필터링을 하는 방법.

spamassassin 을 이용하는 방법은 아주 쉽다.
spamassassin3.x 버전 부터는 기본적으로 spfquery 를 사용할 수 있도록 되어 있다.
spamassassin에서 spf를 이용하기 위해서는 spf perl 라이브러리가 필요하다.
[http]http://www.openspf.org/Implementations 에서 Mail::SPF 모듈을 다운로드 하여 설치하도록 하자.
Mail::SPF 을 설치하기 위해서는 아래와 같은 다른 perl 모듈도 설치를 해줘야 한다.
Module-Build 0.2805
Test-More
Net-DNS-Resolver-Programmable 0.002.1
위의 모듈을 모두 설치한 다음에 Mail::SPF 모듈을 설치하면 된다.
설치하는 방법은 다소 내용이 길어질 수 있어서 생략하도록 하겠다.
Mail::SPF 모듈이 설치가 되었다면 spamassassin 설정 파일을 열어서 SPF 체크를 하도록 하면 된다.

$ vi /etc/mail/spamassassin/init.pre
loadplugin Mail::SpamAssassin::Plugin::SPF

아마 3.x 버전을 설치했다면 아마 기본적으로 설정이 되어 있을 것이다.
spamassassin은 실제 메일 메시지에 대한 reject를 하는 시스템은 아니고 score를 부여하는 역할만 하므로
만약 smtpd 단에서 필터링을 하기를 원한다면 위에서 말한 qmail에 패치를 하여 사용을 하는것이 좋을 것이다.

5.2 DKIM(Domain keys identified mail)

Domain key 는 현재 대표적으로 Yahoo에서 사용하는 메일 인증 시스템으로
기본 원리는 SPF처럼 네임서버에 등록된 정보를 확인하는 구조를 가지고 있다.
그러나 SPF가 IP기반의 인증을 하는 반면에 Domain key는 digital sign을 하는 형태라서 메일의 변조 여부까지 확인할 수 있다.

기본 구조는 다음과 같다

메일 발송서버->메일 수신 서버->메일헤더에 sign 되어진 값을가지고 다시 메일을 발송한 도메인 네임서버에 query->리턴된 public key를 이용하여 메일 메시지 검증

 

*private key 및 public key, signature 이해하기

Domain key가 어떻게 동작하는지 원리를 잠깐 살펴보도록 하자.

$ echo testmail>test.txt $ openssl dgst -sign /etc/domainkeys/nuxinfo.net/default -sha1<test.txt>sign.file $ openssl dgst -verify /etc/domainkeys/nuxinfo.net/rsa.public -sha1 -signature sign.file<test.txt Verified OK test.txt 파일을 약간 변경해서 검증할 때 $ openssl dgst -verify/etc/domainkeys/nuxinfo.net/rsa.public -sha1 -signature sign.file <test.txt Verification Failure

설명) 먼저 메일 발신 서버에서는 test.txt(메일메시지)에 private key를 이용해서 sign을 하고 메일 메시지에 sign.file을 더 덧붙여서 메일을 전송한다.
그리고 메일 수신서버에서는 메일 메시지에 첨부되어 있는 sign 과 네임 서버에 query를 하여 돌아온 public key 를 이용해서 그 메일의 변조 유무를 체크하는것이다.
만약 test.txt파일이 sign 되는 당시와 변경 사항이 있다면 검증 결과는 Failure 를 리턴한다.

  • Qmail에 Domain key 패치하여 설치하기

[http]티니님이 작성한 Domain key 설정법을 참고하기 바란다.

  • SPF 와 Domain key 비교(어디까지나 필자의 생각다 :-) )
SPF Domain key
인증방식 IP기반 RSA 이중키로부터 만들어진Digital Signature
구현방식 DNS에 등록된 IP와 실제 메일 발신 IP대조 발신자의 서명을 검사
장점 적용하기 편리함(네임서버에 등록만 해주면 됨 안전하고 신뢰성이 높음
단점 위/변조 가능성이 있다(IP spoofing) 적용하기가 좀 어려움

6 맺으며

스팸 메일 필터링에 대한 전반적인 이해를 위해 글을 시작했으나 생각보다 설명하고 싶은게 너무 많아
전부 쓰기에는 너무 내용이 방대해질 듯 하여 많은 부분을 생략 했습니다.(설치과정이나 실제 운영하는 방법? 등등)
따라서 좀 내용이 어려울 수도 있다는 생각이 드는군요..^^;
이 문서가 지속적으로 업데이트 될수 있도록 많은 의견들을 바라며…
2007년 9월4일
By stone92