如何測試 SMTP 伺服器?

如何測試 SMTP 伺服器?

我收到了 SMTP 伺服器資訊和憑證,想測試它們是否有效。

如何使用命令列在 Linux 上輕鬆測試 SMTP 連線?

我知道我可以透過 telnet / openssl 來做到這一點,但這看起來很複雜。

那麼如何查看SMTP伺服器呢?

答案1

該工具swaks在這裡派上用場

在 Ubuntu 上是

apt install swaks

然後您可以執行命令並會看到 SMTP 對話框

$ swaks --to [email protected] --server smtp.ionos.de:587
=== Trying smtp.ionos.de:587...
=== Connected to smtp.ionos.de.
<-  220 kundenserver.de (mreue106) Nemesis ESMTP Service ready
 -> EHLO lafto
<-  250-kundenserver.de Hello example [<IP redacted>]
<-  250-8BITMIME
<-  250-AUTH LOGIN PLAIN
<-  250-SIZE 140000000
<-  250 STARTTLS
 -> MAIL FROM:<[email protected]>
<** 530 Authentication required
 -> QUIT
<-  221 kundenserver.de Service closing transmission channel
=== Connection closed with remote host.

正如您在這裡看到的,它需要身份驗證,這就是我們重新運行的原因

$ swaks --to [email protected] --server smtp.ionos.de:587 --auth LOGIN
Username: foo
Password: bar

查看手冊頁以獲取更多信息

答案2

我知道我可以透過 telnet / openssl 做到這一點,但這看起來很複雜

很簡單,google一下就好了SMTP 命令,您可以毫無問題地使用它們。由於您已經回答了自己的問題,因此您可以使用 SWAKS。這裡有一些替代選項。


以下是一些 SMTP 命令:

每個命令都用於透過 SMTP 協定在兩個伺服器之間的正常通訊序列中,以傳送電子郵件。

直升機
這是第一個 SMTP 指令:啟動識別寄件者伺服器的會話,後面通常是其網域名稱。

埃洛
啟動對話的替代命令,其基礎是伺服器使用擴展 SMTP 協定。

郵件來自
使用此 SMTP 命令,操作開始:寄件者在「寄件者」欄位中註明來源電子郵件地址,並實際開始電子郵件傳輸。

RCPT 至
它標識電子郵件的收件者;如果有多個,則該命令只是逐個地址地重複。

尺寸
此 SMTP 指令通知遠端伺服器所附電子郵件的估計大小(以位元組為單位)。它也可用於報告伺服器接受的訊息的最大大小。

數據
使用 DATA 指令,電子郵件內容開始傳輸;它通常後面跟著伺服器給出的 354 回應代碼,授予開始實際傳輸的權限。

VRFY
伺服器被要求驗證特定的電子郵件地址或使用者名稱是否確實存在。

轉動
此命令用於反轉客戶端和伺服器之間的角色,而不需要執行新的連線。

認證
使用 AUTH 命令,用戶端向伺服器驗證自己的身份,並提供其使用者名稱和密碼。這是保證正確傳輸的另一層安全性。

RSET
它通知伺服器正在進行的電子郵件傳輸將被終止,但 SMTP 會話不會關閉(就像 QUIT 的情況一樣)。

指數
此 SMTP 指令要求確認郵件清單的標識。

幫助
這是客戶要求提供一些對成功傳輸電子郵件有用的信息。

辭職
它終止 SMTP 會話。


OpenSSL、testssl.sh 和 GnuTLS

您可以使用openssl s_client,透過運行如下命令:

openssl s_client -starttls smtp -connect mail.example.com:587

您也可以使用一個名為測試ssl.sh用於在 SMTP 伺服器上測試 SSL/TLS,顯然即使它是本地託管的。下載後,將其解壓縮並進入testssl.sh資料夾並運行:

./testssl.sh -t smtp mail.example.com:25

GnuTLS如果安裝了它,您也可以使用:

gnutls-cli mail.example.com -p 25

遠端登入

如果您的 SMTP 伺服器沒有 SSL/TLS,您可以使用telnet。 Telnet 是最基本的工具,但它不支援 SSL/TLS。

telnet mail.example.com 25

PHP郵件程式

如果您使用 PHP,則可以使用PHP郵件程式

<?php
// Import PHPMailer classes into the global namespace
// These must be at the top of your script, not inside a function
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;

// Load Composer's autoloader
require 'vendor/autoload.php';

// Instantiation and passing `true` enables exceptions
$mail = new PHPMailer(true);

try {
    //Server settings
    $mail->SMTPDebug = SMTP::DEBUG_SERVER;                      // Enable verbose debug output
    $mail->isSMTP();                                            // Send using SMTP
    $mail->Host       = 'smtp.example.com';                    // Set the SMTP server to send through
    $mail->SMTPAuth   = true;                                   // Enable SMTP authentication
    $mail->Username   = '[email protected]';                     // SMTP username
    $mail->Password   = 'secret';                               // SMTP password
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;         // Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` encouraged
    $mail->Port       = 587;                                    // TCP port to connect to, use 465 for `PHPMailer::ENCRYPTION_SMTPS` above

    //Recipients
    $mail->setFrom('[email protected]', 'Mailer');
    $mail->addAddress('[email protected]', 'Joe User');     // Add a recipient
    $mail->addAddress('[email protected]');               // Name is optional
    $mail->addReplyTo('[email protected]', 'Information');
    $mail->addCC('[email protected]');
    $mail->addBCC('[email protected]');

    // Attachments
    $mail->addAttachment('/var/tmp/file.tar.gz');         // Add attachments
    $mail->addAttachment('/tmp/image.jpg', 'new.jpg');    // Optional name

    // Content
    $mail->isHTML(true);                                  // Set email format to HTML
    $mail->Subject = 'Here is the subject';
    $mail->Body    = 'This is the HTML message body <b>in bold!</b>';
    $mail->AltBody = 'This is the body in plain text for non-HTML mail clients';

    $mail->send();
    echo 'Message has been sent';
} catch (Exception $e) {
    echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}

儘管這不是您問題的答案。您甚至可以在 PHPMailer 中輕鬆設定 DKIM:

<?php

/**
 * This example shows sending a DKIM-signed message with PHPMailer.
 * More info about DKIM can be found here: http://www.dkim.org/info/dkim-faq.html
 * There's more to using DKIM than just this code - check out this article:
 * @see https://yomotherboard.com/how-to-setup-email-server-dkim-keys/
 * See also the DKIM_gen_keys example code in the examples folder,
 * which shows how to make a key pair from PHP.
 */

//Import the PHPMailer class into the global namespace
use PHPMailer\PHPMailer\PHPMailer;

require '../vendor/autoload.php';

//Usual setup
$mail = new PHPMailer();
$mail->setFrom('[email protected]', 'First Last');
$mail->addAddress('[email protected]', 'John Doe');
$mail->Subject = 'PHPMailer mail() test';
$mail->msgHTML(file_get_contents('contents.html'), __DIR__);

//This should be the same as the domain of your From address
$mail->DKIM_domain = 'example.com';
//See the DKIM_gen_keys.phps script for making a key pair -
//here we assume you've already done that.
//Path to your private key:
$mail->DKIM_private = 'dkim_private.pem';
//Set this to your own selector
$mail->DKIM_selector = 'phpmailer';
//Put your private key's passphrase in here if it has one
$mail->DKIM_passphrase = '';
//The identity you're signing as - usually your From address
$mail->DKIM_identity = $mail->From;
//Suppress listing signed header fields in signature, defaults to true for debugging purpose
$mail->DKIM_copyHeaderFields = false;
//Optionally you can add extra headers for signing to meet special requirements
$mail->DKIM_extraHeaders = ['List-Unsubscribe', 'List-Help'];

//When you send, the DKIM settings will be used to sign the message
if (!$mail->send()) {
    echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
    echo 'Message sent!';
}

Python

(取自https://www.tutorialspoint.com/python3/python_sending_email.htm,因為我不想提供鏈接,所以我只是將整個內容發佈在這裡,因為該頁面可能隨時出現 404 錯誤。

Python 提供了smtplib一個模組,定義了一個 SMTP 用戶端會話對象,該對象可用於將郵件傳送到具有 SMTP 或 ESMTP 偵聽器守護程式的任何 Internet 電腦。

以下是建立 SMTP 物件的簡單語法,該物件稍後可用於發送電子郵件 -

import smtplib

smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] )
Here is the detail of the parameters −
  • 主持人− 這是執行 SMTP 伺服器的主機。您可以指定主機的 IP 位址或網域名稱(例如 example.com)。這是一個可選參數。

  • 港口− 如果您提供主機參數,則需要指定 SMTP 伺服器偵聽的連接埠。通常該連接埠為 25。

  • 本地主機名− 如果您的 SMTP 伺服器在本機電腦上執行,您可以只指定 localhost 該選項。

SMTP 物件有一個名為 的實例方法sendmail,該方法通常用於執行郵寄訊息的工作。它需要三個參數 -

  • 寄件者 - 包含寄件者地址的字串。

  • 接收者 - 字串列表,每個接收者一個。

  • 訊息 - 訊息作為字串,其格式按照各種 RFC 中的指定進行。

例子

這是使用 Python 腳本發送一封電子郵件的簡單方法。嘗試一次 -

#!/usr/bin/python3

import smtplib

sender = '[email protected]'
receivers = ['[email protected]']

message = """From: From Person <[email protected]>
To: To Person <[email protected]>
Subject: SMTP e-mail test

This is a test e-mail message.
"""

try:
   smtpObj = smtplib.SMTP('localhost')
   smtpObj.sendmail(sender, receivers, message)         
   print "Successfully sent email"
except SMTPException:
   print "Error: unable to send email"

在這裡,您在訊息中放置了一封基本電子郵件,使用三重引號,並注意正確設定標題格式。電子郵件需要「寄件者」、「收件者」和「主題」標頭,並以空白行與電子郵件正文分隔。

若要傳送郵件,您可以使用 smtpObj 連線到本機上的 SMTP 伺服器。然後使用 sendmail 方法以及訊息、寄件者地址和目標地址作為參數(即使寄件者和收件者地址位於電子郵件本身內,這些並不總是用於路由郵件)。

如果您的本機電腦上沒有執行 SMTP 伺服器,則可以使用 smtplib 用戶端與遠端 SMTP 伺服器進行通訊。除非您使用網絡郵件服務(例如 gmail 或 Yahoo! Mail),否則您的電子郵件提供者必須向您提供您可以提供的外發郵件伺服器詳細信息,如下所示 -

mail = smtplib.SMTP('smtp.gmail.com', 587)

使用 Python 傳送 HTML 電子郵件 當您使用 Python 傳送文字訊息時,所有內容都會被視為簡單文字。即使您在文字訊息中包含 HTML 標籤,它也會顯示為簡單文本,且 HTML 標籤不會根據 HTML 語法進行格式化。但是,Python 提供了將 HTML 訊息作為實際 HTML 訊息發送的選項。

傳送電子郵件時,您可以指定 Mime 版本、內容類型和字元集以傳送 HTML 電子郵件。

例子

以下是將 HTML 內容作為電子郵件發送的範例。嘗試一次 -

#!/usr/bin/python3

import smtplib

message = """From: From Person <[email protected]>
To: To Person <[email protected]>
MIME-Version: 1.0
Content-type: text/html
Subject: SMTP HTML e-mail test

This is an e-mail message to be sent in HTML format

<b>This is HTML message.</b>
<h1>This is headline.</h1>
"""

try:
   smtpObj = smtplib.SMTP('localhost')
   smtpObj.sendmail(sender, receivers, message)         
   print "Successfully sent email"
except SMTPException:
   print "Error: unable to send email"

以電子郵件形式傳送附件 若要傳送包含混合內容的電子郵件,需要將內容類型標頭設定為多部分/混合。然後,可以在邊界內指定文字和附件部分。

邊界以兩個連字符開始,後面跟著一個唯一的數字,該數字不能出現在電子郵件的訊息部分中。表示電子郵件最後部分的最終邊界也必須以兩個連字號結束。

附件檔案pack("m")應在傳輸前使用 Base 64 編碼功能進行編碼。

範例 以下是一個範例,它將文件/tmp/test.txt作為附件發送。嘗試一次 -

#!/usr/bin/python3

import smtplib
import base64

filename = "/tmp/test.txt"

# Read a file and encode it into base64 format
fo = open(filename, "rb")
filecontent = fo.read()
encodedcontent = base64.b64encode(filecontent)  # base64

sender = '[email protected]'
reciever = '[email protected]'

marker = "AUNIQUEMARKER"

body ="""
This is a test email to send an attachement.
"""
# Define the main headers.
part1 = """From: From Person <[email protected]>
To: To Person <[email protected]>
Subject: Sending Attachement
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=%s
--%s
""" % (marker, marker)

# Define the message action
part2 = """Content-Type: text/plain
Content-Transfer-Encoding:8bit

%s
--%s
""" % (body,marker)

# Define the attachment section
part3 = """Content-Type: multipart/mixed; name=\"%s\"
Content-Transfer-Encoding:base64
Content-Disposition: attachment; filename=%s

%s
--%s--
""" %(filename, filename, encodedcontent, marker)
message = part1 + part2 + part3

try:
   smtpObj = smtplib.SMTP('localhost')
   smtpObj.sendmail(sender, reciever, message)
   print "Successfully sent email"
except Exception:
   print ("Error: unable to send email")

搖擺:

要安裝它:

  • 烏班圖:sudo apt install swaks
  • CentOS:首先:sudo yum install epel-release、和sudo yum install swakssudo dnf install swaks
  • 拱門Linux:sudo pacman -S swaks

然後您可以執行命令並會看到 SMTP 對話框:

$ swaks --to [email protected] --server smtp.example.com:587
=== Trying smtp.example.com:587...
=== Connected to smtp.example.com.
<-  220 example.com (something) Foo ESMTP Service ready
 -> EHLO somenamehere
<-  250-example.com Hello example [<IP redacted>]
<-  250-8BITMIME
<-  250-AUTH LOGIN PLAIN
<-  250-SIZE 140000000
<-  250 STARTTLS
 -> MAIL FROM:<[email protected]>
<** 530 Authentication required
 -> QUIT
<-  221 example.com Service closing transmission channel
=== Connection closed with remote host.

正如您在這裡看到的,它需要身份驗證,這就是我們重新運行的原因

$ swaks --to [email protected] --server mail.example.com:587 --auth LOGIN
Username: yourusername
Password: yourpassword

您也可以使用 AUTH PLAIN --auth PLAIN,具體取決於伺服器支援的方法。使用 來查看手冊頁以獲取更多資訊man swaks

MX工具箱

您可以使用 MXToolBox電子郵件伺服器測試對於某些有時可能有用的測試,但您無法指定您想用它做什麼。所以,你最好使用上面的東西。

或者,只需使用mail命令...

答案3

可以透過多種方式進行測試:

  1. 正如已經提到的,使用 python 庫。
  2. 也使用sendmail客戶端測試smpt伺服器。
  3. 您也可以設定 postfix 和 dovcot 來執行郵件操作。

相關內容