关于仅安装Sendmail客户端(不含MTA)的可行性及兼容API文档的咨询
仅安装Sendmail客户端(不含MTA)的可行性及兼容API文档咨询
嘿,这个问题戳中了很多自定义MTA使用者的痛点——像cron这类系统工具确实默认依赖sendmail兼容的接口来投递邮件,不想装完整的MTA又不想自己从零造轮子,太合理了。下面分两部分给你捋清楚:
一、不安装完整Sendmail MTA,用轻量级兼容客户端搞定
完全可以做到,不需要自己开发,有几个现成的轻量级工具刚好匹配你的需求:
1. msmtp(最推荐)
msmtp是一款专注于邮件提交的轻量级SMTP客户端,自带sendmail兼容模式。安装后只需要简单配置,就能让系统工具无缝调用:
- 安装完成后,编辑全局配置文件
/etc/msmtprc(或者用户级的~/.msmtprc),添加指向你本地MTA的配置:account default host localhost port 25 from your-default-sender@example.com - 然后创建软链接,让系统能找到“sendmail”命令:
ln -s /usr/bin/msmtp /usr/sbin/sendmail
这样cron或者其他程序调用sendmail -t时,实际是msmtp把邮件提交到你自己的MTA的25端口,完全不会干扰现有服务。
2. ssmtp
ssmtp是另一款专为转发邮件设计的轻量工具,本身就提供sendmail兼容的二进制,不需要额外做链接:
- 安装后编辑
/etc/ssmtp/ssmtp.conf,配置指向本地MTA:mailhub=localhost:25 FromLineOverride=YES
配置完成后,系统工具直接调用sendmail命令就能把邮件转交给你的MTA。
3. 单独编译Sendmail的提交客户端(进阶玩法)
如果你一定要用官方的sendmail二进制,也可以从源码单独编译仅负责提交的部分,不安装完整MTA:
- 下载sendmail源码包,进入
sendmail目录; - 修改Makefile或使用编译参数,只编译
sendmail二进制,跳过MTA所需的守护进程、配置脚本等组件; - 编译完成后把
sendmail放到/usr/sbin/,再写一个极简的sendmail.cf配置文件,仅设置将邮件转发到localhost:25即可。不过这个方法相对繁琐,不如上面的轻量工具省心。
二、如果要自己实现Sendmail兼容接口,这些规范要遵守
如果上面的工具都不符合你的需求,需要自己写一个sendmail兼容程序,核心要覆盖以下规范:
1. 核心命令行参数兼容
系统工具最常用的调用方式是sendmail -t,必须支持以下关键参数:
-t:从邮件头的To/Cc/Bcc字段提取收件人;-i:忽略邮件内容中的单点行(避免触发SMTP的终止命令);-f <sender>:指定发件人地址;-F <name>:指定发件人显示名称;
建议额外支持-v( verbose模式),方便调试问题。
2. 输入输出与SMTP流程规范
- 从标准输入读取完整的RFC 5322格式邮件(包含头和正文);
- 收件人处理:如果命令行没有指定收件人,就解析邮件头的To/Cc/Bcc(注意Bcc字段不能出现在最终发送的邮件头里,仅用于SMTP的RCPT命令);
- SMTP提交流程:建立到localhost:25的TCP连接,按标准流程发送:
- 发送
EHLO命令标识客户端 - 发送
MAIL FROM:<发件人>指定发件人 - 给每个收件人发送
RCPT TO:<收件人> - 发送
DATA命令,随后发送邮件内容,最后用.(单点加换行)结束内容 - 发送
QUIT命令关闭连接
- 发送
3. 退出码规范
返回标准Unix退出码:
- 0:邮件提交成功;
- 非0:提交失败(不同退出码可区分错误类型,比如连接失败、收件人无效等,不过多数工具只关心成功/失败)。
参考依据
- 直接看
sendmail的man手册(man sendmail),里面详细列出了所有参数和行为规范; - 必须参考RFC 5321(SMTP协议规范)和RFC 5322(邮件格式规范);
- 也可以参考msmtp、ssmtp这类工具的源码,看看它们是如何实现兼容接口的。
备注:内容来源于stack exchange,提问作者InterLinked




