2008年1月14日星期一

[Mutt]用msmtp替代esmtp作发信代理

刚开始使用mutt的时候,由于也没有什么经验,在MDA选择方面抓了一个esmtp就用上了。说实话,esmtp也一直工作的很好,就是发信的时候需要傻傻等着(参见muttrc的sendmail_wait参数),如果不等待也可以,发送失败你就不知道了。虽然失败的情况比较少,一般都是邮件比较大或者网络不太好的情况才会发生,但我们外发的邮件往往都是比较重要的,真想有一种能够自动重试的发信代理,于是就查到了msmtp。

msmtpesmtp两个软件作者都不多,但msmtp确实更新频繁一些,而esmtp作者说 现在已经不需要怎么添加功能了,只是维护bug。在多账户配置方面,好像msmtp的配置方法要"聪明"一些,账号规则有一些"继承"的小把戏。在发信队列方面,esmtp在Features中明显声明不支持,而msmtp有一个msmtpqueue,国内用的人非常少,只看到cu blog 上提到了一点,smtpqueue能够把要外发的邮件集中在一起,单独发送,但没有说失败处理的事情;再到msmtp在sf.net上的cvs中查msmtpqueue的README文件,终于搞清楚了,和我的需要比较吻合。

msmtpqueue会"冒充"成一个MDA,当mutt发信时,它接收外发邮件并返回成功信息,而实际上只是把信件保存在QUEUEDIR里了,当调用msmtp-runqueue.sh的时候,再进行实际的发送处理。发送成功一封信,就会从QUEUEDIR中删除,发送失败就继续保持不动,下次再调用msmtp-runqueue.sh的时候自然又会处理(相当于重发)了。比起mutt中的邮件失败重发还会多生成一个邮件副本(我设定了发信的同时record在当前目录)应该是好多了。

Mails sent successfully will be deleted from the queue directory. Mails whose delivery failed will be left untouched; you may want to edit them, delete them by hand or simply run msmtp-runqueue.sh at a later time. 

工作开始,首先通过apt安装msmtp,很小的,加上TLS/SSL所需的libgsasl7,一共才182k。然后配置账号文件~/.msmtprc,格式和~/.esmtprc比较类似:

# Default value for all following accounts defaults #      tls on     tls_trust_file /etc/ssl/certs/ca-certificates.crt     keepbcc on     logfile ~/log/msmtp.log  # Gmail account gmail     host smtp.gmail.com     port 587     auth on     tls on  account mailbox@gmail.com : gmail     from mailbox@gmail.com     user "mailbox@gmail.com"     password "secret"  # Another mail service account another_mailbox@domain.com     host smtp.domain.com     auth on     from another_mailbox@domain.com     user "another_mailbox"     password "another_secret"  # Default account account default : mailbox@gmail.com 

Copy自官方文档,语法很简单,最开始的defaults是默认设置,然后的account就是各个账号的设置了,账号名称最好和邮件中的From:对应,这样msmtp就能知道调用哪个账号了。最有意思的是,account可以用冒号 :来"继承"其它已定义账号的设置,使用这个机制,就为所有gmail邮箱指定了host、port、auth、tls四个属性,然后在具体的账号设置中,只要再设定from、user、password就可以了,很方便,"继承"多个账号的话用逗号隔开。最后默认发信账号(匹配寻找account失败时使用)default可以直接"继承"某个账号的设置过来。

然后设置~/.muttrc,用msmtp来发信:

set sendmail="/path/to/msmtp" set use_from=yes set from="Fwolf " set envelope_from=yes set sendmail_wait=0 

测试一下,发信正常,现在可以让msmtpqueue出场了。由于msmtpqueue只是在"转达"msmtp发信的命令,所以需要先把msmtp调试好以后再配置。

msmtpqueue已经随msmtp安装上了,放在/usr/share/doc/msmtp/examples下,按照这里README文件的说明,把msmtp-enqueue.shmsmtp-runqueue.sh两个文件加上执行属性,然后ln到$HOME/.mutt下,再在这里创建一个新目录msmtpqueue ,ln成~/.msmtpqueue(两个脚本默认的QUEUEDIR),最后修改muttrc中的sendmail:

set sendmail = "~/.mutt/msmtp-enqueue.sh" 

好了,现在再来发信,是不是瞬间就完成了?再看~/.mutt/msmtpqueue目录下,也多了两个文件,分别以.mail.msmtp结尾,他们分别包含了刚才所发信件的信件内容和发送命令。现在运行msmtp-runqueue.sh

~/.mutt$ ./msmtp-runqueue.sh *** Sending 2008-01-12-23.03.52.mail... 2008-01-12-23.03.52.mail sent successfully 

邮件就这样顺利的发出去了。

工作到这里基本就都完成了,发信时按y嗖一下就完成的感觉真不错,为了更方便的发送邮件,还可以在mutt中定义启动邮件发送程序的快捷键:

macro generic S "!~/.mutt/msmtp-runqueue.sh\n" 

ubuntu的包里没有,但svn上还有一个msmtp-listqueue.sh脚本,列出当前QUEUEDIR中信件的From/To/主题,凑合能用,但用RFC2047编码方式的中文标题自然是不能正常显示的了。

Source: http://www.fwolf.com/blog/post/379