msmtp
msmtp 是一个非常简单易用的 SMTP 客户端,具有相当完整的 sendmail 兼容性。
安装
安装 msmtp 软件包。此外,安装 msmtp-mta,它会创建一个指向 msmtp 的 sendmail 别名。
基本设置
从 msmtp 1.8.6 版本开始,你可以将用户配置文件放置在 ~/.msmtprc
或 $XDG_CONFIG_HOME/msmtp/config
。以下是一个 msmtp 配置示例(该文件基于位于 /usr/share/doc/msmtp/msmtprc-user.example
的用户示例文件;系统配置文件位于 /etc/msmtprc
,其对应的示例文件位于 /usr/share/doc/msmtp/msmtprc-system.example
)。
- 使用 OAuth,通过 #OAuth2 设置。
- 如果你使用两步验证:创建应用密码。
~/.msmtprc
# Set default values for all following accounts. defaults auth on tls on tls_trust_file /etc/ssl/certs/ca-certificates.crt logfile ~/.msmtp.log # Gmail account gmail host smtp.gmail.com port 465 tls_starttls off from username@gmail.com user username password plain-text-password # A freemail service account freemail host smtp.freemail.example from joe_smith@freemail.example ... # Set a default account account default: gmail
用户 配置文件必须显式设置为所有者可读/可写,否则 msmtp 将会失败
$ chmod 600 ~/.msmtprc
为了避免以纯文本形式将密码保存在配置文件中,请使用 passwordeval 启动外部程序,或参阅下面的 #密码管理 章节。这个使用 GnuPG 的示例通常用于执行密码解密
echo -e "password\n" | gpg --encrypt -o .msmtp-gmail.gpg # enter id (email...)
gpg --encrypt -o .msmtp-gmail.gpg -r <email> -
。结尾的破折号不是笔误,而是使 gpg 使用 stdin。运行该代码段后,输入你的密码,按 Enter 键,然后按 Control-d,以便 gpg 可以加密你的密码。~/.msmtprc
passwordeval "gpg --quiet --for-your-eyes-only --no-tty --decrypt ~/.msmtp-gmail.gpg"
OAuth2 设置
当站点配置不支持或不希望使用基本的用户名/密码身份验证时,可以使用 OAuth2 来安全地验证 msmtp。
oama
msmtp 本身缺乏续订或授权 OAuth2 凭据的能力。一个全面的解决方案是使用 oama 实用程序,该实用程序为 IMAP/SMTP 客户端提供 OAuth2 凭据的续订和授权功能。
要使用 oama,安装 oama-binAUR 并配置 msmtp 以使用它
# account at Google with oauth2 access account YOUR_EMAIL_NAME@gmail.com from YOUR_EMAIL_NAME@gmail.com user YOUR_EMAIL_NAME@gmail.com auth oauthbearer passwordeval oama access YOUR_EMAIL_NAME@gmail.com host smtp.gmail.com port 587 tls on tls_trust_file /etc/ssl/certs/ca-certificates.crt
访问令牌续订在后台自动发生,对用户透明。
使用 mail 命令
要使用 mail
命令发送邮件,你必须安装 s-nail 软件包,它也提供了 mailx
命令。你还需要提供一个与 sendmail
兼容的 MTA,可以通过安装 msmtp-mta(它将 sendmail
符号链接到 msmtp
)或通过编辑 /etc/mail.rc
来设置 sendmail 路径
/etc/mail.rc
set mta=/usr/bin/msmtp
每个想要发送邮件的用户的主目录中都需要一个 .msmtprc
文件,或者可以使用系统范围的 /etc/msmtprc
。
msmtp 也理解别名。将以下行添加到 msmtprc 的 defaults 部分或你的本地配置文件中
/etc/msmtprc
aliases /etc/aliases
并在 /etc
中创建一个别名文件
/etc/aliases
# Example aliases file # Send root to Joe and Jane root: joe_smith@example.com, jane_chang@example.com # Send everything else to admin default: admin@domain.example
测试功能
account 选项 (--account=,-a
) 告知要使用哪个帐户作为发件人
$ echo "hello there username." | msmtp -a default username@domain.com
或者,发送主题和正文
$ printf "Subject: Test\n\nhello there username." | msmtp -a default username@domain.com
或者,地址在一个文件中
To: username@domain.com From: username@gmail.com Subject: A test Hello there.
$ cat test.mail | msmtp -a default <username>@domain.com
--read-envelope-from
而不是 -a default
来根据你要发送的邮件中的 From: 字段自动选择帐户。你也可以使用 --read-recipients,-t
从邮件的 To、Cc 和 Bcc 标头中读取收件人地址,以及命令行中给出的收件人。Cronie 默认邮件客户端
要使 Cronie 使用 msmtp 而不是 sendmail,请确保安装了 msmtp-mta,或编辑 cronie.service
systemd 单元
/etc/systemd/system/cronie.service.d/msmtp.conf
[Service] ExecStart= ExecStart=/usr/bin/crond -n -m '/usr/bin/msmtp -t'
然后你必须告诉 cronie 或 msmtp 你的电子邮件地址。一种实现此目的的方法是将其添加到 msmtp 配置中
- 添加到
/etc/msmtprc
aliases /etc/aliases
- 创建
/etc/aliases
your_username: email@address.com
或者,你可以直接将其添加到 crontab 中
- 在 crontab 中添加
MAILTO
行MAILTO=email@address.com
- 在 crontab 中添加
MAILFROM
行MAILFROM=email@address-from-msmtp.com
- 最后一部分是必要的,以防止此错误
sendmail: server message: 550 5.7.1 Rejected due to unmatching envelope and header sender.
密码管理
msmtp 的密码 可以存储 在纯文本、加密文件或密钥环中。
GNOME Keyring
msmtp 本机支持将密码存储在 GNOME Keyring 中。按照链接的 wiki 页面上的描述设置密钥环,并安装 libsecret。然后,通过运行以下命令存储密码
secret-tool store --label=msmtp host smtp.your.domain service smtp user yourusername
msmtp 现在应该会自动找到密码。
GnuPG
可以省略 password
指令。在这种情况下,如果相关帐户的 auth
设置为除 off
之外的合法值,则从交互式 shell 调用 msmtp 将在发送邮件前询问密码。如果 msmtp 由另一种类型的应用程序(例如 Mutt)调用,则不会提示。对于这种情况,可以使用 --passwordeval
参数来调用外部密钥环工具,如 GnuPG。
为此,设置 GnuPG,包括 gpg-agent,以避免每次都输入密码。然后,为 msmtp 创建一个加密的密码文件,如下所示。创建一个权限为 700
的安全目录,该目录位于 tmpfs 上,以避免将未加密的密码写入磁盘。在该目录中创建一个包含邮件帐户密码的纯文本文件。然后,使用你的私钥加密该文件
$ gpg --default-recipient-self -e /path/to/plain/password
删除纯文本文件,并将加密文件移动到最终位置,例如 ~/.mail/.msmtp-credentials.gpg
。在 ~/.msmtprc
中添加
~/.msmtprc
passwordeval "gpg --quiet --for-your-eyes-only --no-tty --decrypt ~/.mail/.msmtp-credentials.gpg"
通常,这足以在例如从 Mutt 发送消息时显示 GUI 密码提示。如果无法发出 gpg 提示输入密码,请先启动 gpg-agent。启动代理的一个简单技巧是在你的 muttrc 中使用反引号 `command`
语法执行外部命令。例如,你可以将以下内容放在你的 muttrc 中
muttrc
set my_msmtp_pass=`gpg -d mypwfile.gpg`
Mutt 将在启动时执行此操作,gpg-agent 将缓存你的密码,msmtp 将会很高兴,你可以发送邮件。
另一种方法是将密码放在 ~/.netrc
中,该文件可以充当 msmtp、OfflineIMAP 和相关工具的公共池。
pass
你可以将你的凭据存储在 pass 密码管理器中。
如果你使用你的主密码(通常存储在你的 pass 文件的第一行)登录到你的 SMTP 服务器,你可以将以下内容添加到你的 .msmptrc
中
~/.msmtprc
passwordeval "pass your_email_password_entry | head -n1"
如果你使用 Gmail,并且已设置 应用密码,则以下配置更适合你。将你的应用密码保存在你的 pass
密码文件中,但带有 msmtp:
前缀
your_email_password_entry
your_main_password login: your_username url: the_url_of_your_email msmtp: your_msmtp_app_password
然后将以下内容添加到你的 .msmptrc
中
~/.msmtprc
passwordeval "pass your_email_password_entry | awk '/^msmtp:/ { print $2; }'"
在任何一种情况下,尝试使用 msmtp 发送电子邮件都会触发 pass
,如果你最近没有输入过 pass
主密码,则可能会要求你输入。
其他
离线使用 msmtp
虽然 msmtp 很棒,但它要求你在线才能使用它。这对于使用间歇性 Internet 连接或拨号用户的笔记本电脑用户来说并不理想。已经编写了几个脚本来弥补这一事实,统称为 msmtpqueue。
这些脚本安装在 /usr/share/doc/msmtp/msmtpqueue
下。你可能想要将这些脚本复制到你计算机上的方便位置(/usr/local/bin
是一个不错的选择)。
最后,更改你的 MUA 以在使用发送电子邮件时使用 msmtp-enqueue.sh 而不是 msmtp。默认情况下,排队的消息将存储在 ~/.msmtpqueue
中。要更改此位置,请更改脚本中的 QUEUEDIR=$HOME/.msmtpqueue
行(或删除该行,并在 .bash_profile
中导出 QUEUEDIR 变量,如下所示:export QUEUEDIR="$XDG_DATA_HOME/msmtpqueue"
)。
当你想要发送任何已创建和排队的邮件时,运行
$ /usr/local/bin/msmtp-runqueue.sh
如果手动执行此操作,将 /usr/local/bin
添加到你的 PATH 可以节省一些击键次数。脚本附带的 README 文件包含一些有用的信息,建议阅读。
Vim 语法高亮
msmtp 源代码发行版包含一个用于 Vim 的 msmtprc
语法高亮脚本,该脚本位于 /usr/share/vim/vimfiles/syntax/msmtp.vim
。文件类型不会自动检测。启用它的最简单方法是在文件顶部或底部添加一个 modeline,即
# vim:filetype=msmtp
使用 PHP 通过 msmtp 发送邮件
在你的 php.ini
中查找 sendmail_path
选项,并像这样编辑
sendmail_path = "/usr/bin/msmtp -C /path/to/your/config -t"
请注意,如果你计划将 msmtp 用作 php 或类似程序的 sendmail 替代品,则不能使用用户配置文件(即:~ / 下的配置文件)。在这种情况下,只需创建 /etc/msmtprc,并删除你的用户配置(或者如果你计划将其用于其他用途,则不删除)。还要确保你使用的任何程序(php、django 等)都可以读取它。
来自 msmtp 手册:用户配置文件中定义的帐户将覆盖系统配置文件中的帐户。用户配置文件必须具有不超过用户读/写的权限
因此,不可能在 ~ / 下有一个 conf 文件,并且仍然可以被 php 用户读取。
要对其进行测试,请将此文件放在你的启用 php 的服务器中,或使用 php-cli。
<?php mail("your@email.com", "Test email from PHP", "msmtp as sendmail for PHP"); ?>
php-fpm
将无法发送邮件,并记录警告:PHP Warning: mail(mail.log): failed to open stream
,除非你将 /etc/msmtprc 的权限设置为用户读/写 (600)。
故障排除
TLS 问题
如果你看到以下消息
msmtp: TLS certificate verification failed: the certificate hasn't got a known issuer
这可能意味着你的 tls_trust_file 不正确。
只需按照 精细手册 进行操作。它解释了如何找出给定 smtp 服务器的服务器证书颁发者。然后,你可以浏览 /usr/share/ca-certificates/
目录,以查看你需要的证书是否碰巧在那里。如果不是,你将必须自行获取证书。如果你正在使用自己的证书,则可以通过将以下内容添加到你的 ~/.msmtprc
中来使 msmtp 信任它
tls_fingerprint <SHA1 (recommended) or MD5 fingerprint of the certificate>
如果你尝试通过 Gmail 发送邮件并收到此错误,请查看 此 线程,或直接使用上面的第二个 Gmail 示例。
如果你完全绝望,但 100% 确定你正在与正确的服务器通信,则始终可以暂时禁用证书检查
$ msmtp --tls-certcheck off
如果你看到以下消息
msmtp: TLS handshake failed: the operation timed out
你可能会受到此 错误 的影响。使用 --with-ssl=openssl
重新编译(msmtp 默认使用 GnuTLS 编译)。
服务器发送空回复
如果你收到 “server sent empty reply” 错误,这可能意味着邮件服务器不支持端口 587 上的 STARTTLS,但需要端口 465 上的 TLS。
要让 msmtp 使用端口 465 上的 TLS,请将以下行添加到 ~/.msmtprc
tls_starttls off
Zoho SMTP 服务器
当邮件在邮件标头和邮件正文之间没有空行时,也可能发生在 Zoho SMTP 服务器上(请参阅 Debian 错误 #917260)。解决此问题的方法是在两者之间添加一个额外的空格
"test-header\n\ntest-body"
GSSAPI 问题
如果你收到以下错误
GNU SASL: GSSAPI error in client while negotiating security context in gss_init_sec_context() in SASL library. This is most likely due insufficient credentials or malicious interactions.
尝试将你的 .msmtprc 文件中的 auth 设置更改为 plain,而不是 gssapi [1]
auth plain
信封未被接受
如果是以下情况
msmtp: envelope from address mail@server not accepted by the server msmtp: server message: 530 5.5.1 Authentication Required. msmtp: could not send mail (account default from /etc/msmtprc)
尝试启用身份验证,使用
auth on
或任何其他方法。