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

     本文档的重点在过滤器的配置,以及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命令,图形化设置
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
设置完毕后,保存退出即可,如果需要设置DNS服务器地址,可以在下图所示的“Edit
DNS configuration”处设置。
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
2、使用命令行,手工录入
命令行模式,要比图形界面方便快捷,如下图所示。输入“vi /etc/sysconfig/network-
scripts/ifcfg-eth0” 即可对网卡1进行配置
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
               DEVICE                         设备名称,禁止修改
               BROADCAST               广播地址
               IPADDR                        IP地址
               NETMASK                    子网掩码
               NETWORK                   网络地址
               GATEWAY                     网关地址
               ONBOOT                      是否随系统启动
               TYPE                              网卡类型
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
设置完成后,需要手工对网卡进行重新启动。
 DNS地址设置路径为 /etc/resolv.conf ,这里所说的DNS与我们要架设的DNS服务器的配置不一样。这里只是告诉系统DNS服务器的IP地址是多少而已。
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
至此,裸系统安装完毕,网络也能够连通了。配置yum需要外网的,如果在公司内部架设,不仅需要外网,还需要能够不受行为管理设备的控制。
二、设置yum
1、删除Linux系统自带的yum
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
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/ 
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
3、或者从其他机器复制安装包,如果知道哪台linux机器里有上面所说的安装包,linux之间互拷更快。示例只演示其中的一条拷贝命令,举一反三,真的很好用,强烈推荐。
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
               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会出现如下错误提示
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
解决方法很简单,进入 /root/.ssh/ 目录下,rm - rf(删除)掉 known_hosts 即可。
4、安装yum安装包
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
如上图所示,我们首先需要到安装包所在位置才能使用rpm进行安装,这个道理Windows也是一样的。之所以用rpm –ivh yum-* 是因为我这里所要安装的三个包有依赖关系,使用yun-* 系统自己就可以搞定了。
5、确认安装信息
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
6、下载源配置文件CentOS-Base.repo
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
需要到上图所示的路径下载源配置文件,并且该配置文件需要放在 /etc/yum.repos.d/目录下,千万不要搞错了哦。
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
7、激活yum (看命令“i386”应该是32位的,但是激活后也可以用)
需要补充说明一下,复制上面的激活地址,import 前面是 两个 --,最好是自己输入
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
8、更新yum
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
更新的过程是个漫长的过程,根据网速可能需要10到15分钟可能还会更长时间,不过好在系统会给你个动态的窗口显示出来,让你知道,系统还没死,在活着。
9、清空yum缓存
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
三、Sendmail 安装
A、 RPM包安装(推荐)
1、首先需要挂载光盘
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
              cd /mnt                 切换到根目录下的 mnt下面
              mkdir     cdrom    新建文件夹cdrom,这个目录是为了给光盘挂载的路径,必须得有才行。
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
        mount                  挂载的命令,无解释
        iso9660                光盘
         -t                           挂载的类型还是什么东东,忘了啥意思,反正挂载的时候需要
         /dev/cdrom         是光盘原位置,雷打不动,绝大部分都是用这个。光盘的话
        /mnt/cdrom         这是我们刚才新设的挂载点,类似于Windows的文件夹。光盘内容就到这里找。
2、Sendmail安装
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
               rpm –qa | grep sendmail 查询sendmail是否安装或者说已经安装了哪些包
需要说明的是,上面显示的是5个包,其中2个看上去以上,实际是1个32位、1个64位。
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
    cd  /mnt/cdrom/Server           切换到/mnt/cdrom/Server目录,其中Server是所有安装包的位置
     rpm –ivh                                   rpm包的安装方法,-ivh必须有
后边跟的一长串不解释,有大概名字之后,tab键可以补全这里只演示了一个安装包,另外四个用同样的方法举一反三
B、 YUM安装
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
     yum install         是yum安装的命令,后边跟上要安装的包的名称即可,yum会自动解决掉所有的包依赖性。方便!
C、 源码安装
1、编译安装准备
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
卸载系统自带的sendmail
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
确认sasl是否已经安装,如果没有,需要重新安装一下sasl
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
挂载光盘
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
2、下载源码包
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
通过官方服务器下载:wget ftp://ftp.sendmail.org/pub/sendmail/sendmail.8.14.6.tar.gz
示例说明:
        [root@sendmail ~]#   根据此提示,下载后的root账户的家目录下。以root账户登录,cd后就是家目录,其他账户以此类推,或者在下载前,pwd,看下自己处在哪个目录下面。
3、解压tar.gz包
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
          tar –zxvf              不要搞错,解压后的在同级目录下面,会有个sendmail.8.14.6 的子目录4、编译源码
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
备份site.config.m4.sample文件至此,三种不同方式的安装方式都介绍结束,在linux不太熟悉
情况下,类似我这样的,可以使用rpm安装或者yum安装。编译不太建议!!
四、Sendmail配置
其实Sendmail的需要配置的内容真的不是很多,/etc/mail/access /etc/mail/sendmail.mc
这两个文档之外貌似就只有/etc/hosts 了。下面逐一截图说明一下需要修改的地方。
       1、/etc/mail/access
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
                            vi /etc/mail/access 使用vi编辑器打开/etc/mail/access
                            Connect:17.16 RELAY转发来自172.16.0.0网段的所有邮件
修改完成后,需要使用makemap hash将access转换为access.db
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
       2、/etc/mail/sendmail.mc
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
如果在m4的时候出现上图这样的错误,是因为没有安装sendmail-cf,通过yun安装一下就可以了
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
       3、/etc/hosts
本次配置,该文档不用修改:
1、重启sendmail服务并测试sendmail发送
重启sendmail
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
测试sendmail发送邮件
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
                      helo                     与sendmail服务器连接,后边的ddd 随便输入都可以
                      mail from:          发件箱,同样可以随便写,Sender ok 表示成功
                      rcpt to:                 收件箱                              Recipient ok 表示成功
                      data                     邮件正文开始,换行 .表示结束
                      quit                      退出发件状态
2、设置sendmail随系统自动启动
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
              -bd         表示将sendmail你daemon(可以想成常驻内存)的类型启动
              -q           后边跟着时间表示每隔多少时间,会将放置在邮件队列(一般在/var/spool/mqueue)的邮件尝试邮寄一次。
3、远程客户端测试
类似于本章节步骤4,只需要在非sendmail服务器本机上的其他机器,通过telnet
172.16.10.99  25 测试即可,具体细节与步骤4一致。
五、自定义Mail Filter
A、 安装GCC
1、检查gcc的安装情况:
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
上图的命令在安装sendmail的时候解释过,这里飘过
图示中的两个libgcc不是我们要的,所以要在下一个步骤通过yum安装。
2、通过yum安装gcc:
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
当出现gcc-4.1.2-54.el5时表示已经安装上去,同事也满足需求了。
3、通过rpm包安装:
gcc的安装依赖5个不同的安装包,本操作不方便,建议yum安装。
B、 编译sendmail
1、下载sendmail
本部分在第三章节第三小节里有介绍,本段跳过
2、解压sendmail
本部分在第三章节第三小节里有介绍,本段跳过
3、
C、 编译libmilter
1、sh Build
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
多个目录下都有Build,一定要看清楚再运行 sh Build ,以免对后续操作造成影响。当出现下图
所示时,表示命令已经完成。
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
2、sh Build install
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
3、find  /-name libmilter.a
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
对照上图的路径,执行上图的命令,对照上图的结果,无误表示运行成功。无其他解释。
D、编译libsm
1、sh Build
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
出现上图结果,表示已经运行成功!
2、find /-name libsm.a
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
对照上图输入命令,对照上图查看执行情况,无解释。
E、新建mliter
1、新建mliter
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
在root家目录下新建子目录mliter
2、拷贝libmilter.a 和 libsm.a 以及 libmilter 目录
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建示例说明:
               Linux的基本命令,主要用于复制粘贴,源文件在前,目标文件在后。
下面截图用的 /* 表示该目录下的所有文件都在复制粘贴的范围之内。
3、新建sample.c文件
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
               sample.c 文档的源码在附件一中。
F、配置加载Filter文件(最为关键
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
上句命令是指通过sample.c libmitler.a libsm.a 生成一个新的sample程序文件
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
G、启动Fiter(关键步骤
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
       ./sample                     是/root/mliter目录下面的一个程序,是上一个步骤生成的。
       9876@localhost        是在上一个步骤新增的端口(9876)监听,在文挡/etc/mail/sendmail.mc的最后一行
                       &                                在后台运行
H、测试Filter(关键步骤
1、测试Filter是否成功,需要首先在/root/mliter目录下新增一个类似于白名单的whiteuser.list,该文件里面的内容如下截图所显示,每个授权外发邮箱新增一行。没有的邮箱只能发公司内部邮箱或者goldendragobus.com。
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
每个邮箱地址一行
3、在测试前完成添加whiteuser.list名单后,同时开启两个ssh窗口,一个运行
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建 另一个窗口则是通过telnet localhost 25 的方式发送邮件,分别测试白名单内有的邮箱地址和白名单内没有的地址。当出现下图所示,即表示fiter测试成功RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
以上两个截图,是在不同的SSH窗口同时显示出来的结果。
测试过程中,如果出现意外导致linux长时间无响应,可以通过如下命令杀死相关进程。
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
至此,Sendmail的配置全部结束。后边的附件一位sample.c的源码,附件二为一些服务器优化数据,仅供参考。
六、远程控制SSHD配置
这里说明一下,本段配置之选择了设置于sendmail.xmjl.com这台服务器上的功能选项,更多细节,参考Redhat Linux 5 x64 SSHD配置
1、备份sshd_config配置文件
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
       pwd              查看当面所处目录
       cp                 备份,前部分为源文件,后部分为目标文件
需要注意的是,在/etc/ssh 目录下还有另外一个类似于 sshd_config的 文件ssh_config,在编辑的时候一定要注意,不要搞错了。
2、配置sshd_config
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
              port                                SSHD开放端口
              protocol                        SSHD所使用的协议版本,一般用版本2
              listenaddress              这里只能单个多行添加IP地址,不能添加网段。
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
              Logingracetime          登录时不输入密码的等待时间
              Permitrootlogin no     表示禁止root账户直接通过sshd登陆,yes表示可以
              Maxauthtries                忘了啥意思了,反正这里配置了
七、防火墙iptables配置
这里说明一下,本段配置之选择了设置于sendmail.xmjl.com这台服务器上的功能选项,更多细
节,参考Redhat Linux 5 x64 iptables配置
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
              Iptables的所有策略都保存在/etc/sysconfig/iptables里,修改完毕后直接重启iptables即可生效。
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
              #                   注释此条策略,不使其生效
拒绝所有流入本机的数据
拒绝所有通过本机转发的数据
允许所有流出本机的数据
允许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是否已经生效,可以通过下面命令查看
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
              -L                          查看当前表的所有规则,默认查看的是filter表
              --line-nu              显示带有序号的防火墙策略
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
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地址。建议如此,比较好用!
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
示例说明:
              pwd                     查看
              cp                        复制文档
              vi                          编辑文档
最后一行的意思是允许172.16.28.0/255.255.255.0 网段的主机通过sshd连接服务器,除此之外的所有IP地址全部拒绝。
2、/etc/services配置
本文档可以修改各个服务默认的端口号信息,本次配置修改了sshd的默认端口号,所以在iptables里,本来是要显示dport是56088的,因为修改后,变成了sshd了。
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建
九、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 邮件服务器搭建

上一篇:Linux(Ubuntu)下如何安装JDK


下一篇:小程序,Canvas,文本换行