配置使用SMTP发送邮件
配置使⽤SMTP发送邮件
mail、mailx和sendmail
  先看⼀下三者的关系:mail是mailx的别名,最初叫nail(与arch linux⽬前⽤的S nail基因相同);mail是Heirloom的⼀个⼦项
⽬,sendmail是Eric Allman的作品,都是开源项⽬;mail是⽤户代理(客户端),sendmail是邮件传输代理(服务器);mail默认使⽤sendmail对外发送邮件。
  总结:mail和mailx是同⼀个东西,⼤约类似于发信⽤的foxmail、outlook等⼯具,sendmail⼤约相当于163/qq邮箱的服务器软件。SSL、TLS和STARTTLS
  由前⽂我们知道云服务器基本上不允许25端⼝对外通信,要对外发邮件只能考虑465和587端⼝。那么465和587端⼝有什么区别?这要先从SSL、TLS和STARTTLS的区别开始说。
  SSL(Secure Socket Layer)是加密传输层,TLS(Transport Layer Security)是SSL的继承者和升级版,提供更好的安全性和性能。SSL有SSL v2、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就⼀直这么被⽤到今天。
  简单来说,465端⼝只⽀持加密传输,不符合互联⽹号码分配结构(The Internet Assigned Numbers Authority,IANA)的标准,但⼀直被使⽤和⽀持;587端⼝专门被设计⽤来提交邮件,传输可以加密也可以不加密。
配置rc.mail
  明⽩了基本概念,接下来配置mail使⽤SMTP对外发送邮件。mail命令的系统级配置⽂件是/,⽤户级别的默认配置⽂件是~/.mailrc,也可以通过MAILRC环境变量设置配置⽂件路径。
作为普通⽤户,我们在本地的~/.mailrc⽂件进⾏配置,SMTP的主要配置如下:
set smtp=smtps://:465  # 这⾥填⼊smtp地址
set smtp-auth=login                # 认证⽅式
set smtp-auth-user=user@xxx    # 这⾥输⼊邮箱账号
set smtp-auth-password=password    # 这⾥填⼊密码
set ssl-verify=ignore              # 忽略证书警告
set nss-config-dir=/etc/pki/nssdb  # 证书所在⽬录
set from=user@xxx              # 设置发信⼈邮箱和昵称
#set smtp-use-starttls=yes          # STARTTLS时使⽤
⼏个注意点:
  如果是465端⼝,需要加上smtps://协议;如果是587端⼝,不需要加smtps://或者写smtp://;
  如果使⽤587端⼝通讯,应当显⽰设置smtp-use-starttls;
  邮件的来源应当与邮箱相同,或者将发信⼈姓名写在邮箱后的括号中。例如:set from=user@xxxx或set
from=user@xxx(nickname);如果邮箱与认证的不⼀致,将出现“smtp-server: 553 Mail from must equal authorized
user”的错误;
  有些邮件服务器的587端⼝不是使⽤STARTTLS⽽是SMTPS,此时仍需加上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:465
陆龟种类set smtp-auth=login
高考加油的句子set smtp-auth-user=user@126
set smtp-auth-password=password
set ssl-verify=ignore
set nss-config-dir=/etc/pki/nssdb
set from=password@126
}
# QQ邮箱⽀持STARTTLS,使⽤587端⼝lol荣誉系统
account qq {
set smtp=smtp://smtp.qq:587
set smtp-auth=login
set smtp-auth-user=user@qq
set smtp-auth-password=password
set ssl-verify=ignore
set nss-config-dir=/etc/pki/nssdb
set from="user@qq(nickname)"
set smtp-use-starttls=yes
}
  配置⽂件中定义了两个账户,发送邮件时可⽤-A参数指定发信账户:
  echo 'mail test for 126' | mail -A 126 -s 'mail test' user@xxx
  echo 'mail test for qq' | mail -A qq -s 'mail test' user@xxx
  除了配置⽂件,也可以在命令⾏中⽤-S参数进⾏设置。例如:
  echo 'mail test for command line option' | mail -s 'mail test' -S smtp=smtp://smtp.qq:587 -S smtp-auth=login -S smtp-auth-user=user@qq -S smtp-auth-password=password -S ssl-verify=ignore -S nss-config-dir=/etc/pki/nssdb -S from="user@qq(nickname)" -S smtp-use-starttls=yes user@xxx
  这种⽅法⽐较繁琐,就是将配置⽂件的每⼀⾏都作为选项写在命令中。在程序中调⽤mail命令发送邮件时可以采取这种⽅法。
解决警告
  虽然邮件能顺利发送,但每次运⾏都会出现⼀⾏警告:“Error in certificate: Peer's certificate issuer is not recognized.”。这是由于使⽤加密通信,但客户端不能确认证书是否真实。如果我们将配置中的set ssl-verify=ignore改成set ssl-verify=strict,连接将直接中断⽽不会继续发邮件。
  要解决这个警告,需要将邮件服务器的证书加⼊到信任列表。操作步骤如下:
  获取邮件服务器证书:
  echo -n "" | openssl s_client -:465 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' >
  # 587端⼝
  echo -n | openssl s_client -starttls smtp -:587 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' >
  # 也可以直接在浏览器上打开⽹页版,保存证书为PEM(base64格式)格式然后上传到服务器
  将证书添加到受信任列表:
  certutil -A -n 'xxxx' -t "P,P,P" -d . -i ./
  上述命令中-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://即可。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。