如何测试 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 来做到这一点,但这看起来很复杂

这很简单,你可以谷歌一下SMTP 命令,您可以毫无问题地使用它们。正如您自己回答的问题一样,您可以使用 SWAKS。以下是一些替代选项。


这些是一些 SMTP 命令:

每个命令都用于通过 SMTP 协议在两个服务器之间进行正常通信,以传递电子邮件。

直升机
这是第一个 SMTP 命令:它启动识别发送方服务器的对话,并且通常后面跟着其域名。

埃希氏藻毒素
启动对话的替代命令,底层服务器正在使用扩展 SMTP 协议。

邮件来自
通过此 SMTP 命令,操作开始:发件人在“发件人”字段中注明源电子邮件地址,并实际开始电子邮件传输。

回执单
它标识电子邮件的收件人;如果有多个收件人,则只需逐个地址重复该命令。

尺寸
此 SMTP 命令会通知远程服务器附件电子邮件的估计大小(以字节为单位)。它还可用于报告服务器可接受的邮件的最大大小。

数据
通过 DATA 命令,电子邮件内容开始传输;通常随后服务器会给出 354 回复代码,以允许开始实际传输。

虚拟仿真系统
要求服务器验证特定的电子邮件地址或用户名是否确实存在。

转动
此命令用于在客户端和服务器之间转换角色,而无需运行新的连接。

验证
使用 AUTH 命令,客户端向服务器验证自己的身份,提供其用户名和密码。这是另一层安全措施,可确保传输正确。

复位
它向服务器传达正在进行的电子邮件传输即将终止,尽管 SMTP 对话不会关闭(如同 QUIT 的情况)。

扩展网
此 SMTP 命令要求确认邮件列表的身份。

帮助
这是客户对一些信息的请求,这些信息对于成功传输电子邮件很有用。

辞职
它终止 SMTP 对话。


OpenSSL、testssl.sh 和 GnuTLS

您可以使用openssl s_client,通过运行以下命令:

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

您还可以使用名为测试sl.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

phpmailer 插件

如果你使用 PHP,你可以使用phpmailer 插件

<?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 监听守护进程的互联网机器发送邮件。

以下是创建一个 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"

将附件作为电子邮件发送 要发送包含混合内容的电子邮件,需要将 Content-type 标头设置为 multipart/mixed。然后,可以在边界内指定文本和附件部分。

边界以两个连字符开头,后跟一个唯一数字,该数字不能出现在电子邮件的正文部分。表示电子邮件最后部分的最终边界也必须以两个连字符结尾。

附加文件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
  • Arch 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 来执行邮件操作。

相关内容