我正在运行 Centos 6.4 服务器,其中安装了 Directadmin 和 Exim。我们正在使用传出过滤和 Spamexperts.com。不知何故,当我使用 PHP 发送电子邮件时,信封发件人被重写为默认的 Directadmin 用户。我找不到原因。
PHP 脚本:
<?php
$to = '[email protected]';
$subject = 'the subject';
$message = 'hello';
$headers = 'From: [email protected]' . "\r\n" .
'Reply-To: [email protected]' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
//mail($to, $subject, $message, $headers, "[email protected]");
mail($to, $subject, $message, $headers);
?>
执行上述 PHP 代码时,Exim 将记录以下内容:
2014-03-19 10:32:29 1WQCrN-000511-4Z <= [email protected] U=userX P=local S=446 T="the subject" from <[email protected]> for [email protected]
2014-03-19 10:32:29 1WQCrN-000511-4Z ** [email protected] F=<[email protected]> R=spamexperts_smarthost_router T=spamexperts_smarthost_transport: SMTP error from remote mail server after MAIL FROM:<[email protected]> SIZE=1483: host smtp.antispamcloud.com [46.165.209.5]: 550-Verification failed for <[email protected]>\n550-Previous (cached) callout verification failure\n550 Invalid sender <[email protected]>
2014-03-19 10:32:29 1WQCrN-000516-I1 <= <> R=1WQCrN-000511-4Z U=mail P=local S=1544 T="Mail delivery failed: returning message to sender" from <> for [email protected]
2014-03-19 10:32:29 1WQCrN-000511-4Z Completed
2014-03-19 10:32:32 1WQCrN-000516-I1 => [email protected] F=<> R=spamexperts_smarthost_router T=spamexperts_smarthost_transport S=1586 H=smtp.antispamcloud.com [46.165.209.5] X=TLSv1:DHE-RSA-AES256-SHA:256 C="250 OK id=1WQCrW-00033I-Lu"
2014-03-19 10:32:32 1WQCrN-000516-I1 Completed
关键部分是粗体部分:
2014-03-19 10:32:29 1WQCrN-000511-4Z <=[电子邮件保护]U=用户X P=本地 S=446 T="主题"来自 <[电子邮件保护]>为了[电子邮件保护]
当我将 PHP 脚本更改为:
<?php
$to = '[email protected]';
$subject = 'the subject';
$message = 'hello';
$headers = 'From: [email protected]' . "\r\n" .
'Reply-To: [email protected]' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $message, $headers, "[email protected]");
//mail($to, $subject, $message, $headers);
?>
Exim 日志显示以下内容:
2014-03-19 10:48:09 1WQD6X-000569-IR <= [email protected] U=userX P=local S=442 T="the subject" from <[email protected]> for [email protected]
2014-03-19 10:48:13 1WQD6X-000569-IR => [email protected] F=<[email protected]> R=spamexperts_smarthost_router T=spamexperts_smarthost_transport S=459 H=smtp.antispamcloud.com [198.7.58.154] X=TLSv1:DHE-RSA-AES256-SHA:256 C="250 OK id=1WQD6P-0002nu-00"
2014-03-19 10:48:13 1WQD6X-000569-IR Completed
看到关键部分没有被重写:
2014-03-19 10:48:09 1WQD6X-000569-IR <=[电子邮件保护]U=用户X P=本地 S=442 T="主题"来自 <[电子邮件保护]>为了[电子邮件保护]
附加信息:
剥离 exim.conf
[...]
syslog_duplication = false
local_from_check = false
local_sender_retain = false
untrusted_set_sender = *
[...]
# TRUSTED USERS
# OPTIONAL MODIFICATIONS:
# if you must add additional trusted users, do so here; continue the
# colon-delimited list
#trusted_users = mail:majordomo:apache:diradmin:${readfile{/etc/exim.users}}
trusted_users = mail:majordomo:apache:diradmin:userX:
trusted_groups = apache:userX
######################################################################
# REWRITE CONFIGURATION #
######################################################################
begin rewrite
#* [email protected] F
# There are no rewriting specifications in this default configuration file.
######################################################################
# ROUTERS CONFIGURATION #
# Specifies how remote addresses are handled #
######################################################################
# ORDER DOES MATTER #
# A remote address is passed to each in turn until it is accepted. #
######################################################################
# Spamexperts
begin routers
spamexperts_smarthost_router:
driver = manualroute
domains = ! +local_domains
ignore_target_hosts = 127.0.0.0/8
condition = "${perl{check_limits}}"
transport = spamexperts_smarthost_transport
route_list = $domain smtp.antispamcloud.com::587
no_more
# Remote addresses are those with a domain that does not match any item
# in the "local_domains" setting above.
# This router routes to remote hosts over SMTP using a DNS lookup. Any domain
# that resolves to an IP address on the loopback interface (127.0.0.0/8) is
# treated as if it had no DNS entry.
#lookuphost:
# driver = dnslookup
# domains = ! +local_domains
# ignore_target_hosts = 127.0.0.0/8
# condition = "${perl{check_limits}}"
# transport = remote_smtp
# no_more
[...]
# Spamexperts
begin transports
spamexperts_smarthost_transport:
driver = smtp
hosts_require_tls = smtp.antispamcloud.com
# Spam Assassin
spamcheck:
driver = pipe
batch_max = 100
command = /usr/sbin/exim -oMr spam-scanned -bS
current_directory = "/tmp"
group = mail
home_directory = "/tmp"
log_output
message_prefix =
message_suffix =
return_fail_output
no_return_path_add
transport_filter = /usr/bin/spamc -u ${lookup{$domain}lsearch*{/etc/virtual/domainowners}{$value}}
use_bsmtp
user = mail
# must use a privileged user to set $received_protocol on the way back in!
[...]
*补充说明:
- local_from_check = false、local_sender_retain = false 和 untrusted_set_sender = * 没有效果。
- userX 是 Directadmin 用户/经销商
- 当我启用 exim 重写部分时,邮件将被投递,但当然每封邮件都会有一个返回路径 <[电子邮件保护]> 这是不可取的。*
答案1
简短的回答:在我看来最好不要使用 mail(),而是向您的应用程序添加一个好的 php 邮件类,比如 PHPMailer。
详细解答:
发送电子邮件时必须管理两个主要部分:
- 邮件头/正文。
- 邮件服务器之间的 smtp 对话确定发件人和收件人,通常称为信封设置。
您的代码正在设置标头,这些标头仅针对项目 #1 中的内容。您的代码的问题在于,作为项目 #2 一部分的“信封发件人”未明确设置,因此 Exim 使用默认值,即 $USER@$HOSTNAME。Google 搜索“SMTP 对话示例“了解原因和什么时候这些事情很重要。
一般情况下使用 php邮件()命令,很难也不明显如何将信封设置设置为您想要的值。相反,使用具有更多可配置性的东西,可以建立实际的 SMTP 连接(而不是直接调用 /usr/sbin/sendmail)。是的,当 SMTP 服务器位于本地主机时,情况会更好,同样的原则也适用。当您可以为实际的 SMTP 连接指定信封中的所有内容时,例如PHPMailer 类,你所面对的所有这些问题都将消失。
还值得注意的是,下面的答案显示了如何使用 ini_set() 来解决邮件()命令,但我还是更喜欢使用PHPMailer。