利用mailx和Office365 SMTP發送郵件

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

安裝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發送郵件

發送本地郵件

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

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

From [email protected]  Wed Nov  7 09:44:20 2018
Return-Path: <[email protected]>
X-Original-To: ec2-user@localhost
Delivered-To: [email protected]
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: [email protected]
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: <[email protected]>
From: [email protected] (Cloud User)

Hello COCO

從文件讀取內容發送:

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

向多人發送:

$ mail -s "Hello COCO" [email protected],[email protected] < hello.txt

發送附件:

$ echo "Hello COCO" | mail -s "Hello COCO" -a hello.txt [email protected]

指定Reply To:

$ echo "Hello COCO" | mail -s "Hello COCO" -S replyto="Jason<[email protected]>"  [email protected]

讀取郵件

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 "[email protected]" -s "Hello COCO" -S smtp="smtp.office365.com:587" -S smtp-use-starttls -S smtp-auth=login -S smtp-auth-user="[email protected]" -S smtp-auth-password="password" -S ssl-verify=ignore -S nss-config-dir=~/.mozilla/firefox/default.clm [email protected]
選項 說明
smtp 指定SMTP地址(host or ip:port)
smtp-use-starttls 使用TLS加密來保證通訊安全
smtp-auth 設置SMTP驗證方法,可選值: login、cram-md5、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 "[email protected]" -s "Hello COCO" -S smtp="smtp.office365.com:587" -S smtp-use-starttls -S smtp-auth=login -S smtp-auth-user="[email protected]" -S smtp-auth-password="password" -S ssl-verify=ignore -S nss-config-dir=~/.certs [email protected]

配置mail.rc

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

set [email protected]
set smtp=smtp.office365.com:587
set smtp-auth=login
set [email protected]
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" [email protected]

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章