You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否在AWS Lightsail实例上通过AWS SES发邮件?权限问题求解

在AWS Lightsail实例中使用Node.js AWS SDK调用SES发信失败的问题

问题背景

我在AWS Lightsail实例上运行Node.js AWS SDK代码调用SES发送邮件时失败,但相同代码在本地开发环境正常运行。Lightsail上的WordPress通过WP Mail SMTP用SES SMTP凭证(TLS 587端口)能正常发信,说明实例本身可以和SES通信。

之前误以为是25端口限制,提交解除请求被拒,AWS建议用SES,但后续询问Lightsail能否用SES发信得到“无法批准请求”的回复,怀疑是自动回复。

报错信息

AccessDenied: User arn:aws:sts::(some number):assumed-role/AmazonLightsailInstanceRole/i-(some alphanumeric number) is not authorized to perform ses:SendEmail on resource `arn:aws:ses:us-east-1:(some number):identity/(recipient email address)'

代码片段

import { readFile } from 'fs/promises';
import * as path from 'path';
import { SESClient, SendEmailCommand } from "@aws-sdk/client-ses";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const awsConfigFileFullName = "aws_config.json";
let awsConfigFileFullPath = path.join(__dirname, awsConfigFileFullName);

const awsConfig = await readFile(awsConfigFileFullPath).then(json => JSON.parse(json)).catch(() => null);

const aws_ses_client = new SESClient({ 
  region: awsConfig.region, 
  accessKeyId: awsConfig.accessKeyId, 
  secretAccessKey: awsConfig.secretAccessKey 
});

const createSendEmailCommand = (toAddress, fromAddress, htmlContent, textContent, emailSubject) => {
  return new SendEmailCommand({
    Destination: {
      ToAddresses: [toAddress],
    },
    Message: {
      Body: {
        Html: {
          Charset: "UTF-8",
          Data: htmlContent,
        },
        Text: {
          Charset: "UTF-8",
          Data: textContent,
        },
      },
      Subject: {
        Charset: "UTF-8",
        Data: emailSubject,
      },
    },
    Source: `${emailSenderName}<${fromAddress}>`,
  });
};

const sendEmailCommand = createSendEmailCommand(
  recipientEmailAddress,
  senderEmailAddress,
  htmlEmailContent,
  textEmailContent,
  emailSubject
);

try {
  await aws_ses_client.send(sendEmailCommand);
} catch (e) {
  console.error("Failed to send email.", e);
}

疑问

  1. 能否为AmazonLightsailInstanceRole角色授予SES发信权限?如何操作?
  2. 如何在Lightsail实例上用Node.js SDK实现SES发信?

解决方案

一、为AmazonLightsailInstanceRole添加SES权限

Lightsail实例关联的AmazonLightsailInstanceRole默认不在IAM控制台直接显示,可通过以下两种方式修改权限:

  1. Lightsail控制台操作

    • 登录Lightsail控制台,进入目标实例详情页
    • 切换到权限标签页,点击附加策略
    • 选择AmazonSESFullAccess(或自定义更严格的策略)完成附加
  2. AWS CLI自定义最小权限策略

    • 创建自定义策略文件ses-send-policy.json:
      {
        "Version": "2012-10-17",
        "Statement": [
          {
            "Effect": "Allow",
            "Action": "ses:SendEmail",
            "Resource": "arn:aws:ses:你的区域:你的AWS账号ID:identity/你的发件邮箱地址"
          }
        ]
      }
      
    • 执行CLI命令附加策略:
      aws iam put-role-policy --role-name AmazonLightsailInstanceRole --policy-name SES-Send-Email-Policy --policy-document file://ses-send-policy.json
      
    • 替换命令中的区域、账号ID和发件邮箱地址

二、Node.js SDK发信的正确实现

  1. 修复代码问题

    • 补充导入SendEmailCommand(原代码遗漏)
    • Source字段直接用模板字符串拼接,无需转义<>
    • 优先使用实例角色身份验证(无需硬编码密钥,SDK自动从实例元数据获取凭证):
      const aws_ses_client = new SESClient({ region: awsConfig.region });
      
  2. 备选方案:用SMTP协议发送
    借助nodemailer库通过SES SMTP发送(和WordPress插件逻辑一致):

    import nodemailer from 'nodemailer';
    
    const transporter = nodemailer.createTransport({
      host: 'email-smtp.你的区域.amazonaws.com',
      port: 587,
      secure: false,
      auth: {
        user: '你的SES SMTP用户名',
        pass: '你的SES SMTP密码'
      }
    });
    
    const mailOptions = {
      from: `${emailSenderName}<${senderEmailAddress}>`,
      to: recipientEmailAddress,
      subject: emailSubject,
      text: textEmailContent,
      html: htmlEmailContent
    };
    
    try {
      await transporter.sendMail(mailOptions);
      console.log('Email sent successfully');
    } catch (error) {
      console.error('Error sending email:', error);
    }
    

验证步骤

  1. 确认SES发件邮箱已验证(或账户已移出沙箱)
  2. 在Lightsail实例中执行aws ses send-email --from 发件邮箱 --to 收件邮箱 --subject "Test" --text "Test content",验证权限配置是否生效
  3. 运行修改后的Node.js代码,检查发信状态

内容的提问来源于stack exchange,提问作者Coder1979

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 06:05:27