ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

PHPMailer 6.9 如何用 XCLIENT 扩展属性向 Postfix 网关传递转发身份

PHPMailer 6.9 如何用 XCLIENT 扩展属性向 Postfix 网关传递转发身份 PHPMailer 6.9 如何用 XCLIENT 扩展属性向 Postfix 网关传递转发身份【免费下载链接】PHPMailerThe classic email sending library for PHP项目地址: https://gitcode.com/GitHub_Trending/ph/PHPMailer当你的 PHP 应用不直接连外网邮件服务器而是先把信交给内网的 Postfix 网关再由网关转发出去时网关只知道连接来自哪台机器却不知道真实用户的登录身份。Postfix 的 XCLIENT 扩展就是解决这个的客户端在 SMTP 会话中发送一条XCLIENT命令把LOGIN、ADDR、HELO等属性传递给网关。PHPMailer 6.9.0 起提供了setSMTPXclientAttribute和getSMTPXclientAttributes两个方法支持这个扩展见 changelog.md仓库当前版本为 6.9.3。这篇文章只讲一件事如何用这两个方法把转发身份传给 Postfix 网关并确认命令确实发出去了。前提条件composer.json 声明的最低要求是 PHP5.5.0以及ext-ctype、ext-filter、ext-hash三个扩展。安装库composer require phpmailer/phpmailer网关侧需要 Postfix 已配置好smtpd_client_restrictions中的 XCLIENT 支持并且允许来自你这台客户端的 XCLIENT 属性——这是 XCLIENT 机制本身的前提PHPMailer 这边无法替代。PHPMailer 源码注释明确指出允许的 XCLIENT 属性由 SMTP 服务器决定PHPMailer 不会检查 EHLO 响应见 src/SMTP.php。允许的 XCLIENT 属性SMTP类中维护了一个白名单 SMTP::$xclient_allowed_attributes只有这 8 个属性名可以被设置和发送NAME, ADDR, PORT, PROTO, HELO, LOGIN, DESTADDR, DESTPORT典型转发场景用的是LOGIN真实登录名、ADDR客户端真实 IP、HELO客户端 HELO 域名。设置 XCLIENT 属性并发送参考 examples/smtp.phps 中的用法示例中这几行以注释形式给出取消注释并替换为你自己的值即可。下面是一个最小可用脚本ADDR、LOGIN、HELO的值需要替换为你转发链路上的真实值?php use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\SMTP; date_default_timezone_set(Etc/UTC); require vendor/autoload.php; $mail new PHPMailer(); $mail-isSMTP(); // 打开调试DEBUG_SERVER 同时显示客户端和服务端消息 $mail-SMTPDebug SMTP::DEBUG_SERVER; $mail-Host mail.example.com; // 你的 Postfix 网关地址 $mail-Port 25; // SMTP XCLIENT 属性 $mail-setSMTPXclientAttribute(ADDR, 10.10.10.10); // 客户端真实 IP $mail-setSMTPXclientAttribute(LOGIN, userexample.com); // 真实登录身份 $mail-setSMTPXclientAttribute(HELO, client.example.com); if (!$mail-send()) { echo Mailer Error: . $mail-ErrorInfo; } else { echo Message sent!; }属性的增删改规则由 setSMTPXclientAttribute 实现属性名不在 8 项白名单内时方法直接返回false不会保存传入非null值时保存或覆盖该属性返回true对已存在的属性传入null表示删除该属性。发送时 XCLIENT 命令如何发出在 PHPMailer::smtpSend 中一旦设置了任何 XCLIENT 属性send()会先建立 SMTP 连接然后在MAIL FROM之前调用$this-smtp-xclient($this-SMTPXClient)。SMTP::xclient() 把属性拼成XCLIENT ADDR... LOGIN...这样的命令发送给服务器并期望返回码 250服务器返回其他码时该命令返回false。也就是说如果网关没有放行你的 XCLIENT 属性发信流程会在这里失败send()抛出异常或返回false$mail-ErrorInfo中能看到错误详情。验证属性是否生效仓库测试 testSmtpXclient 展示了完整的核对方式可以照搬做本地验证$mail-isSMTP(); $mail-SMTPAuth false; $mail-setSMTPXclientAttribute(ADDR, 127.0.0.1); $mail-setSMTPXclientAttribute(LOGIN, userexample.com); $mail-setSMTPXclientAttribute(HELO, test.example.com); // 白名单外的属性名返回 false var_dump($mail-setSMTPXclientAttribute(INVALID, value)); // false // 读取当前保存的全部 XCLIENT 属性 var_dump($mail-getSMTPXclientAttributes()); // [ADDR 127.0.0.1, LOGIN userexample.com, HELO test.example.com] // 传 null 删除属性 $mail-setSMTPXclientAttribute(HELO, null); var_dump($mail-getSMTPXclientAttributes()); // [ADDR 127.0.0.1, LOGIN userexample.com]运行时的另一条验证路径是把SMTPDebug设为SMTP::DEBUG_SERVER调试输出会同时显示客户端发往服务器的消息可以直接看到XCLIENT ADDR... LOGIN...命令和服务器给出的应答码。测试中在preSend()后调用send()并断言返回true即为整条链路含 XCLIENT 命令通过。限制与边界PHPMailer 不解析 EHLO 响应来判断服务器是否支持 XCLIENT属性是否被接受完全取决于服务器对XCLIENT命令的应答250 才算成功只有 8 个白名单属性可用其余名字一律被setSMTPXclientAttribute拒绝未设置任何 XCLIENT 属性时xclient()直接返回true不会发送任何命令——所以没报错不等于命令已发出需要靠getSMTPXclientAttributes()或DEBUG_SERVER输出确认。【免费下载链接】PHPMailerThe classic email sending library for PHP项目地址: https://gitcode.com/GitHub_Trending/ph/PHPMailer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表