我有一个 GCP 实例,其中运行 whm/cpanel 并使用 exim 设置 mailgun 来使用多个域的多个帐户。
当前设置适用于所有域,但仅对主域进行验证。Mailgun 支持具有多个凭据的多个域。
当从“c*********t.com”以外的域名发送电子邮件时,电子邮件中会出现 Gmail 中的 VIA,因为它们header.from
不匹配。
dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=c*****s.com
部分:AUTH
mailgun_login:
driver = plaintext
public_name = LOGIN
hide client_send = : postmaster@c*********t.com :
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
部分:ROUTERSTART
mailgun:
driver = manualroute
domains = ! +local_domains
transport = mailgun_transport
route_list = "* smtp.mailgun.org::2525 byname"
host_find_failed = defer
no_more
部分:TRANSPORTSTART
mailgun_transport:
driver = smtp
hosts = smtp.mailgun.org
hosts_require_auth = smtp.mailgun.org
hosts_require_tls = smtp.mailgun.org
如有任何建议或替代方案,我们将不胜感激。谢谢。
更新 根据以下提供的答案,日志中的当前错误:
LOG: MAIN
cwd=/usr/local/cpanel/whostmgr/docroot 4 args: /usr/sbin/exim -v -M
1gPYIq-0001cc-UL
delivering 1gPYIq-0001cc-UL
Transport port=25 replaced by host-specific port=2525
Connecting to smtp.mailgun.org [**.**.**.***]:2525 ... connected
SMTP<< 220 ak47 ESMTP ready
SMTP>> EHLO instance-1
SMTP<< 250-ak47
250-AUTH PLAIN LOGIN
250-SIZE 52428800
250-8BITMIME
250-ENHANCEDSTATUSCODES
250-SMTPUTF8
250 STARTTLS
SMTP>> STARTTLS
SMTP<< 220 2.0.0 Start TLS
SMTP>> EHLO instance-1
SMTP<< 250-ak47
250-AUTH PLAIN LOGIN
250-SIZE 52428800
250-8BITMIME
250-ENHANCEDSTATUSCODES
250 SMTPUTF8
SMTP>> AUTH LOGIN
SMTP<< 334 VXNlcm5hbWU6
SMTP>> *
SMTP<< 500 5.5.1 Invalid command
SMTP>> QUIT
SMTP(close)>>
Transport port=25 replaced by host-specific port=2525
Connecting to smtp.mailgun.org [**.**.**.***]:2525 ... connected
SMTP<< 220 ak47 ESMTP ready
SMTP>> EHLO instance-1
SMTP<< 250-ak47
250-AUTH PLAIN LOGIN
250-SIZE 52428800
250-8BITMIME
250-ENHANCEDSTATUSCODES
250-SMTPUTF8
250 STARTTLS
SMTP>> STARTTLS
SMTP<< 220 2.0.0 Start TLS
SMTP>> EHLO instance-1
SMTP<< 250-ak47
250-AUTH PLAIN LOGIN
250-SIZE 52428800
250-8BITMIME
250-ENHANCEDSTATUSCODES
250 SMTPUTF8
SMTP>> AUTH LOGIN
SMTP<< 334 VXNlcm5hbWU6
SMTP>> *
SMTP<< 500 5.5.1 Invalid command
SMTP>> QUIT
SMTP(close)>>
Transport port=25 replaced by host-specific port=2525
Connecting to smtp.mailgun.org [**.**.**.***]:2525 ... connected
SMTP<< 220 ak47 ESMTP ready
SMTP>> EHLO instance-1
SMTP<< 250-ak47
250-AUTH PLAIN LOGIN
250-SIZE 52428800
250-8BITMIME
250-ENHANCEDSTATUSCODES
250-SMTPUTF8
250 STARTTLS
SMTP>> STARTTLS
SMTP<< 220 2.0.0 Start TLS
SMTP>> EHLO instance-1
SMTP<< 250-ak47
250-AUTH PLAIN LOGIN
250-SIZE 52428800
250-8BITMIME
250-ENHANCEDSTATUSCODES
250 SMTPUTF8
SMTP>> AUTH LOGIN
SMTP<< 334 VXNlcm5hbWU6
SMTP>> *
SMTP<< 500 5.5.1 Invalid command
SMTP>> QUIT
SMTP(close)>>
LOG: MAIN
== *********@gmail.com R=mailgun T=mailgun_transport defer (-42): authentication required but authentication attempt(s) failed
答案1
通过 Caracos 的答案(我试过但无法正常工作),我能够找到这个论坛帖子,在修改 Mailgun 的详细信息后,它运行得很好。我也喜欢这个解决方案,因为它可以根据需要扩展到其他邮件中继服务。
https://forums.cpanel.net/threads/how-to-send-email-from-different-domains-using-different-smarthosts.641949/
我仅概述我用于 Mailgun 的设置,但请参阅链接以获得更详细的解释、图片和其他示例,如 Sendgrid、Mailjet 和 Sendpulse。
- 在 WHM 中,转到“Exim 配置管理器”(主页 > 服务配置 > Exim 配置管理器)。之后,单击“高级编辑器”选项卡。
(也许备份设置在进行这些更改之前)
部分:AUTH
#Smart Host Sending
sendbysmarthosts:
driver = plaintext
public_name = LOGIN
hide client_send = : ${extract{user}
{${lookup{$sender_address_domain}lsearch{/etc/exim_smarthosts}}}}: ${extract{pass}{${lookup{$sender_address_domain}lsearch{/etc/exim_smarthosts}}}}
部分:预路由器
#Smart Host Sending
sendbysmarthostsrouter:
driver = manualroute
domains = ! +local_domains
condition = "${if eq{${lookup{$sender_address_domain}partial-
lsearch{/etc/exim_smarthosts}{$value}}}{}{false}{true}}"
ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
headers_add = "${perl{mailtrapheaders}}"
transport = sendbysmarthoststransport
route_list = * ${extract{smtp} {${lookup{$sender_address_domain}lsearch{/etc/exim_smarthosts}}}}
部分:TRANSPORTSTART
#Smart Host Sending
sendbysmarthoststransport:
driver = smtp
port = ${extract{port}
{${lookup{$sender_address_domain}lsearch{/etc/exim_smarthosts}}}}
hosts_require_auth = $host_address
hosts_require_tls = $host_address
滚动到页面底部并保存 Exim 配置,并确保 Exim 重新启动。
- 使用 Mailgun 或其他智能主机参数在“/etc”目录中创建名为“exim_smarthosts”的文件。
这是一些示例数据,更改域、用户和密码。
#Sending by Mailgun
domain1.com: domain=domain1.com [email protected] pass=MAILGUN_password smtp=smtp.mailgun.org port=587
domain2.com: domain=domain2.com [email protected] pass=MAILGUN_password smtp=smtp.mailgun.org port=587
domain3.com: domain=domain3.com [email protected] pass=MAILGUN_password smtp=smtp.mailgun.org port=587
第三个示例使用 domain2.com 的凭证作为 domain3.com 的凭证,这将起作用,但电子邮件将包含通过 mg.domain2.com
现在,从 cPanel 在各自域上创建的电子邮件帐户发送的电子邮件将被进出口银行拦截(允许连接到外部 SMTP 服务器)并通过 Mailgun 中继,前提是 /etc/exim_smarthosts 中的凭据正确且 DNS 设置正确。但是,WHM 安全设置仍然限制所有 cPanel 帐户连接到任何外部 SMTP 服务,因此我们需要再执行一步才能利用上述设置进行基于应用程序的电子邮件发送。
仅供参考:这是应该的设置继续限制外部 SMTP 连接
WHM Admin >> 调整设置 >> 邮件 >> 将传出 SMTP 限制为 root、exim 和 mailman
要从 Joomla、Wordpress 或其他 CMS 或应用程序发送电子邮件,请按照以下步骤操作
a) 在 cPanel 中创建电子邮件帐户并获取安全登录凭据。cPanel
>> 电子邮件帐户 >> (新电子邮件)>> 连接设备 >> 设置电子邮件客户端b) 在您的 Joomla、WordPress 或其他 CMS/应用程序/插件中使用此用户名、密码和传出服务器详细信息
现在,您的 CMS、插件和应用程序仅连接到内部 SMTP 帐户,但当该帐户发送时,它会通过第一步中的外部 SMTP 设置进行中继。
非常感谢 DigitalComunic在 cPanel 论坛上,他们的辛勤工作和故障排除为我们提供了一个强大的解决方法,在未来几年内应该会很有用!!
答案2
我有相同的设置(VPS + WHM/cPanel + Exim + Mailgun),在进行了一些在线研究后,我找到了一些有关此主题的有用网站,并设法找到了正确的配置。以下是我目前在 VPS 上使用的解决方案,希望它也能对您有所帮助。它应该可以解决您的“via”问题,也可能解决 Mailgun 间歇性的“550 5.7.1 中继被拒绝”错误:
转到 WHM 中的“Exim 配置编辑器”。选择“高级编辑器”并插入以下配置:
部分:AUTH
mailgun_login:
driver = plaintext
public_name = LOGIN
hide client_send = ": ${extract{login}{${lookup{$sender_address_domain}lsearch{/etc/exim_mailgun}{$value}fail}}} : ${extract{password}{${lookup{$sender_address_domain}lsearch{/etc/exim_mailgun}{$value}fail}}}"
部分:ROUTERSTART
mailgun:
driver = manualroute
domains = ! +local_domains
transport = mailgun_transport
route_list = "* smtp.mailgun.org::587 byname"
host_find_failed = defer
no_more
部分:TRANSPORTSTART
mailgun_transport:
driver = smtp
hosts = smtp.mailgun.org
hosts_require_auth = smtp.mailgun.org
hosts_require_tls = smtp.mailgun.org
然后创建一个名为 /etc/exim_mailgun 的文件并插入类似于以下结构的内容(将其替换为已验证的 Mailgun 域登录凭据):
domain1.com: [email protected] password=abcdefghi
domain2.com: [email protected] password=jklmnopqr
更新:
正如@Supamic 所评论的,我有时会遇到他提到的电子邮件通过邮件传递系统发送电子邮件时出现的错误([电子邮件保护])到我的外部电子邮件帐户(Gmail):
authentication required but authentication attempt(s) failed
我的猜测可能是由于 Mailer-Daemon 的“发件人识别”部分,因为 Exim 无法从我的 /etc/exim_mailgun 获取登录凭据,因为没有发件人的域:
“Sender identification U=mailnull D=-system- S=mailnull”
为了解决这个问题,cPanel 技术支持建议我将 Mailer-Daemon 的所有电子邮件转发到我服务器上托管的本地电子邮件地址,然后使用转发器功能将电子邮件传递到我的 Gmail 帐户。
至于间歇性的“550 5.7.1 中继被拒绝”错误,在联系 cPanel 技术支持后,他们给我的建议是通过在 /etc/hosts 中设置静态 IP 将 smtp.mailgun.org 强制为单个 IP,而不是允许 Exim 将 smtp.mailgun.org 解析为多个 IP。
当 Exim 将 smtp.mailgun.org 解析为多个 IP 时,将开始发生身份验证错误。cPanel 技术支持无法指出此“550 5.7.1 中继被拒绝”错误的确切原因。也许 Mailgun 在其冗余 SMTP 基础设施中维护身份验证时出现了问题。
您可以使用以下任一命令来解析 Mailgun 的 SMTP 服务器 IP:
nslookup smtp.mailgun.org
dig +short smtp.mailgun.org @resolver1.opendns.com
使用结果中的一个 IP 并将其放入 /etc/hosts 文件中:
xxx.xxx.xxx.xxx smtp.mailgun.org
我想重复@Supamic 的话十分感谢棒极了cPanel 技术支持团队他们在解决问题上的奉献精神值得称赞。
答案3
有用!
我以此为灵感来配置。(虽然我没有使用 cpanel,但基本上是一样的)我需要通过提供商的服务器而不是我自己的服务器来发送来自某些域的邮件,因为 SPF 检查之类的功能会失败,因为我的服务器不会被列为允许发送。上面的配置示例给我带来了一些问题,尤其是在使用 IPv6 地址时。
以下是我想出的办法,只是为了对上面的内容进行一些改进:
宏(文件顶部 /main/debian 00_macros):
# Smarthost auth - comment out to disable:
SMARTHOST_AUTH = /etc/exim4/exim_smarthosts
路由器
ROUTER_DNSLOOKUP_IGNORE_TARGET_HOSTS
似乎是基于 Debian exim conf 的默认设置,因此在我的配置中其他地方使用,因此不妨保持一致并将其用于此路由器。这在我的配置中就在路由器之前,但它也可以放在顶部,在主/宏 conf 中。
# ignore private rfc1918, loopback, APIPA/link-local, local broadcast, unspecified, unique local, linked-scoped unicast and discard-Only:
.ifndef ROUTER_DNSLOOKUP_IGNORE_TARGET_HOSTS
ROUTER_DNSLOOKUP_IGNORE_TARGET_HOSTS = <; 0.0.0.0 ; 127.0.0.0/8 ; 192.168.0.0/16 ; 172.16.0.0/12 ; 10.0.0.0/8 ; 169.254.0.0/16 ; 255.255.255.255 ; ::/128 ; ::1/128 ; fc00::/7 ; fe80::/10 ; 100::/64
.endif
现在路由器本身
更好地利用 exim 的 manualroute 功能。允许指定具有不同端口等的多个服务器。使用 address_data 一次性获取文件中的所有数据,而不是多次查找文件:
.ifdef SMARTHOST_AUTH
# Route some senders to use different outgoing smarthost instead
# of direct sending. Lookup from SMARTHOST_AUTH file:
r_sendbysmarthost:
debug_print = "R: $router_name for $local_part@$domain"
driver = manualroute
domains = ! +local_domains
condition = ${lookup{$sender_address_domain}partial-lsearch{SMARTHOST_AUTH}{true}{false}}
address_data = ${lookup{$sender_address_domain}partial-lsearch{SMARTHOST_AUTH}}
ignore_target_hosts = ROUTER_DNSLOOKUP_IGNORE_TARGET_HOSTS
transport = t_sendbysmarthost
route_data = <,${extract{smtp}{$address_data}}
host_find_failed = ignore
host_all_ignored = defer
hosts_randomize = true
# remove previous Received headers for privacy if needed:
headers_remove = Received
# cPanel requirement:
# headers_add = "${perl{mailtrapheaders}}"
more = no
.endif
运输
我已将其简化,因此它仅设置 smtp 端口和身份验证要求。端口默认为 587,但如果需要,exim 路由器允许在文件中按服务器覆盖它。
hosts_require_auth
和hosts_require_tls
是主机列表,在使用和冒号时,IPv6 地址存在问题$host_address
。(IPv6 地址包含冒号,这会破坏冒号分隔的主机列表。我们可以修复这个问题,但由于路由器已经决定使用此传输,我们只需在此处指定“*”。)
t_sendbysmarthost:
debug_print = "T: $transport_name for $local_part@$domain"
driver = smtp
port = 587
connect_timeout = 30s
hosts_require_auth = *
hosts_require_tls = *
授权
如果配置了多个 LOGIN 身份验证,则添加条件以防止 exim 使用错误的身份验证器。使用$address_data
(由路由器设置)而不是更多文件查找。
.ifdef SMARTHOST_AUTH
auth_smarthost:
driver = plaintext
public_name = LOGIN
client_condition = "${extract{smtp}{$address_data}{true}{false}}"
hide client_send = ": ${extract{user}{$address_data}}:${extract{pass}{$address_data}}"
.endif
查找文件
文件定义SMARTHOST_AUTH
(例如/etc/exim4/exim_smarthosts
)
例子:
# Simple - Select a single server:
domain1.com: [email protected] pass=PASSWORD_HERE smtp=smtp.domain1.com
# List of servers to try (separated with ",")
domain2.com: [email protected] pass=PASSWORD_HERE smtp=server1.domain2.com,server2.domain2.com
# Subdomain, give a list of servers, specify non-standard port (overrides transport)
*.domain3.com: [email protected] pass=PASSWORD_HERE smtp=weirdserver1.domain3.com:444,weirdserver3.domain3.com:587
# List of servers, grouped primary, secondary MX-like behaviour.
# Separate groups with "+".
domain4.com: [email protected] pass=PASSWORD_HERE smtp=smtp1.domain4.com,smtp2.domain4.com,smtp3.domain4.com+backup1.domain4.com,backup2.domain4.com
编辑:如果任何值包含空格,则必须将其括在双引号中,并且任何用双引号括起来的值都要经过转义处理。
请勿在分隔符周围添加空格,例如“,”或“+”。