Using Amazon Mail Manager SMTP to send email via Amazon Simple Email Service

Post Syndicated from Josephine Elea Schlage original https://aws.amazon.com/blogs/messaging-and-targeting/using-amazon-mail-manager-smtp-to-send-email-using-amazon-simple-email-service/

If you’re running applications or mail servers that need to send email over Simple Mail Transfer Protocol (SMTP), you may find that the classic Amazon Simple Email Service (Amazon SES) SMTP endpoint (email-smtp.<region>.amazonaws.com) is not available in every AWS Region.

This applies to some newer AWS Regions and partitions, including eusc-de-east-1 in the AWS European Sovereign Cloud (ESC). In these AWS Regions, services configured with a traditional SMTP hostname and credentials, such as Postfix relays, cannot use the classic SES SMTP integration pattern. Amazon SES Mail Manager provides an alternative: an authenticated SMTP ingress endpoint that accepts connections using a hostname, port, and credentials, just like any standard SMTP server.

In addition to SMTP connectivity, Mail Manager introduces a configurable email pipeline between acceptance and delivery. This pipeline gives you traffic filtering, message archiving, and rule-based routing that are not available with the classic SES SMTP endpoint.

In this post, you configure Amazon SES Mail Manager to send outbound email in a Region that does not offer the classic SES SMTP endpoint. This post uses eusc-de-east-1 (AWS European Sovereign Cloud) as an example, but the same steps apply to AWS Regions where Mail Manager is available and the classic SMTP endpoint is not. By the end, you have a working Mail Manager pipeline that can:

  • Control outbound email flow with traffic policies.
  • Archive outgoing messages for compliance.
  • Deliver messages to recipients through a managed SMTP pipeline.

This post walks through a practical setup in eusc-de-east-1 with step-by-step instructions for configuring each component.

Solution overview

In this walkthrough, you configure Amazon SES Mail Manager in eusc-de-east-1 with the following components:

  • Traffic policy: You create a traffic policy with a default action set to Deny. The policy includes two policy statements connected by an OR condition. Policy Statement 1 allows messages that use TLS protocol version 1.2 or higher. Policy Statement 2 allows messages where the recipient address ends with a specific domain, filtering outgoing mail to approved recipients only.
  • Rule set: You create a rule set containing a single rule with two actions that archive outgoing email and then deliver it to recipients.
  • Ingress endpoint: You create an authenticated Mail Manager ingress endpoint that receives, routes, and manages messages based on your configured traffic policy and rule set.

After setting up these components, you use sample Python code to send an email through the ingress endpoint. Optionally, you can integrate with Postfix for relay-based delivery. You also configure Amazon CloudWatch logging to monitor how each message flows through the pipeline. To verify functionality, you check the email archive to confirm that outgoing messages are stored and that the email is received in the intended inbox.

The following diagram shows the message flow: Application or Amazon Elastic Compute Cloud (Amazon EC2) instance → ingress endpoint → traffic policy (allow or deny) → rule set (archive, then send to internet) → recipient inbox.

Walkthrough

This walkthrough covers the prerequisites and the step-by-step setup. Before you create traffic policies and a rule set, you first set up email archiving and AWS Identity and Access Management (IAM) roles, which are needed when you create the traffic policies and rules.

Prerequisites

Before beginning, verify that you have completed domain verification in the eusc-de-east-1 (ESC) Region and moved out of the Amazon SES sandbox. Domain verification is a required first step that confirms your authority to send email through SES from your domain. In this tutorial, you use a sample Python program to send email programmatically through an ingress SMTP endpoint (ARecord). You can run this program on your local machine through the AWS Command Line Interface (AWS CLI).

  • An active AWS account in the AWS European Sovereign Cloud with access to the eusc-de-east-1 Region.
  • A domain to verify as a sending identity in Amazon SES.
  • The AWS CLI, installed and configured for eusc-de-east-1 (required for Amazon CloudWatch logging).
  • An AWS Secrets Manager secret to store ingress endpoint credentials.
  • (Optional) An Amazon Virtual Private Cloud (Amazon VPC) with at least two subnets and an Amazon EC2 instance, if you plan to configure VPC endpoint connectivity.
  • IAM permissions for Amazon SES, AWS Key Management Service (AWS KMS), AWS Secrets Manager, and CloudWatch for the user who is signed in to the AWS Management Console.

Step 1: Create and verify an identity

To create and verify a sending identity in Amazon SES:

  1. In the Amazon SES console, choose Configuration, and then select Identities.
  2. Create the identity (domain or email address). If you verify a domain identity, configure email authentication with Sender Policy Framework (SPF), DomainKeys Identified Mail (DKIM), and Domain-based Message Authentication and Reporting and Conformance (DMARC) to prevent email from being marked as spam or failing delivery. See the following guides:
    1. Authenticating Email with DKIM in Amazon SES.
    2. Authenticating Email with SPF in Amazon SES.
    3. Complying with DMARC authentication protocol in Amazon SES.

    If you verify an email address identity without also verifying the parent domain, your messages may be quarantined or rejected depending on the domain’s DMARC policy.

  3. Complete the verification process.

Note: For eusc-de-east-1, the Custom MAIL FROM Domain Name System (DNS) records use amazonses.eu instead of amazonses.com.

Step 2: Configure an email archive for compliance and retention

Create an email archive to store outgoing messages. You configure this archive as the first action in your rule. The archive serves as a repository for outgoing messages.

  1. In the Amazon SES console, choose Mail Manager, then Email Archiving.
  2. Under Manage archives, select Create archive.
    1. Enter a unique name in the Archive name field.
    2. (Optional) Select a retention period to override the default of 180 days (6 months).
    3. (Optional) Set up encryption by either entering your own AWS Key Management Service (AWS KMS) key in the AWS KMS key ARN field, or selecting Create new key.
  3. Choose Create archive.
  4. After it is created, this archive stores your email according to the rules you define in the next step.

Step 3: Create an IAM role permission policy for the send to internet rule action

Configure an IAM role that permits Mail Manager to send email to external domains. This role is referenced in the rule for the second action, “send to internet,” which delivers email to recipients.

  1. Go to the IAM console.
  2. Choose Roles, and then choose Create role.
  3. For trusted entity, select Custom trust policy and paste the following (replace XXXXXXXXXXX with your AWS EUSC account ID):
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "Statement1",
          "Effect": "Allow",
          "Principal": {
            "Service": "ses.amazonaws.com"
          },
          "Action": "sts:AssumeRole",
          "Condition": {
            "StringEquals": {
              "aws:SourceAccount": "XXXXXXXXXXX"
            },
            "ArnLike": {
              "aws:SourceArn": "arn:aws-eusc:ses:eusc-de-east-1:XXXXXXXX:mailmanager-rule-set/*"
            }
          }
        }
      ]
    }

  4. Skip add permissions, name review, and create your role.
  5. Open your newly created role and select Add permissions.
  6. From the menu, choose Create inline policy.
  7. Select JSON in the policy editor and paste the following (replace example.com with your verified domain, XXXXXXXXXXX with your AWS account ID, and my-configuration-set with your configuration set name if applicable). This policy grants the necessary permissions to send email to recipients on the internet, which is used in rule 2 of your rule set.
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "VisualEditor0",
          "Effect": "Allow",
          "Action": [
            "ses:SendEmail",
            "ses:SendRawEmail"
          ],
          "Resource": [
            "arn:aws-eusc:ses:eusc-de-east-1:XXXXXXXXXXX:identity/example.com",
            "arn:aws-eusc:ses:eusc-de-east-1:XXXXXXXXXXX:configuration-set/my-configuration-set"
          ],
          "Condition": {
            "StringEquals": {
              "ses:FromAddress": "example.com"
            }
          }
        }
      ]
    }

  8. Review and save the policy.

Your newly created role now has the custom trust policy in Trusted entities, and a customer-managed inline permission policy under Permissions.

Step 4: Create a traffic policy

Traffic policies act as security checkpoints for your email infrastructure. They control which messages can enter your system based on rules you define. To create a traffic policy that enforces security requirements for your email:

  1. Open the Amazon SES console.
  2. Go to Mail Manager and select Traffic policies.
  3. Choose Create traffic policy.
  4. Enter a unique name for your policy.
  5. Set Default action to Deny.
  6. In your traffic policy, select “add new policy statement.”
    1. For Allow or deny properties, select Allow.
    2. For Properties, select TLS protocol version.
    3. For Operator, select Minimum version or Is version.
    4. For Value, select TLS 1.2 (minimum) or TLS 1.3 (Is version).
  7. Now, add a second condition to the same policy statement to filter outgoing mail to *example.com domains:
    1. For Properties, select Recipient address.
    2. For Operator, select “Ends with” and for Value enter example.com.

    Configure your policy statements as you like.

  8. Choose Create traffic policy.

Traffic policies are evaluated in a specific sequence:

  1. Deny policy statements are evaluated in order. If any match, the email is immediately blocked and no further evaluation occurs.
  2. If no Deny statements match, all Allow policy statements are evaluated in order. Multiple statements within a policy are connected by OR logic. If any statement matches, the email is allowed.
  3. Within each individual policy statement, multiple conditions are connected by AND logic. Each condition must be true for the statement to match.
  4. If no policy statements match (neither Deny nor Allow), the default action of the traffic policy (either Allow or Deny) is applied.

This policy denies traffic by default and allows only messages that meet the TLS 1.2 minimum requirement and are addressed to approved recipient domains.

Default action: Deny by default. Email traffic is initially blocked unless explicitly allowed by the following policy statements.

Policy statement 1: Allows messages to be sent if the recipient’s address ends with *example.com AND meets the minimum TLS protocol version of TLS 1.2.

Step 5: Create a rule set

Rule sets define how your messages are processed after they pass through your traffic policy. In this example, the rule set establishes a sequential email processing workflow. First, you add the action for archiving outgoing messages, and then you add a second action to deliver messages to recipients.

To create a rule set:

  1. Open the Amazon SES console.
  2. Go to Mail Manager and select Rule sets.
  3. Choose Create rule set.
  4. Enter a unique name for your rule set.
  5. On the rule set’s overview page, select Edit, then select Create new rule.

Step 6: Create rules

In this step, you create rules within your rule set that define the actions performed on each email: archiving for compliance and delivering to recipients.

Email add-ons are optional: In your rule set, you can configure the Vade Advanced Email Security Add On for scanning or dropping messages, archiving for compliance, writing to Amazon Simple Storage Service (Amazon S3) for future analysis, and sending email out. Configure these rules accordingly. This guide covers email sending and archiving in the rule below.

  • Add conditions or exceptions as needed:
    • Select Add new condition to specify what messages the rule applies to.
    • Select EXCEPT in the case of and select Add new exception for exclusions.
  • Configure actions by choosing Add new action.
  • For multiple actions, use the up and down arrows to set the execution order.

Action 1: Archive outgoing email. Stores a copy of each outgoing email in a Mail Manager archive. Archived email can be searched and retrieved directly from the Amazon SES console under Email archiving, supporting compliance and audit requirements.

Action 2: Send to internet. Delivers the email to the intended recipient using Amazon SES.

After you create your rule set, add rules that define how email is processed. You create a rule set containing a single rule with two actions that execute in sequential order.

Follow these steps to create and configure your rules.

  1. In the created rule set’s overview page, select Edit, then choose Create new rule.
  2. In the Rule details sidebar, enter a unique name for your rule.
    1. In the rule details on the right side, select “add new action.”
    2. From the menu, choose “archive,” and choose the archive you created at Step 2.
    3. Then add another action: select “add new action” and from the menu, choose “Send to internet.”
    4. Choose the IAM role that you created in Step 3. This role grants SES Mail Manager access to your resource.
  3. When finished creating your rules, choose Save rule set to apply your changes.

Rule 1: Archive and send email to recipients

The rule processes messages that have successfully passed through the traffic policy. The archive action confirms that messages are archived and searchable. The send to internet action then forwards messages to their intended recipients, completing the email delivery workflow.

Step 7: Store password in AWS Secrets Manager for the ingress endpoint

Before you create an ingress endpoint, set up a password in AWS Secrets Manager and an AWS KMS customer managed key:

1. Create a customer managed key policy for your ingress endpoint.

  1. Open the AWS KMS console.
  2. Select Customer managed key (not AWS managed keys).
  3. Create the key.
  4. Define key administrative permissions.
  5. Define key usage permissions.
  6. In your key policy editor, when you review the key statements, paste the following (replace XXXXXXXXXXX with your AWS account ID):
    {
      "Sid": "Allow use of the key",
      "Effect": "Allow",
      "Principal": {
        "Service": "ses.amazonaws.com"
      },
      "Action": "kms:Decrypt",
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "XXXXXXX",
          "kms:ViaService": "secretsmanager.eusc-de-east-1.amazonaws.com"
        },
        "ArnLike": {
          "aws:SourceArn": "arn:aws-eusc:ses:eusc-de-east-1:XXXXXXXX:mailmanager-ingress-point/*"
        }
      }
    }

2. Set up a password in AWS Secrets Manager.

  1. Go to the AWS Secrets Manager console and select Store a new secret.
  2. Choose Other type of secret.
  3. Enter password as the key and your chosen password as the value.
  4. For encryption key, choose the customer managed key you created above.
  5. Choose Next to proceed to Configure secret.
  6. Enter a secret name and choose Edit permissions, then update the resource policy (replace XXXXXXXXXXX with your AWS account ID).
    {
      "Version": "2012-10-17",
      "Id": "Id",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Service": "ses.amazonaws.com"
          },
          "Action": "secretsmanager:GetSecretValue",
          "Resource": "*",
          "Condition": {
            "StringEquals": {
              "aws:SourceAccount": "XXXXXXXXXXX"
            },
            "ArnLike": {
              "aws:SourceArn": "arn:aws-eusc:ses:eusc-de-east-1:XXXXXXXXXXX:mailmanager-ingress-point/*"
            }
          }
        }
      ]
    }

  7. Choose Next, then create and store your secret.

Step 8: Create an authenticated ingress endpoint (ARecord)

Now that you have created your traffic policy and rule set and stored your credentials, you can create the ingress endpoint:

  1. In the Amazon SES console, choose Mail Manager and then select Ingress endpoints.
  2. Choose Create ingress endpoint.
  3. Configure your endpoint:
    1. For type, select authenticated, then select the Secret ARN you created in Secrets Manager.
    2. Choose the traffic policy you created earlier.
    3. Choose the rule set you created earlier.
    4. Configure Network Type: Public Network (Standard Setup). If you select Private Network, follow Step 9 first in a new tab.
    5. Enter a unique name for your endpoint.
  4. Choose Create ingress endpoint.

After your ingress endpoint is created, note the following details from the General details section:

  • Amazon Resource Name (ARN): arn:aws-eusc:ses:eusc-de-east-1:XXXXXXXXXXX:mailmanager-ingress-point/inp-XXXXX
  • Username: inp-XXXXXXXXXXX
  • Host: XXXXXXXXXXX.mail-manager-smtp.eusc-de-east-1.amazonaws.eu (ARecord)

You need these details when configuring your email client or application to send email through this endpoint.

Step 9: Configure VPC endpoint for SES Mail Manager (optional enhanced security)

A VPC endpoint allows your Postfix EC2 instance to reach Mail Manager privately, without sending traffic over the public internet. To use this option, create the VPC endpoint in the same VPC as your Postfix instance. Configure security group rules to allow traffic on port 587.

  • VPC: The VPC endpoint must be created in the same VPC where your Postfix EC2 instance resides.
  • Security groups:
    • Postfix EC2 SG: Outbound rule to VPC endpoint SG on port 587.
    • VPC endpoint SG: Inbound rule from Postfix EC2 SG on port 587.
  • Subnets: The VPC endpoint should be in subnets that are routable from your EC2 instance’s subnet.

Create a security group for the VPC endpoint:

  1. Open the Amazon VPC console.
  2. Select Security groups.
  3. Choose Create security group.
    1. Name: mail-manager-vpce-sg (example).
    2. VPC: Choose the VPC where your Postfix EC2 instance resides.
  4. Add an inbound rule:
    1. Type: Custom TCP.
    2. Port: 587 (or 25 if using port 25).
    3. Source: Security Group ID of your Postfix EC2 instance (or create a placeholder, update later).
  5. Choose Create security group. Note the Security Group ID for the next step.
  6. Choose Endpoints in the VPC console.
  7. Choose Create endpoint.
    1. Name: mailmanager-ingress-endpoint (example).
    2. For Service category, select AWS services.
    3. For Service Name, select com.amazonaws.eusc-de-east-1.mail-manager-smtp.auth.
    4. For VPC, choose the VPC where your Postfix server resides.
    5. Subnets: Select at least 2 (private) subnets (for high availability).
    6. Security Groups: Choose the security group you created.
  8. Choose Create Endpoint.

Wait for the endpoint status to become Available. After the endpoint status becomes Available, note the DNS name from the endpoint details. Use the regional (non-AZ-specific) DNS name for your Postfix relay configuration:

auth.mail-manager-smtp.eusc-de-east-1.on.amazonwebservices.eu

Step 10: Mail Manager logging (AWS CLI)

Now that you have created your Mail Manager resources, you can configure log delivery through the AWS CLI to track message flow from ingress endpoints through rule set processing. After it is configured, you can view these logs in CloudWatch Log Groups.

  1. Open your terminal (CLI).
  2. Log in to your AWS account using the following command:
    aws configure

  3. Create a CloudWatch Log Group:
    aws logs create-log-group \
        --log-group-name /aws/mailmanager/ruleset-logs \
        --region eusc-de-east-1

    Before you proceed, copy the log group ARN for the step Create the Delivery Destination.

  4. Create the Log Delivery Source:Add your rule set ID to the resource-arn parameter below. You can find the resource ARN for the rule set when you click on the rule set name under rule sets in the SES console.
    aws logs put-delivery-source \
        --name rs-default \
        --resource-arn arn:aws-eusc:ses:eusc-de-east-1:XXXXXX:mailmanager-ruleset/YOUR-RULESET-ID \
        --log-type APPLICATION_LOGS

  5. Create the Log Delivery Destination:Add your log group ARN to the destinationResourceArn parameter below:
    aws logs put-delivery-destination \
        --name mailmanager-destination \
        --output-format json \
        --delivery-destination-configuration '{"destinationResourceArn":"arn:aws-eusc:logs:eusc-de-east-1:XXXXXX:log-group:/aws/mailmanager/ruleset-logs:*"}'

    Copy the delivery destination ARN for the step below.

  6. Link Log Delivery Source to Log Delivery Destination (Create Delivery):
    aws logs create-delivery \
        --delivery-source-name rs-default \
        --delivery-destination-arn arn:aws-eusc:logs:eusc-de-east-1:XXXXXX:delivery-destination:mailmanager-destination

    Verification commands:

    aws logs describe-log-groups --region eusc-de-east-1
    aws logs describe-delivery-sources --region eusc-de-east-1
    aws logs describe-delivery-destinations --region eusc-de-east-1
    aws logs describe-deliveries --region eusc-de-east-1

  7. Send an email and view your logs for your rule set:
    1. Open the Amazon CloudWatch console.
    2. Select Log Groups in the sidebar navigation.
    3. Select the log group you would like to view logs for.
    4. Select the log you would like to view under Log Streams.

Example output of an email that was sent successfully:

{
  "resource_arn": "arn:aws-eusc:ses:eusc-de-east-1:account-id:mailmanager-rule-set/ruleset-id",
  "event_timestamp": 3456789876,
  "message_id": "message-id",
  "rule_set_name": "send",
  "rule_name": "sendtointernet",
  "rule_index": 1,
  "recipients_matched": "[\"[email protected]\"]",
  "action_metadata": {
    "action_name": "SEND",
    "action_index": 1,
    "action_status": "SUCCESS"
  }
}

Step 11: Send email using an ingress endpoint

Code example with Python:

import smtplib
import ssl

# Your ingress endpoint and port
smtp_server = "*****.eusc-de-east-1.amazonaws.eu"
# Or for VPC: "vpce-xxxxx.mail-manager-smtp.auth.eusc-de-east-1.vpce.amazonaws.eu"
smtp_port = 587

# Your SMTP credentials retrieved from Secrets Manager
username = "****"
password = "[REDACTED_PASSWORD]"

sender_email = "[email protected]"  # Your verified identity
receiver_email = "[email protected]"

# Properly formatted email message with headers
message = f"""From: Firstname Lastname <{sender_email}>
To: Firstname Lastname <{receiver_email}>
Subject: Test Email from Python

This email was sent via the Mail Manager ingress endpoint and delivered
to the recipient through the "Send to Internet" rule action.
"""

server = None
try:
    print(f"Connecting to {smtp_server}:{smtp_port}...")
    server = smtplib.SMTP(smtp_server, smtp_port)
    server.set_debuglevel(1)

    print("\nStarting TLS...")
    context = ssl.create_default_context()
    server.starttls(context=context)

    print("\nLogging in...")
    server.login(username, password)

    print("\nSending email...")
    server.sendmail(sender_email, receiver_email, message)
    print("\nEmail sent successfully.")
except Exception as e:
    print(f"\nError: {e}")
    import traceback
    traceback.print_exc()
finally:
    if server:
        server.quit()

Step 12: Integrate with your existing email server

Use Postfix or SMTP clients on Amazon EC2 to relay outbound email through Mail Manager, which then forwards it through the “Send to internet” action configured in Step 3.

If you choose to integrate with Postfix in this guide, your relay host is the ingress endpoint or the VPC endpoint you created. Your port is typically 587.

relayhost = [<ARecord>]:<port>

Example with Postfix

/etc/postfix/main.cf:

relayhost = [xxxx.eusc-de-east-1.amazonaws.eu]:587 or 25
relayhost = [vpce-xxxxx.mail-manager-smtp.auth.eusc-de-east-1.vpce.amazonaws.eu]:587

Clean up

Clean up your AWS environment by removing all resources created during this walkthrough, including Mail Manager configurations, ingress endpoints, rule sets, traffic policies, archives, IAM roles, Secrets Manager secrets, AWS KMS keys, and CloudWatch log groups.

Conclusion

In this post, you configured Amazon SES Mail Manager in the eusc-de-east-1 Region of the AWS European Sovereign Cloud to send outbound email over SMTP. You created a traffic policy to enforce TLS and recipient filtering, a rule set to archive and deliver messages, and an authenticated ingress endpoint that serves as a compatible SMTP relay for your applications.

To learn more, see the Amazon SES Mail Manager documentation, open the Amazon SES console to start configuring your own pipeline, or visit the Amazon SES service page for additional features.

Additional references

For more information, see the following references:


About the authors