配置 msmtp 在 shell 中发送邮件(使用 Gmail 的 App password 用户验证)

背景

希望在 bash 脚本中发送邮件,只需要纯文本邮件即可;不安装 sendmail, postfix 等服务,万一因为漏洞被坏人利用狂发垃圾邮件很麻烦,使用第三方邮件服务,首选支持 Gmail;无后台服务(daemon进程),对小内存服务器友好。

这就相当于需要一款可以有 shell 调用的邮件客户端。 msmtp 正好完美匹配。

配置步骤

安装 msmtp

epel 有收入,直接安装即可

yum install msmtp

单用户的配置文件

msmtp 的用法还是比较丰富的,这里仅仅是为了让 Linux 下的单个用户在 shell 下使用,所以仅用最简单的配置

参照使用官方配置文件示例 https://marlam.de/msmtp/msmtp.html#Examples

写入文件 ~/.msmtprc ,并在其基础上做修改,有点长,但只需要修改少数几处即可

# Example for a user configuration file ~/.msmtprc
#
# This file focusses on TLS and authentication. Features not used here include
# logging, timeouts, SOCKS proxies, TLS parameters, Delivery Status Notification
# (DSN) settings, and more.


# Set default values for all following accounts.
defaults

# Use the mail submission port 587 instead of the SMTP port 25.
port 587

# Always use TLS.
tls on

# Set a list of trusted CAs for TLS. The default is to use system settings, but
# you can select your own file.
#tls_trust_file /etc/ssl/certs/ca-certificates.crt


# A freemail service
account gmail

# Host name of the SMTP server
host smtp.gmail.com

# As an alternative to tls_trust_file, you can use tls_fingerprint
# to pin a single certificate. You have to update the fingerprint when the
# server certificate changes, but an attacker cannot trick you into accepting
# a fraudulent certificate. Get the fingerprint with
# $ msmtp --serverinfo --tls --tls-certcheck=off --host=smtp.freemail.example
#tls_fingerprint 00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33

# Envelope-from address
from yourname@gmail.com

# Authentication. The password is given using one of five methods, see below.
auth on
user yourname@gmail.com

# Password method 1: Add the password to the system keyring, and let msmtp get
# it automatically. To set the keyring password using Gnome's libsecret:
# $ secret-tool store --label=msmtp \
#   host smtp.freemail.example \
#   service smtp \
#   user joe.smith

# Password method 2: Store the password in an encrypted file, and tell msmtp
# which command to use to decrypt it. This is usually used with GnuPG, as in
# this example. Usually gpg-agent will ask once for the decryption password.
passwordeval "cat ~/script/gmail_login_auth.apppswd"

# Password method 3: Store the password directly in this file. Usually it is not
# a good idea to store passwords in cleartext files. If you do it anyway, at
# least make sure that this file can only be read by yourself.
#password secret123

# Password method 4: Store the password in ~/.netrc. This method is probably not
# relevant anymore.

# Password method 5: Do not specify a password. Msmtp will then prompt you for
# it. This means you need to be able to type into a terminal when msmtp runs.


# A second mail address at the same freemail service
account freemail2 : gmail
from joey@freemail.example


# The SMTP server of your ISP
account isp
host mail.isp.example
from smithjoe@isp.example
auth on
user 12345


# Set a default account
account default : gmail

简单来说,这个配置文件支持配置多个邮件账户,每一个账户以 account 指令开始,后面的账户可以用前面配置过的账户作为模板(继承),再设置有不同的配置值(覆盖)。这里只配置一个叫 gmail 的,最后定义为默认。需要注意是其中 passwordeval … 一行,其中的路径是密码保存的文件。

Gmail 配置:

Gmail 不支持直接登录密码的用户验证,这里选用 “应用专用密码 App password”,这是一串16个字符的字符串,要在 Google 账户开启二次登录验证(2FA)之后才能生成应用专用密码(目前的Google 账户应该早已普遍开通过2FA了吧)。

Gmail 似乎也不太推荐这个验证手段了,在Google账户页面里甚至已经没有了入口链接,可以在 Google 账户后台里搜索”app password”或”应用专用密码“,有如下的帮助页面,上面有完整的说明,包括链接入口(https://myaccount.google.com/apppasswords)、应用专用密码的生成、管理、疑难解释等

使用应用专用密码登录 https://support.google.com/accounts/answer/185833?hl=zh-Hans

生成一个密码,按前面配置文件里passwordeval 指定的路径,写入文件,设置权限为600

echo 'abcd efgh ijkl mnop' > ~/script/gmail_login_auth.apppswd
chmod 600 ~/script/gmail_login_auth.apppswd

应用专用密码Appgle password的管理要点:在Google 账户后台里,生成 App password 后,只显示一次,无法再次查看;丢失只能重新生成;最好每个用途生成一个,不要混用;可以随时吊销,删除某个 App Password 不影响其他 App Password、不影响主账号。

其他邮箱的验证

如果使用其他邮箱服务,一般是普通的用户名、密码的验证方式,或者是与Gmail类似的”第三方客户端授权码“,配置方式类似。甚至还可以直接把密码写在脚本里 password your-password 就像很多文章里使用 password 指定明文密码的那种写法);而是使用 passwordeval 指令,方便管理(比如其他机制定时更新或分发的密码)

account qqmail02
host smtp.qq.com
port 587
tls on
auth on
user your-qq-number@qq.com
passwordeval "cat ~/path/to/qqmail_auth.passwd"
from your-qq-number@qq.com

# OR, use raw password as below line, instead of the line passwordeval xxx
# password your-password

调用测试

$cat <<EOF | msmtp yourname@gmail.com
Subject: App passwd test for msmtp

It works.
EOF

这里如果没有报错,应该就能收到邮件。

 

Last Updated on 2025/12/24

发表评论

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理