所有文章

Linux - 发送邮件的两种方式

很多情况下,我们需要在服务器上向外发送邮件,用来获得任务报告、安全监控等等,到这里有人会说了:这还不简单!我一条命令分分种就可以搞定。 而实际上,还是有点难度的,难在哪?我想一定有人在Linux下发邮件的时候碰到过下面这样的情况 我们先来发一份邮件,Linux下发送邮件很简单:

echo "hello" | mail -s "title" mybox@163.com -a nginx.log

这样发出去有两种结果,要么提示你发送失败,要么石沉大海,然后你各种尝试,,各种搜资料,,各种失败,, 说到底,主要是因为国内垃圾邮件太多导致的,在国内很多人利用邮箱向他们所谓的“客户”(那些并没有订阅的人)或其它使用邮箱的人群发送大量的广告,以此牟利,甚至还发往国外,使得各大邮箱服务商不得不想办法来过滤这些垃圾邮件,像上面那封邮件也会被当成是垃圾邮件,然后让我们这些用邮箱干正事的人也跟着受罪,无知的人们哪。。那我们该怎么办?本文将介绍两种可行的方法。

在Linux下发送邮件,按照发送原理大概分为两类

  1. 一种是把 Linux 本身当做邮件服务器,由它来直接发送给其它发件人,但这种方式有个弊端,假设我要给 abc@163.com 发一份邮件,那么邮件到达 163 服务时,它可能把我们的邮件当成垃圾邮件,导致邮件被拒收,本文不介绍此种方式。
  2. 还有一种方式是通过第三方服务器发送,假设我要给 abc@163.com 发一份邮件,我可以先把邮件交给 qq 邮件服务器,qq 服务器再转发给 163 服务器,这样就会降低被拒收的概率,但这种方式需要先通过 qq 邮件服务器的登录认证才行,这也是本文重点介绍的方式。

先引用两句名言

勿以恶小而为之,勿以善小而不为

地势坤,君子以厚德载物

两种可行的方法

方法一,利用mailx命令

这个方法相对简单,但只支持smtp协议,以CentOS7.2为例,如果有防火墙,请将25端口加入白名单,sendmail服务可以关闭 先安装mailx

sudo yum install mailx -y

修改配置文件

sudo echo "set from=${user}@163.com smtp=smtp.163.com smtp-auth-user=$user \
smtp-auth-password=$passwd smtp-auth=login" >> /etc/mail.rc 

发送邮件测试

echo -e '任务序号:0001' | mail -s '任务成功:0001' my_mail@163.com

如果发送成功的话,不需要等太久,一般一分种足够了,然后去检查一下自己的邮箱吧,, 如果你的25端口没开,或者因为其它原因导致连不到服务器,它会有提示告诉你连接超时,像下面这样:

could not connect: 连接超时
"/home/user/dead.letter" 13/344
. . . message not sent.

如果两分种以上还没收到邮件,且没有任何提示,那可能是被服务器拒收了,而且笔者也没有找到mail的日志在哪。

方法二,利用python脚本

用puthon脚本的好处是,我们可以自定义很多参数,这些参数是通过邮箱服务器认证的重要因素 这种方式同时支持smtp和smtps协议,且需要启动sendmail服务,如果有防火墙,需放行25、465端口。

下面给出一个例子

[user@node1 ~]$ vi send_mail.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import smtplib
from email.mime.text import MIMEText
from email.header import Header
from email.mime.multipart import MIMEMultipart
mailto_list=["user_name@163.com"]
mail_host="smtp.163.com"
mail_user="user_name"
mail_pass="passwd"
mail_postfix="163.com"
 
def send_mail_att(to_list,sub,content,att_file):
  # 下面几个参数是通过认证的关键因素
  me="splash_update_apks"+"<"+mail_user+"@"+mail_postfix+">"
  msg = MIMEMultipart()
  msg['Subject'] = Header(sub, 'utf-8')
  msg['From'] = me
  msg['To'] = ";".join(to_list)
 
  # 邮件正文内容
  msg.attach(MIMEText(content, 'plain', 'utf-8'))
 
  # 构造附件
  att1 = MIMEText(open(att_file, 'rb').read(), 'base64', 'utf-8')
  #att1["Content-Type"] = 'application/octet-stream'
  att1["Content-Disposition"] = 'attachment; filename="run.log"'
  msg.attach(att1)
 
  try:
    server = smtplib.SMTP()
    server.connect(mail_host)
    server.login(mail_user,mail_pass)
    server.sendmail(me, to_list, msg.as_string())
    server.close()
    return True
  except Exception, e:
    print str(e)
    return False
 
if __name__=="__main__":
  import time
   
  time_for_now = str(time.strftime(ISOTIMEFORMAT, time.localtime()))
  send_mail_att(mailto_list, sys.argv[1], sys.argv[2], sys.argv[3])

发送邮件测试

python send_mail.py titel context /var/log/log.att

同上,如果发送成功,很快就能收到邮件,如果服务器拒收,则立即会输出提示信息 如是迟迟收不到邮件,用以下命令可以查看没有发送出去的邮件,并且可以看到该邮件发送失败的原因

sendmail -bp

-End-


编写日期:2017-03-12