AWS SES PHP调用SendEmail报错cURL error7:无法连接主机或代理
AWS SES SendEmail接口cURL错误7的排查解决
问题背景
- 已完成AWS SES身份验证与自定义MAIL FROM域验证
- 使用PHP的
SesClient调用SendEmail接口时触发错误:7: Failed to connect() to host or proxy,具体为AWS HTTP错误:cURL error 7,请求地址为https://email.us-east-1.amazonaws.com - 执行以下命令测试SMTP连接正常,返回证书验证通过及
250 Ok:openssl s_client -crlf -quiet -starttls smtp -connect email-smtp.us-east-1.amazonaws.com:587
核心原因
你当前代码中使用的是AWS SES SMTP凭证(用户名/密码),但SesClient默认调用的是AWS SES的REST API接口,需要的是IAM用户的访问密钥ID和秘密访问密钥,而非SMTP凭证。另外,REST API的端点是email.us-east-1.amazonaws.com(走HTTPS 443端口),而你测试的是SMTP端点email-smtp.us-east-1.amazonaws.com(走587端口),二者属于不同的服务协议/端口。
解决方案
方案1:改用SMTP协议发送邮件(使用现有SMTP凭证)
如果要继续使用已有的SMTP凭证,不要用SesClient,直接用PHPMailer等SMTP库发送:
require 'vendor/autoload.php'; use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\SMTP; $mail = new PHPMailer(true); try { // SMTP配置 $mail->isSMTP(); $mail->Host = 'email-smtp.us-east-1.amazonaws.com'; $mail->SMTPAuth = true; $mail->Username = '你的SMTP用户名'; $mail->Password = '你的SMTP密码'; $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; $mail->Port = 587; // 邮件内容 $mail->setFrom('已验证的发件邮箱', '发件人名称'); $mail->addAddress('收件人邮箱', '收件人名称'); $mail->Subject = '测试邮件'; $mail->Body = '这是通过AWS SES SMTP发送的测试邮件'; $mail->send(); echo '邮件发送成功'; } catch (Exception $e) { echo "发送失败:{$mail->ErrorInfo}"; }
方案2:使用IAM访问密钥调用REST API(继续用SesClient)
- 创建或使用已有IAM用户,为其附加
AmazonSESFullAccess权限(或仅ses:SendEmail的精细权限) - 获取该IAM用户的访问密钥ID和秘密访问密钥,替换代码中的凭证:
require('vendor/autoload.php'); use Aws\Ses\SesClient; use Aws\Exception\AwsException; // 替换为IAM用户的访问密钥ID和秘密访问密钥 $accessKeyId = '你的IAM访问密钥ID'; $secretAccessKey = '你的IAM秘密访问密钥'; $SesClient = new SesClient([ 'version' => '2010-12-01', 'region' => 'us-east-1', 'credentials' => [ 'key' => $accessKeyId, 'secret' => $secretAccessKey ] ]); // 调用SendEmail示例 try { $result = $SesClient->sendEmail([ 'Destination' => [ 'ToAddresses' => ['收件人邮箱'], ], 'Message' => [ 'Body' => [ 'Text' => [ 'Charset' => 'UTF-8', 'Data' => '这是通过AWS SES REST API发送的测试邮件', ], ], 'Subject' => [ 'Charset' => 'UTF-8', 'Data' => '测试邮件', ], ], 'Source' => '已验证的发件邮箱', ]); echo "邮件发送成功,消息ID:" . $result['MessageId']; } catch (AwsException $e) { echo $e->getMessage(); }
额外排查点
- 检查服务器防火墙/安全组是否允许出站访问443端口(REST API依赖HTTPS 443)
- 确认服务器无全局代理配置导致cURL无法连接AWS端点
- 检查PHP的cURL扩展是否正常启用,且支持TLS 1.2及以上版本
内容的提问来源于stack exchange,提问作者Zeke
相关产品推荐
相关产品推荐

