首页 > 系统服务 > 详细

RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建

时间:2014-04-08 03:07:22      阅读:1720      评论:0      收藏:0      [点我收藏+]

     本文档的重点在过滤器的配置,以及sample的生成,其他尽量从简,相应章节的安装过程可以参考相应的操作文档。 

一、从简架设裸Linux服务器
1、为了节约系统资源,采用文本安装的方式,输入 Linux text 按 回车 键,这样系统安装完毕后,会默认工作在 init 3 的级别下,同时不会使用RedHat 的图形界面安装,可以节约安装时间及效率。里面有个地方涉及到需要输入 installation number ,经过验证,可以输入:550dd56b51499bd
2、下面简单说下分区分区要求:通常情况安装系统是/boot; /; swap 三个分区。
序号
挂载点
容量
说明
1
/boot 
200M
作为单独的/boot系统引导区,即使主要的root分区出了问题,计算机依然能够启动。同时将容量调整为200M,以备后用
2
swap
8G
交互分区,大小一般设定为机器物理内存的1-2倍。
3
/
15G
是根目录“/的所在地,启动系统所须的文件和系统配置文件
5
/home
20G
用户的home目录所在地,用户登录分区,同时可以对用户或者用户分组实行硬盘限额功能,这样当进行升级或者安装新版本的linux操作系统时,就不会覆盖原有的用户登录数据了。这个分区的大小取决于有多少用户,根用户可以很好地控制普通用户使用计算机,如对用户或者用户组实行硬盘限量使用,限制普通用户访问哪些文件等。
6
/var
10G
主要存放系统日志,设立单独分区,即使系统日志文件出现问题,也不影响系统主分区。也就不会使计算机崩溃。如WEB服务器,可分20GB或根据实际情况加大
7
/tmp
4G
存放临时文件。对于多用户系统或网络服务器是有必要的。即使程序运行时生成大量的临时文件,或用户对系统进行了错误操作,文件系统的其它部分仍是安全的。因为文件系统的这一部分仍然还承受着读写操作,所以它通常会比其它的部分更快地发生问题。
8
/u01
剩余空间
存放数据库文件,或同类的大量的数据文件
注:上表中的容量只是参考值,或者说是最小值,具体部署时要根据业务数据要求来调整容量。
3、将下面默认都进行安装的组件都取消。原因:下面的组件经过确认都是不常用的组
件。其实下面的组件取消后,几乎已经没有会被安装的组件了。
         4、计算机会自动开始安装系统。 至此裸系统安装完毕
一、设置网络
1、使用setup命令,图形化设置
bubuko.com,布布扣
bubuko.com,布布扣
bubuko.com,布布扣
bubuko.com,布布扣
设置完毕后,保存退出即可,如果需要设置DNS服务器地址,可以在下图所示的“Edit
DNS configuration”处设置。
bubuko.com,布布扣
2、使用命令行,手工录入
命令行模式,要比图形界面方便快捷,如下图所示。输入“vi /etc/sysconfig/network-
scripts/ifcfg-eth0” 即可对网卡1进行配置
bubuko.com,布布扣
bubuko.com,布布扣
示例说明:
               DEVICE                         设备名称,禁止修改
               BROADCAST               广播地址
               IPADDR                        IP地址
               NETMASK                    子网掩码
               NETWORK                   网络地址
               GATEWAY                     网关地址
               ONBOOT                      是否随系统启动
               TYPE                              网卡类型
bubuko.com,布布扣
设置完成后,需要手工对网卡进行重新启动。
 DNS地址设置路径为 /etc/resolv.conf ,这里所说的DNS与我们要架设的DNS服务器的配置不一样。这里只是告诉系统DNS服务器的IP地址是多少而已。
bubuko.com,布布扣
至此,裸系统安装完毕,网络也能够连通了。配置yum需要外网的,如果在公司内部架设,不仅需要外网,还需要能够不受行为管理设备的控制。
二、设置yum
1、删除Linux系统自带的yum
bubuko.com,布布扣
2、下载指定的yum安装包,从下图可以看出,yum-*yum-fastestmirror-*yum-metadata-parser*-这三个安装包都是从http://centos.ustc.edu.cn/centos/5/os/x86_64/CentOS/ 下载得来的,还有就是需要注意,本次下载都是64的安装包。32位的安装包在这里http://centos.ustc.edu.cn/centos/5/os/i386/CentOS/ 
bubuko.com,布布扣
bubuko.com,布布扣
bubuko.com,布布扣
3、或者从其他机器复制安装包,如果知道哪台linux机器里有上面所说的安装包,linux之间互拷更快。示例只演示其中的一条拷贝命令,举一反三,真的很好用,强烈推荐。
bubuko.com,布布扣
示例说明:
               Scp                linux间互相拷贝的命令
               -r                    可以传输整个文件夹,没有这个参数,只能拷贝单个文件
源文件在前,需指定绝对路径,系统会补全,后边同样是绝对路径,系统不能补全,只要指定需要复制到的文件夹即可
root@172.16.10.99:   root是目标主机有管理权限的账户,172.16.10.99是目标主机IP地址,ip地址前面的@符号和地址后边的冒号必须有,命令格式如此,无解释。
命令执行过程中,可能会让你选择yes或者no,个人理解应该是yes ,root@172.16.10.99‘s password: 需要输入的是目标主机的root账户的密码。
另外需要注意的是,当同一个IP地址用在不同的linux主机上时,SCP会出现如下错误提示
bubuko.com,布布扣
解决方法很简单,进入 /root/.ssh/ 目录下,rm - rf(删除)掉 known_hosts 即可。
4、安装yum安装包
bubuko.com,布布扣
如上图所示,我们首先需要到安装包所在位置才能使用rpm进行安装,这个道理Windows也是一样的。之所以用rpm –ivh yum-* 是因为我这里所要安装的三个包有依赖关系,使用yun-* 系统自己就可以搞定了。
5、确认安装信息
bubuko.com,布布扣
6、下载源配置文件CentOS-Base.repo
bubuko.com,布布扣
需要到上图所示的路径下载源配置文件,并且该配置文件需要放在 /etc/yum.repos.d/目录下,千万不要搞错了哦。
bubuko.com,布布扣
7、激活yum (看命令“i386”应该是32位的,但是激活后也可以用)
需要补充说明一下,复制上面的激活地址,import 前面是 两个 --,最好是自己输入
bubuko.com,布布扣
8、更新yum
bubuko.com,布布扣
更新的过程是个漫长的过程,根据网速可能需要10到15分钟可能还会更长时间,不过好在系统会给你个动态的窗口显示出来,让你知道,系统还没死,在活着。
9、清空yum缓存
bubuko.com,布布扣
三、Sendmail 安装
A、 RPM包安装(推荐)
1、首先需要挂载光盘
bubuko.com,布布扣
示例说明:
              cd /mnt                 切换到根目录下的 mnt下面
              mkdir     cdrom    新建文件夹cdrom,这个目录是为了给光盘挂载的路径,必须得有才行。
bubuko.com,布布扣
        mount                  挂载的命令,无解释
        iso9660                光盘
         -t                           挂载的类型还是什么东东,忘了啥意思,反正挂载的时候需要
         /dev/cdrom         是光盘原位置,雷打不动,绝大部分都是用这个。光盘的话
        /mnt/cdrom         这是我们刚才新设的挂载点,类似于Windows的文件夹。光盘内容就到这里找。
2、Sendmail安装
bubuko.com,布布扣
示例说明:
               rpm –qa | grep sendmail 查询sendmail是否安装或者说已经安装了哪些包
需要说明的是,上面显示的是5个包,其中2个看上去以上,实际是1个32位、1个64位。
bubuko.com,布布扣
示例说明:
    cd  /mnt/cdrom/Server           切换到/mnt/cdrom/Server目录,其中Server是所有安装包的位置
     rpm –ivh                                   rpm包的安装方法,-ivh必须有
后边跟的一长串不解释,有大概名字之后,tab键可以补全这里只演示了一个安装包,另外四个用同样的方法举一反三
B、 YUM安装
bubuko.com,布布扣
示例说明:
     yum install         是yum安装的命令,后边跟上要安装的包的名称即可,yum会自动解决掉所有的包依赖性。方便!
C、 源码安装
1、编译安装准备
bubuko.com,布布扣
卸载系统自带的sendmail
bubuko.com,布布扣
确认sasl是否已经安装,如果没有,需要重新安装一下sasl
bubuko.com,布布扣
挂载光盘
bubuko.com,布布扣
bubuko.com,布布扣
bubuko.com,布布扣
bubuko.com,布布扣
bubuko.com,布布扣
bubuko.com,布布扣
2、下载源码包
bubuko.com,布布扣
通过官方服务器下载:wget ftp://ftp.sendmail.org/pub/sendmail/sendmail.8.14.6.tar.gz
示例说明:
        [root@sendmail ~]#   根据此提示,下载后的root账户的家目录下。以root账户登录,cd后就是家目录,其他账户以此类推,或者在下载前,pwd,看下自己处在哪个目录下面。
3、解压tar.gz包
bubuko.com,布布扣
bubuko.com,布布扣
示例说明:
          tar –zxvf              不要搞错,解压后的在同级目录下面,会有个sendmail.8.14.6 的子目录4、编译源码
bubuko.com,布布扣
bubuko.com,布布扣
备份site.config.m4.sample文件至此,三种不同方式的安装方式都介绍结束,在linux不太熟悉
情况下,类似我这样的,可以使用rpm安装或者yum安装。编译不太建议!!
四、Sendmail配置
其实Sendmail的需要配置的内容真的不是很多,/etc/mail/access /etc/mail/sendmail.mc
这两个文档之外貌似就只有/etc/hosts 了。下面逐一截图说明一下需要修改的地方。
       1、/etc/mail/access
bubuko.com,布布扣
bubuko.com,布布扣
示例说明:
                            vi /etc/mail/access 使用vi编辑器打开/etc/mail/access
                            Connect:17.16 RELAY转发来自172.16.0.0网段的所有邮件
修改完成后,需要使用makemap hash将access转换为access.db
bubuko.com,布布扣
       2、/etc/mail/sendmail.mc
bubuko.com,布布扣
如果在m4的时候出现上图这样的错误,是因为没有安装sendmail-cf,通过yun安装一下就可以了
bubuko.com,布布扣
       3、/etc/hosts
本次配置,该文档不用修改:
1、重启sendmail服务并测试sendmail发送
重启sendmail
bubuko.com,布布扣
测试sendmail发送邮件
bubuko.com,布布扣
示例说明:
                      helo                     与sendmail服务器连接,后边的ddd 随便输入都可以
                      mail from:          发件箱,同样可以随便写,Sender ok 表示成功
                      rcpt to:                 收件箱                              Recipient ok 表示成功
                      data                     邮件正文开始,换行 .表示结束
                      quit                      退出发件状态
2、设置sendmail随系统自动启动
bubuko.com,布布扣
示例说明:
              -bd         表示将sendmail你daemon(可以想成常驻内存)的类型启动
              -q           后边跟着时间表示每隔多少时间,会将放置在邮件队列(一般在/var/spool/mqueue)的邮件尝试邮寄一次。
3、远程客户端测试
类似于本章节步骤4,只需要在非sendmail服务器本机上的其他机器,通过telnet
172.16.10.99  25 测试即可,具体细节与步骤4一致。
五、自定义Mail Filter
A、 安装GCC
1、检查gcc的安装情况:
bubuko.com,布布扣
示例说明:
上图的命令在安装sendmail的时候解释过,这里飘过
图示中的两个libgcc不是我们要的,所以要在下一个步骤通过yum安装。
2、通过yum安装gcc:
bubuko.com,布布扣
bubuko.com,布布扣
示例说明:
当出现gcc-4.1.2-54.el5时表示已经安装上去,同事也满足需求了。
3、通过rpm包安装:
gcc的安装依赖5个不同的安装包,本操作不方便,建议yum安装。
B、 编译sendmail
1、下载sendmail
本部分在第三章节第三小节里有介绍,本段跳过
2、解压sendmail
本部分在第三章节第三小节里有介绍,本段跳过
3、
C、 编译libmilter
1、sh Build
bubuko.com,布布扣
示例说明:
多个目录下都有Build,一定要看清楚再运行 sh Build ,以免对后续操作造成影响。当出现下图
所示时,表示命令已经完成。
bubuko.com,布布扣
2、sh Build install
bubuko.com,布布扣
3、find  /-name libmilter.a
bubuko.com,布布扣
bubuko.com,布布扣
示例说明:
对照上图的路径,执行上图的命令,对照上图的结果,无误表示运行成功。无其他解释。
D、编译libsm
1、sh Build
bubuko.com,布布扣
示例说明:
出现上图结果,表示已经运行成功!
2、find /-name libsm.a
bubuko.com,布布扣
bubuko.com,布布扣
示例说明:
对照上图输入命令,对照上图查看执行情况,无解释。
E、新建mliter
1、新建mliter
bubuko.com,布布扣
示例说明:
在root家目录下新建子目录mliter
2、拷贝libmilter.a 和 libsm.a 以及 libmilter 目录
bubuko.com,布布扣
bubuko.com,布布扣示例说明:
               Linux的基本命令,主要用于复制粘贴,源文件在前,目标文件在后。
下面截图用的 /* 表示该目录下的所有文件都在复制粘贴的范围之内。
3、新建sample.c文件
bubuko.com,布布扣
示例说明:
               sample.c 文档的源码在附件一中。
F、配置加载Filter文件(最为关键
bubuko.com,布布扣
示例说明:
上句命令是指通过sample.c libmitler.a libsm.a 生成一个新的sample程序文件
bubuko.com,布布扣
bubuko.com,布布扣
bubuko.com,布布扣
G、启动Fiter(关键步骤
bubuko.com,布布扣
示例说明:
       ./sample                     是/root/mliter目录下面的一个程序,是上一个步骤生成的。
       9876@localhost        是在上一个步骤新增的端口(9876)监听,在文挡/etc/mail/sendmail.mc的最后一行
                       &                                在后台运行
H、测试Filter(关键步骤
1、测试Filter是否成功,需要首先在/root/mliter目录下新增一个类似于白名单的whiteuser.list,该文件里面的内容如下截图所显示,每个授权外发邮箱新增一行。没有的邮箱只能发公司内部邮箱或者goldendragobus.com。
bubuko.com,布布扣
示例说明:
每个邮箱地址一行
3、在测试前完成添加whiteuser.list名单后,同时开启两个ssh窗口,一个运行
bubuko.com,布布扣 另一个窗口则是通过telnet localhost 25 的方式发送邮件,分别测试白名单内有的邮箱地址和白名单内没有的地址。当出现下图所示,即表示fiter测试成功bubuko.com,布布扣
bubuko.com,布布扣
示例说明:
以上两个截图,是在不同的SSH窗口同时显示出来的结果。
测试过程中,如果出现意外导致linux长时间无响应,可以通过如下命令杀死相关进程。
bubuko.com,布布扣
至此,Sendmail的配置全部结束。后边的附件一位sample.c的源码,附件二为一些服务器优化数据,仅供参考。
六、远程控制SSHD配置
这里说明一下,本段配置之选择了设置于sendmail.xmjl.com这台服务器上的功能选项,更多细节,参考Redhat Linux 5 x64 SSHD配置
1、备份sshd_config配置文件
bubuko.com,布布扣
bubuko.com,布布扣
示例说明:
       pwd              查看当面所处目录
       cp                 备份,前部分为源文件,后部分为目标文件
需要注意的是,在/etc/ssh 目录下还有另外一个类似于 sshd_config的 文件ssh_config,在编辑的时候一定要注意,不要搞错了。
2、配置sshd_config
bubuko.com,布布扣
示例说明:
              port                                SSHD开放端口
              protocol                        SSHD所使用的协议版本,一般用版本2
              listenaddress              这里只能单个多行添加IP地址,不能添加网段。
bubuko.com,布布扣
示例说明:
              Logingracetime          登录时不输入密码的等待时间
              Permitrootlogin no     表示禁止root账户直接通过sshd登陆,yes表示可以
              Maxauthtries                忘了啥意思了,反正这里配置了
七、防火墙iptables配置
这里说明一下,本段配置之选择了设置于sendmail.xmjl.com这台服务器上的功能选项,更多细
节,参考Redhat Linux 5 x64 iptables配置
bubuko.com,布布扣
              Iptables的所有策略都保存在/etc/sysconfig/iptables里,修改完毕后直接重启iptables即可生效。
bubuko.com,布布扣
示例说明:
              #                   注释此条策略,不使其生效
拒绝所有流入本机的数据
拒绝所有通过本机转发的数据
允许所有流出本机的数据
允许172.16.28.0/24网段使用tcp协议通过eth0网口以目的端口为56088的数据进入本机
允许172.16.28.0/24网段使用udp协议通过eth0网口以目的端口为56088的数据进入本机
允许使用tcp协议通过eth0网口以目的端口为25的数据进入本机
允许使用udp协议通过eth0网口以目的端口为25的数据进入本机
允许使用tcp协议通过eth0网口以源端口为53的数据进入本机
允许使用tcp协议通过eth0网口以目的端口为53的数据进入本机
允许使用icmp协议(俗称ping)通过eth0网口的数据进入本机
允许使用icmp协议(俗称ping)通过eth0网口的数据进入本机
              ……………….
允许所有的数据流出本机
如果想看到iptables是否已经生效,可以通过下面命令查看
bubuko.com,布布扣
示例说明:
              -L                          查看当前表的所有规则,默认查看的是filter表
              --line-nu              显示带有序号的防火墙策略
bubuko.com,布布扣
示例说明:
1、允许172.16.28.0/24段IP地址通过tcp协议目的端口56088流量进入eth0网口
2、允许172.16.28.0/24段IP地址通过udp协议目的端口56088流量进入eth0网口
3、允许通过tcp协议目的端口25流量进入eth0网口
4、允许通过udp协议目的端口25流量进入eth0网口
5、允许通过udp协议源端口53流量进入eth0网口
6、允许通过udp协议目的端口53流量进入eth0网口
7、允许通过icmp 协议(俗称ping)流量进入本机
8、允许通过icmp协议(俗称ping)流量进入本机
。。。。。。。。
9、拒绝通过本机转发的所有数据流量
10、允许通过本机流出的所有数据流量
有时候iptables未能生效,service iptables restart 也不行,这样就需要重启系统了。
八、安全管控
1、/etc/hosts.deny配置
由于sshd只能逐行添加IP地址,在生产环境中操作非常不便,所以在这里通过服务器系统层面来管控可以接入这台服务器的IP地址。建议如此,比较好用!
bubuko.com,布布扣
bubuko.com,布布扣
bubuko.com,布布扣
示例说明:
              pwd                     查看
              cp                        复制文档
              vi                          编辑文档
最后一行的意思是允许172.16.28.0/255.255.255.0 网段的主机通过sshd连接服务器,除此之外的所有IP地址全部拒绝。
2、/etc/services配置
本文档可以修改各个服务默认的端口号信息,本次配置修改了sshd的默认端口号,所以在iptables里,本来是要显示dport是56088的,因为修改后,变成了sshd了。
bubuko.com,布布扣
bubuko.com,布布扣
九、sendmail日常维护
1、查看队列
#mailq      查看MTA队列的滞留情况(等价于sendmail -bp)     
#mailq -Ac  查看MSP队列的滞留情况(等价于sendmail -bp -Ac)
2、强制发送队列邮件
#/usr/sbin/sendmail -q -v                  对MTA队列强制送信
#/usr/sbin/sendmail -q -v -Ac               对MSP队列强制送信
3、邮件日志
#tail –f /var/log/maillog实时查看linux日志
#tail -1000 /var/log/maillog查看linux日志的最后1000行
#cat /var/log/maillog | grep ‘1234@abcl.com’查看与某个指定账户有关的记录
#egrep ‘23456@abcl.com|1234@abcl.com’ /var/log/maillog 以两个关键词来查询日志
附件一:sample.c 源码
#include <sys/param.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sysexits.h>
#include <string.h>
#include <time.h>
#include "mfapi.h"
#include "mfdef.h"
#define MAXADDRESS 128
#define MAXHEADER 1024
#define MAXHEADERS 32
#define MAXIP      16
#define MAXRCPTS   32
#define TMPPATH    "/tmp/exfiXXXXXX"
FILE *fp;
struct private {
        int nhdrs;
        int nrcpts;
        int fd;
        FILE *fp;
        char *jobid;
        char tf[MAXPATHLEN];
        char host[MAXHOSTNAMELEN];
        char ip[MAXIP];
        char sender[MAXADDRESS];
        char hdrs[MAXHEADERS][MAXHEADER];
        char rcpts[MAXRCPTS][MAXADDRESS];
};
/*
 * Copy src to string dst of size siz. At most siz-1 characters
 * will be copied. Always NUL terminates (unless siz == 0).
 * Returns strlen(src); if retval >= siz, truncation occurred.
 */
size_t strlcpy(dst, src, siz)
char *dst;
const char *src;
size_t siz;
{
        register char *d = dst;
        register const char *s = src;
        register size_t n = siz;
        /* Copy as many bytes as will fit */
        if (n != 0 && --n != 0) {
                do {
                        if ((*d = *s ) == 0)
                                break;
                } while (--n != 0);
        }
        /* Not enough room in dst, add NUL and traverse rest of src */
        if (n == 0) {
                if (siz != 0)
                        *d = ‘\0‘;      /* NUL-terminate dst */
                while (*s )
                        ;
        }
        return(s - src - 1);    /* count does not include NUL */
}
int exfi_connect(SMFICTX *ctx, char *host,
                 _SOCK_ADDR *addr)
{
        struct private *prv;
        struct sockaddr *sa;
        prv = malloc(sizeof *prv);
        if (prv == NULL)
                return SMFIS_TEMPFAIL;
        memset(prv, ‘\0‘, sizeof *prv);
        prv->fd = -1;
        smfi_setpriv(ctx, prv);
        strlcpy(prv->host, host,
                sizeof prv->host);
        /*sa = addr;
        if (sa != NULL &&
            sa->sa_family == AF_INET) {
                struct sockaddr_in *sin;
                sin = addr;
                strlcpy(prv->ip,
                        inet_ntoa(sin->sin_addr),
                        sizeof prv->ip);
        }
*/
        fp = fopen("/tmp/mail.log","a ");
        if(fp) {
                time_t rec_time;
                time(&rec_time);
                fprintf(fp,"%s hostname: %s    ip_address: %s \r\n", ctime(&rec_time),prv->host,prv->ip);
                printf("%s hostname: %s        ip_address: %s \r\n", ctime(&rec_time),prv->host,prv->ip);
        }
        return SMFIS_CONTINUE;
}
int exfi_envfrom(SMFICTX *ctx,
                 char **args)
{
        struct private *prv;
        prv = smfi_getpriv(ctx);
        strlcpy(prv->sender,
                args[0],
                sizeof prv->sender);
        prv->jobid =
            smfi_getsymval(ctx, "i");
        prv->nrcpts = 0;
        prv->nhdrs = 0;
        prv->fd = -1;
        return SMFIS_CONTINUE;
}
char *substr_right(char *dst,char *src, int n)
{
    char *p = src;
    char *q = dst;
    int len = strlen(src);
    if(n>len) n = len;
    p = (len-n);
    while(*(q ) = *(p ));
    return dst;
}
int user_check(char *usermail)
{
        FILE *fp;
        fp = fopen("whiteuser.list", "r");
        if(fp == NULL) {
                return 0;
        }
        fseek( fp , 0 , SEEK_END );
        int file_size;
        file_size = ftell( fp );
        if(file_size<=0)
                return 0;
        char *filetmp;
        fseek( fp , 0 , SEEK_SET);
        filetmp = (char *)malloc( file_size * sizeof( char ) );
        fread( filetmp , file_size , sizeof(char) , fp);
        char *p;
        p=strstr(filetmp,usermail);
        if(p) {
                /*printf("user check sucess!%s",p);*/
                return 1;
        }
        else {
                /*printf("user check fail!");*/
                return 0;
        }
//2013-07-13 newadd “free(filetmp);”
              free(filetmp);
//2013-07-13 end
        fclose(fp);
}
int indexOf(char *str1,char *str2)
{
        char *p=str1;
        int i=0;
        p=strstr(str1,str2);
        if(p==NULL)
                return -1;
        else {
                while(str1!=p) {
                        str1 ;
                        i ;
                }
        }
        return i;
}
void trim_char(char s[],int c)
{
        int i,j;
        for (i = 0, j = 0; s[i] != ‘\0‘; i ) {
                if (s[i] != c) {
                        s[j ] = s[i];
                }
        }
        s[j] = ‘\0‘;
}
int exfi_envrcpt(SMFICTX *ctx, char **args)
{
        char mail_passerver1[50]="@goldendragonbus.com";
        char mail_passerver2[20]="@test.com";
        char mail_buf[50];
        char send_user[50];
        struct private *prv;
        prv = smfi_getpriv(ctx);
        if (prv->nrcpts >= MAXRCPTS)
                return SMFIS_TEMPFAIL;
        strlcpy(prv->rcpts[prv->nrcpts],
                args[0],
                sizeof prv->rcpts[prv->nrcpts]);
        int rcpt_len=strlen(prv->rcpts[prv->nrcpts]);
        int e_pos=indexOf(prv->rcpts[prv->nrcpts],"@");
        strncpy(mail_buf,prv->rcpts[prv->nrcpts] e_pos,rcpt_len);
        trim_char(mail_buf,‘>‘);
        strlcpy(send_user,prv->sender,sizeof send_user);
        trim_char(send_user,‘<‘);
        trim_char(send_user,‘>‘);
        /*printf("send_user:%s\r\n",send_user);*/
        /*printf("rcpt :%s,lenth is:%d,pos is:%d,mail_buf is:%s\r\n" ,prv->rcpts[prv->nrcpts],rcpt_len,e_pos,mail_buf);*/
        int sender_check= user_check(send_user);
        if(strcasecmp(mail_buf,mail_passerver1)!=0 && sender_check==0)
        {
                if(fp) {
                        fprintf(fp," sender:%s reciver[%d] is : %s     send Fail!\r\n", prv->sender,prv->nrcpts,prv->rcpts[prv->nrcpts]);
                        printf(" sender:%s     reciver[%d] is : %s     send Fail!\r\n", prv->sender,prv->nrcpts,prv->rcpts[prv->nrcpts]);
                }
                return SMFIS_REJECT;
              //return SMFIS_TEMPFAIL;
        }
        if(fp) {
                fprintf(fp," sender:%s reciver[%d] is : %s     send Sucess!\r\n", prv->sender,prv->nrcpts,prv->rcpts[prv->nrcpts]);
                printf(" sender:%s     reciver[%d] is : %s     send Sucess!\r\n", prv->sender,prv->nrcpts,prv->rcpts[prv->nrcpts]);
        }
        prv->nrcpts ;
        return SMFIS_CONTINUE;
}
int exfi_close(SMFICTX *ctx)
{
        struct private *prv;
        prv = smfi_getpriv(ctx);
        free(prv);
        smfi_setpriv(ctx, NULL);
        if(fp) {
                fclose(fp);
        }
        return SMFIS_CONTINUE;
}
struct smfiDesc filter = {
        "Example Filter",
        SMFI_VERSION,
        SMFIF_ADDHDRS,
        exfi_connect,
        NULL,
        exfi_envfrom,
        exfi_envrcpt,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL
};
int main(int argc, char **argv)
{
        if (argc != 2) {
                fprintf(stderr,
                        "usage: %s socket\n",
                        argv[0]);
                return EX_USAGE;
        }
        smfi_setconn(argv[1]);
        smfi_register(filter);
        if (smfi_main() == 0)
                return EX_OK;
        else
                return EX_OSERR;
}
附录二:批量执行脚本
A、 单台转发
并发数量
邮件处理
50
正常
80
正常
100
失败
因为我们的环境是单台服务器的转发,所以并发数量为80个数量左右,而邮件服务器,
正常是由队列发出的,邮件服务器domino需要控制并发发送的数量。
B、 多台转发
并发数量
邮件处理
20
正常
30
正常
50
失败
为了测试,在2台客户端机器上执行该脚本,在2台客户端上上执行,如果循环50次的话,会出现内存问题,而退出过滤条件,而稳定在30个循环,即并发数量在每秒50个邮件左右。后续需要改进程序,加强效率。
附录三:SMTP交互指令说明
SMTP基本命令集:
命令
描述
HELO
向服务器标识用户身份
MAIL
初始化邮件传输 mail from:
RCPT
标识单个的邮件接收人;常在MAIL命令后面,可有多个rcpt to:
DATA
在单个或多个RCPT命令后,表示所有的邮件接收人已标识,并初始化数据传输,以.结束
QUIT
结束会话
MAIL FROM
命令中指定的地址是称作envelope from地址,不需要和发送者自己的地址是一致的
RCPT TO
与之等同,指明的接收者地址称为envelope to地址,而与实际的to:行是什么无关
现在的SMTP服务器一般都需要身份验证,下面是一个telnet发送邮件的例子:
C:\>telnet smtp.163.com 25    //登陆 smtp.163.com 端口号为 25
220 163.com Anti-spam GT for Coremail System(163com[071018])
HELO localhost // 与服务器打招呼,并告知客户端使用的机器名字,可以随便填写
250 OK 
AUTH LOGIN  //使用身份认证登陆指令
334 dXNlcm5hbWU6
cmVkc25zMw== //输入base64_encode()过的用户名,只输入用户名,不需要带@163.com
334 UGFzc3dvcmQ6
MbM2MMQ35Q== //输入base64_encode()过的密码
235 Authentication successful
MAIL FROM:<rain@163.com> //告诉服务器发信人的地址,必须和前面输入的用户名一致。
附录四:自动发送脚本
A、 脚本代码
                          [root@Sendmail ~]# vi telnet.sh
#!/usr/bin/expect
set smtp    [lindex $argv 0]
set from    [lindex $argv 1]
set to      [lindex $argv 2]
set title   [lindex $argv 3]
set content [lindex $argv 4]
spawn telnet $smtp 25
expect "220"
send "HELO xinhua.org\r"
expect "250 OK"
send "MAIL FROM: $from\r"
expect "250 Mail OK"
send "RCPT TO: $to\r"
expect "250 Mail OK"
send "DATA\r"
expect "354"
send "TO: $to\r"
send "FROM: $from\r"
send "SUBJECT: $title\r"
send "\r"
send "$content\r"
send ".\r"
expect "250"
send "QUIT"
B、 脚本测试(stmp的意义参考附录三)
[root@Sendmail ~]# ./telnet.sh  localhost abc123@163.com abc1230@gmail.com subjects content spawn  telnet  localhost  25
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is ‘^]‘.
220 localhost.localdomain ESMTP Sendmail 8.14.6/8.13.8; Wed, 27 Feb 2013 16:14:40 0800
HELO xinhua.org
250 localhost.localdomain Hello localhost.localdomain [127.0.0.1], pleased to meet you
MAIL FROM: <abc123@163.com>
250 2.1.0 < abc123@163.com >... Sender ok
RCPT TO: abc1230@gmail.com
250 2.1.5 abc1230@gmail.com... Recipient ok
DATA
354 Enter mail, end with "." on a line by itself
TO: abc1230@gmail.com
FROM: abc123@163.com
SUBJECT: subjects
content
.
250 2.0.0 r1R8EeNW025980 Message accepted for delivery
附录五:批量发送脚本
                     [root@xml-ora1 ~]# vi parasend.sh
#!/bin/sh
for((i=0;i<50;i ));do
{
echo "$i send start `date` pid:$!.";
echo `./telnet.sh 172.16.28.127 $i@126.com abc1230@gmail.com subjects$i content`
echo `./telnet.sh 172.16.28.127 987654321@qq.com abc1230@gmail.com subjects$i content$i`
echo `./telnet.sh 172.16.28.127 $i@1.com abc1230@gmail.com subjects$i content`
echo `./telnet.sh 172.16.28.127 $i@qq.com wujianhua@goldendragonbus.com subjects$i content$i`
echo 1>> aa && echo "$i send complete `date` pid:$!.";
} &
done
wait
cat aa | wc -l
rm aa


 

RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建,布布扣,bubuko.com

RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建

原文:http://pangshayu.blog.51cto.com/1087721/1391678

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!