无法连接到 SMTP 主机

无法连接到 SMTP 主机
  1. 我有一台 VPS 服务器
  2. 我在该 VPS 服务器上运行着一个 Postfix 邮件服务器(我按照教程通过命令行安装了它)
  3. 我在该 VPS 服务器上运行着一个 SMTP 服务器
  4. 我也有邮件服务器所需的记录,例如(MX 记录、SPF 记录、PTR 记录、DMARC 记录、A 记录),我通过 mxtoolbox 检查器检查了它们,结果全部正确

但不幸的是,无论我使用什么方式,我仍然无法发送或接收邮件:

  1. usermin(端口:20000)
  2. 甚至从我的网站使用 PHPMailer 库

我的 Postfix 配置文件是:

# See /usr/share/postfix/main.cf.dist for a commented, more complete version


# Debian specific:  Specifying a file name will cause the first
# line of that file to be used as the name.  The Debian default
# is /etc/mailname.
#myorigin = /etc/mailname

smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no

# appending .domain is the MUA's job.
append_dot_mydomain = no

# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h

readme_directory = no

# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 2 on
# fresh installs.
compatibility_level = 2

# TLS parameters
smtpd_tls_cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file = /etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
myhostname = mainserver.mskillsa.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = $myhostname, mskillsa.com, mainserver.mskillsa.com, localhost.mskillsa.com, localhost
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_command = procmail -a "$EXTENSION"
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all
smtp_sasl_auth_enable = yes

我的域名是:mskillsa.com

我的主机名是:mainserver.mskillsa.com

我的电子邮件地址是 :[电子邮件保护]

一些记录检查器告诉我,我没有 DKIM 记录,我尝试使用第三方 DKIM 记录生成器,并且我使用它,但仍然有同样的 DKIM 记录问题 !!!

我的PHPMailer代码:

<?php

// Include required phpmailer files

require "includes/PHPMailer.php";
require "includes/SMTP.php";
require "includes/Exception.php";
// Define name spaces

use PHPMailer\PHPMailer\PHPMailer;

use PHPMailer\PHPMailer\SMTP;

use PHPMailer\PHPMailer\Exception;

// Create instance of phpmailer

$mail = new PHPMailer();

// Set mailer to use SMTP

$mail->isSMTP();

// Define SMTP host

$mail->Host = "mail.mskillsa.com";

// enable SMTP authentication

$mail->SMTPAuth = "true";

// Set type of encryption (ssl/tls)

$mail->SMTPSecure = "ssl";

// Set port to connect SMTP

$mail->Port = "465";

// Set username

$mail->Username = "[email protected]";

// Set password

$mail->Password = "password";

// Set email Subject

$mail->Subject = "Hello Info Testing";

// Set sender email

$mail->setFrom("[email protected]");

// Email Body

$mail->Body = "Hello testing...";

// Add recipient

$mail->addAddress('[email protected]');

// Finally Send Email

if ($mail->send()) {
    echo "Sent";
} else {
    echo "Not Sent";
}

// Closing SMTP Connection

$mail->smtpClose();

我收到以下错误:

2022-08-08 15:42:54 CLIENT -> SERVER: EHLO mskillsa.com
2022-08-08 15:42:54 CLIENT -> SERVER: STARTTLS
SMTP Error: Could not connect to SMTP host. Connection failed. stream_socket_enable_crypto(): Peer certificate CN=`localhost.localdomain' did not match expected CN=`mainserver.mskillsa.com'
2022-08-08 15:42:54 CLIENT -> SERVER: QUIT
2022-08-08 15:42:54
SMTP connect() failed. https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting
Not Sent

我的master.cf文件:

#
# Postfix master process configuration file.  For details on the format
# of the file, see the master(5) manual page (command: "man 5 master" or
# on-line: http://www.postfix.org/master.5.html).
#
# Do not forget to execute "postfix reload" after editing this file.
#
# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (no)    (never) (100)
# ==========================================================================
smtp      inet  n       -       y       -       -       smtpd
#smtp      inet  n       -       y       -       1       postscreen
#smtpd     pass  -       -       y       -       -       smtpd
#dnsblog   unix  -       -       y       -       0       dnsblog
#tlsproxy  unix  -       -       y       -       0       tlsproxy
#submission inet n       -       y       -       -       smtpd
#  -o syslog_name=postfix/submission
#  -o smtpd_tls_security_level=encrypt
#  -o smtpd_sasl_auth_enable=yes
#  -o smtpd_tls_auth_only=yes
#  -o smtpd_reject_unlisted_recipient=no
#  -o smtpd_client_restrictions=$mua_client_restrictions
#  -o smtpd_helo_restrictions=$mua_helo_restrictions
#  -o smtpd_sender_restrictions=$mua_sender_restrictions
#  -o smtpd_recipient_restrictions=
#  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
#  -o milter_macro_daemon_name=ORIGINATING
#smtps     inet  n       -       y       -       -       smtpd
#  -o syslog_name=postfix/smtps
#  -o smtpd_tls_wrappermode=yes
#  -o smtpd_sasl_auth_enable=yes
#  -o smtpd_reject_unlisted_recipient=no
#  -o smtpd_client_restrictions=$mua_client_restrictions
#  -o smtpd_helo_restrictions=$mua_helo_restrictions
#  -o smtpd_sender_restrictions=$mua_sender_restrictions
#  -o smtpd_recipient_restrictions=
#  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
#  -o milter_macro_daemon_name=ORIGINATING
#628       inet  n       -       y       -       -       qmqpd
pickup    unix  n       -       y       60      1       pickup
cleanup   unix  n       -       y       -       0       cleanup
qmgr      unix  n       -       n       300     1       qmgr
#qmgr     unix  n       -       n       300     1       oqmgr
tlsmgr    unix  -       -       y       1000?   1       tlsmgr
rewrite   unix  -       -       y       -       -       trivial-rewrite
bounce    unix  -       -       y       -       0       bounce
defer     unix  -       -       y       -       0       bounce
trace     unix  -       -       y       -       0       bounce
verify    unix  -       -       y       -       1       verify
flush     unix  n       -       y       1000?   0       flush
proxymap  unix  -       -       n       -       -       proxymap
proxywrite unix -       -       n       -       1       proxymap
smtp      unix  -       -       y       -       -       smtp
relay     unix  -       -       y       -       -       smtp
        -o syslog_name=postfix/$service_name
#       -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
showq     unix  n       -       y       -       -       showq
error     unix  -       -       y       -       -       error
retry     unix  -       -       y       -       -       error
discard   unix  -       -       y       -       -       discard
local     unix  -       n       n       -       -       local
virtual   unix  -       n       n       -       -       virtual
lmtp      unix  -       -       y       -       -       lmtp
anvil     unix  -       -       y       -       1       anvil
scache    unix  -       -       y       -       1       scache
#
# ====================================================================
# Interfaces to non-Postfix software. Be sure to examine the manual
# pages of the non-Postfix software to find out what options it wants.
#
# Many of the following services use the Postfix pipe(8) delivery
# agent.  See the pipe(8) man page for information about ${recipient}
# and other message envelope options.
# ====================================================================
#
# maildrop. See the Postfix MAILDROP_README file for details.
# Also specify in main.cf: maildrop_destination_recipient_limit=1
#
maildrop  unix  -       n       n       -       -       pipe
  flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient}
#
# ====================================================================
#
# Recent Cyrus versions can use the existing "lmtp" master.cf entry.
#
# Specify in cyrus.conf:
#   lmtp    cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4
#
# Specify in main.cf one or more of the following:
#  mailbox_transport = lmtp:inet:localhost
#  virtual_transport = lmtp:inet:localhost
#
# ====================================================================
#
# Cyrus 2.1.5 (Amos Gouaux)
# Also specify in main.cf: cyrus_destination_recipient_limit=1
#
#cyrus     unix  -       n       n       -       -       pipe
#  user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user}
#
# ====================================================================
# Old example of delivery via Cyrus.
#
#old-cyrus unix  -       n       n       -       -       pipe
#  flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user}
#
# ====================================================================
#
# See the Postfix UUCP_README file for configuration details.
#
uucp      unix  -       n       n       -       -       pipe
  flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
#
# Other external delivery methods.
#
ifmail    unix  -       n       n       -       -       pipe
  flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
bsmtp     unix  -       n       n       -       -       pipe
  flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient
scalemail-backend unix  -   n   n   -   2   pipe
  flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension}
mailman   unix  -       n       n       -       -       pipe
  flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py
  ${nexthop} ${user}

我在 https://www.mail-tester.com/ 测试了我的电子邮件分数,您可以查看我的分数

答案1

使用 PHPmailer 时事情变得过于复杂。

由于你的 SMTP 服务器位于本地主机,因此你可以做的最简单的事情是不使用 $mail->isSMTP()并且不设置$mail->Host$mail->SMTPAuth$mail->SMTPSecure$mail->Port$mail->Username的任何值。同样$mail->Password省略。因此你只剩下$mail->smtpClose()

$mail = new PHPMailer();
$mail->Subject = "Hello Info Testing";
$mail->setFrom("[email protected]");
$mail->Body = "Hello testing...";
$mail->addAddress('[email protected]');

if ($mail->send()) {
    echo "Sent";
} else {
    echo "Not Sent";
}

就像第一个例子一样本教程(“如何使用 PHPmailer 发送您的第一封电子邮件”)。

通过这种方法,PHPmailer 将使用与 PHP 内部函数完全相同的邮件发送方法mail(),即使用 将邮件直接提交到本地邮件服务器sendmail。在我看来,这是在运行本地 SMTP 服务器的机器上发送邮件的最合适方法。如果此方法以前对您有效(mail从命令行和 PHPmail()函数),那么它在这里也应该有效。

但是,如果您坚持使用 SMTP,那么有几种方法可以实现,但每种方法都需要对您的参数进行一些更正。

首先,您尝试使用安全连接到本地服务器 ( $mail->SMTPSecure = "ssl")。如果您连接到本地主机,这绝对不会带来任何安全优势,这是导致问题的主要原因,因为您发布的错误对话框显示 PHPmailer 证书验证失败。因此,首先尝试完全摆脱加密。替换

$mail->Host = "mail.mskillsa.com";

经过

$mail->Host = "localhost";

或者

$mail->Host = "127.0.0.1";

并删除该行$mail->SMTPSecure = "ssl"。您可能还需要添加以下内容:

$mail->SMTPAutoTLS = false;

如果 PHPmailer 发现服务器支持加密,则阻止它自动使用加密。

由于您的 Postfix 服务器信任 localhost(这绝对正确)- localhost 地址包含在 中mynetworks=。因此,您只需连接到标准 SMTP 端口 25。您还应该摆脱身份验证,因为您当前的 Postfix 配置确实不是支持身份验证,至少在端口 25 上支持(您没有发布您的master.cf,其中可能定义了端口 465 上的提交服务的配置,因此我不确定那里是否支持身份验证,但从您发布的对话框(编辑之前的上一个版本)中,我看到服务器没有宣传 AUTH)。因此,删除$mail->SMTPAuth$mail->Username$mail->Password行,然后设置

$mail->Port = 25;

因此下一个可行的选择应该是:

$mail = new PHPMailer();
$mail->isSMTP();
$mail->Host = "localhost";
$mail->SMTPAutoTLS = false;
$mail->Port = 25;
$mail->Subject = "Hello Info Testing";
$mail->setFrom("[email protected]");
$mail->Body = "Hello testing...";
$mail->addAddress('[email protected]');

if ($mail->send()) {
    echo "Sent";
} else {
    echo "Not Sent";
}

$mail->smtpClose();

最后,如果您真的想使用加密认证提交(尽管我想再次强调,连接到本地 SMTP 服务器时它没有意义),您还需要修复一些 Postfix 配置。

正如我所说,您的 Postfix 配置未启用身份验证。您可能希望使用以下行启用它smtp_sasl_auth_enable = yes,但这会为 Postfix 启用身份验证作为客户端连接到另一台服务器并向其发送邮件,而不是 Postfix 中的 SMTP 服务器。您通常不希望出现这种情况。如果没有附带参数smtp_sasl_password_maps(定义 Postfix 应该用来向远程服务器进行身份验证的凭据),此参数根本不起作用。因此,请从 中删除此行main.cf

Postfix 中开启身份验证的参数服务器smtpd_sasl_auth_enable = yes(请注意名称中的“d”),但是你不应该把它放在你的main.cf因为在配置邮件服务器时启用端口 25 上的身份验证并不是一个好习惯。相反,您应该仅在提交服务的端口 465 上启用身份验证,该端口在 中定义master.cf。您还没有发布您的master.cf,所以我无法告诉您如何更正它。

假设您已经修复了您的master.cf,您的 PHPmailer 参数中仍有一些问题需要修复。PHPmailer 证书验证失败,因为您有一个自签名在您的服务器和 PHPmailer 上进行证书验证默认情况下需要证书颁发机构的“官方”证书并尝试验证它。因此,除了 PHPmailer 代码中已有的内容外,您还需要添加以下内容:

/* Disable some SSL checks. */
$mail->SMTPOptions = array(
   'ssl' => array(
   'verify_peer' => false,
   'verify_peer_name' => false,
   'allow_self_signed' => true
   )
);

我从教程我已经链接了,请参阅“如何使用自定义 SMTP 服务器”下的第二个示例。这是第三个变体,应该适合您。

更新:现在您发布了master.cf内容,我发现您根本没有启用提交服务。因此,我想知道最初连接到端口 465(如您的 PHPmailer 代码中指定)对您来说是如何工作的。您是否在端口 465 上运行了其他软件?因为根据您的说明master.cf,Postfix 仅监听端口 25。

无论如何,为了使经过身份验证的提交工作,您需要取消注释以下行master.cf并重新启动 Postfix:

#smtps     inet  n       -       y       -       -       smtpd
#  -o syslog_name=postfix/smtps
#  -o smtpd_tls_wrappermode=yes
#  -o smtpd_sasl_auth_enable=yes
#  -o smtpd_reject_unlisted_recipient=no
#  -o smtpd_client_restrictions=$mua_client_restrictions
#  -o smtpd_helo_restrictions=$mua_helo_restrictions
#  -o smtpd_sender_restrictions=$mua_sender_restrictions
#  -o smtpd_recipient_restrictions=
#  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
#  -o milter_macro_daemon_name=ORIGINATING

但是,您还需要定义一些验证器来检查用户凭证。这是 Postfix 外部的一些程序,例如 Dovecot。您需要在两个地方配置身份验证。首先,您需要将以下内容添加到您的 Postfixmain.cf文件中:

smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth

然后,您需要在 Dovecot 中为 Postfix 配置身份验证服务。有一个Dovecot 网站上的教程怎么做。

相关内容