SMTP(Simple Mail Transfer Protocol),是传输邮件的协议。大概流程如下图所示。
发件人MUA(Mail User Agent)通过SMTP协议将要发送的邮件传输给MSA(Mail Submission Agent),然后通过MTA(Mail Transfer Agent)将邮件转发。中间可能经过几个Relay,是邮件最终到达目的MDA(Mail Delivery Agent ),收件人就可以通过IMAP,POP3等获取邮件。
SMTP现在也可以实现加密,防止信息泄漏。但是他坑爹的地方是可以实现匿名发送。不想看下去的话,使用这个Fake Mailer,冒充奥巴马给自己发封邮件,或者google fake mail。这个事情就很不有趣了。为了深入了解一下他的工作原理,我就尝试看看RFC 821吧。然后用软件实现一个自己的SMTP MTA。
首先可以使用python,简单实现一个本地的SMTP。使用smtpd,以及源代码。找一个免费的relay,比如jangosmtp。就可以实现转发。分别在两个终端运行下面python代码,可以实现转发。完整代码见github。
1 2 3 4 | import smtpd import asyncore server = smtpd.PureProxy(('127.0.0.1',1025),('relay.jangosmtp.net',25)) asyncore.loop() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # -*- coding: utf-8 -*- import smtplib import email.utils from email.mime.text import MIMEText Toemail = "test@qq.com" Fromemail = "joker@joker.com" msg = MIMEText(u"你好!\n 你作业写完了吗?".encode('utf-8'), _charset='utf-8') msg['To'] = email.utils.formataddr(("Recipient",Toemail)) msg['From'] = email.utils.formataddr(("joker",Fromemail)) msg['Subject'] = u"作业问题" server = smtplib.SMTP('127.0.0.1',1025) server.set_debuglevel(True) try: server.sendmail(Fromemail,[Toemail],msg.as_string()) finally: server.quit() |
还可以使用google服务转发邮件,只有30天免费我就不尝试了。也可以建一个真正的邮件服务器 (我用的是sendmail,感觉配置更简单),但是真正的邮件服务器很可能被其他邮件服务商拒收。有很多因素会导致邮件被拒。总得来说有一下几点。
- 静态ip
- ip不在垃圾邮件黑名单
- dns反向解析,要找ISP干活。但是很多VPS就提供了反向解析,如digital ocean
满足以上几点就可以开始建一个自己的Mail Server了。
- 配置域名。 在DNS记录里加MX记录。然后在digitalocean(我的VPS提供商)里的控制面板更改主机的名字,与主域名(domain.com)相同。然后在修改主机的hosts , hostname,分别修改为domian.com。
- 检测是否成功。在随便哪里的终端运行:12host ipdig mx domain.comsd
- 安装sendmail。apt直接来。sendmail建立服务器,linode指南。我反正直接安装就好了。为了显示自己的域名,我设置了一下域名。123456cd /etc/mail/sudo vim sendmail.mc#找到MASQUERADE_AS(`')dnl,在最后几行。改成MASQUERADE_AS(`domain.com')dnl#然后更新sudo bash -c 'm4 sendmail.mc > sendmail.cf'sudo service sendmail restart
- 尝试一下,输入发送邮件的命令,然后登录相应邮箱看看是否显示为你的域名发送。1echo "hello york: have you done the homework? send to me! thanks" | mail -s "About Homework" 9762051@qq.com
如果到这结束就不好玩了。我的目的是fake mail。我要匿名,假冒,当然是开玩笑啊,你看4月1日快到了。。。也很容易。打开邮箱,发现是joker发的。剩下的恶作剧只能靠你想象了。不仅如此,今天(2014.04.27)我发现email还有reply to 的功能,所以又是一个钓鱼法。
1 | echo "hello york: have you done the homework? send to me! thanks" | mail -s "About Homework" -r joker@joker.com 976205183@qq.com |
由于SMTP关于utf-8的处理比较麻烦,命令行发送中文邮件(英文容易被当成垃圾邮件)比较捉机。所以python有上场了,如上的sendmail.py只要把1025端口改成25,就可以发送中文邮件了。所以如果知道一个人的关系库,那很容易就能欺骗到他,这个弱点一定要好好防范。
还有不用的时候最好关掉,防止被别人利用,把你的ip变成垃圾邮件的ip就不好办了。
所以为什么SMTP能实现匿名发送邮件呢?主要原因是转发机制,只要我有一个MTA,我可以投递到任何一个邮箱服务器,这个邮箱服务器可以是目的邮箱服务器,也可以是中间服务器。然而这些服务器就不可能对谁发送的做验证了。服务器能做的只是检测你的MTA是不是垃圾邮件服务器,只能检测你的MTA是否有资格发送邮件,就是上面说的3个条件。他不可能看看你的邮件服务器里有哪些用户。说到底,邮件里的FROM,只是个头衔,没有任何意义。
既然这么大个漏洞,为什么影响不是那么大呢?主要原因是MTA不是每个人都能建的(有VPS就好办多了)。然后就算你建了这么个匿名服务器,然后发送大量匿名邮件,没过几天,你的ip和域名就列入黑名单了。所以目前为止影响不是很大。
有用链接:
那这样的话可以冒充任何邮件域名发邮件给别人了?
是啊,愚人节可以玩玩,捉弄同学
有些邮箱会拦截,用自己搭的邮箱服务器成功率更高