设为首页 收藏本站
查看: 716|回复: 0

[经验分享] RedHat Linux 5.5 x86 系统Sendmail 邮件服务器搭建

[复制链接]

尚未签到

发表于 2018-5-11 10:44:12 | 显示全部楼层 |阅读模式
  本文档的重点在过滤器的配置,以及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命令,图形化设置




  设置完毕后,保存退出即可,如果需要设置DNS服务器地址,可以在下图所示的“Edit
  DNS configuration”处设置。

  2、使用命令行,手工录入
  命令行模式,要比图形界面方便快捷,如下图所示。输入“vi /etc/sysconfig/network-
  scripts/ifcfg-eth0” 即可对网卡1进行配置


  示例说明:
  DEVICE                         设备名称,禁止修改
  BROADCAST               广播地址
  IPADDR                        IP地址
  NETMASK                    子网掩码
  NETWORK                   网络地址
  GATEWAY                     网关地址
  ONBOOT                      是否随系统启动
  TYPE                              网卡类型

  设置完成后,需要手工对网卡进行重新启动。
  DNS地址设置路径为 /etc/resolv.conf ,这里所说的DNS与我们要架设的DNS服务器的配置不一样。这里只是告诉系统DNS服务器的IP地址是多少而已。

  至此,裸系统安装完毕,网络也能够连通了。配置yum需要外网的,如果在公司内部架设,不仅需要外网,还需要能够不受行为管理设备的控制。
  二、设置yum
  1、删除Linux系统自带的yum

  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/



  3、或者从其他机器复制安装包,如果知道哪台linux机器里有上面所说的安装包,linux之间互拷更快。示例只演示其中的一条拷贝命令,举一反三,真的很好用,强烈推荐。

  示例说明:
  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会出现如下错误提示

  解决方法很简单,进入 /root/.ssh/ 目录下,rm - rf(删除)掉 known_hosts 即可。
  4、安装yum安装包

  如上图所示,我们首先需要到安装包所在位置才能使用rpm进行安装,这个道理Windows也是一样的。之所以用rpm –ivh yum-* 是因为我这里所要安装的三个包有依赖关系,使用yun-* 系统自己就可以搞定了。
  5、确认安装信息

  6、下载源配置文件CentOS-Base.repo

  需要到上图所示的路径下载源配置文件,并且该配置文件需要放在 /etc/yum.repos.d/目录下,千万不要搞错了哦。

  7、激活yum (看命令“i386”应该是32位的,但是激活后也可以用)
  64位系统激活:rpm –import http://ftp.sjtu.edu.cn/centos/5/os/x86_64/RPM-GPG-KEY-CentOS-5
  32位系统激活:rpm –import http://ftp.sjtu.edu.cn/centos/5/os/i386/RPM-GPG-KEY-CentOS-5
  需要补充说明一下,复制上面的激活地址,import 前面是 两个 --,最好是自己输入

  8、更新yum

  更新的过程是个漫长的过程,根据网速可能需要10到15分钟可能还会更长时间,不过好在系统会给你个动态的窗口显示出来,让你知道,系统还没死,在活着。
  9、清空yum缓存

  三、Sendmail 安装
  A、 RPM包安装(推荐)
  1、首先需要挂载光盘

  示例说明:
  cd /mnt                 切换到根目录下的 mnt下面
  mkdir     cdrom    新建文件夹cdrom,这个目录是为了给光盘挂载的路径,必须得有才行。

  mount                  挂载的命令,无解释
  iso9660                光盘
  -t                           挂载的类型还是什么东东,忘了啥意思,反正挂载的时候需要
  /dev/cdrom         是光盘原位置,雷打不动,绝大部分都是用这个。光盘的话
  /mnt/cdrom         这是我们刚才新设的挂载点,类似于Windows的文件夹。光盘内容就到这里找。
  2、Sendmail安装

  示例说明:
  rpm –qa | grep sendmail 查询sendmail是否安装或者说已经安装了哪些包
  需要说明的是,上面显示的是5个包,其中2个看上去以上,实际是1个32位、1个64位。

  示例说明:
  cd  /mnt/cdrom/Server           切换到/mnt/cdrom/Server目录,其中Server是所有安装包的位置
  rpm –ivh                                   rpm包的安装方法,-ivh必须有
  后边跟的一长串不解释,有大概名字之后,tab键可以补全这里只演示了一个安装包,另外四个用同样的方法举一反三
  B、 YUM安装

  示例说明:
  yum install         是yum安装的命令,后边跟上要安装的包的名称即可,yum会自动解决掉所有的包依赖性。方便!
  C、 源码安装
  1、编译安装准备

  卸载系统自带的sendmail

  确认sasl是否已经安装,如果没有,需要重新安装一下sasl

  挂载光盘






  2、下载源码包

  通过官方服务器下载:wget ftp://ftp.sendmail.org/pub/sendmail/sendmail.8.14.6.tar.gz
  示例说明:
[root@sendmail ~]#   根据此提示,下载后的root账户的家目录下。以root账户登录,cd后就是家目录,其他账户以此类推,或者在下载前,pwd,看下自己处在哪个目录下面。

  3、解压tar.gz包


  示例说明:
  tar –zxvf              不要搞错,解压后的在同级目录下面,会有个sendmail.8.14.6 的子目录4、编译源码


  备份site.config.m4.sample文件至此,三种不同方式的安装方式都介绍结束,在linux不太熟悉
  情况下,类似我这样的,可以使用rpm安装或者yum安装。编译不太建议!!
  四、Sendmail配置
  其实Sendmail的需要配置的内容真的不是很多,/etc/mail/access /etc/mail/sendmail.mc
  这两个文档之外貌似就只有/etc/hosts 了。下面逐一截图说明一下需要修改的地方。
  1、/etc/mail/access


  示例说明:
  vi /etc/mail/access 使用vi编辑器打开/etc/mail/access
  Connect:17.16 RELAY转发来自172.16.0.0网段的所有邮件
  修改完成后,需要使用makemap hash将access转换为access.db

  2、/etc/mail/sendmail.mc

  如果在m4的时候出现上图这样的错误,是因为没有安装sendmail-cf,通过yun安装一下就可以了

  3、/etc/hosts
  本次配置,该文档不用修改:
  1、重启sendmail服务并测试sendmail发送
  重启sendmail

  测试sendmail发送邮件

  示例说明:
  helo                     与sendmail服务器连接,后边的ddd 随便输入都可以
  mail from:          发件箱,同样可以随便写,Sender ok 表示成功
  rcpt to:                 收件箱                              Recipient ok 表示成功
  data                     邮件正文开始,换行 .表示结束
  quit                      退出发件状态
  2、设置sendmail随系统自动启动

  示例说明:
  -bd         表示将sendmail你daemon(可以想成常驻内存)的类型启动
  -q           后边跟着时间表示每隔多少时间,会将放置在邮件队列(一般在/var/spool/mqueue)的邮件尝试邮寄一次。
  3、远程客户端测试
  类似于本章节步骤4,只需要在非sendmail服务器本机上的其他机器,通过telnet
  172.16.10.99  25 测试即可,具体细节与步骤4一致。
  五、自定义Mail Filter
  A、 安装GCC
  1、检查gcc的安装情况:

  示例说明:
  上图的命令在安装sendmail的时候解释过,这里飘过
  图示中的两个libgcc不是我们要的,所以要在下一个步骤通过yum安装。
  2、通过yum安装gcc:


  示例说明:
  当出现gcc-4.1.2-54.el5时表示已经安装上去,同事也满足需求了。
  3、通过rpm包安装:
  gcc的安装依赖5个不同的安装包,本操作不方便,建议yum安装。
  B、 编译sendmail
  1、下载sendmail
  本部分在第三章节第三小节里有介绍,本段跳过
  2、解压sendmail
  本部分在第三章节第三小节里有介绍,本段跳过
  3、
  C、 编译libmilter
  1、sh Build

  示例说明:
  多个目录下都有Build,一定要看清楚再运行 sh Build ,以免对后续操作造成影响。当出现下图
  所示时,表示命令已经完成。

  2、sh Build install

  3、find  /-name libmilter.a


  示例说明:
  对照上图的路径,执行上图的命令,对照上图的结果,无误表示运行成功。无其他解释。
  D、编译libsm
  1、sh Build

  示例说明:
  出现上图结果,表示已经运行成功!
  2、find /-name libsm.a


  示例说明:
  对照上图输入命令,对照上图查看执行情况,无解释。
  E、新建mliter
  1、新建mliter

  示例说明:
  在root家目录下新建子目录mliter
  2、拷贝libmilter.a 和 libsm.a 以及 libmilter 目录

示例说明:

  Linux的基本命令,主要用于复制粘贴,源文件在前,目标文件在后。
  下面截图用的 /* 表示该目录下的所有文件都在复制粘贴的范围之内。
  3、新建sample.c文件

  示例说明:
  sample.c 文档的源码在附件一中。
  F、配置加载Filter文件(最为关键

  示例说明:
  上句命令是指通过sample.c libmitler.a libsm.a 生成一个新的sample程序文件



  G、启动Fiter(关键步骤

  示例说明:
  ./sample                     是/root/mliter目录下面的一个程序,是上一个步骤生成的。
  9876@localhost        是在上一个步骤新增的端口(9876)监听,在文挡/etc/mail/sendmail.mc的最后一行
  &                                在后台运行
  H、测试Filter(关键步骤
  1、测试Filter是否成功,需要首先在/root/mliter目录下新增一个类似于白名单的whiteuser.list,该文件里面的内容如下截图所显示,每个授权外发邮箱新增一行。没有的邮箱只能发公司内部邮箱或者goldendragobus.com。

  示例说明:
  每个邮箱地址一行
  3、在测试前完成添加whiteuser.list名单后,同时开启两个ssh窗口,一个运行
另一个窗口则是通过telnet localhost 25 的方式发送邮件,分别测试白名单内有的邮箱地址和白名单内没有的地址。当出现下图所示,即表示fiter测试成功


  示例说明:
  以上两个截图,是在不同的SSH窗口同时显示出来的结果。
  测试过程中,如果出现意外导致linux长时间无响应,可以通过如下命令杀死相关进程。

  至此,Sendmail的配置全部结束。后边的附件一位sample.c的源码,附件二为一些服务器优化数据,仅供参考。
  六、远程控制SSHD配置
  这里说明一下,本段配置之选择了设置于sendmail.xmjl.com这台服务器上的功能选项,更多细节,参考Redhat Linux 5 x64 SSHD配置
  1、备份sshd_config配置文件


  示例说明:
  pwd              查看当面所处目录
  cp                 备份,前部分为源文件,后部分为目标文件
  需要注意的是,在/etc/ssh 目录下还有另外一个类似于 sshd_config的 文件ssh_config,在编辑的时候一定要注意,不要搞错了。
  2、配置sshd_config

  示例说明:
  port                                SSHD开放端口
  protocol                        SSHD所使用的协议版本,一般用版本2
  listenaddress              这里只能单个多行添加IP地址,不能添加网段。

  示例说明:
  Logingracetime          登录时不输入密码的等待时间
  Permitrootlogin no     表示禁止root账户直接通过sshd登陆,yes表示可以
  Maxauthtries                忘了啥意思了,反正这里配置了
  七、防火墙iptables配置
  这里说明一下,本段配置之选择了设置于sendmail.xmjl.com这台服务器上的功能选项,更多细
  节,参考Redhat Linux 5 x64 iptables配置

  Iptables的所有策略都保存在/etc/sysconfig/iptables里,修改完毕后直接重启iptables即可生效。

  示例说明:
  #                   注释此条策略,不使其生效
  拒绝所有流入本机的数据
  拒绝所有通过本机转发的数据
  允许所有流出本机的数据
  允许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是否已经生效,可以通过下面命令查看

  示例说明:
  -L                          查看当前表的所有规则,默认查看的是filter表
  --line-nu              显示带有序号的防火墙策略

  示例说明:
  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地址。建议如此,比较好用!



  示例说明:
  pwd                     查看
  cp                        复制文档
  vi                          编辑文档
  最后一行的意思是允许172.16.28.0/255.255.255.0 网段的主机通过sshd连接服务器,除此之外的所有IP地址全部拒绝。
  2、/etc/services配置
  本文档可以修改各个服务默认的端口号信息,本次配置修改了sshd的默认端口号,所以在iptables里,本来是要显示dport是56088的,因为修改后,变成了sshd了。


  九、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 != '\0'; i ) {
  if (s != c) {
  s[j ] = s;
  }
  }
  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
  


  原文转载自:http://www.pangshayu.com/html/8366.html

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-458546-1-1.html 上篇帖子: RedHat Linux 5.5 x64系统NTP时钟服务器架设过程 下篇帖子: redhat6.4 for oracle10g
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表