Ir al contenido

Amazon SES

Amazon Simple Email Service (SES) es la forma más barata de enviar grandes volúmenes de correo transaccional y una elección natural si ya trabajas en AWS. Requiere algo más de configuración que otros proveedores (IAM, una región, salir del sandbox), pero después es muy fiable.

Elige SES si envías miles de correos al mes o más, te importa el precio por mensaje o quieres tenerlo todo dentro de tu propia cuenta de AWS. Si quieres la configuración más rápida posible, es más fácil empezar con Postmark, Resend o Mailgun. Consulta el resumen de los servicios.

  • Una cuenta de AWS con SES activado en la región desde la que quieres enviar.
  • Una identidad verificada en esa región: preferiblemente un dominio completo (SES → Identities → Create identity → Domain) o, como mínimo, la dirección From concreta.
  • Acceso de producción (salir del sandbox) antes de enviar a cualquier destinatario; consulta Sandbox y límites.
  • Un usuario de IAM dedicado con una clave de acceso y solo estos permisos:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["ses:SendEmail", "ses:SendRawEmail", "ses:GetAccount"],
"Resource": "*"
}
]
}

ses:SendEmail / ses:SendRawEmail son necesarios para enviar (Frontmail usa la API v2 de SES con un mensaje MIME sin procesar), y ses:GetAccount para Probar conexión y la comprobación de estado diaria, que también lee tu cuota y si estás en el sandbox. Puedes restringir Resource a los ARN de tu identidad y de tu configuration set. No uses las credenciales de root ni un usuario administrador.

  1. Abre Servicios de correo → Añadir servicio → Amazon SES.
  2. Rellena los campos:
Campo Dónde encontrarlo Ejemplo
Región de AWS La región donde está verificada tu identidad (arriba a la derecha en la consola de SES) eu-central-1
Access key ID IAM → Users → frontmail-ses → Security credentials → Create access key AKIAIOSFODNN7EXAMPLE
Secret access key Se muestra una sola vez al crear la clave de acceso wJalrXUtnFEMI/K7MDENG/…
Configuration set SES → Configuration sets (necesario para los eventos de entrega) frontmail
ARN del tema de SNS Opcional; SNS → Topics: los eventos de otros temas se ignoran arn:aws:sns:eu-central-1:123456789012:frontmail-events
Correo del remitente predeterminado Opcional; una identidad verificada en la región seleccionada (una dirección de un dominio verificado o una dirección verificada). Se usa cuando la plantilla no tiene From hello@example.com
Nombre del remitente predeterminado Opcional; nombre visible del remitente predeterminado Acme
Máx. de correos por segundo Opcional; mantenlo igual o por debajo de tu velocidad máxima de envío en SES 14
  1. Haz clic en Verificar y guardar. Frontmail llama a GetAccount y muestra si la cuenta sigue en el sandbox, su velocidad máxima de envío y su cuota de 24 horas.
  2. El servicio se guarda cuando la comprobación es correcta. SES no tiene una «dirección de la cuenta», así que define aquí un Correo del remitente predeterminado o un correo del remitente en cada plantilla; si no, el envío falla con sender_not_configured (consulta Remitente predeterminado). Puedes cambiarlo después en la página del servicio sin volver a verificar.
  3. La clave de acceso se cifra con cifrado de sobre de AWS KMS; solo se descifra dentro del proceso de envío.

Easy DKIM: al crear una identidad de dominio, SES te da tres registros CNAME:

abcdef1234._domainkey.example.com. CNAME abcdef1234.dkim.amazonses.com.
ghijkl5678._domainkey.example.com. CNAME ghijkl5678.dkim.amazonses.com.
mnopqr9012._domainkey.example.com. CNAME mnopqr9012.dkim.amazonses.com.

AWS rota automáticamente las claves que hay detrás. Cuando se resuelven, la identidad aparece como Verified.

SPF mediante un dominio MAIL FROM personalizado: por defecto, el remitente del sobre es una dirección de amazonses.com, así que SPF pasa, pero no está alineado con tu dominio. Para que SPF también quede alineado con DMARC, configura un MAIL FROM personalizado (p. ej. bounce.example.com) en la identidad y publica:

bounce.example.com. MX 10 feedback-smtp.eu-central-1.amazonses.com.
bounce.example.com. TXT "v=spf1 include:amazonses.com ~all"

(Sustituye eu-central-1 por tu región.)

DMARC: empieza en modo de supervisión y luego endurécelo:

_dmarc.example.com. TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com"

SES es regional: las identidades, el estado del sandbox, las cuotas, los configuration sets y las listas de supresión son todos por región. La región que elijas en Frontmail debe ser aquella en la que:

  • está verificado tu dominio o tu dirección,
  • solicitaste el acceso de producción,
  • están tu configuration set y tu tema de SNS.

La clave de acceso de IAM es global, pero usarla en una región donde no hay nada configurado falla con «Email address is not verified». Para mantener los datos en la UE, elige una región europea como eu-central-1 (Fráncfort), eu-west-1 (Irlanda) o eu-north-1 (Estocolmo).

Toda cuenta nueva de SES empieza en el sandbox en cada región:

  • solo puedes enviar a direcciones o dominios verificados,
  • como máximo 200 mensajes cada 24 horas,
  • como máximo 1 mensaje por segundo.

Solicita el acceso de producción en SES → Account dashboard → Request production access. Describe el caso de uso (correo transaccional desde un formulario web a través de Frontmail), cómo dieron su consentimiento los destinatarios y cómo gestionas los rebotes y las quejas. La aprobación suele tardar alrededor de un día.

Tras la aprobación, tu cuota empieza en un nivel modesto (p. ej. 50 000 al día, 14 por segundo) y crece con un buen historial de envíos. Probar conexión muestra los valores actuales; configura Máx. de correos por segundo igual o por debajo de tu velocidad máxima de envío.

SES publica los eventos a través de Amazon SNS. Frontmail se suscribe a tu tema de SNS por HTTPS.

  1. SNS → Topics → Create topic (Standard), p. ej. frontmail-events, en la misma región.

  2. Create subscription → protocolo HTTPS → endpoint = la URL del webhook de la página del servicio en Frontmail (botón de copiar):

    https://api.frontmail.dev/webhooks/providers/ses/<token>

    Deja desactivado raw message delivery. Frontmail verifica la firma de SNS y confirma la suscripción automáticamente: en unos segundos el estado de la suscripción pasa de Pending confirmation a Confirmed.

  3. SES → Configuration sets → Create set (p. ej. frontmail) → Event destinations → Add destination → elige los tipos de evento → destino Amazon SNS → tu tema.

  4. Escribe el nombre del configuration set (y, si quieres, el ARN del tema) en el servicio de Frontmail y guarda.

Tipo de evento de SES Evento de Frontmail
Deliveries delivered
Rebotes permanentes (Permanent) bounced: se añade a la lista de supresión
Rebotes temporales (Transient), retrasos de entrega se registran en el mensaje
Complaints complained: se añade a la lista de supresión
Opens opened
Clicks clicked
Rejects, fallos de renderizado se registran en el mensaje

Verificación de la firma: cada mensaje de SNS está firmado. Frontmail descarga el certificado de firma solo desde sns.<region>.amazonaws.com, verifica la firma (SignatureVersion 1 o 2) y rechaza los mensajes de más de una hora de antigüedad. Si configuras el ARN del tema de SNS, se rechazan las notificaciones de cualquier otro tema. Si lo dejas vacío, Frontmail fija el tema del primer mensaje con una firma válida (normalmente la confirmación de la suscripción) y a partir de ahí rechaza los mensajes de cualquier otro tema: una firma de SNS solo demuestra que el mensaje lo envió alguna cuenta de AWS.

Frontmail añade a cada correo una etiqueta de mensaje frontmail_message_id para poder asociar los eventos con el mensaje.

  • auth: el servicio no funciona (clave de acceso no válida o eliminada, falta un permiso de IAM, envío en pausa, remitente sin verificar). El servicio se marca como unhealthy y el propietario recibe un correo y un aviso en el panel. Si la plantilla tiene un servicio de respaldo, el mensaje sale por él; si no, se devuelve el crédito y el mensaje espera en la cola de correos retenidos como held_service_error hasta que arregles el servicio (se vuelve a comprobar al guardar y en la comprobación de estado diaria), y entonces se envía automáticamente.
  • permanent: este mensaje no se puede enviar (destinatario no válido o sin verificar, contenido rechazado). Servicio de respaldo si está configurado; si no, failed y se devuelve el crédito.
  • transient: limitación, tiempos de espera agotados, 5xx. Se reintenta con espera exponencial; tras el último reintento, failed y se devuelve el crédito.
Error de SES Clase Qué hacer
InvalidClientTokenId / UnrecognizedClientException / SignatureDoesNotMatch auth El ID o el secreto de la clave de acceso son incorrectos o se han eliminado. Crea una clave nueva para el usuario de IAM.
AccessDeniedException: … not authorized to perform ses:SendRawEmail auth Añade la acción que falta a la política de IAM (ver arriba).
MessageRejected: Email address is not verified … hello@example.com (el remitente) auth Verifica el dominio o la dirección From en la región seleccionada.
MailFromDomainNotVerifiedException auth Corrige los registros MX/TXT del MAIL FROM personalizado o elimina el MAIL FROM personalizado.
SendingPausedException / AccountSuspendedException auth AWS ha pausado el envío (a menudo por una tasa alta de rebotes o quejas). Revisa SES → Reputation metrics y los avisos de AWS.
MessageRejected: Email address is not verified … customer@gmail.com (un destinatario) permanent La cuenta sigue en el sandbox: solicita el acceso de producción o verifica el destinatario.
BadRequestException / ValidationException (dirección no válida) permanent Consulta destinatario no válido.
TooManyRequestsException / Throttling: Maximum sending rate exceeded transient Baja Máx. de correos por segundo a tu velocidad de envío de SES; pide a AWS una cuota más alta.
InternalFailure, ServiceUnavailable, tiempos de espera agotados transient Nada: Frontmail reintenta.
  • Identidad de dominio verificada con Easy DKIM (3 CNAME) en la región elegida
  • MAIL FROM personalizado (MX + SPF) y DMARC p=none publicados
  • Acceso de producción concedido en esa región
  • Usuario de IAM solo con ses:SendEmail, ses:SendRawEmail, ses:GetAccount
  • Probar conexión funciona y muestra sandbox: false
  • Configuration set → tema de SNS → suscripción HTTPS a la URL del webhook de Frontmail, estado Confirmed
  • Nombre del configuration set introducido en Frontmail
  • Máx. de correos por segundo igual o por debajo de tu velocidad de envío de SES