转载请注明文章出处:tlanyan.me/config-mail…php
前文“PHP回顾之发送邮件”介绍了邮件中的一些基本概念,今天分享在Linux上使用mail
命令经过SMTP对外发送邮件。html
先看一下三者的关系:mail
是mailx
的别名,最初叫nail
(与arch linux目前用的S nail
基因相同);mail
是Heirloom的一个子项目,sendmail
是Eric Allman的做品,都是开源项目;mail
是用户代理(客户端),sendmail
是邮件传输代理(服务器);mail
默认使用sendmail
对外发送邮件。linux
总结:mail和mailx是同一个东西,大约相似于发信用的foxmail、outlook等工具,sendmail大约至关于163/qq邮箱的服务器软件。git
由前文咱们知道云服务器基本上不容许25端口对外通讯,要对外发邮件只能考虑465和587端口。那么465和587端口有什么区别?这要先从SSL、TLS和STARTTLS的区别开始说。github
SSL(Secure Socket Layer)是加密传输层,TLS(Transport Layer Security)是SSL的继承者和升级版,提供更好的安全性和性能。SSL有SSL v二、SSL v3两个版本,目前都不建议使用。TLS有TSL v1.0-v1.3,建议至少使用TLS v1.2。浏览器
TLS和STARTTLS二者关系不大,但更让人容易产生误解,缘由是名字中都带有TLS。STARTTLS是升级非安全链接为安全链接的协议,并无强制使用加密。当服务端支持时,客户端和服务端才协商将已经创建的链接升级到SSL或者TLS加密。安全
接着看465端口和587端口。咱们知道25端口刚被设计出来时是用于转发邮件的,没有考虑认证、加密等问题。随着垃圾邮件泛滥、网络安全问题严重,MSA、ESMTP/SMTPS等概念和协议被设计出来。1997年465端口被注册用于加密方式(SMTPS)提交邮件,那时STARTTLS尚未捣腾出来。1998年STARTLS标准出炉,规定用587端口以STARTTLS方式提交邮件,465端口被吊销。然而许多客户端不支持STARTTLS,加上很是多邮件服务提供商都在使用465端口做为加密提交端口,因而465就一直这么被用到今天。bash
简单来讲,465端口只支持加密传输,不符合互联网号码分配结构(The Internet Assigned Numbers Authority,IANA)的标准,但一直被使用和支持;587端口专门被设计用来提交邮件,传输能够加密也能够不加密。服务器
明白了基本概念,接下来配置mail
使用SMTP对外发送邮件。mail
命令的系统级配置文件是/etc/mail.rc
,用户级别的默认配置文件是~/.mailrc
,也能够经过MAILRC
环境变量设置配置文件路径。做为普通用户,咱们在本地的~/.mailrc
文件进行配置,SMTP的主要配置以下:网络
set smtp=smtps://smtp.xxx.com:465 # 这里填入smtp地址
set smtp-auth=login # 认证方式
set smtp-auth-user=user@xxx.com # 这里输入邮箱帐号
set smtp-auth-password=password # 这里填入密码
set ssl-verify=ignore # 忽略证书警告
set nss-config-dir=/etc/pki/nssdb # 证书所在目录
set from=user@xxx.com # 设置发信人邮箱和昵称
#set smtp-use-starttls=yes # STARTTLS时使用
复制代码
几个注意点:
smtps://
协议;若是是587端口,不须要加smtps://
或者写smtp://
;smtp-use-starttls
;set from=user@xxxx.com
或set from=user@xxx.com(nickname)
;若是邮箱与认证的不一致,将出现“smtp-server: 553 Mail from must equal authorized user”的错误;smtps://
协议,例如126邮箱。配置好后,使用mail
命令发送邮件:
echo '邮件内容' | mail -s '邮件标题' 收件人邮箱
#或者:
cat 邮件内容.txt | mail -s '邮件标题' 收件人邮箱
#或者
mail -s '邮件标题' 收件人邮箱 < 邮件内容.txt
复制代码
mail
命令的选项很是丰富,具体可查看其文档或这篇文章。
若是想切换发送邮箱怎么办?答案是利用配置文件的account
指令或在命令行中指定配置。先看配置文件中指定,在~/.mailrc
中将配置改为以下:
# 126不支持STARTTLS,使用465端口
account 126 {
set smtp=smtps://smtp.126.com:465
set smtp-auth=login
set smtp-auth-user=user@126.com
set smtp-auth-password=password
set ssl-verify=ignore
set nss-config-dir=/etc/pki/nssdb
set from=password@126.com
}
# QQ邮箱支持STARTTLS,使用587端口
account qq {
set smtp=smtp://smtp.qq.com:587
set smtp-auth=login
set smtp-auth-user=user@qq.com
set smtp-auth-password=password
set ssl-verify=ignore
set nss-config-dir=/etc/pki/nssdb
set from="user@qq.com(nickname)"
set smtp-use-starttls=yes
}
复制代码
配置文件中定义了两个帐户,发送邮件时可用-A参数指定发信帐户:
echo 'mail test for 126' | mail -A 126 -s 'mail test' user@xxx.com
echo 'mail test for qq' | mail -A qq -s 'mail test' user@xxx.com
复制代码
除了配置文件,也能够在命令行中用-S参数进行设置。例如:
echo 'mail test for command line option' | mail -s 'mail test' -S smtp=smtp://smtp.qq.com:587 -S smtp-auth=login -S smtp-auth-user=user@qq.com -S smtp-auth-password=password -S ssl-verify=ignore -S nss-config-dir=/etc/pki/nssdb -S from="user@qq.com(nickname)" -S smtp-use-starttls=yes user@xxx.com
复制代码
这种方法比较繁琐,就是将配置文件的每一行都做为选项写在命令中。在程序中调用mail
命令发送邮件时能够采起这种方法。
虽然邮件能顺利发送,但每次运行都会出现一行警告:“Error in certificate: Peer's certificate issuer is not recognized.”。这是因为使用加密通讯,但客户端不能确认证书是否真实。若是咱们将配置中的set ssl-verify=ignore
改为set ssl-verify=strict
,链接将直接中断而不会继续发邮件。
要解决这个警告,须要将邮件服务器的证书加入到信任列表。操做步骤以下:
# 465端口
echo -n "" | openssl s_client -connect smtp.xxx.com:465 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > xxx.crt
# 587端口
echo -n | openssl s_client -starttls smtp -connect smtp.xxx.com:587 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > xxx.crt
# 也能够直接在浏览器上打开网页版,保存证书为PEM(base64格式)格式而后上传到服务器
复制代码
certutil -A -n 'xxxx' -t "P,P,P" -d . -i ./xxx.crt
复制代码
上述命令中-A表示添加,-n是nickname,能够随意取,例如126或qq;-t表示受信任的标签,可取值是t/c/p三种或者其组合;-d表示证书所在目录,-i指示证书文件的位置。
# 指向证书文件目录
set nss-config-dir=/path/to/cert-dir
复制代码
网上许多教程的-t标签都是"C,,"
,实践中发现使用该标签仍会报错(gmail的证书是google本身签发的,用C标签没问题,许多博主估计没试就直接抄来)。经过查阅certutil
的用法,使用P标签顺利解决问题。
配置完成后,再使用mail
命令发送邮件,烦人的警告消失不见。
"Unexpected EOF on SMTP connection",基本上是因为端口只支持SMTPS致使,将协议改为smtps://
便可。