Sendmail环境下对抗垃圾邮件的处理方法

12/3/2006来源:Qmail人气:5951

传统的邮件传送协定 (SMTP)由于不具备对使用者身份进行认证的功能,此问题很容易被恶意用户滥用,而导致自己的邮件服务器成为广告邮件或垃圾邮件的中转站。由于没有身份认证功能的邮件传送机制,也造成系统管理或是网路管理人员,处理问题邮件追踪时的困难,导致你的服务器被列入黑名单,所有发出的邮件信息,不管是正常的,还是非正常的邮件,都有可能补拒收。
Sendmail从8.9.3版本开始缺省设置禁止转发垃圾邮件,,在此之前的版本在这方面都存在着严重的安全缺陷。因此,有必要把您的Sendmail 升级到 8.9.3 以上版本。考虑到其它方面的安全漏洞,我们建议您升级到当前最新版本,您可以在Sendmail的主页上http://www.sendmail.org 下载最新的版本。
新安装的Sendmail 默认不允许转发任何邮件,如果你的邮件服务器需要为某些用户提供转发服务,你需要对Sendmail的配置文件进行设置。设置方法有多种,比较简单的方法是在/etc/mail/下生成一个名字为relay-domains 的文件,在该文件中列出需要relay的ip或域名;或把用户的IP加入到/etc/mail/access中,他才能使用邮件服务器发邮件。但是这样对于移动用户或没有固定的IP的用户,将无法通过此邮件服务器发送邮件。
针对这种情况,网上解决的办法有很多,本文主要就目前比较好的两种实现方法作安装说明:
%26#61548; SMTP认证服务器 (SMTP AUTH)
%26#61548; 动态转发授权控制(Dynamic Relay Authorization Control)

1.SMTP认证服务器 (SMTP AUTH)的实现方法
本文所用的编译和测试环境是Redhat linux 6.2,使用cyrus-SASL 1.5.24和Sendmail 8.11.6。在Redhat Linux 7.1以上版本中已经不需要再编译,只需要生成自己的sendmail.cf即可。
cyrus-sasl可以到ftp://ftp.andrew.cmu.edu/pub/cyrus-mail 下载最新的版本
Sendmail可以到http://www.sendmail.org 的网站上下载。
将sendmail.8.11.6.tar.gz和cyrus-sasl-1.5.24.tar.gz源程序在/usr/local/src目录下,方便下面安装。
[root@firewall src]# cd /usr/local/src
[root@firewall src]# tar zxf sendmail.8.11.6.tar.gz
[root@firewall src]# tar zxf cyrus-sasl-1.5.24.tar.gz
[root@firewall src]# cd cyrus-sasl-1.5.24/
[root@firewall cyrus-sasl-1.5.24]# ./configure -PRefix=/usr --enable-login --with-pwcheck --with-digest
[root@firewall cyrus-sasl-1.5.24]# make
[root@firewall cyrus-sasl-1.5.24]# make install
此时,你的cyrus-sasl已自动安装所有的SASL库文件在/usr/lib/sasl/目录和头文件在/usr/include/目录下。
[root@firewall cyrus-sasl-1.5.24]# mkdir /var/pwcheck
[root@firewall cyrus-sasl-1.5.24]# cd /usr/lib/sasl/
[root@firewall sasl]# cat >Sendmail.conf
pwcheck_method: shadow
^D
设置 sendmail 的使用者身份检查验证方式,这里使用系统帐号的密码来进行验证。
下面是编译Sendmail,相信各位朋友都很熟悉了吧。
[root@firewall sasl]# cd /usr/local/src/sendmail-8.11.6/
[root@firewall sendmail-8.11.6]# cd devtools/Site/
[root@firewall Site]# cat >site.config.mc
PREPENDDEF(`confMAPDEF',`-DMAP_REGEX')
PREPENDDEF(`confOPTIMIZE',`-O6')
PREPENDDEF(`confOPTIMIZE',`-O6')
APPENDDEF(`confENVDEF',`-DSASL')
APPENDDEF(`conf_sendmail_LIBS',`-lsasl')
APPENDDEF(`confLIBDIRS',`-L/usr/local/lib -L/usr/lib/sasl')
APPENDDEF(`confINCDIRS',`-I/usr/local/include -I/usr/include/sasl')
^D
[root@firewall Site]# cd /usr/local/src/sendmail-8.11.6/sendmail/
[root@firewall sendmail]# sh Build -c -f ../devtools/Site/site.config.mc
[root@firewall sendmail]# sh Build install
[root@firewall sendmail]# cd ../cf/cf/
[root@firewall cf]# cat >sendmail.mc
divert(-1)
dnl This is the macro config file used to generate the /etc/sendmail.cf
dnl file. If you modify thei file you will have to regenerate the
dnl /etc/sendmail.cf by running this macro config through the m4
dnl preprocessor:
dnl m4 /etc/sendmail.mc > /etc/sendmail.cf
dnl You will need to have the Sendmail-cf package installed for this to work.
include(`/usr/local/src/sendmail-8.11.6/cf')
define(`confDEF_USER_ID',`8:12')
OSTYPE(`linux')
undefine(`UUCP_RELAY')
undefine(`BITNET_RELAY')
define(`confAUTO_REBUILD')
define(`confTO_CONNECT', `1m')
define(`confTRY_NULL_MX_LIST',true)
define(`confDONT_PROBE_INTERFACES',true)
define(`PROCMAIL_MAILER_PATH',`/usr/bin/procmail')
FEATURE(`smrsh',`/usr/sbin/smrsh')
FEATURE(`mailertable',`hash -o /etc/mail/mailertable')
FEATURE(`virtusertable',`hash -o /etc/mail/virtusertable')
FEATURE(redirect)
FEATURE(always_add_domain)
FEATURE(use_cw_file)
FEATURE(local_procmail)
MAILER(smtp)
MAILER(procmail)
FEATURE(`access_db')
FEATURE(`blacklist_recipients')
dnl We strongly recommend to comment this one out if you want to protect
dnl yourself from spam. However, the laptop and users on computers that do
dnl not hav 24x7 DNS do need this.
FEATURE(`accept_unresolvable_domains')
dnl FEATURE(`relay_based_on_MX')
TRUST_AUTH_MECH(`LOGIN PLAIN ')dnl
define(`confAUTH_MECHANISMS', `LOGIN PLAIN')dnl
FEATURE(`no_default_msa')dnl turn off default entry for MSA
DAEMON_OPTIONS(`Port=25, Name=MSA, M=E')dnl
^D
[root@firewall cf]# sh Build sendmail.cf
[root@firewall cf]# cp sendmail.cf /etc/mail <-将新生成的sendmail.cf复制到/etc/mail下
[root@firewall cf]# touch /etc/mail/local-host-names
最后启动sendmail
[root@firewall cf]# /usr/sbin/sendmail -bd -q20m

以下是测试过程:
检查SASL是否已经生效。过程如下:

[root@firewall cf]# sendmail -d0.1 -bv root | grep SASL
NETINET NETUNIX NEWDB QUEUE SASL SCANF SMTP USERDB XDEBUG

其中有SASL,表示Sendmail确实支持SASL了。
[root@firewall cf]# telnet 0 25
Trying 0.0.0.0...
Connected to 0.
Escape character is '^]'.
220 localhost.localdomain ESMTP Sendmail 8.11.6/8.11.6; Sat, 11 Aug 2001 17:21:10 +0800
ehlo 1
250-localhost.localdomain Hello IDENT:root@firewall [127.0.0.1], pleased to meet you
250-ENHANCEDSTATUSCODES
250-EXPN
250-VERB
250-8BITMIME
250-SIZE
250-DSN
250-ONEX
250-XUSR
250-AUTH LOGIN PLAIN
250 HELP

[root@firewall cf]# /etc/rc.d/rc3.d/S80sendmail restart
启动Sendmail服务来看看,你的Sendmail服务已加SMTP AUTH功能啦。下次在发Mail的时候,别忘啦在你的邮件软件的设置中,把“发送邮件服务器中”——“我的服务器需要认证”打下勾。这样你可以不怕没有固定IP和出差在外,不能使用公司的邮件服务器发送邮件啦。

2.动态转发授权控制(Dynamic Relay Authorization Control) 的实现方法
Sendmail环境下除了修改SMTP服务器,加入SMTP认证以外,还有一种灵活的方法来实现——动态转发授权控制(Dynamic Relay Authorization Control),简称DRAC。
采用动态控制,在用户收取邮件时,进行身份验证。对于验证通过的用户,后台监控程序(DRAC守护过程)会实时地将用户当前的IP记录到数据库中。具体实现过程是:先“收”后“发”, 收件时要经用户身份认证,认证后POP或IMAP服务器使用RPC调用请求DRAC守护进程将用户的IP加入数据库,IP地址在SMTP Server的数据库中保存30分钟(具体看管理员设置时间)。每收取一次邮件,计时重新开始。30分钟内如果用户不使用邮件服务收发,则DRAC将用户的IP从数据库中删除。这种做法保证了移动用户可以收发自己的邮件。
实现方法如下:
文中所涉及到的源文件:
Sendmail可以到http://www.sendmail.org 的网站上下载。
Qpopper(POP3服务器)的源文件包可以从http://www.eudora.com/qpopper网站下载。本文使用的qpopper的版本是4.04
drac源文件包可以从http://mail.cc.umanitoba.ca/drac/index.html网站下载。本文使用的是drac的版本是1.11。
[root@test src]# cd /usr/local/src
[root@test src]# wget ftp://ftp.cc.umanitoba.ca/src/drac.tar.Z
--20:54:29-- ftp://ftp.cc.umanitoba.ca/src/drac.tar.Z
=> `drac.tar.Z'
Resolving ftp.cc.umanitoba.ca... done.
Connecting to ftp.cc.umanitoba.ca[130.179.16.23]:21... connected.
Logging in as anonymous ... Logged in!
==> SYST ... done. ==> PWD ... done.
==> TYPE I ... done. ==> CWD /src ... done.
==> PORT ... done. ==> RETR drac.tar.Z ... done.
Length: 19,736 (unauthoritative)
100%[=====================================>] 19,736 3.42K/s ETA 00:00

20:54:47 (3.42 KB/s) - `drac.tar.Z' saved [19736]

因darc.tar.Z未含路径,故需建立一个新的目录
[root@test src]# mkdir darc
[root@test src]# cd darc
[root@test darc]# tar zxf ../drac.tar.Z
解开源程序包后,可以看看INSTALL的说明来一步步的安装。

2.1 根据你的系统来修改Makefile文件
For Solaris:
INSTALL = /usr/ucb/install
EBIN = /usr/local/sbin
MAN = /usr/local/man/man
DEFS = -DTI_RPC -DFCNTL_LOCK -DSYSINFO
CC =
RANLIB = :
CFLAGS = $(DEFS) -g -I/path/to/db/include
LDLIBS = -L/path/to/db/library -lnsl -ldb
TSTLIBS = -L. -ldrac -lnsl
MANLIB = 3
MANADM = 1m

For SunOS 4.x:
INSTALL = install
EBIN = /usr/local/etc
MAN = /usr/local/man/man
DEFS = -DSOCK_RPC -DFLOCK_LOCK -DGETHOST
CC =
RANLIB = ranlib
CFLAGS = -Dstrtoul=strtol $(DEFS) -g -I/path/to/db/include
LDLIBS = -L/path/to/db/library -ldb
TSTLIBS = -L. -ldrac
RPCGENFLAGS = -I
MANLIB = 3
MANADM = 8

For BSDI:
INSTALL = install
EBIN = /usr/local/sbin
MAN = /usr/local/man/man
DEFS = -DSOCK_RPC -DFCNTL_LOCK -DGETHOST
CC =
RANLIB = ranlib
CFLAGS = $(DEFS) -g -I/path/to/db/include
LDLIBS = -L/path/to/db/library -ldb
TSTLIBS = -L. -ldrac
MANLIB = 3
MANADM = 8

For IRIX 6.2:
INSTALL = /usr/bin/X11/bsdinst
EBIN = /usr/local/sbin
MAN = /usr/local/man/man
DEFS = -DTI_RPC -DFCNTL_LOCK -DSYSINFO -D_SVR4_TIRPC
CC =
RANLIB = :
CFLAGS = $(DEFS) -g -I/path/to/db/include
LDLIBS = -L/path/to/db/library -lnsl -ldb
TSTLIBS = -L. -ldrac -lnsl
MANLIB = 3
MANADM = 1m

For NetBSD:
INSTALL = install
EBIN = /usr/local/sbin
MAN = /usr/local/man/man
DEFS = -DSOCK_RPC -DFCNTL_LOCK -DGETHOST -DDASH_C
CC =
RANLIB = ranlib
CFLAGS = $(DEFS) -g -I/path/to/db/include
LDLIBS =
TSTLIBS = -L. -ldrac
RPCGENFLAGS = -C
MANLIB = 3
MANADM = 8

For FreeBSD 2.2.x:
INSTALL = install
EBIN = /usr/local/sbin
MAN = /usr/local/man/man
DEFS = -DSOCK_RPC -DFLOCK_LOCK -DGETHOST -DDASH_C
CC =
RANLIB = ranlib
CFLAGS = $(DEFS) -g -I/path/to/db/include
LDLIBS =
TSTLIBS = -L. -ldrac
RPCGENFLAGS = -I -C
MANLIB = 3
MANADM = 8

For FreeBSD-4.1 with gdbm-1.8
INSTALL = install
EBIN = /usr/local/sbin
MAN = /usr/local/man/man
DEFS = -DSOCK_RPC -DFLOCK_LOCK -DGETHOST -DDASH_C
CC = cc
RANLIB = :
CFLAGS = $(DEFS) -g -I/usr/local/include
LDLIBS =
TSTLIBS = -L. -ldrac
RPCGENFLAGS = -C
MANLIB = 3
MANADM = 1m

For Linux:
INSTALL = install
EBIN = /usr/local/sbin
MAN = /usr/local/man/man
DEFS = -DSOCK_RPC -DFCNTL_LOCK -DGETHOST -DDASH_C
CC =
RANLIB = :
CFLAGS = $(DEFS) -g
LDLIBS = -ldb
TSTLIBS = -L. -ldrac
RPCGENFLAGS = -C -I
MANLIB = 3
MANADM = 8
本例中的系统是Redhat6.2,属于Linux,按照上面的说明,对Makefile进行了修改。
【注】:cc=改为cc=gcc。

2.2 编译DRAC程序
[root@test drac]# make
gcc -DSOCK_RPC -DFCNTL_LOCK -DGETHOST -DDASH_C -g -c -o dracauth.o dracauth.c
rm -f libdrac.a
ar cq libdrac.a dracauth.o drac_xdr.o drac_clnt.o
: libdrac.a
gcc -o testing testing.o -L. -ldrac
gcc -DSOCK_RPC -DFCNTL_LOCK -DGETHOST -DDASH_C -g -c -o rpc.dracd.o rpc.dracd.c
gcc -DSOCK_RPC -DFCNTL_LOCK -DGETHOST -DDASH_C -g -c -o drac_svc.o drac_svc.c
gcc -o rpc.dracd rpc.dracd.o drac_xdr.o drac_svc.o –ldb
2.3 安装DRAC程序及其帮助文档
[root@test drac]# make install
gcc -DSOCK_RPC -DFCNTL_LOCK -DGETHOST -DDASH_C -g -c -o rpc.dracd.o rpc.dracd.c
gcc -o rpc.dracd rpc.dracd.o drac_xdr.o drac_svc.o -ldb
install -c -o bin -g bin -m 0755 rpc.dracd /usr/local/sbin
[root@test drac]# make install-man
install -c -m 0444 rpc.dracd.1m /usr/local/man/man8/rpc.dracd.8
install -c -m 0444 dracauth.3 /usr/local/man/man3/dracauth.3
[root@test drac]# cat >/etc/rc.d/init.d/dracd

#!/bin/sh -
#
# dracd
PATH=/bin:/sbin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin
export PATH
DAEMON=rpc.dracd
#DRACD_PID=`ps -axc | grep 'rpc.dracd$' | sed -e 's/^ *//' -e 's/ .*//'`
DRACD_PID=`ps -e | grep 'rpc.drac$' | sed -e 's/^ *//' -e 's/ .*//'`
dracd_running() {
ps -p $DRACD_PID >/dev/null 2>%26amp;1
}
case "$1" in
start)
if dracd_running; then
echo "$DAEMON is already running" >%26amp;2
else
echo "starting $DAEMON" >%26amp;2
$DAEMON %26amp;
fi
;;
stop)
if dracd_running; then
echo "stopping $DAEMON" >%26amp;2
kill $DRACD_PID
else
echo "$DAEMON is not running" >%26amp;2
fi
;;
*)
echo "Usage: /etc/init.d/dracd {start|stop}" >%26amp;2
;;
esac
#!/end

[root@test drac]# chmod +x /etc/rc.d/init.d/dracd
[root@test drac]# ln –s /etc/rc .d/init.d/dracd /etc/rc.d/rc3.d/S99dracd

2.4 启动DRAC
[root@test drac]# /etc/rc.d/init.d/dracd start
这样会启动一个运行在后台的服务进程——dracd,由它来充当服务器,它将POP/IMAP提交的用户IP动态加入到邮件服务器的数据库中。
【注】:因DRAC守护进程需要调用RPC,所以需要保护机器上的RPC服务是正常运转的。
[root@test drac]# /etc/rc.d/init.d/portmap start
Starting portmapper: [ OK ]

2.5 编译支持DRAC的POP3服务器
在Qpopper新的版本中,我们可以看到,新的版本已提供DRAC的支持。不需要再加装补丁程序啦。
[root@test drac]# cp libdrac.a /usr/local/lib
[root@test drac]# cd /usr/local/src
[root@test src]# tar zxf qpopper4.0.4.tar.gz
[root@test src]# cd qpopper4.0.4
[root@test qpopper4.0.4]# ./configure --help|grep drac
--with-drac=lib-path Compile in DRAC support
编译Qpopper程序
# ./configure -- --enable-specialauth --with-drac=lib-path=/usr/local/lib/
[root@test qpopper4.0.4]# make
[root@test qpopper4.0.4]# make install
[root@test qpopper4.0.4]# whereis popper
popper: /usr/local/sbin/popper
[root@test qpopper4.0.4]# echo “pop3 stream tcp nowait root /usr/local/lib/popper qpopper –s”>>/etc/inetd.conf
然后再重启inetd服务,这样,POP server支持DRAC的功能开始生效了。

2.6 配置Sendmail.cf
Sendmail服务默认不支持DRAC的,所以我们还需要配置Sendmail.cf文件。
在你的机器上的.mc文件中在LOCAL_CONFIG的下面插入以下代码:
# dynamic relay authorization control map
Kdrac btree /etc/mail/dracd
and the following under LOCAL_RULESETS...

SLocal_check_rcpt
# allow recent POP/IMAP mail clients to relay
R$* $: $%26amp;{client_addr}
R$+ $: $(drac $1 $: ? $)
R? $@ ?
R$+ $@ $#OK
然后,使用m4编译sendmail.mc:
#m4 sendmail.mc > /etc/mail/sendmail.cf
最后,重新启动Sendmail

2.7 测试DRAC
通过网络中的另一台Linux主机(IP地址:192.168.0.100)远程登录邮件服务器的110端口:
[chenjun@test /chenjun]$ telnet 192.168.0.2 110
系统显示:
Trying 192.168.0.2
Connected to test.net (192.168.0.2).
Escape character is '^]'.
+OK ready
user chenjun
+OK PassWord required for chenjun.
pass chenjun
+OK chenjun has 0 visible messages (0 hidden) in 0 octets. (服务器上有0个邮件)
quit
+OK Pop server at test.net signing off.
Connection closed by foreign host.
[chenjun@test mail]$ db_dump -p dracd.db
format=print
type=btree
bt_minkey=2
db_pagesize=512
HEADER=END
192.168.0.100 (登录成功主机的IP)
911955927
从上面的显示结果,我们看到192.168.0.100已经加入到动态数据库中了。
然后你在192.168.0.100的机器发封Mail到其他的邮件,看信发出去啦。
OK,DRAC成功安装。
,