2008. 10. 14.

grep,egrep,sed,awk사용법(정규표현식)

▒ grep : 패턴을 이용한 search => regular expression을 잘 만드는 것이 필요하다.

grep option(s) pattern filename(s)

OS/tdir] grep -n dba /etc/group # -n : 파일 안에서의 패턴이 발견된 라인 및 라인 번호
OS/tdir] grep -v dba /etc/group # -v : 패턴이 발견되지 않은 라인
OS/tdir] grep -n dba /etc/group /etc/passwd # 파일을 여러개 나열...
OS/tdir] grep -i the ~/tdir/* # -i : 대소구분 무시(ignore) => the 대소구분 없이
OS/tdir] grep -li the ~/tdir/* # -l : 패턴이 들어있는 파일 이름만...
OS/tdir] grep -c the ~/tdir/* # -c : 패턴이 들어있는 라인 번호만...

[패턴을 좀더 정교하게 표현하려면 regular expression을 사용해야 한다]

^ : ^패턴 : 패턴으로 시작하는 모든 라인 찾기
$ : 패턴$ : 패턴으로 끝나는 모든 라인 찾기
. : d... : d로 시작하는 4자리 character 찾기
* : [a-d]* : a, b, c, d로 시작하는 character 찾기
[] : [Dd]atabase : Database 또는 database 찾기
[^] : [^D] : D가 나타나지 않는 라인 찾기

OS/tdir] grep -i ^the ~/tdir/* # the로 시작하는 라인 찾기
OS/tdir] grep -i meal.$ ~/tdir/* # meal.으로 끝나는 라인 찾기
OS/tdir] grep c...d ~/tdir/* # c로 시작하고 d로 끝나는 5자리 character 찾기

================================================================

▒ egrep(expression grep) : searches files for a pattern of characters
and prints all lines that contain that pattern.



OS/tdir] egrep '(a|A)d+' /etc/passwd # ad 또는 Ad가 포함된 라인 찾기
OS/tdir] vi grep_test # 아래 내용을 추가하세요... 붙여넣기... ^^

An Oracle database is a collection of data treated as a unit.
The purpose of a database is to store and retrieve related information.
A database server is the key to solving the problems of information management.

OS/tdir] egrep 'Oracle|purpose' grep_test # Oracle 또는 purpose가 포함된 라인 찾기

===============================================================

▒ sed : stream editor => file을 열지 않고 data를 편집하는 기능

sed [-options] [address] command file... [>newfile]



# sed '/pattern/d' filename # file에서 패턴이 포함된 라인을 지우고 그 결과를 화면에 표시
# 원본 파일에는 아무런 변화가 없다.

OS/tdir] cp grep_test sed_test
OS/tdir] cat sed_test
OS/tdir] sed '/purpose/d' sed_test # purpose 라는 단어가 들어간 라인 삭제

# sed '#d' filename : # 라인만 삭제
# sed '$d' filename : 마지막 라인 삭제
# sed '#,$d' filename : # 라인부터 마지막 라인까지 지우기
# sed '#,#d' filename : # 라인부터 # 라인까지 지우기

OS/tdir] sed '1d' sed_test # 1 라인만 삭제
OS/tdir] sed '$d' sed_test # 마지막 라인만 삭제

OS/tdir] sed '/purpose/d' sed_test > set_out # sed 처리 결과를 sed_out 으로 저장
OS/tdir] cat set_out

OS/tdir] sed '/purpose/p' sed_test # 패턴이 포함된 라인이 두번 출력(print)된다.
OS/tdir] sed -n '/purpose/p' sed_test # 패턴이 포함된 라인만 출력된다.

OS/tdir] sed 's/$/ Oracle/' sed_test # 각 라인의 마지막에 원하는 글자 추가

OS/tdir] sed 's/ */#/g' sed_test # space를 찾아서 #기호로 변환한다.
OS/tdir] sed 's/ */-/g' sed_test # space를 찾아서 -기호로 변환한다.
# * 기호 앞에 space가 두개라는 점에 유의

OS/tdir] # 한번에 여러 가지 편집 수행
OS/tdir] sed -e 's/database/DATABASE/g' -e 's/information/INFORMATION/g' sed_test

===============================================================

▒ awk : 패턴 검색과 처리를 위한 언어

=> 명령어의 이름은 개발자인 Alfred V. Aho, Peter J. Weinberger, Brian W. Kernighan 3인의
머리글자를 사용해서 만든 것이다.

awk '{ action}' filename

OS/tdir] ls -l | awk '{print $0}' # 전체 필드가 모두 나타나도록...

drwxr-xr-x 2 prof9i4 dba 512 4월 25일 15:44 a_dir
drwxr-xr-x 2 prof9i4 dba 512 4월 18일 23:53 b_dir

$1 $2 $3 $4 $5 $6 $7 $8 $9
$0




OS/tdir] ls -l | awk '{print $1}' # 1번 필드만 나타도록...
OS/tdir] ls -l | awk '{print $1, $9}' # 1번과 9번 필드만 나타나도록...
OS/tdir] ls -l | awk '{print $3 "\t" $4 "\t" $9}' # Tab 키가 적용된 결과...
OS/tdir] ls -lt | awk '{print $9, "is using", $5, "bytes"}' # text 추가
OS/tdir] ls -lt | awk '$5 <= 200 {print $0}' # 5번 필드가 200 이하일 경우 출력

AWK

AWK
awk는 직접 사용자로부터 입력을 받거나 아니면 지정한 파일을 가공하여 표준 출력한다
표준 출력을 리다이렉션할 수 있다
사용법
awk [옵션] '스크립트' [-v 변수=값] [파일(들)]
awk [옵션] -f 스크립트 파일 [-v 변수=값] [파일(들)]
cf) 편집 스크립트 파일의 사용법
ed : ed -s(script) sourcefile < scriptfile
sed : sed -f(file) scriptfile sourcefile > outputfile
awk : awk -f(file) scriptfile sourcefile > outputfile
옵션
-Fc : field separator 지정
c는 필드 사이를 구분하는 구분자이다

직접 지정하지 않으면 공백을 기준으로 한다

시스템 변수 FS를 지정하는 것과 같은 효과를 지닌다
-v 변수 = 값
스크립트를 실행하기 전에 미리 변수를 지정하여 준다
-f 스크립트 파일
스크립트를 파일에서 가져온다
-f 옵션을 여러번 사용하여 여러개의 스크립트 파일을 동시에 불러와 지정한 파일에 적용할 수 있다
스크립트
패턴 { 동작 }
커맨드 라인에서는 패턴, 동작 전체를 단일 따옴표로 묶는다
패턴만 있는 경우 : 패턴과 일치하는 레코드(라인)를 화면에 출력한다
동작만 있는 경우 : 모든 레코드(라인)가 동작의 대상이 된다
패턴
/정규표현식/
sed가 지원하지 않는 +, ?, |, ( ) 등의 메타문자도 지원한다 또한
^, $를 각 필드의 처음과 끝을 의미하도록 사용할 수도 있다
비교연산
숫자 기준, 알파벳 기준 모두 사용 가능하다
패턴 매칭 연산
~ : 일치하는 부분을 나타낸다
!~ : 일치하지 않는 부분을 나타낸다
BEGIN
첫 번째 레코드가 읽혀지기 전에 어떤 동작을 정의하여 사용하고 싶을 때 사용한다
END
마지막 레코드가 모두 읽혀진 후 어떤 동작을 정의하여 실행하고 싶을 때 사용한다
동작
동작은 모두 { }로 둘러싸야 한다
예제
good이라는 문자열을 포함하는 모든 레코드를 출력할 때
/good/
각 레코드의 첫 번째 필드를 출력할 때
{ print $1 }
good이라는 문자열을 포함하는 레코드의 첫 번째 필드를 출력할 때
/good/ { print $1 }
두 개 이상의 필드를 가지는 레코드를 전부 출력할 때(비교연산)
NF > 2
한 라인(n)을 필드로, 빈 라인("")을 레코드로 구분할 때
BEGIN { FS = "n" ; RS = ""}
첫 번째 필드가 good와 일치하는 레코드에 대해 세 번째 필드를 먼저 출력하고 두 번째 필드를 나중에 출력하고 싶을 때
$1 ~ /good/ { print $3 , $2 }
good이라는 문자열이 몇 개나 들어가 있는지 계산하여 마지막 부분에서 출력하고 싶을 때
/good/ { ++x }
END { print x }
두 번째 필드를 모두 합하고 마지막 부분에서 두 번째 필드의 총합계를 출력하고 싶을 때
{ total += $2 }
END { print "Total of $2: " , total }
레코드의 길이가 20자 이하인 것을 출력하고 싶을 때
length($0) < 20
네 개의 필드를 가지며 good이라는 단어로 시작하는 모든 레코드를 출력하고 싶을 때
NF == 4 && /^good/
빈줄을 제외한 모든 줄을 화면에 출력한다
NF > 0
awk 시스템 변수

FILENAME 현재 파일명 $0 입력 레코드
FS 입력 필드 구분
디폴트 : 공백 $n 입력 레코드의 N번째 필드
NF 현재 레코드 필드 갯수 ARGC 커맨드 라인의 인자 갯수
NR 현재 레코드 번호 ARGV 커맨드 라인 인자를 포함하는 배열
OFMT 숫자에 대한 출력 포맷
디폴트 : %.6g ENVIRON 환경 변수들을 모아둔 관계형 배열
OFS 출력 필드 구분
디폴트 : 빈줄 FNR NR과 동일
단지 현재 파일에 적용된다는 점이 다름
ORS 출력 레코드 구분
디폴트 : newline RSTART 지정한 매칭 연산을 만족하는 문자열의 맨 앞부분
RS 입력 레코드 구분
디폴트 : newline RLENGTH 지정한 매칭 연산을 만족하는 문자열의 길이

awk 연산자

산술 : =, +=, -=, *=, /=, %= 조건 : ? : 논리 : ||, &&, ! 패턴 : ~, !~
비교 : <, <=, >, >=, !=,== 증감 : ++, -- 필드참조 : $

제어문(C의 제어문과 같다)
break
continue
do {실행} while (조건)
exit
for (관계형 배열의 요소) {실행}
펄의 foreach와 같다
if (조건) {실행} else {실행}
return
while
awk 명령어
문자열 연산
gsub(reg,s)
입력 문자열의 전반에 걸쳐 정규표현식 r을 문자열 s로 대치한다
gsub(reg,s1,s2)
문자열 s2에서 정규표현식 r을 s1으로 대치한다
index(s1,s2)
s1에서 s2의 위치를 넘겨준다 만약 없다면 0을 넘겨준다
length(arg)
인자의 길이를 넘겨준다
match(s,r)
문자열 s에서 정규표현식 r과 매칭되는 부분의 위치를 넘겨준다
split(string,array[,seperator])
구분자를 기준으로(지정하지 않으면 공백 기준)해서 지정한 문자열을 배열로 만든다 배열[1], 배열[2], .......
sub(r,s), sub(r,s1,s2)
gsub과 동일하다
단지 정규표현식과 일치하는 문자열이 여러개라도 처음 문자열만 대치된다
substr(s,m)
문자열 s에서 m번째 위치에서 끝까지의 문자를 리턴한다
substr(s,m,n)
문자열 s에서 m번째 위치에서 n번째까지의 문자를 리턴한다
tolower(str)
toupper(str)
수치 연산
atan2(x,y)
y/x의 arctangent값을 라디안 단위로 넘겨준다
cos(x)
exp(arg)
int(arg)
log(arg)
rand()
0과 1사이의 난수를 발생한다
sin(x)
sqrt(arg)
srand(expr)
인자를 가지고 난수를 발생한다
인자가 주어지지 않으면 시간을 가지고 난수를 발생한다
입출력/프로세스
close(filename)
지정한 파일을 닫는다
close(cmd)
지정한 명령어 파이프를 닫는다
delete array[element]
지정한 배열 요소를 지운다
getline()
다음 레코드를 읽어 들인다
getline[variable] [< "filename"]
파일에서 읽어들인다
next
다음 레코드(라인)을 입력받는다
getline()과 유사하지만 /패턴/동작을 새롭게 시작한다
getline()은 다음 라인을 읽기만 한다
print [args] [> "filename"]
인자를 출력한다
printf "format" [,expressions] [> "filename"]
형식에 맞춰 출력한다
sprintf (format [,expressions])
printf와 마찬가지로 사용하는데 값을 리턴하기만 하고 출력은 하지 않는다
system(command)
시스템 내부 명령어를 실행한다
간단한 예
awk ' BEGIN { for (i = 1;i<=7,i++) print int(101*rand()) }'
화면에 1이상 100이하의 난수 일곱 개를 출력한다
ls -l file1 file2 file3 | awk ' { x += $5 } ; END { print "Total bytes : " x } '
파일들의 크기를 모두 합하여 총 바이트 수를 표시한다
awk ' END { print NR } ' filename
지정한 파일의 라인이 몇 개인지를 표시한다
awk ' NR % 2 == 0 '
지정한 파일의 짝수번째의 라인만을 출력해 준다

2008. 9. 22.

리눅스 시간동기화

시간동기화에 대해서 가끔 중요성을 상실할때가 너무많다.

심하게 둔한 관리자는 몇주, 몇달후 날짜가 안맞다는 고객의 제보로 수정 경우도...

저같은 경우는 시스템 설치직후 이 작업부터 시행합니다 ^^;




1. rdate 를 이용한 동기화



- 레드햇계열 및 여타 배포판에서도 별도의 설치과정필요없이 사용할수있다.

쉘스크립파일을 하나 작성한다.



ex) time-sync.cron ---------------------------

#!/bin/bash
/usr/bin/rdate -s time.bora.net && /sbin/clock -w

---------------------------------------------



저장후 실행권한 부여

#chmod 755 time-sync.cron



작성한 파일을 /etc/cron.daily 로 복사 ( 일일 새벽 4시에 동기화 스크립트를 수행함 )









2. ntp 를 이용한 동기화



- rdate 를 이용한 방법보다 소수점 몇몇점이하까지 상세히 동기화해준다고해서 애용중;

#rpm -qa | grep ntp 명령으로 "ntp-버젼" 이 출력되지않으면

http://rpmfind.net 에서 "ntp" 로 검색해서 배포판에 해당하는 패키지를 설치한다



ex1)

OS : Fedora Core 3

#wget ftp://rpmfind.net/linux/fedora/core/3/i386/os/Fedora/RPMS/ntp-4.2.0.a.20040617-4.i386.rpm

#rpm -Uvh ntp-4.2.0.a.20040617-4.i386.rpm



ex2)

#rpm -Uvh ftp://rpmfind.net/linux/fedora/core/3/i386/os/Fedora/RPMS/ntp-4.2.0.a.20040617-4.i386.rpm



- 동기화



  #ntpdate -b -s time.kriss.re.kr

  // -s : 결과를 화면이 아닌 syslog 로 보냄



* 다음과 같은 오류가 발생한 경우


 [root@truefeel root]# ntpdate -b time.kriss.re.kr
 17 Mar 21:03:25 ntpdate[8244]: no server suitable for synchronization found


 -> NTP 프로토콜은 UDP port 123 을 사용하는데, 이 포트가 방화벽 등으로
    막혀있는 경우에는

    #ntpdate -u time.kriss.re.kr

    처럼 -u 를 옵션을 사용해서 다른 포트 사용하거나

IPTABLE 을 사용중이면 OUTBOUNT UDP 123 포트를 열어준다



- cron.daily 에 등록 ( 쉘스크립트 파일 작성 )



ex) time-sync.ntp ---------------------------

#!/bin/bash
/usr/sbin/ntpdate -b -s time.kriss.re.kr && /sbin/clock -w

---------------------------------------------

저장후 실행권한 부여

#chmod 755 time-sync.ntp



작성한 파일을 /etc/cron.daily 로 복사 ( 일일 새벽 4시에 동기화 스크립트를 수행함 )

2008. 9. 21.

FreeNX 설치 방법

vnc보다 freenx가 빠르다고 합니다
그래서 freenx를 설치해봤습니다

설치환경 : server(centos5.2) client(fedora9)

1) 기존 freenx 삭제
sudo yum remove nx freenx

2) http://www.nomachine.com/download-package.php?Prod_Id=6
freenx server로 사용할 컴퓨터에 client node server 순서로 다운받고 설치한다

3) 클라이언트 컴퓨터에는 freenx client만 설치하면 된다

4) 터미널을 실행한다 설치 스크립트 실행한다
/usr/NX/scripts/setup/nxserver --install

5) NX> 704 ERROR: Cannot add user: nx
이런 오류가 난다면 터미널에서 다음을 실행
sudo userdel nx

6) 키 생성을 위해 다음을 실행
/usr/NX/bin/nxserver --keygen

7) /usr/NX/share/keys/default.id_dsa.key 의 내용을 복사해서
nx client(fedora9)의 프로그램>>인터넷>>NX client for linux>>NX client for linux 클릭
configure버튼 클릭>key버튼 클릭 위의 복사한 내용을 붙여넣기>저장

8) sudo gedit /usr/NX/etc/server.cfg 설정 파일을 수정한다
EnableUserDB = "1"
EnablePasswordDB = "1"
EnableClipboard = "both"
0을 1로 변경 #마크 제거한다

9) nxserver --useradd username
패스워드 설정

10) 방화벽 설정
sudo vi /etc/sysconfig/iptables
위의 파일에 다음을 추가
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 5000:6000 -j ACCEPT

11) 서비스 재시작
/etc/rc.d/init.d/nxserver restart
/etc/rc.d/init.d/iptables restart

12) 클라이언트쪽에서
프로그램>>인터넷>>NX client for linux>>NX client for linux 클릭해서 ip입력
9번에서 설정한 사용자명과 비밀번호 입력하면 원격접속이 된다


------------------------------------------------------------------------------------
http://www.nomachine.com/download-package.php?Prod_Id=6

http://www.nomachine.com/select-package.php?os=linux&id=1


http://www.nomachine.com/download-package.php?Prod_Id=4


wget http://64.34.161.181/download/3.2.0/Linux/nxnode-3.2.0-13.i386.rpm
wget http://64.34.161.181/download/3.2.0/Linux/FE/nxserver-3.2.0-16.i386.rpm
wget http://64.34.161.181/download/3.2.0/Linux/nxclient-3.2.0-14.i386.rpm

rpm -ivh nxclient-3.2.0-14.i386.rpm
rpm -ivh nxnode-3.2.0-13.i386.rpm
rpm -ivh nxserver-3.2.0-16.i386.rpm


vi /etc/sysconfig/iptables
-A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT

/etc/init.d/iptables restart

/etc/init.d/nxserver restart


http://www.nomachine.com/download-package.php?Prod_Id=65

윈도우 패키지를 받는다.

vi /usr/NX/etc/server.cfg

EnableUserDB = "1"
EnablePasswordDB = "1"
EnableClipboard = "both"

0을 1로 변경 # 마크를 제거한다.

접근 사용자 생성


방화벽 설정
sudo vi /etc/sysconfig/iptables
위의 파일에 다음을 추가
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 5000:6000 -j ACCEPT

서비스 재시작
/etc/rc.d/init.d/nxserver restart
/etc/rc.d/init.d/iptables restart


클라이언트쪽에서
프로그램>>인터넷>>NX client for linux>>NX client for linux 클릭해서 ip입력

2008. 9. 18.

회사 사람들



회사 사람들

qmail에 DomainKeys 적용

이번 강좌는 발신지변조 방지 기술중 하나인 DomainKeys 시스템에 대해 다뤄보도록 하겠습니다.
도메인키 시스템은 Yahoo에서 주도하여 개발된 새로운 인증 방법으로써 최근엔 쥐메일 등과 같은
업체에서도 시범적 적용을 하고 있는 기술 입니다.
이 기술은 발신지 메일서버의 비밀키로 사인(Sign)되어온 메일의 도메인 정보를 가지고
수신지에서 발신지의 공개키(public key)를 이용하여 발신지 서버에 인증을 한뒤
메일의 정상유무를 확인하는 방법으로 최근 유행하는 피싱(phising) 또는 발신지 변조메일 등을
원천적으로 차단할 수 있습니다.
이는 기존 AOL의 SPF 기술보다 한단계 진보한 기술이라 볼 수 있습니다.

만약 이 기술에 대해서 자세한 문헌을 보고 싶다면 아래 URL을 참조하시기 바랍니다.
※ http://domainkeys.sf.net/ , http://antispam.yahoo.com/domainkeys

1. libdomainkeys 다운로드 (최신버전: http://sourceforge.net/projects/domainkeys/)
libdomainkeys는 gmail.com 의 운영자인 Russell Nelson 씨가 만든 라이브러리로써,
쉽고 빠르게 적용할 수 있다는 장점이 있습니다.
[root@localhost]# wget http://nchc.dl.sourceforge.net/sourceforge/domainkeys/libdomainkeys-0.68.tar.gz
[root@localhost]# tar xfz libdomainkeys-0.68.tar.gz
[root@localhost]# cd libdomainkeys-0.68
[root@localhost]# make


2. qmail-dk 패치 적용
[root@localhost]# wget http://www.qmail.org/qmail-1.03-dk-0.54.patch
[root@localhost]# tar xfz qmail-1.03.tar.gz
[root@localhost]# cd qmail-1.03
[root@localhost]# patch -p1 < ../qmail-1.03-dk-0.54.patch

※ 만약 smtp relay allow 방식이 qmail + vpopmail를 사용하는 방법이 아니라
  qmail + smtp-auth 방식을 사용하시는 분들은 위 패치를 하신뒤 아래 패치도
  같이 해주셔야 되며, vpopmail을 이용하시는 분들은 3번 섹션으로 넘기시면 됩니다.
[root@localhost]# wget http://jeremy.kister.net/code/qmail-dk-0.54-auth.patch
[root@localhost]# cd qmail-1.03
[root@localhost]# patch -p1 < ../qmail-dk-0.54-auth.patch


3. qmail-dk 바이너리 파일의 생성 및 설치
이제 DomainKeys 시스템에서 사용될 바이너리 파일을 생성하도록 하겠습니다.
하지만 컴파일 하기에 앞서 주의하셔야 될 사항이 있습니다.
바로 큐메일소스 디렉토리의 위치 입니다.
위에서 적용한 qmail-dk 패치의 내용중에는 qmail-dk.c 라는 원시코드가 생성이 되는 부분이 있는데
이 원시코드에서 libdomainkeys의 헤더를 자신의 상위 디렉토리에 찾도록 코딩되어 있습니다.
따라서 큐메일소스 디렉토리는 반드시 libdomainkeys 디렉토리 내에 존재해야 됩니다.
[root@localhost]# mv qmail-1.03 libdomainkeys-0.68/
[root@localhost]# cd libdomainkeys-0.68/qmail-1.03
[root@localhost]# make qmail-dk
[root@localhost]# cp qmail-dk /var/qmail/bin/
[root@localhost]# chown root.qmail /var/qmail/bin/qmail-dk
[root@localhost]# cp qmail-dk.8 /var/qmail/man/man8/


4. RSA DomainKeys 생성
이곳에서 생선된 RSA Key가 실제 메일헤더에 적용되어 발송될 인증키 입니다.
[root@localhost]# mkdir -p /etc/domainkeys/foobar.com/
[root@localhost]# cd /etc/domainkeys/foobar.com/
[root@localhost]# openssl genrsa -out rsa.private 768
[root@localhost]# openssl rsa -in rsa.private -out rsa.public -pubout -outform PEM
[root@localhost]# mv rsa.private default
[root@localhost]# chown -R qmaild .
[root@localhost]# chmod 600 default


5. public Domainkey 추출
DomainKeys를 적용하려면 DNS의 Zone 파일에 TXT 레코드와 공용키를 추가시켜야 됩니다.
따라서 TXT 레코드에서 사용할 공용키(public key)를 추출하도록 합니다.
[root@localhost]# grep -v ^- rsa.public | perl -e 'while(<>){chop;$l.=$_;}print "t=y; p=$l;\n";'


6. Zone 파일에 TXT 레코드 추가
위에서 말했듯이 도메인키 시스템을 적용하려면 존 파일에 TXT 레코드가 필요 합니다.
따라서 기존 존파일에 아래의 내용을 추가시켜 줍니다.
_domainkey   IN   TXT   "t=y; o=-;"
default._domainkey   IN   TXT   "public DomainKey"

※ 위의 내용만으로는 어디에 적용하실지 혼동하시는 분이 계실까봐 샘플을 보여드립니다.
[root@localhost]# cat /var/named/zone-foobar.com
$TTL 86400
@       IN   SOA   ns.foobar.com. root.foobar.com. (
                2007010100 ; Serial
                 10800   ; Refresh (3 hours, 10800)
                 3600    ; Retry (1 hours, 3600)
                 1209600  ; Expire (2 weeks, 1209600)
                 86400   ; Minimum (1 days, 86400)
                 )
;
; Default Setting (NS, MX, A)
        IN   NS   ns.foobar.com.
        IN   MX 10  mail.foobar.com.
        IN   A    192.168.0.1
;
; DomainKeys Setting (TXT)
_domainkey   IN   TXT   "t=y; o=-;"
default._domainkey   IN   TXT   "t=y; p=MHwwDQYJKoZIhvcNAQ...."
;
; Name servers (registered at InterNIC)
ns       IN   A    192.168.0.1
;
; Hosts Here - This is comments
www      IN   A    192.168.0.1



7. qmail-queue 파일의 교체
이제 큐메일에서 메일을 발송할 때 domainkey를 메일헤더에 추가하여 발송하도록
위에서 설치했던 qmail-dk를 사용하도록 큐메일 파일을 교체해주어야 합니다.
[root@localhost]# ln /var/qmail/bin/qmail-queue /var/qmail/bin/qmail-queue.orig
[root@localhost]# ln /var/qmail/bin/qmail-dk /var/qmail/bin/qmail-queue.new
[root@localhost]# mv /var/qmail/bin/qmail-queue.new /var/qmail/bin/qmail-queue


8. tcp.smtp 수정
처음 패치를 했을때와 마찬가지로 이 부분도 smtp-auth 사용자와 vpopmail 사용자는
각각 다른 내용으로 tcp.smtp에 추가를 해주어야 됩니다.
1. smtp-auth 사용자
[root@localhost]# vi /etc/tcp.smtp
:allow,DKVERIFY="DEGIJKfh",QMAILQUEUE="bin/qmail-dk"
[root@localhost]# tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtp

2. vpopmail 사용자
[root@localhost]# vi /home/vpopmail/etc/tcp.smtp
127.0.0.1:allow,RELAYCLIENT="",DKSIGN="/etc/domainkeys/foobar.com/default",QMAILQUE
UE="bin/qmail-dk"
192.168.0.1:allow,RELAYCLIENT="",DKSIGN="/etc/domainkeys/foobar.com/default",QMAILQU
EUE="bin/qmail-dk"
:allow,DKVERIFY="DEGIJKfh",QMAILQUEUE="bin/qmail-dk"
[root@localhost]# /home/vpopmail/bin/clearopensmtp


이제 DomainKeys를 사용할 준비가 모두 끝났습니다.
실제로 yahoo와 gmail로 메일을 발송해보시기 바랍니다.

9. DomainKeys 적용확인
야후에서는 도메인키 인증이 되면 메일을 읽었을 때 "발신:" 부분에 아래와 같은 메시지가 남습니다.
야후! 도메인키는, 이 메세지가 다음 도메인으로 부터 보내진것을 입증합니다 : foobar.com.

구글에서는 메일을 읽은뒤, 오른쪽에 보시면 "추가옵션" 이라는 부분이 있습니다.
클릭하시면 보낸사람 오른쪽으로 "서명한 사람: foobar.com" 이라는 메시지가 붙습니다.
혹은 제목 아래의 옵션들중 "원본 보기"를 클릭하시면 메일헤더를 보실 수 있는데
아래와 같은 메일헤더가 추가되어 있으면 성공적으로 도메인키가 적용이 된것 입니다.
DomainKey-Status: good (test mode)
Received: (qmail 23592 invoked from network); 13 Jan 2007 21:21:12 +0900
Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys
DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws;
s=default; d=foobar.com;
b=oIozmfhoDF+L3+hhO0ncfSh4FdLBp3yiyBkvIJ27FqNRzsXZrRe6Q03XjwN0h10uUZrjphyX...


10. 다수 도메인 사용
만약 도메인키를 적용할 도메인이 많다면 아래와 같이 소프트링크를 걸어주셔야 됩니다.
이것은 수신측 메일서버에서 메일을 받은 경우, 송신 메일서버로 dkverify 쿼리를 요청하는데
송신 메일서버의 qmail-dk가 default키를 /etc/domainkeys/도메인/default 에서 찾기 때문입니다.
[root@localhost]# ln -s /etc/domainkeys/foobar.com /etc/domainkeys/foobar2.com

※ 필자의 경우 qmail-dk.c 자체를 수정해서 사용하고 있습니다.
만약 위의 방법 말고 더 좋은 방법을 찾은 분은 리플 남겨주시기 바랍니다.

qmail에 DomainKeys 적용

이번 강좌는 발신지변조 방지 기술중 하나인 DomainKeys 시스템에 대해 다뤄보도록 하겠습니다.
도메인키 시스템은 Yahoo에서 주도하여 개발된 새로운 인증 방법으로써 최근엔 쥐메일 등과 같은
업체에서도 시범적 적용을 하고 있는 기술 입니다.
이 기술은 발신지 메일서버의 비밀키로 사인(Sign)되어온 메일의 도메인 정보를 가지고
수신지에서 발신지의 공개키(public key)를 이용하여 발신지 서버에 인증을 한뒤
메일의 정상유무를 확인하는 방법으로 최근 유행하는 피싱(phising) 또는 발신지 변조메일 등을
원천적으로 차단할 수 있습니다.
이는 기존 AOL의 SPF 기술보다 한단계 진보한 기술이라 볼 수 있습니다.

만약 이 기술에 대해서 자세한 문헌을 보고 싶다면 아래 URL을 참조하시기 바랍니다.
※ http://domainkeys.sf.net/ , http://antispam.yahoo.com/domainkeys

1. libdomainkeys 다운로드 (최신버전: http://sourceforge.net/projects/domainkeys/)
libdomainkeys는 gmail.com 의 운영자인 Russell Nelson 씨가 만든 라이브러리로써,
쉽고 빠르게 적용할 수 있다는 장점이 있습니다.
[root@localhost]# wget http://nchc.dl.sourceforge.net/sourceforge/domainkeys/libdomainkeys-0.68.tar.gz
[root@localhost]# tar xfz libdomainkeys-0.68.tar.gz
[root@localhost]# cd libdomainkeys-0.68
[root@localhost]# make


2. qmail-dk 패치 적용
[root@localhost]# wget http://www.qmail.org/qmail-1.03-dk-0.54.patch
[root@localhost]# tar xfz qmail-1.03.tar.gz
[root@localhost]# cd qmail-1.03
[root@localhost]# patch -p1 < ../qmail-1.03-dk-0.54.patch

※ 만약 smtp relay allow 방식이 qmail + vpopmail를 사용하는 방법이 아니라
  qmail + smtp-auth 방식을 사용하시는 분들은 위 패치를 하신뒤 아래 패치도
  같이 해주셔야 되며, vpopmail을 이용하시는 분들은 3번 섹션으로 넘기시면 됩니다.
[root@localhost]# wget http://jeremy.kister.net/code/qmail-dk-0.54-auth.patch
[root@localhost]# cd qmail-1.03
[root@localhost]# patch -p1 < ../qmail-dk-0.54-auth.patch


3. qmail-dk 바이너리 파일의 생성 및 설치
이제 DomainKeys 시스템에서 사용될 바이너리 파일을 생성하도록 하겠습니다.
하지만 컴파일 하기에 앞서 주의하셔야 될 사항이 있습니다.
바로 큐메일소스 디렉토리의 위치 입니다.
위에서 적용한 qmail-dk 패치의 내용중에는 qmail-dk.c 라는 원시코드가 생성이 되는 부분이 있는데
이 원시코드에서 libdomainkeys의 헤더를 자신의 상위 디렉토리에 찾도록 코딩되어 있습니다.
따라서 큐메일소스 디렉토리는 반드시 libdomainkeys 디렉토리 내에 존재해야 됩니다.
[root@localhost]# mv qmail-1.03 libdomainkeys-0.68/
[root@localhost]# cd libdomainkeys-0.68/qmail-1.03
[root@localhost]# make qmail-dk
[root@localhost]# cp qmail-dk /var/qmail/bin/
[root@localhost]# chown root.qmail /var/qmail/bin/qmail-dk
[root@localhost]# cp qmail-dk.8 /var/qmail/man/man8/


4. RSA DomainKeys 생성
이곳에서 생선된 RSA Key가 실제 메일헤더에 적용되어 발송될 인증키 입니다.
[root@localhost]# mkdir -p /etc/domainkeys/foobar.com/
[root@localhost]# cd /etc/domainkeys/foobar.com/
[root@localhost]# openssl genrsa -out rsa.private 768
[root@localhost]# openssl rsa -in rsa.private -out rsa.public -pubout -outform PEM
[root@localhost]# mv rsa.private default
[root@localhost]# chown -R qmaild .
[root@localhost]# chmod 600 default


5. public Domainkey 추출
DomainKeys를 적용하려면 DNS의 Zone 파일에 TXT 레코드와 공용키를 추가시켜야 됩니다.
따라서 TXT 레코드에서 사용할 공용키(public key)를 추출하도록 합니다.
[root@localhost]# grep -v ^- rsa.public | perl -e 'while(<>){chop;$l.=$_;}print "t=y; p=$l;\n";'


6. Zone 파일에 TXT 레코드 추가
위에서 말했듯이 도메인키 시스템을 적용하려면 존 파일에 TXT 레코드가 필요 합니다.
따라서 기존 존파일에 아래의 내용을 추가시켜 줍니다.
_domainkey   IN   TXT   "t=y; o=-;"
default._domainkey   IN   TXT   "public DomainKey"

※ 위의 내용만으로는 어디에 적용하실지 혼동하시는 분이 계실까봐 샘플을 보여드립니다.
[root@localhost]# cat /var/named/zone-foobar.com
$TTL 86400
@       IN   SOA   ns.foobar.com. root.foobar.com. (
                2007010100 ; Serial
                 10800   ; Refresh (3 hours, 10800)
                 3600    ; Retry (1 hours, 3600)
                 1209600  ; Expire (2 weeks, 1209600)
                 86400   ; Minimum (1 days, 86400)
                 )
;
; Default Setting (NS, MX, A)
        IN   NS   ns.foobar.com.
        IN   MX 10  mail.foobar.com.
        IN   A    192.168.0.1
;
; DomainKeys Setting (TXT)
_domainkey   IN   TXT   "t=y; o=-;"
default._domainkey   IN   TXT   "t=y; p=MHwwDQYJKoZIhvcNAQ...."
;
; Name servers (registered at InterNIC)
ns       IN   A    192.168.0.1
;
; Hosts Here - This is comments
www      IN   A    192.168.0.1



7. qmail-queue 파일의 교체
이제 큐메일에서 메일을 발송할 때 domainkey를 메일헤더에 추가하여 발송하도록
위에서 설치했던 qmail-dk를 사용하도록 큐메일 파일을 교체해주어야 합니다.
[root@localhost]# ln /var/qmail/bin/qmail-queue /var/qmail/bin/qmail-queue.orig
[root@localhost]# ln /var/qmail/bin/qmail-dk /var/qmail/bin/qmail-queue.new
[root@localhost]# mv /var/qmail/bin/qmail-queue.new /var/qmail/bin/qmail-queue


8. tcp.smtp 수정
처음 패치를 했을때와 마찬가지로 이 부분도 smtp-auth 사용자와 vpopmail 사용자는
각각 다른 내용으로 tcp.smtp에 추가를 해주어야 됩니다.
1. smtp-auth 사용자
[root@localhost]# vi /etc/tcp.smtp
:allow,DKVERIFY="DEGIJKfh",QMAILQUEUE="bin/qmail-dk"
[root@localhost]# tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtp

2. vpopmail 사용자
[root@localhost]# vi /home/vpopmail/etc/tcp.smtp
127.0.0.1:allow,RELAYCLIENT="",DKSIGN="/etc/domainkeys/foobar.com/default",QMAILQUE
UE="bin/qmail-dk"
192.168.0.1:allow,RELAYCLIENT="",DKSIGN="/etc/domainkeys/foobar.com/default",QMAILQU
EUE="bin/qmail-dk"
:allow,DKVERIFY="DEGIJKfh",QMAILQUEUE="bin/qmail-dk"
[root@localhost]# /home/vpopmail/bin/clearopensmtp


이제 DomainKeys를 사용할 준비가 모두 끝났습니다.
실제로 yahoo와 gmail로 메일을 발송해보시기 바랍니다.

9. DomainKeys 적용확인
야후에서는 도메인키 인증이 되면 메일을 읽었을 때 "발신:" 부분에 아래와 같은 메시지가 남습니다.
야후! 도메인키는, 이 메세지가 다음 도메인으로 부터 보내진것을 입증합니다 : foobar.com.

구글에서는 메일을 읽은뒤, 오른쪽에 보시면 "추가옵션" 이라는 부분이 있습니다.
클릭하시면 보낸사람 오른쪽으로 "서명한 사람: foobar.com" 이라는 메시지가 붙습니다.
혹은 제목 아래의 옵션들중 "원본 보기"를 클릭하시면 메일헤더를 보실 수 있는데
아래와 같은 메일헤더가 추가되어 있으면 성공적으로 도메인키가 적용이 된것 입니다.
DomainKey-Status: good (test mode)
Received: (qmail 23592 invoked from network); 13 Jan 2007 21:21:12 +0900
Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys
DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws;
s=default; d=foobar.com;
b=oIozmfhoDF+L3+hhO0ncfSh4FdLBp3yiyBkvIJ27FqNRzsXZrRe6Q03XjwN0h10uUZrjphyX...


10. 다수 도메인 사용
만약 도메인키를 적용할 도메인이 많다면 아래와 같이 소프트링크를 걸어주셔야 됩니다.
이것은 수신측 메일서버에서 메일을 받은 경우, 송신 메일서버로 dkverify 쿼리를 요청하는데
송신 메일서버의 qmail-dk가 default키를 /etc/domainkeys/도메인/default 에서 찾기 때문입니다.
[root@localhost]# ln -s /etc/domainkeys/foobar.com /etc/domainkeys/foobar2.com

※ 필자의 경우 qmail-dk.c 자체를 수정해서 사용하고 있습니다.
만약 위의 방법 말고 더 좋은 방법을 찾은 분은 리플 남겨주시기 바랍니다.

qmail 릴레이 허용 방법 소개

큐메일에서 특정 사용자에게 smtp relay를 열어주기 위한 방법은 많이 있습니다.
이 때문에 큐메일을 처음 접하시는 분들은 혼란을 초래하기도 하죠.
그러나 조금만 각도를 달리해서 생각해보면 그만큼 유연한 설정이 가능하다는 장점이 될 수 있습니다.

이번 강좌에서는 큐메일에서 smtp relay를 열어주기 위한 방법을 소개만 하겠습니다.
실제적인 적용법을 다 적기에는 너무 많군요.

1. qmail + smtp-auth 패치를 적용해서 사용하는 경우
qmail-smtpd를 패치하여 smtp 인증을 사용하는 방법 입니다.
패치된 qmail-smtpd는 다양한 인증 프로그램을 사용할 수 있으므로 유연한 설정이 가능하죠
대표적인 인증 프로그램으로는 다음과 같은 프로그램들이 있습니다.
1. vchkpw
  vchkpw는 vpopmail의 pop 인증 프로그램 입니다.
  vpopmail 가상 유저들에게 smtp 서비스를 해줄 수 있는 프로그램이죠.
2. cmd5checkpw
  계정과 암호를 별도의 파일(/etc/poppasswd)에서 관리를 합니다.
  많지 않은 사용자에게만 smtp 서비스를 해줄 때 사용 됩니다.
3. checkpassword
  sendmail처럼 시스템 계정(/etc/passwd)을 사용하여 smtp 서비스를 해줍니다.
4. checkpassword + mysql
  checkpassword에 mysql 패치를 적용해서 시스템 계정과 DB에 만든 가상 계정을
  동시에 사용하여 smtp 서비스를 해줄 수 있습니다.


2. vpopmail 을 사용할 경우
1. vpopmail의 로밍 서비스
  vpopmail의 로밍 서비스를 가능하도록 컴파일 했다면(--enable-roaming-users=y)
  vpopmail로 만들어준 가상 유저들은 pop에 로그인후 smtp 서비스를 사용할 수 있습니다.
  이것은 vpopmail이 해당 유저가 pop 인증에 성공했을 경우에 cdb 파일을 자동으로
  업데이트 해주기 때문 입니다.
  이렇게 업데이트 된 cdb 파일을 qmail-smtpd를 구동시키는 tcpserver가 참고하고
  그 뒤에 RELAYCLIENT 환경 변수를 만들어서 relay가 허용이 됩니다.
2. vpopmail + mysql
  vpopmail을 mysql과 함께 사용할 수 있도록 컴파일 했을 경우에는 pop 인증이 성공할 경우
  lastauth 라는 테이블이 업데이트 됩니다.
  또한 tcpserver + Matt Simerson의 mysql 패치를 사용하면 이 테이블에서 pop 접근에
  성공한 ip 주소를 읽어들여 smtp relay를 허용합니다.
  만약 매우 많은 pop 유저를 가지는 대형 서버의 경우 이 방법이 좋습니다.
  왜냐하면 매번 cdb 파일을 다시 읽어드리거나 업데이트 하지 않아도 되기 때문 입니다.
  qmail-smtpd 스크립트의 tcpserver에는 -x 옵션 자체를 사용하지 않게 됩니다.


3. qmail + vida 형식으로 운영하는 경우
이것은 한국에는 매우 드문 방식이지만, 주로 일본에서 많이 사용되는 방법 입니다.
필자가 일본에서 처음으로 외주를 맡았을때 vida 라는 형식을 사용하는것을 처음 알았습니다.
vida는 qmail Virtual Domain and Authentication package 라고 불리웁니다.
정말로 큰 대규모 메일서버라면 qmail+vpopmail 보다는 qmail+vida 시스템이 빠르다는것을
어떤 문서에서 본 기억이 나는군요.
저도 잠깐 다뤄본 것이기 때문에 깊게 설명을 해드릴 수는 없고, 간략한 특징만 알려드리겠습니다.
그저 그냥 이런게 있구나~ 정도로 알아두시면 될 듯 합니다.
- checkpassword의 인증 방식의 추가(CRAM-MD5, APOP 대응)
- checkpassword의 SMTP 인증 대응
- qmail-smtpup 프로그램의 추가
- 가상 메일 박스 대응
- IP주소 베이스 및 로그인 ID베이스의 버추얼 도메인 대응
- 패스워드 데이타베이스는 CDB 를 이용하기 때문에 유저수가 많아도 빠름
- D.J.Bernstein씨의 라이브러리를 적극적으로 이용

MTA Error Code

▶ SERVER REPLY: 501 Denied domain name
; 도메인주소를 잘못 입력 or 수신측에서 도메인을 수신거부한 경우

▶ 421 Server too busy.
; 수신측 서버의 응답지연. 수신서버의 트래픽등으로 메일을 수신 받지 못하는 상황에서 발송자에게 리턴 메일을 보냄.

▶ 421-Microsoft ESMTP MAIL Service, Version: 5.0.2195.5600 ready at Service not available, closing transmission channel
; MS사의 smtp 서버의 장애로 인해 메일을 수신받지 못하는 상황에서 리턴된 메시지.

▶ 421 4.3.2 Your IP(218.236.206.104) is filtered and this connection will be closed. You must register your IP to spammaster@hanafos.com By SpaceLee, the Lord of mail server.
; 우리쪽 (mail.hanafos.com) 서버로 메일을 발송시 필터링 조건에 위배되어 스패머로 인식되고 필터링 되어 발신자에게 리턴되는 메시지.

▶ 441 4.4.1 No answer from host
; 수신측 서버의 응답이 없어서 리턴된 메시지.

▶ 451 4.4.0 DNS resolving error
; 수신측 서버의 도메인을 못찾아 리턴된 메시지.

▶ 451 4.3.0 Other or undefined mail system status
; 수신측 메일 시스템의 프로토콜이 틀리거나 수신 smtp 서버가 아닐경우 리턴되는 메시지.

▶ 451 4.3.0 Temporary system failure. Please try again later.
; 수신 서버의 일시적인 장애로 인해 메일을 수신받지 못해 리턴된 메시지.

▶ 451 4.4.2 Bad connection (io timeout)
; 수신 서버의 응답이 없어서 응답시간이 초과 되어 리턴된 메시지.

▶ 451 Relay Server Not Ready.
; 수신측 서버에서 릴레이 기능이 안돼어 리턴된 메시지.

▶ 452 4.4.5 Insufficient disk space; try again later
; 수신서버의 디스크용량이 부족하여 메일을 수신받지 못해 리턴된 메시지.

▶ 452 4.4.5 ... Insufficient disk space; try again later
; 수신자(leo@buffgame.com)의 메일함 용량이 부족하여 메일을 수신받지 못해 리턴된 메시지

▶ 500 Syntax Error, Command Unrecognized EHLO mo02.hanafos.com
; 발송자의 메일 발송기(아웃룩, 유도라 등등)에서 메일발송시 수신측 메일 서버에서 SMTP 명령어를 인식하지 못해 리턴된 메시지.

▶ 500 5.5.1 Command unrecognized: "XXXX mo02.hanafos.com"
; 수신서버가 SMTP 명령어를 인식 하지 못함. (위와 동일).

▶ 501 5.1.8 Sender domain must exist(honorstech.com)
; 수신측 도메인(honorstech.com) 이 존재 하지 않아 리턴된 메시지.

▶ 502 Not implemented
; 수신측 서버가 smtp 명령어를 인식 하지 못해 리턴된 메시지.

▶ 505 Authentication required
; 수신측 서버가 릴레이 인증 등을 허용하지 않아 리턴된 메시지.

▶ 512 5.1.2 Bad destination system address
; 수신 서버의 장애나 네트웍 트래픽등으로 인헤 수신서버가 응답이 없을 때 리턴된 메시지.

▶ 550 5.1.1 Suspended user
; 수신자의 사용자의 계정이 중단 상태.

▶ 550 5.1.2 ... Unsupported mail destination
; 수신 서버가 응답이 지연되어 리턴된 메시지.

▶ 550 5.7.1 ... Access denied.(211.202.13.144)
; 수신자(gyunu@chollian.net)가 발신자의 메일주소를 수신 거부한 상태.

▶ 550 5.7.1 ... Relaying denied. IP name lookup failed [211.202.13.144]
; 수신 서버에서 발신자의 IP에 대해 릴레이 거부를 하여 메일을 보내지 못해 리턴된 메시지.

▶ 550 Requested action not taken: mailbox unavailable
; 수신자의 메일함을 찾지 못해 리턴된 메시지.

▶ 550 Mail is reject ( filtering reject )
; 수신 서버에서 발신자의 메일 주소나 IP를 필터링 하여 거부되어 리턴된 메시지.

▶ 550 5.1.1 ... User unknown
; 수신자 (hkaprk@jeill.co.kr)계정을 찾지 못해 리턴된 메시지.

▶ 550 5.7.1 Unable to relay for lyc410@hanafos.net
; 수신 서버에서 릴레이 거부를 하여 리턴된 메시지.

▶ 550 Invalid recipient lobster@fernand.com
; 수신자 계정을 찾지 못해 리턴된 메시지 .

▶ 550 RCPT ERROR. Mailbox doesn't exist
; 수신자 메일함이 존재 하지 않아서 리턴된 메시지.

▶ 553 5.3.0 ... spam
; 발송자의 계정이 수신서버 상에서 스패머로 등록이 되어 메일 수신 거부를 해서 리턴된 메시지

▶ 553 sorry, your envelope sender is in my badmailfrom list
; 발신자의 메일 주소가 수신서버상에서 블랙리스트에 올라 거부되어 리턴됨.

▶ 553 sorry, that domain isn't in my list of allowed rcpt hosts
; 발신자의 메일 도메인주소 자체가 수신 서버에서 차단되어 리턴된 메시지.

▶ 553 5.1.8 ... Domain of sender address uni@honorstech.com does not exist
; 발신자의 도메인에 대해 수신서버에서 체크 하여 없는 도메인일 경우 리턴시킨 메시지.

▶ 553 5.0.0 We do not accept mail from spammers - If you have questions,please email admin@www.narun.net.
; 발신자의 메일 계정이 스패머로 수신서버에서 등록이 되어 리턴된 메시지.

▶ 553 5.0.0 Your message may contain the Win32.Klez worm!!- If you have questions,please email postmaster@ecweb-1.blueweb.co.kr.
; 발신자의 메일에서 Win32.Klez 라는 웜바이러스가 발견되어 리턴된 메시지.

▶ 553 sorry, your envelope sender is enlisted as spammer.
; 발신자의 메일 주소가 수신서버상의 스패머 리스트에 등록 되어 리턴된 메시지.

▶ 553-This target address is not our MX service
; 수신자의 주소가 수신서버에서 서비스 안하는 도메인일 경우 리턴된 메시지.

▶ 554 5.3.2 Rejected by mailbox host. REPLY:(250 ... Sender ok)
; 수신자가 발송자의 메일 계정에 대해 수신 거부를 하여 리턴된 메시지 .

▶ 554 5.3.0 Mail have traversed Too many hops. Reject it.
; 발신자가 메일을 보낼 때 동보메일로 수신자의 메일 계정을 수신서버의 제한량 이상 넣어 보내어 리턴된 메시지.

▶ 554 5.3.2 Rejected by mailbox host. REPLY:(550 5.1.1 unknown or illegal alias: kgng_h_w@samsung.com)
; 수신자가 발송자의 메일 계정에 대해 수신거부를 설정하여 리턴된 메시지.

▶ 554 1048035239.13309.hanmir accept failed. [code=-1]
; hanmir 서버에서 응답이 안돼어 리턴된 메시지.

▶ 554 delivery error: dd Sorry, your message to bk6218@yahoo.co.kr cannot be delivered. This account is over quota. - mta111.mail.yahoo.co.kr
; 수신자의 메일함 용량 초과로 인해 리턴된 메시지.

▶ 554 5.1.0 Sender Denied
; 발신자의 계정을 수신서버에서 수신 거부함.

▶ 554 : Recipient address rejected: Access denied
; 수신자가 발신자의 계정에 대해 수신 거부를 설정함.

qmail + vpopmail 사용환경에서의 procmail 설정

메일서버를 운영하면서 골치아픈것 제 1순위를 뽑자면 역시 스팸메일 일것입니다.
물론 각종 스팸툴등을 사용하는 방법도 있습니다만 시스템에 부하를 많이 가져온다는 단점이 있죠
또한 최근 유행하는 reverse domain 체크라던지 SPF 적용도 한가지 방법일 수 있을것입니다.
그러나 최대한 안귀찮게(?) 스팸을 걸러내는 방법은 procmail이 좋을듯 합니다.

1. hcode 설치
hcode는 한글코드를 인/디코딩 하기 위해 필요한 바이너리 파일 입니다.
검색엔진에서 쉽게 구할 수 있으나, 제대로 작동하지 않는 소스가 상당수 차지하고 있죠
따라서 필자는 임은재님께서 올려주신 hcode 소스를 사용하도록 하겠습니다.
[root@localhost]# wget http://people.kldp.org/~eunjea/tmp/hcode2.1-mailpatch3-TABpatch.tgz
[root@localhost]# tar xfz hcode2.1-mailpatch3-TABpatch.tgz
[root@localhost]# cd hcode2.1-mailpatch3-TABpatch
[root@localhost]# make
[root@localhost]# cp -pf hcode /var/qmail/bin/


2. procmail 설정
레드헷 계열이라면 기본적으로 procmail이 rpm으로 설치되어 있을 것입니다.
만약 설치되지 않아있다면 yum등을 이용해 설치를 하시면 되겠습니다.
procmail의 설정 방법은 매우 간단합니다.
아마 이곳저곳 찾아보신 발빠른 분들이라면 필자의 필터링 설정과 약간 다르다는걸 눈치채신 분들도
있을거라 예상하지만 대부분의 문서는 vpopmail 로밍 환경이 아닌 mysql 환경을 타겟으로
제작된 문서가 상당수 입니다.

[root@localhost]# vi /etc/procmailrc
LOGFILE=/var/log/qmail/procmail.log

## Filtering Rules
# 인코드되어 날아오는 헤더를 디코드 하는 부분.
:0 Efhw
*^(Subject|From|Cc):.*=\?EUC-KR\?(B|Q)\?
|/usr/bin/formail -c | /var/qmail/bin/hcode -dk -m

:0 Efhw
*^(Subject|From|Cc):.*=\?ks_c_5601-1987\?(B|Q)\?
|/usr/bin/formail -c | /var/qmail/bin/hcode -dk -m

:0 Efhw
*^(Subject|From|Cc):.*=\?KSC5601\?(B|Q)\?
|/usr/bin/formail -c | /var/qmail/bin/hcode -dk -m

:0 Efhw
*^(Subject|From|Cc):.*=\?ISO-8859-1\?(b|B|Q)\?
|/usr/bin/formail -c | /var/qmail/bin/hcode -dk -m

# 영문
:0
* ^Subject:.*(advert|sex|porno|casino)
"/home/vpopmail/domains/foobar.com/spam/Maildir/"

# 한글
:0
* ^Subject:.*(광고|홍보|廣告|몰카|성인|광 고|홍 보|몰 카|성 인|포르노|광.고|홍.보|몰.카|성.인)
"/home/vpopmail/domains/foobar.com/spam/Maildir/"

# 괄호
:0
* ^Subject:.*(\[광고\]|\[홍보\]|\[몰카\]|\[성인\])
"/home/vpopmail/domains/foobar.com/spam/Maildir/"

※ 이 부분에서 유의해야 할 부분이 있습니다.
만약 실제계정(account)가 아닌 가상계정(vpopmail)을 사용하고 계신다면 반드시 필터링룰에 의해
걸러진 스팸메일이 어디로 보내져야 되는지 "절대경로"로 써주셔야 됩니다.
위 예제는 spam@foobar.com 이라는 계정을 생성해주고 필터링된 메일을 모두 spam 계정으로
전송되도록 설정 해놓은 것입니다.
만약 직접 삭제되도록 하고 싶다면 "/dev/null" 이런식으로 변경하시면 됩니다.

3. procmail log 파일 생성
걸러진 스팸메일의 목록을 확인하기 위해 로그 파일을 생성하도록 하겠습니다.
[root@localhost]# touch /var/log/qmail/procmail.log
[root@localhost]# chmod 666 /var/log/qmail/procmail.log


4. vpopmail과 procmail의 연동
모든 설정이 끝났으므로 vpopmail과 연동하도록 설정하면 됩니다.
vpopmail의 로밍 서비스를 이용하게 되면 전체 컨트롤 파일인 /var/qmail/rc 에서
반영되도록 할 수는 없고 모든 메일 도메인계정 아래에 있는 .qmail-default에서 연동해줘야 됩니다.
[root@localhost]# cd /home/vpopmail/domains/foobar.com
[root@localhost]# vi .qmail-default
| (/var/qmail/bin/preline /usr/bin/procmail -p -m /etc/procmailrc || /home/vpopmail/bin/vdelivermail '' bounce-no-mailbox )