钉子 发表于 2003-6-23 16:55:53

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

<br>
<br>
作者:陈军(chenjun_cn@163.com) <br>
<br>
传统的邮件传送协定 (SMTP)由于不具备对使用者身份进行认证的功能,此问题很容易被恶意用户滥用,而导致自己的邮件服务器成为广告邮件或垃圾邮件的中转站。由于没有身份认证功能的邮件传送机制,也造成系统管理或是网路管理人员,处理问题邮件追踪时的困难,导致你的服务器被列入黑名单,所有发出的邮件信息,不管是正常的,还是非正常的邮件,都有可能补拒收。 <br>
Sendmail从8.9.3版本开始缺省设置禁止转发垃圾邮件,,在此之前的版本在这方面都存在着严重的安全缺陷。因此,有必要把您的Sendmail 升级到 8.9.3 以上版本。考虑到其它方面的安全漏洞,我们建议您升级到当前最新版本,您可以在Sendmail的主页上<a target=_blank href=http://www.sendmail.org>http://www.sendmail.org</a> 下载最新的版本。 <br>
新安装的Sendmail 默认不允许转发任何邮件,如果你的邮件服务器需要为某些用户提供转发服务,你需要对Sendmail的配置文件进行设置。设置方法有多种,比较简单的方法是在/etc/mail/下生成一个名字为relay-domains 的文件,在该文件中列出需要relay的IP或域名;或把用户的IP加入到/etc/mail/access中,他才能使用邮件服务器发邮件。但是这样对于移动用户或没有固定的IP的用户,将无法通过此邮件服务器发送邮件。 <br>
针对这种情况,网上解决的办法有很多,本文主要就目前比较好的两种实现方法作安装说明: <br>
 SMTP认证服务器 (SMTP AUTH) <br>
 动态转发授权控制(Dynamic Relay Authorization Control) <br>
<br>
1.SMTP认证服务器 (SMTP AUTH)的实现方法 <br>
本文所用的编译和测试环境是Redhat Linux 6.2,使用cyrus-SASL 1.5.24和Sendmail 8.11.6。在Redhat Linux 7.1以上版本中已经不需要再编译,只需要生成自己的sendmail.cf即可。 <br>
cyrus-sasl可以到<a target=_blank href=ftp://ftp.andrew.cmu.edu/pub/cyrus-mail>ftp://ftp.andrew.cmu.edu/pub/cyrus-mail</a> 下载最新的版本 <br>
Sendmail可以到<a target=_blank href=http://www.sendmail.org>http://www.sendmail.org</a> 的网站上下载。 <br>
将sendmail.8.11.6.tar.gz和cyrus-sasl-1.5.24.tar.gz源程序在/usr/local/src目录下,方便下面安装。 <br>
# cd /usr/local/src <br>
# tar zxf sendmail.8.11.6.tar.gz <br>
# tar zxf cyrus-sasl-1.5.24.tar.gz <br>
# cd cyrus-sasl-1.5.24/ <br>
# ./configure -prefix=/usr --enable-login --with-pwcheck --with-digest <br>
# make <br>
# make install <br>
此时,你的cyrus-sasl已自动安装所有的SASL库文件在/usr/lib/sasl/目录和头文件在/usr/include/目录下。 <br>
# mkdir /var/pwcheck <br>
# cd /usr/lib/sasl/ <br>
# cat >Sendmail.conf <br>
pwcheck_method: shadow <br>
^D <br>
设置 sendmail 的使用者身份检查验证方式,这里使用系统帐号的密码来进行验证。 <br>
下面是编译Sendmail,相信各位朋友都很熟悉了吧。 <br>
# cd /usr/local/src/sendmail-8.11.6/ <br>
# cd devtools/Site/ <br>
# cat >site.config.mc <br>
PREPENDDEF(`confMAPDEF',`-DMAP_REGEX') <br>
PREPENDDEF(`confOPTIMIZE',`-O6') <br>
PREPENDDEF(`confOPTIMIZE',`-O6') <br>
APPENDDEF(`confENVDEF',`-DSASL') <br>
APPENDDEF(`conf_sendmail_LIBS',`-lsasl') <br>
APPENDDEF(`confLIBDIRS',`-L/usr/local/lib -L/usr/lib/sasl') <br>
APPENDDEF(`confINCDIRS',`-I/usr/local/include -I/usr/include/sasl') <br>
^D <br>
# cd /usr/local/src/sendmail-8.11.6/sendmail/ <br>
# sh Build -c -f ../devtools/Site/site.config.mc <br>
# sh Build install <br>
# cd ../cf/cf/ <br>
# cat >sendmail.mc <br>
divert(-1) <br>
dnl This is the macro config file used to generate the /etc/sendmail.cf <br>
dnl file. If you modify thei file you will have to regenerate the <br>
dnl /etc/sendmail.cf by running this macro config through the m4 <br>
dnl preprocessor: <br>
dnl m4 /etc/sendmail.mc > /etc/sendmail.cf <br>
dnl You will need to have the Sendmail-cf package installed for this to work. <br>
include(`/usr/local/src/sendmail-8.11.6/cf') <br>
define(`confDEF_USER_ID',`8:12') <br>
OSTYPE(`linux') <br>
undefine(`UUCP_RELAY') <br>
undefine(`BITNET_RELAY') <br>
define(`confAUTO_REBUILD') <br>
define(`confTO_CONNECT', `1m') <br>
define(`confTRY_NULL_MX_LIST',true) <br>
define(`confDONT_PROBE_INTERFACES',true) <br>
define(`PROCMAIL_MAILER_PATH',`/usr/bin/procmail') <br>
FEATURE(`smrsh',`/usr/sbin/smrsh') <br>
FEATURE(`mailertable',`hash -o /etc/mail/mailertable') <br>
FEATURE(`virtusertable',`hash -o /etc/mail/virtusertable') <br>
FEATURE(redirect) <br>
FEATURE(always_add_domain) <br>
FEATURE(use_cw_file) <br>
FEATURE(local_procmail) <br>
MAILER(smtp) <br>
MAILER(procmail) <br>
FEATURE(`access_db') <br>
FEATURE(`blacklist_recipients') <br>
dnl We strongly recommend to comment this one out if you want to protect <br>
dnl yourself from spam. However, the laptop and users on computers that do <br>
dnl not hav 24x7 DNS do need this. <br>
FEATURE(`accept_unresolvable_domains') <br>
dnl FEATURE(`relay_based_on_MX') <br>
TRUST_AUTH_MECH(`LOGIN PLAIN ')dnl <br>
define(`confAUTH_MECHANISMS', `LOGIN PLAIN')dnl <br>
FEATURE(`no_default_msa')dnl turn off default entry for MSA <br>
DAEMON_OPTIONS(`Port=25, Name=MSA, M=E')dnl <br>
^D <br>
# sh Build sendmail.cf <br>
# cp sendmail.cf /etc/mail <-将新生成的sendmail.cf复制到/etc/mail下 <br>
# touch /etc/mail/local-host-names <br>
最后启动sendmail <br>
# /usr/sbin/sendmail -bd -q20m <br>
<br>
以下是测试过程: <br>
检查SASL是否已经生效。过程如下: <br>
<br>
# sendmail -d0.1 -bv root | grep SASL <br>
NETINET NETUNIX NEWDB QUEUE SASL SCANF SMTP USERDB XDEBUG <br>
<br>
其中有SASL,表示Sendmail确实支持SASL了。 <br>
# telnet 0 25 <br>
Trying 0.0.0.0... <br>
Connected to 0. <br>
Escape character is '^]'. <br>
220 localhost.localdomain ESMTP Sendmail 8.11.6/8.11.6; Sat, 11 Aug 2001 17:21:10 +0800 <br>
ehlo 1 <br>
250-localhost.localdomain Hello IDENT:root@firewall , pleased to meet you <br>
250-ENHANCEDSTATUSCODES <br>
250-EXPN <br>
250-VERB <br>
250-8BITMIME <br>
250-SIZE <br>
250-DSN <br>
250-ONEX <br>
250-XUSR <br>
250-AUTH LOGIN PLAIN <br>
250 HELP <br>
<br>
# /etc/rc.d/rc3.d/S80sendmail restart <br>
启动Sendmail服务来看看,你的Sendmail服务已加SMTP AUTH功能啦。下次在发Mail的时候,别忘啦在你的邮件软件的设置中,把“发送邮件服务器中”——“我的服务器需要认证”打下勾。这样你可以不怕没有固定IP和出差在外,不能使用公司的邮件服务器发送邮件啦。 <br>
<br>
2.动态转发授权控制(Dynamic Relay Authorization Control) 的实现方法 <br>
Sendmail环境下除了修改SMTP服务器,加入SMTP认证以外,还有一种灵活的方法来实现——动态转发授权控制(Dynamic Relay Authorization Control),简称DRAC。 <br>
采用动态控制,在用户收取邮件时,进行身份验证。对于验证通过的用户,后台监控程序(DRAC守护过程)会实时地将用户当前的IP记录到数据库中。具体实现过程是:先“收”后“发”, 收件时要经用户身份认证,认证后POP或IMAP服务器使用RPC调用请求DRAC守护进程将用户的IP加入数据库,IP地址在SMTP Server的数据库中保存30分钟(具体看管理员设置时间)。每收取一次邮件,计时重新开始。30分钟内如果用户不使用邮件服务收发,则DRAC将用户的IP从数据库中删除。这种做法保证了移动用户可以收发自己的邮件。 <br>
实现方法如下: <br>
文中所涉及到的源文件: <br>
Sendmail可以到<a target=_blank href=http://www.sendmail.org>http://www.sendmail.org</a> 的网站上下载。 <br>
Qpopper(POP3服务器)的源文件包可以从<a target=_blank href=http://www.eudora.com/qpopper>http://www.eudora.com/qpopper</a>网站下载。本文使用的qpopper的版本是4.04 <br>
drac源文件包可以从<a target=_blank href=http://mail.cc.umanitoba.ca/drac/index.html>http://mail.cc.umanitoba.ca/drac/index.html</a>网站下载。本文使用的是drac的版本是1.11。 <br>
# cd /usr/local/src <br>
# wget <a target=_blank href=ftp://ftp.cc.umanitoba.ca/src/drac.tar.Z>ftp://ftp.cc.umanitoba.ca/src/drac.tar.Z</a> <br>
--20:54:29-- <a target=_blank href=ftp://ftp.cc.umanitoba.ca/src/drac.tar.Z>ftp://ftp.cc.umanitoba.ca/src/drac.tar.Z</a> <br>
=> `drac.tar.Z' <br>
Resolving ftp.cc.umanitoba.ca... done. <br>
Connecting to ftp.cc.umanitoba.ca:21... connected. <br>
Logging in as anonymous ... Logged in! <br>
==> SYST ... done. ==> PWD ... done. <br>
==> TYPE I ... done. ==> CWD /src ... done. <br>
==> PORT ... done. ==> RETR drac.tar.Z ... done. <br>
Length: 19,736 (unauthoritative) <br>
100%[=====================================>] 19,736 3.42K/s ETA 00:00 <br>
<br>
20:54:47 (3.42 KB/s) - `drac.tar.Z' saved <br>
<br>
因darc.tar.Z未含路径,故需建立一个新的目录 <br>
# mkdir darc <br>
# cd darc <br>
# tar zxf ../drac.tar.Z <br>
解开源程序包后,可以看看INSTALL的说明来一步步的安装。 <br>
<br>
2.1 根据你的系统来修改Makefile文件 <br>For Solaris: <br>
INSTALL = /usr/ucb/install <br>
EBIN = /usr/local/sbin <br>
MAN = /usr/local/man/man <br>
DEFS = -DTI_RPC -DFCNTL_LOCK -DSYSINFO <br>
CC = <your compiler> <br>
RANLIB = : <br>
CFLAGS = $(DEFS) -g -I/path/to/db/include <br>
LDLIBS = -L/path/to/db/library -lnsl -ldb <br>
TSTLIBS = -L. -ldrac -lnsl <br>
MANLIB = 3 <br>
MANADM = 1m <br>
<br>For SunOS 4.x: <br>
INSTALL = install <br>
EBIN = /usr/local/etc <br>
MAN = /usr/local/man/man <br>
DEFS = -DSOCK_RPC -DFLOCK_LOCK -DGETHOST <br>
CC = <your compiler> <br>
RANLIB = ranlib <br>
CFLAGS = -Dstrtoul=strtol $(DEFS) -g -I/path/to/db/include <br>
LDLIBS = -L/path/to/db/library -ldb <br>
TSTLIBS = -L. -ldrac <br>
RPCGENFLAGS = -I <br>
MANLIB = 3 <br>
MANADM = 8 <br>
<br>For BSDI: <br>
INSTALL = install <br>
EBIN = /usr/local/sbin <br>
MAN = /usr/local/man/man <br>
DEFS = -DSOCK_RPC -DFCNTL_LOCK -DGETHOST <br>
CC = <your compiler> <br>
RANLIB = ranlib <br>
CFLAGS = $(DEFS) -g -I/path/to/db/include <br>
LDLIBS = -L/path/to/db/library -ldb <br>
TSTLIBS = -L. -ldrac <br>
MANLIB = 3 <br>
MANADM = 8 <br>
<br>For IRIX 6.2: <br>
INSTALL = /usr/bin/X11/bsdinst <br>
EBIN = /usr/local/sbin <br>
MAN = /usr/local/man/man <br>
DEFS = -DTI_RPC -DFCNTL_LOCK -DSYSINFO -D_SVR4_TIRPC <br>
CC = <your compiler> <br>
RANLIB = : <br>
CFLAGS = $(DEFS) -g -I/path/to/db/include <br>
LDLIBS = -L/path/to/db/library -lnsl -ldb <br>
TSTLIBS = -L. -ldrac -lnsl <br>
MANLIB = 3 <br>
MANADM = 1m <br>
<br>For NetBSD: <br>
INSTALL = install <br>
EBIN = /usr/local/sbin <br>
MAN = /usr/local/man/man <br>
DEFS = -DSOCK_RPC -DFCNTL_LOCK -DGETHOST -DDASH_C <br>
CC = <your compiler> <br>
RANLIB = ranlib <br>
CFLAGS = $(DEFS) -g -I/path/to/db/include <br>
LDLIBS = <br>
TSTLIBS = -L. -ldrac <br>
RPCGENFLAGS = -C <br>
MANLIB = 3 <br>
MANADM = 8 <br>
<br>For FreeBSD 2.2.x: <br>
INSTALL = install <br>
EBIN = /usr/local/sbin <br>
MAN = /usr/local/man/man <br>
DEFS = -DSOCK_RPC -DFLOCK_LOCK -DGETHOST -DDASH_C <br>
CC = <your compiler> <br>
RANLIB = ranlib <br>
CFLAGS = $(DEFS) -g -I/path/to/db/include <br>
LDLIBS = <br>
TSTLIBS = -L. -ldrac <br>
RPCGENFLAGS = -I -C <br>
MANLIB = 3 <br>
MANADM = 8 <br>
<br>For FreeBSD-4.1 with gdbm-1.8 <br>
INSTALL = install <br>
EBIN = /usr/local/sbin <br>
MAN = /usr/local/man/man <br>
DEFS = -DSOCK_RPC -DFLOCK_LOCK -DGETHOST -DDASH_C <br>
CC = cc <br>
RANLIB = : <br>
CFLAGS = $(DEFS) -g -I/usr/local/include <br>
LDLIBS = <br>
TSTLIBS = -L. -ldrac <br>
RPCGENFLAGS = -C <br>
MANLIB = 3 <br>
MANADM = 1m <br>
<br>For Linux: <br>
INSTALL = install <br>
EBIN = /usr/local/sbin <br>
MAN = /usr/local/man/man <br>
DEFS = -DSOCK_RPC -DFCNTL_LOCK -DGETHOST -DDASH_C <br>
CC = <your compiler> <br>
RANLIB = : <br>
CFLAGS = $(DEFS) -g <br>
LDLIBS = -ldb <br>
TSTLIBS = -L. -ldrac <br>
RPCGENFLAGS = -C -I <br>
MANLIB = 3 <br>
MANADM = 8 <br>
本例中的系统是Redhat6.2,属于Linux,按照上面的说明,对Makefile进行了修改。 <br>
【注】:cc=<your compiler>改为cc=gcc。 <br>
<br>
2.2 编译DRAC程序 <br>
# make <br>
gcc -DSOCK_RPC -DFCNTL_LOCK -DGETHOST -DDASH_C -g -c -o dracauth.o dracauth.c <br>
rm -f libdrac.a <br>
ar cq libdrac.a dracauth.o drac_xdr.o drac_clnt.o <br>
: libdrac.a <br>
gcc -o testing testing.o -L. -ldrac <br>
gcc -DSOCK_RPC -DFCNTL_LOCK -DGETHOST -DDASH_C -g -c -o rpc.dracd.o rpc.dracd.c <br>
gcc -DSOCK_RPC -DFCNTL_LOCK -DGETHOST -DDASH_C -g -c -o drac_svc.o drac_svc.c <br>
gcc -o rpc.dracd rpc.dracd.o drac_xdr.o drac_svc.o –ldb <br>
2.3 安装DRAC程序及其帮助文档 <br>
# make install <br>
gcc -DSOCK_RPC -DFCNTL_LOCK -DGETHOST -DDASH_C -g -c -o rpc.dracd.o rpc.dracd.c <br>
gcc -o rpc.dracd rpc.dracd.o drac_xdr.o drac_svc.o -ldb <br>
install -c -o bin -g bin -m 0755 rpc.dracd /usr/local/sbin <br>
# make install-man <br>
install -c -m 0444 rpc.dracd.1m /usr/local/man/man8/rpc.dracd.8 <br>
install -c -m 0444 dracauth.3 /usr/local/man/man3/dracauth.3 <br>
# cat >/etc/rc.d/init.d/dracd <br>
<br>
#!/bin/sh - <br>
# <br>
# dracd <br>
PATH=/bin:/sbin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin <br>
export PATH <br>
DAEMON=rpc.dracd <br>
#DRACD_PID=`ps -axc | grep 'rpc.dracd$' | sed -e 's/^ *//' -e 's/ .*//'` <br>
DRACD_PID=`ps -e | grep 'rpc.drac$' | sed -e 's/^ *//' -e 's/ .*//'` <br>
dracd_running() { <br>
ps -p $DRACD_PID >/dev/null 2>&1 <br>
} <br>
case "$1" in <br>
start) <br>
if dracd_running; then <br>
echo "$DAEMON is already running" >&2 <br>
else <br>
echo "starting $DAEMON" >&2 <br>
$DAEMON & <br>
fi <br>
;; <br>
stop) <br>
if dracd_running; then <br>
echo "stopping $DAEMON" >&2 <br>
kill $DRACD_PID <br>
else <br>
echo "$DAEMON is not running" >&2 <br>
fi <br>
;; <br>
*) <br>
echo "Usage: /etc/init.d/dracd {start|stop}" >&2 <br>
;; <br>
esac <br>
#!/end <br>
<br>
# chmod +x /etc/rc.d/init.d/dracd <br>
# ln –s /etc/rc .d/init.d/dracd /etc/rc.d/rc3.d/S99dracd <br>
<br>
2.4 启动DRAC <br>
# /etc/rc.d/init.d/dracd start <br>
这样会启动一个运行在后台的服务进程——dracd,由它来充当服务器,它将POP/IMAP提交的用户IP动态加入到邮件服务器的数据库中。 <br>
【注】:因DRAC守护进程需要调用RPC,所以需要保护机器上的RPC服务是正常运转的。 <br>
# /etc/rc.d/init.d/portmap start <br>
Starting portmapper: [ OK ] <br>
<br>
2.5 编译支持DRAC的POP3服务器 <br>
在Qpopper新的版本中,我们可以看到,新的版本已提供DRAC的支持。不需要再加装补丁程序啦。 <br>
# cp libdrac.a /usr/local/lib <br>
# cd /usr/local/src <br>
# tar zxf qpopper4.0.4.tar.gz <br>
# cd qpopper4.0.4 <br>
# ./configure --help|grep drac <br>--with-drac=lib-path Compile in DRAC support <br>
编译Qpopper程序 <br>
# ./configure -- --enable-specialauth --with-drac=lib-path=/usr/local/lib/ <br>
# make <br>
# make install <br>
# whereis popper <br>
popper: /usr/local/sbin/popper <br>
# echo “pop3 stream tcp nowait root /usr/local/lib/popper qpopper –s”>>/etc/inetd.conf <br>
然后再重启inetd服务,这样,POP server支持DRAC的功能开始生效了。 <br>
<br>
2.6 配置Sendmail.cf <br>
Sendmail服务默认不支持DRAC的,所以我们还需要配置Sendmail.cf文件。 <br>
在你的机器上的.mc文件中在LOCAL_CONFIG的下面插入以下代码: <br>
# dynamic relay authorization control map <br>
Kdrac btree /etc/mail/dracd <br>and the following under LOCAL_RULESETS... <br>
<br>
SLocal_check_rcpt <br>
# allow recent POP/IMAP mail clients to relay <br>
R$* $: $&{client_addr} <br>
R$+ $: $(drac $1 $: ? $) <br>
R? $@ ? <br>
R$+ $@ $#OK <br>
然后,使用m4编译sendmail.mc: <br>
#m4 sendmail.mc > /etc/mail/sendmail.cf <br>
最后,重新启动Sendmail <br>
<br>
2.7 测试DRAC <br>
通过网络中的另一台Linux主机(IP地址:192.168.0.100)远程登录邮件服务器的110端口: <br>
$ telnet 192.168.0.2 110 <br>
系统显示: <br>
Trying 192.168.0.2 <br>
Connected to test.net (192.168.0.2). <br>
Escape character is '^]'. <br>
+OK ready <br>
user chenjun <br>
+OK Password required for chenjun. <br>
pass chenjun <br>
+OK chenjun has 0 visible messages (0 hidden) in 0 octets. (服务器上有0个邮件) <br>
quit <br>
+OK Pop server at test.net signing off. <br>
Connection closed by foreign host. <br>$ db_dump -p dracd.db <br>
format=print <br>
type=btree <br>
bt_minkey=2 <br>
db_pagesize=512 <br>
HEADER=END <br>
192.168.0.100 (登录成功主机的IP) <br>
911955927 <br>
从上面的显示结果,我们看到192.168.0.100已经加入到动态数据库中了。 <br>
然后你在192.168.0.100的机器发封Mail到其他的邮件,看信发出去啦。 <br>
OK,DRAC成功安装。 <br>
页: [1]
查看完整版本: Sendmail环境下对抗垃圾邮件的处理方法