PHP使用sendmail发送Gmail邮件时Sender认证失败及配置找回求助
首先,从你提供的日志能明确看到问题核心:sendmail实际是以本地daemon@localhost.localdomain身份发送邮件,而非你指定的sender@gmail.com,而Gmail要求SMTP必须认证,所以直接被拒绝了。下面我帮你一步步梳理如何查看现有配置,以及重新配置认证的步骤:
一、查看已有的Sendmail SASL认证配置
你之前安装了SASL相关模块,配置文件通常在这些位置:
- Sendmail主配置:
/etc/mail/sendmail.mc(宏配置文件,需生成.cf文件生效)或/etc/mail/sendmail.cf
用命令快速检索SASL相关配置:grep -i "sasl\|auth" /etc/mail/sendmail.mc - SASL认证配置:不同发行版位置可能不同,常见的有
/etc/sasl2/Sendmail.conf或/etc/mail/sasl/smtpd.conf
查看内容:cat /etc/sasl2/Sendmail.conf 2>/dev/null || cat /etc/mail/sasl/smtpd.conf 2>/dev/null - 密码哈希文件:如果之前配置过认证,可能存在
/etc/mail/auth/client-info.db(哈希文件),对应的明文文件是client-info
二、重新配置Sendmail的Gmail SMTP认证
如果找不到之前的配置,直接按以下步骤重新设置:
1. 准备Gmail应用密码
如果你的Gmail开启了两步验证,必须用应用密码(App Password)代替普通密码;如果没开两步验证,需要先开启“不太安全的应用访问”(不过Google现在默认关闭,更推荐用两步验证+应用密码)。
2. 创建SASL认证密码文件
在/etc/mail/下创建auth目录(如果不存在):
sudo mkdir -p /etc/mail/auth sudo chmod 700 /etc/mail/auth
创建client-info文件,填入你的Gmail账号和应用密码:
sudo nano /etc/mail/auth/client-info
内容如下:
AuthInfo:smtp.gmail.com "U:sender@gmail.com" "P:你的应用密码" "M:PLAIN"
保存后设置严格权限(否则sendmail会拒绝使用):
sudo chmod 600 /etc/mail/auth/client-info sudo chown root:smmsp /etc/mail/auth/client-info
生成哈希数据库文件:
sudo makemap hash /etc/mail/auth/client-info < /etc/mail/auth/client-info
3. 修改Sendmail宏配置文件
编辑/etc/mail/sendmail.mc,添加或修改以下配置:
sudo nano /etc/mail/sendmail.mc
添加内容:
# 指定Gmail作为智能主机 define(`SMART_HOST',`smtp.gmail.com')dnl # 使用587端口(TLS) define(`RELAY_MAILER_ARGS', `TCP $h 587')dnl define(`ESMTP_MAILER_ARGS', `TCP $h 587')dnl # 启用支持的认证机制 define(`confAUTH_MECHANISMS', `EXTERNAL GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')dnl # 指定认证信息文件路径 FEATURE(`authinfo',`hash /etc/mail/auth/client-info')dnl
如果文件里已有类似配置,替换成上面的内容即可。
4. 重新生成Sendmail配置并重启服务
# 从.mc生成.cf配置文件 sudo m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf # 重启sendmail服务 sudo systemctl restart sendmail # 或者用service命令(取决于发行版) # sudo service sendmail restart
三、验证配置是否生效
可以用telnet手动测试SMTP认证:
telnet smtp.gmail.com 587
然后依次输入(注意替换成你的信息):
HELO localhost AUTH PLAIN # 这里需要把「用户名\x00密码」进行Base64编码,比如执行:echo -ne "sender@gmail.com\x00你的应用密码" | base64,把输出结果粘贴到这里 MAIL FROM:<sender@gmail.com> RCPT TO:<mail@gmail.com> DATA Subject: Test Sendmail Auth This is a test email to verify authentication. . QUIT
如果收到250 2.0.0 OK的回复,说明认证成功,再测试你的PHP代码即可。
四、更简单的替代方案:改用PHPMailer
原生mail()函数依赖系统sendmail配置,容易踩坑。PHPMailer直接处理SMTP认证,配置更直观,也更稳定。示例代码如下:
<?php use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\Exception; // 如果你用Composer安装,引入自动加载文件 require 'vendor/autoload.php'; $digits = 4; $random = rand(pow(10, $digits-1), pow(10, $digits)-1); $to = "mail@gmail.com"; $subject = "Verification code of Life Helper"; $message = "<b>Hello, ".$username."</b>. Your verification code is : ".$random; $mail = new PHPMailer(true); try { // SMTP服务器配置 $mail->SMTPDebug = 0; // 0=关闭调试,开启后可以查看详细日志 $mail->isSMTP(); $mail->Host = 'smtp.gmail.com'; $mail->SMTPAuth = true; $mail->Username = 'sender@gmail.com'; $mail->Password = '你的应用密码'; $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; $mail->Port = 587; // 设置发件人和收件人 $mail->setFrom('sender@gmail.com', 'Life Helper'); $mail->addAddress($to); // 邮件内容 $mail->isHTML(true); $mail->Subject = $subject; $mail->Body = $message; $mail->send(); $response["value"] = "sent"; $response["message"] = $random; var_dump(true); } catch (Exception $e) { var_dump(false); echo "邮件发送失败: {$mail->ErrorInfo}"; } ?>
这个方案不需要配置系统sendmail,直接通过PHPMailer连接Gmail SMTP,出错时还能看到详细错误信息,排查问题更方便。
内容的提问来源于stack exchange,提问作者Billy Istiak

