利用mailx和Office365 SMTP發送郵件

Mailx是一個智能郵件處理系統,提供POSIX mailx命令功能,提供MIME、IMAP、POP三、SMTP和S/MIME擴展,經過調用sendmail來發送郵件。linux

安裝mailx:數據庫

# yum install mailx

mailx語法

mailx [-BDdEFintv~] [-s subject] [-a attachment ] [-c cc-addr] [-b bcc-addr] [-r from-addr] [-h hops] [-A account] [-S variable[=value]] to-addr . . .
mailx [-BDdeEHiInNRv~] [-T name] [-A account] [-S variable[=value]] -f [name]
mailx [-BDdeEinNRv~] [-A account] [-S variable[=value]] [-u user]

發送郵件

Options安全

選項 說明
-s subject 主題
-a attachment 附件
-c cc-addr 抄送地址
-b bcc-addr 密送地址
-r from-addr 發件人地址
-h hops 用指定的hop count調用sendmail(hopcount_limit),當使用SMTP時無效
-A account 執行一account命令
to-addr 收件人地址

說明:
hop是源到目標路徑中的一個部分,數據包經過路由器、網關等傳輸,每通過的一個網絡設備即爲一個hop。
利用mailx和Office365 SMTP發送郵件bash

發送本地郵件服務器

$ echo "Hello COCO" | mail -s "Hello COCO" ec2-user@localhost

以上命令向本地用戶ec2-user發送了一個郵件,郵件保存在文件/var/mail/ec2-user內,內容以下:網絡

From ec2-user@test.itrunner.org  Wed Nov  7 09:44:20 2018
Return-Path: <ec2-user@test.itrunner.org>
X-Original-To: ec2-user@localhost
Delivered-To: ec2-user@localhost.itrunner.org
Received: by test.itrunner.org (Postfix, from userid 1000)
        id 7C28999A79; Wed,  7 Nov 2018 09:44:20 +0000 (UTC)
Date: Wed, 07 Nov 2018 09:44:20 +0000
To: ec2-user@localhost.itrunner.org
Subject: Hello COCO
User-Agent: Heirloom mailx 12.5 7/5/10
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Message-Id: <20181107094420.7C28999A79@test.itrunner.org>
From: ec2-user@test.itrunner.org (Cloud User)

Hello COCO

從文件讀取內容發送:ide

$ mail -s "Hello COCO" ec2-user@localhost < hello.txt
或
$ cat hello.txt | mail -s "Hello COCO" ec2-user@localhost

向多人發送:工具

$ mail -s "Hello COCO" jason@163.com,coco@163.com < hello.txt

發送附件:測試

$ echo "Hello COCO" | mail -s "Hello COCO" -a hello.txt coco@163.com

指定Reply To:ui

$ echo "Hello COCO" | mail -s "Hello COCO" -S replyto="Jason<jason@163.com>"  coco@163.com

讀取郵件

Options

選項 說明
-T name 文件名,將郵件信息中'Message-Id' 和 'Article-Id'寫入文件
-f [name] 從指定文件讀取郵件

執行不帶任何參數的mailx命令,將讀取當前用戶的郵件,輸入quit退出。輸出內容以下:

Heirloom Mail version 12.5 7/5/10.  Type ? for help.
"/var/spool/mail/ec2-user": 1 message
>   1 Cloud User            Thu Nov  8 05:41  32/1017  "Hello COCO"
&

從文件讀取郵件並將Message-Id寫入文件

$ mailx -T test -f /var/mail/ec2-user

使用Office365 SMTP發送郵件

SMTP Options

使用外部SMTP服務器時,需用-S設定SMTP參數:

$ echo "Hello COCO" | mail -r "someone@example.com" -s "Hello COCO" -S smtp="smtp.office365.com:587" -S smtp-use-starttls -S smtp-auth=login -S smtp-auth-user="someone@example.com" -S smtp-auth-password="password" -S ssl-verify=ignore -S nss-config-dir=~/.mozilla/firefox/default.clm coco@163.com
選項 說明
smtp 指定SMTP地址(host or ip:port)
smtp-use-starttls 使用TLS加密來保證通信安全
smtp-auth 設置SMTP驗證方法,可選值: login、cram-md五、plain
smtp-auth-user SMTP驗證用戶名
smtp-auth-password SMTP密碼
ssl-verify SSL證書驗證出錯時的處理方式,可選值:strict、ask、warn、ignore
nss-config-dir 包含文件certN.db、keyN.db、secmod.db的目錄

nss-config-dir: 從certN.db中檢索證書, 從keyN.db中檢索私鑰,N爲數字。系統如安裝了Firefox,其profile中包含這些文件。

運行如上命令能夠發送郵件,但有錯誤:Error in certificate: Peer's certificate issuer is not recognized。緣由是未導入office365的證書。上例nss-config-dir配置的是firefox profile目錄,雖然mailx僅讀取其內容不會修改,但若mailx正在運行時其內容被firefox修改時,會致使錯誤。所以實際應用中,需將certN.db、keyN.db、secmod.db複製到新的目錄,或使用certutil建立這些文件。

certutil

certutil是證書和密鑰管理工具
語法:

certutil [options] [[arguments]]
Options
選項 說明
-A 添加證書
-D 刪除證書
-F 刪除私鑰
-G 生成密鑰對
-L 列出全部證書
-M 修改certificate的trust屬性,需使用-t參數
-N 建立證書和密鑰數據庫
-V 檢查證書

Arguments
-d 包含證書和密鑰數據庫文件的目錄
-n nickname,指定證書或密鑰的nickname
-t trust參數

建立證書和密鑰數據庫

$ mkdir ~/.certs
$ certutil -N -d ~/.certs
Enter a password which will be used to encrypt your keys.
The password should be at least 8 characters long,
and should contain at least one non-alphabetic character.

Enter new password:
Re-enter password:

獲取office 365證書

$ echo -n | openssl s_client -starttls smtp -showcerts -crlf -connect smtp.office365.com:587 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ~/.certs/office365.crt

運行以上命令會獲得兩個證書,修改一下只保留第二個CA證書,而後將CA證書導入:

$ certutil -A -n "DigiCert Global Root CA" -t "C,P,C" -d ~/.certs -i ~/.certs/office365.crt

說明:
-t trust參數,對於每一個證書有三類trust參數,順序是:SSL、email、object signing,參數可使用none、any或如下屬性代碼:

  • p - Valid peer
  • P - Trusted peer (implies p)
  • c - Valid CA
  • C - Trusted CA (implies c)
  • T - trusted CA for client authentication (ssl server only)

檢查證書:

$ certutil -L -d ~/.certs

再次執行以下命令將徹底正常的發送郵件:

$ echo "Hello COCO" | mail -r "someone@example.com" -s "Hello COCO" -S smtp="smtp.office365.com:587" -S smtp-use-starttls -S smtp-auth=login -S smtp-auth-user="someone@example.com" -S smtp-auth-password="password" -S ssl-verify=ignore -S nss-config-dir=~/.certs coco@163.com

配置mail.rc

如發送郵件時每次都配置SMTP參數,比較繁瑣,能夠在文件/etc/mail.rc設置默認值,在其末尾添加以下內容:

set from=someone@example.com
set smtp=smtp.office365.com:587
set smtp-auth=login
set smtp-auth-user=someone@example.com
set smtp-auth-password=password
set smtp-use-starttls
set ssl-verify=ignore
set nss-config-dir=~/.certs

再次運行以下命令測試:

$ echo "Hello COCO" | mail  -s "Hello COCO" coco@163.com

Java調用mailx

package org.itrunner.tests.utils;

public class MailSender {
    private MailSender() {
    }

    public static void send(MailInfo mailInfo) throws Exception {
        ProcessBuilder processBuilder = new ProcessBuilder("bash", "-c", getCommand(mailInfo));
        Process process = processBuilder.start();
        process.waitFor();
    }

    private static String getCommand(MailInfo mail) {
        String sendEmailCommand = "echo \"" + mail.getMessage() + "\" | mail";

        if (mail.getCc() != null) {
            sendEmailCommand += " -c" + mail.getCc();
        }

        if (mail.getBcc() != null) {
            sendEmailCommand += " -b" + mail.getBcc();
        }

        sendEmailCommand += " -s \"" + mail.getSubject() + "\" " + mail.getTo();
        return sendEmailCommand;
    }
}

參考文檔

Linux mailx command
Linux sendmail command
certutil - Linux Man Pages
9 mail/mailx command examples to send emails from command line on Linux

相關文章
相關標籤/搜索