邮件群发方式探究
前言
十一期间帮朋友搞了一个邮件群发工具。期间的心路历程记录一下。
朋友是做销售工作的,受疫情影响,开展销售主要靠邮件营销,然而每天某易只允许每天发送1k条邮件,而且大规模的群发导致发送邮件被大量标记为垃圾邮件,然后,号就被ban了。
针对朋友的需求,我想如果某易通过客户端进行计数,并限制的那我是不是可以通过SMTP直接向服务器投递邮件,会不会就可以突破限制;如果是服务器进行计数,那就搭建一个邮件服务器。
抱着这样一个天真的想法,我便信心满满地开始着手这两方面的工作,殊不知从萌生这个想法开始就注定了我接下来一个假期的苦逼探索之旅。
第一部分 使用SMTP协议发送邮件
1.SMTP协议
SMTP是一种提供可靠且有效的电子邮件传输的协议。SMTP是建立在FTP文件传输服务上的一种邮件服务,主要用于系统之间的邮件信息传递,并提供有关来信的通知。SMTP独立于特定的传输子系统,且只需要可靠有序的数据流信道支持,SMTP的重要特性之一是其能跨越网络传输邮件,即“SMTP邮件中继”。使用SMTP,可实现相同网络处理进程之间的邮件传输,也可通过中继器或网关实现某处理进程与其他网络之间的邮件传输。 百度百科
2.基于smtplib 库的python脚本编写
在网上很容易就可以找到使用smtplib库发送邮件的简单脚本。
准备:
1.python环境(smtplib、email库在安装python时已预装)
2.邮箱开启smtp,需要授权码
下面是摘抄的小代码块:
import smtplib
sender = ''
receivers = ['to@todomain.com']
message = """From: From Person <from@fromdomain.com>
To: To Person <to@todomain.com>
Subject: SMTP e-mail test
This is a test e-mail message.
"""
try:
smtpObj = smtplib.SMTP(host,username,password)
smtpObj.sendmail(sender, receivers, message)
except Exception as e:
print e
如果需要发送富文本类邮件,需要使用email库。
三分钟写完代码,加了个多线程,我就交给朋友了。三十分钟之后朋友告诉我,到上限发不了了。淦,其实在写脚本的时候我就想到了,一定没有那么容易,既然如此那就搭个邮件服务器吧。
第二部分 邮件服务器搭建
准备:
1.一台VPS
2.一个 zimbra安装帖子(因为需求很小,所以搭建一个轻量级的邮件服务器,考虑到适配客户端的问题,zimbra无疑是首选)
3.一个域名(godaddy 5元搞定!)
配置的过程类似于傻瓜操作,只有几个小tips需要注意一下:
1.有的VPS /etc/resolv.conf
文件无法更改,需要在/etc/resolvconf/resolv.conf.d/tail
文件中添加nameserver xx.xx.xx.xx
2.不要安装zimbra-dnscache,而是选择安装dnsmasq。当然你也可以选择呢bind9,但是dnsmasq更轻量化,安装也更傻瓜。具体原因我不清楚,在我安装dnscache之后,本地无法解析我自己的域名。
以上算是踩的小坑,不过总的来说zimbra部署得还算顺利。之后,我进行了测试:
内部邮件发送…正常,
外部向我的域名投送…正常,
向外发送邮件…失败,
我逐项检查配置,发现并无问题,直到我百度了“VPS” “25”关键词,我才知道原来由于当垃圾邮件的泛滥,目前主流VPS服务商已经对25端口进行限制,不允许在未授权的情况下使用VPS发送邮件。
第三部分 swaks工具的使用
swaks 号称SMTP瑞士军刀,由John Jetmore编写和维护的一种功能强大,灵活,可脚本化,可向任意目标发送任意内容的邮件的SMTP测试工具。
ubuntu安装:
apt-get install swaks```
centOS安装:
yum install swaks```
官网下载安装:
#下载文件并解压
wget http://www.jetmore.org/john/code/swaks/files/swaks-20190914.0.tar.gz
tar -zxvf swaks-20190914.0.tar.gz
cd swaks-20190914.0/
#测试邮箱的连通性
sudo ./swaks --to 67*****28@qq.com```
使用示例:
swaks --to [DEST_MAIL] --from [SEND_MAIL] --h-From [FAKE_MAIL] --ehlo linkdin.com --data [MAILFILE] -S 2
#其中 --h-From 后面是伪造的发件人,--data后面是.eml文件```
测试成功后,我开始了抓包,抓包之后发现,并不需要25端口通信,之后我注意到SMTP是文本类型协议。
因此,准备使用python语言利用socket写一个多线程的发送工具。
第四部分 群发工具的编写
关键点:
1.telnetlib的read_until()
2.邮件内部使用其他邮件SPF模板
注:telnetlib中的read_until并不好用,因此考虑在下一版本重写telnetlib,或考虑定义新类负责接收参数
工具主要分为两个部分:
客户端
服务端
客户端:
负责将收件人列表和发送的邮件发送至服务器。
服务端:
1.负责接收收件人列表和发送的邮件。
2.在服务端有大量其他邮件模板(里面拥有其他公司的SPF)
3.采用多线程发送,由于端口之间通信,必须保证线程安全。