使用cloudflare时的php邮件和SMTP

Posted

技术标签:

【中文标题】使用cloudflare时的php邮件和SMTP【英文标题】:php mail and SMTP while using cloudflare 【发布时间】:2018-02-14 08:02:29 【问题描述】:

我在我的网站上使用 cloudflare,我想保持我服务器的 IP(ORIGIN IP)私有,以避免 DDoS 攻击直接发送到我的服务器的 IP。我的服务器使用 Apache、phpmysql

当使用 php mail 发送电子邮件时(即使我使用 phpmailer 库通过外部 SMTP 发送电子邮件),我的服务器的 IP 被添加到邮件标题中。 Google SMTP、Mailgun 和其他公司都会出现这种情况,因为他们的政策可能是在标头中写入邮件来自的 IP。

目前,我想到的唯一解决方案需要付出很多努力,即创建自己的 REST API 并通过另一台服务器发送电子邮件,如下所示:

ORIGIN SERVER IP 通过我的 REST API 以文本格式将电子邮件数据发送到我的邮件服务器 IP,然后我的邮件服务器 IP 使用 phpmailer 的 php 邮件功能通过 SMTP 将电子邮件发送给用户。这样,MY MAIL SERVER 的 IP 将出现在电子邮件标题中,而不是 ORIGIN SERVER 的 IP。

有没有更优雅的方法来做到这一点?是否有提供休息 API 的邮件服务,如果我使用他们的 API,他们不会在电子邮件标题中显示我的服务器 IP?或者,也许有一个已经开发的 REST API/库,可以按照我的要求远程发送电子邮件,所以我不必从头开始开发和测试自己的?

【问题讨论】:

【参考方案1】:

您应该通过 mailgun(或 sendgrid、jetmail、或 SES 或 ...)通过他们的 API 而不是 SMTP 协议发送电子邮件,并且您的 IP 不会被泄露。 p>

以 Mailgun SDK 为例:https://github.com/mailgun/mailgun-php

$mg = Mailgun::create('key-example');

# Now, compose and send your message.
# $mg->messages()->send($domain, $params);
$mg->messages()->send('example.com', [
  'from'    => 'bob@example.com',
  'to'      => 'sally@example.com',
  'subject' => 'The PHP SDK is awesome!',
  'text'    => 'It is so simple to send a message.'
]);

但大多数提供商都有 SDK:

Sendgrid php sdk Mailjet php sdk AWS SES PHP SD

此外,我会推荐使用SwiftMailer,它是处理电子邮件的强大库。其中一件很酷的事情是它抽象了传输,您可以使用包从 SMTP 或任何提供程序 API 切换。

【讨论】:

只是为了确认我使用来自 composer 的 Mailgun API,并且我的标头中不存在服务器信息。【参考方案2】:

您可以使用例如mailchimp、amazon SES 或其他邮件服务提供商,他们不应该添加您的 ip。但这些服务是有偿的。

【讨论】:

我尝试使用 mailgun(付费服务),但没有成功。我会看看mailchimp【参考方案3】:

很久以前,在大学,由于防火墙规则,我不能使用 php mail 命令,所以编写了我自己的 SMTP autentication 类。 一段时间后,我开始使用 PHPMailer 类,我再也没有遇到过问题,即使使用 Gmail 作为发件人。 看看https://github.com/PHPMailer/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\Exception;

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

$mail = new PHPMailer(true);                              // Passing `true` enables exceptions
try 
    //Server settings
    $mail->SMTPDebug = 2;                                 // Enable verbose debug output
    $mail->isSMTP();                                      // Set mailer to use SMTP
    $mail->Host = 'smtp1.example.com;smtp2.example.com';  // Specify main and backup SMTP servers
    $mail->SMTPAuth = true;                               // Enable SMTP authentication
    $mail->Username = 'user@example.com';                 // SMTP username
    $mail->Password = 'secret';                           // SMTP password
    $mail->SMTPSecure = 'tls';                            // Enable TLS encryption, `ssl` also accepted
    $mail->Port = 587;                                    // TCP port to connect to

    //Recipients
    $mail->setFrom('from@example.com', 'Mailer');
    $mail->addAddress('joe@example.net', 'Joe User');     // Add a recipient
    $mail->addAddress('ellen@example.com');               // Name is optional
    $mail->addReplyTo('info@example.com', 'Information');
    $mail->addCC('cc@example.com');
    $mail->addBCC('bcc@example.com');

    //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;

【讨论】:

在我的应用程序中,它只显示 SMTP 服务器 IP,而不是应用程序服务器。对不起! 您是否执行了 CTRL+F 并搜索您的应用服务器 IP 的前 2 位数字?有时,当 IP 确实出现在标头中时,它不是用点分隔,而是用下划线分隔。我尝试使用 2 个单独的服务器,PHPMailer 确实显示了原始应用服务器 IP + SMTP 服务器 IP【参考方案4】:

从任何云提供商处获取一个实例,向该实例发送 REST 请求或您喜欢的任何内容,然后您的原始 Web 服务器的 ip 将完全不可见。

【讨论】:

【参考方案5】:

没有 API 或优雅的方法可以从您发送的电子邮件中隐藏您的 IP。任何提供此功能的 SMTP 提供商都值得将其列入黑名单,并且会立即被注册滥用此隐私的垃圾邮件发送者所克服。

在启动 SMTP 之前,您必须使用创建内部 Web 中继系统以发送到其他 IP 的想法。但是设置它的麻烦应该比用另一个 IP 重建您当前的网站要更多麻烦。

这听起来像是将服务器视为宠物而不是牛的经典案例。如果在新 IP 上重建您当前的网站吸引力比构建和维护自定义 Web API 以隐藏您的 IP 不被曝光,那么您需要研究自动化工具。

【讨论】:

以上是关于使用cloudflare时的php邮件和SMTP的主要内容,如果未能解决你的问题,请参考以下文章

CloudFlare 并通过 PHP 记录访问者 IP 地址

PHP爬取一个使用cloudflare的网站

php [cloudflare api] cloudflare php api #security

PHP file_get_contents 函数无法使用 Cloudflare(网络服务器代理)

如何“动态”在 PHP 中向 cloudflare 添加子域?

如何使用 php 或 javascript 绕过 Cloudflare