Configurando Amazon SES para envio de e-mail
Tags: aws, ses, email, iam
Published: 2024-01-30 03:28:50

<div style='text-align: justify;'>
O Amazon Simple Email Service (SES) é um serviço econômico projetado para facilitar o envio de e-mails integrado a diversas aplicações, permitindo a automação de envios em larga escala.

Se você utiliza um software de e-mail para enviar mensagens transacionais, campanhas de marketing ou newsletters, o Amazon SES oferece uma estrutura de pagamento flexível, permitindo que você pague apenas pelo que efetivamente utilizar. Além disso, ele suporta diferentes configurações de implantação, como endereços IP dedicados, compartilhados ou próprios.

Neste tutorial, vou ajudá-lo a configurar o Amazon SES para o seu domínio. Vamos gerar uma credencial SMTP e enviar um e-mail de teste.

## Pré-requisito:
Uma conta AWS e um domínio (irei utilizar o domínio alfredocastro.com.br).
</div>

## Etapa 01 - Configurando o Amazon SES
Acesse a console AWS e procure pelo serviço "Amazon Simple Email Service".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jyn9pt9s6hyfw2dbkv31.png)

No menu lateral a esquerda, clique em "Verified identities".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rdlwt1av2i4wwzv48e5q.png)

Clique em "Create identity".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/svdtarekxv43ldoocj5y.png)

Nesta etapa, você poderá escolher entre a criação de uma identidade do tipo "Domain" ou "Email address".

Uma identidade do tipo "Domain" significa que após o Amazon SES configurado, você terá a capacidade de enviar e-mails representando qualquer endereço vinculado ao domínio configurado, por exemplo, você poderá enviar e-mails representando mkt@alfredocastro.com.br ou marketing@alfredocastro.com.br e assim por diante.

Já com a identidade do tipo "Email address", você irá configurar o Amazon SES para enviar e-mails apenas com um determinado endereço de e-mail.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jnrmc7wr99pquy24zsd2.png)

Para este tutorial, vamos utilizar o tipo "Domain", no campo "Domain" digite o seu domínio, deixe as demais configurações padrões e clique em "Create identity".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t26qnbtnvn8fpnixw96o.png)

Pronto, você concluiu com sucesso a criação da identidade para o seu domínio.

Na próxima tela que abrir, será apresentada uma ação para confirmar que você é o proprietário desse domínio.

Você precisará criar alguns registros do tipo CNAME no seu DNS para configurar o DKIM e, dessa forma, confirmar a propriedade do domínio.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ap2ux4nc0o3i5qx66z0k.png)

Na aba "Authentication", vá até o campo "Publish DNS records", será exibido 3 registro DNS do tipo CNAME para serem criados em seu DNS.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7t80oti4z5nw3b0pa1rv.png)

## Etapa 02 - Criando os registro DNS
Acesse o seu gerenciador de registros DNS do seu domínio.

Crie os registros do tipo CNAME conforme exibido na etapa anterior. Veja um exemplo:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rmazo8apii6ymh9soj1l.png)

Para consultar a propagação do registro criado, consulte o site: [WhatsMyDNS](https://www.whatsmydns.net/)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3qaaoyfuctbw0lvocvu9.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3gf13gfo29d6s8pimile.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/apjdl2bkhsuy1ay9n4ib.png)

Após a propagação, você receberá um e-mail (e-mail que está configurado em sua Root Account da AWS) confirmando que a configuração do DKIM foi realizada com sucesso.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/biothqqffsxfiwwdzjxy.png)

Acesse o Amazon SES e entre na identidade que acabamos de criar, você irá conseguir visualizar o status como "Verified" e o status do DKIM como "Successful".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nh43l0tt291qwp6k4h3w.png)

## Etapa 03 - Solicitando acesso ao Amazon SES produção
Acesse a console AWS e acesse o serviço "Amazon Simple Email Service".

No menu lateral a esquerda, clique em "Account dashboard".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7acye4vc658xf0go8vu3.png)

Veja na mensagem em amarelo, a identidade que acabamos de criar está no modo "Sandbox", clique no botão "View Get set up page".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dpu2246ct8dp3v39bulc.png)

Nossa conta está em "Sandbox" e com algumas restrições de utilização, podemos enviar apenas 200 e-mails por 24 horas e podemos enviar apenas e-mails para a nossa própria identidade verificada.

Para remover essa restrição, precisamos abrir um chamado para a AWS, clique no botão "Request production access".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5dv1l3b0lv4lbyq6n1qg.png)

Precisamos preencher esse formulário explicando para qual finalidade iremos utilizar o Amazon SES, a AWS irá analisar a solicitação e se estiver de acordo irá liberar nossa identidade para o modo "Production".

Em "Mail type" selecione qual tipo de email você irá enviar, se é e-mail do tipo "Marketing" ou "Transactional", para este tutorial irei utilizar como "Transactional".

Em "Website URL" digite a URL do site da sua empresa ou produto para que a AWS possa analisar qual o tipo do conteúdo será enviado.

Em "Use case description", faça uma descrição do tipo de e-mail que será enviado e quais medidas você irá tomar para que os e-mails enviados não sejam considerados pelos usuários como Spam, a AWS solicita que você responda 3 questões:
```text
1) How will you build or acquire your mailing list?
2) How will you handle bounces and complaints?
3) How can recipients unsubscribe from your mailing list, and how will you respond to those requests?
```

Eu utilizei o seguinte texto para a minha solicitação (basicamente expliquei que iria utilizar o Amazon SES como envio de email transacional, e-mails enviados por um novo sistema que estou criando e dei um exemplo do tipo de e-mail "Esqueci minha senha" e e-mails com novas postagens, também expliquei que para não ter meus e-mails marcados como indesejados ou serem enviados para o Spam, irei criar um link para que os usuários possam remover seu e-mail da lista de envio ou podem acessar o sistema e remover o envio de e-mails):
```text
How will you build or acquire your mailing list?
It's a new system, I will use AWS SES to send emails to new registered users, to send "I forgot my password" emails and to send notifications of new posts made on the website.

How will you handle bounces and complaints?
Each user will can cancelate the notification of system. Or via a link that will be sent along with the email.

How can recipients unsubscribe from your mailing list, and how will you respond to those requests?
Each user will can cancelate the notification of system through of a option 'help' inside the system. Or via a link that will be sent along with the email.

As it is a new system, I believe that daily emails will be sent around 100 emails.
```
Marque a caixa "I agree to the AWS Service Terms and Acceptable Use Policy (AUP)" e clique em "Submit request".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hvv08b4dma7a7vnpka6e.png)

Você receberá uma mensagem informando que a requisição foi enviada com sucesso e a AWS irá revisar em 24 horas. O status será alterado para "Under review".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fq2rdwqn0kycrg6lxyck.png)

Atualize a página e você irá visualizar uma mensagem com o ID do ticket aberto para a AWS. Você pode clicar no link e ir até o ticket para enviar mais informações para a AWS, caso a AWS encontre alguma inconsistencia, ela irá enviar uma mensagem pelo ticket.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ofxipjlxd7ji15f9hc62.png)

Após a análise da AWS, você irá receber uma e-mail (e-mail da conta Root Account) avisando que o Amazon SES foi liberado para o modo "Production".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kdjqq171ow03xd0lrdqg.png)

Acesse o serviço novamente e clique em "Account dashboard", agora podemos ver que a nossa cota para envios de e-mails foi alterada para 50.000 e-mails por 24 horas e o nosso status está como "Healthy".

Esse número de e-mails foi definido pela AWS, você consegue solicitar um ajuste conforme a utilização.

A AWS fornece um dashboard onde podemos ver como está nossa utilização diária.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0oyq9saketwposf5455w.png)

## Etapa 04 - Criando credencial SMTP via AWS Console
Agora que já possuimos o nosso Amazon SES configurado e habilitado para envio de e-mails, devemos gerar uma credencial SMTP.

Acesse a console AWS e acesse o serviço "Amazon Simple Email Service".

No menu lateral a esquerda, clique em "SMTP settings".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/84np77dx1rfzpxuf2wpn.png)

Clique no botão "Create SMTP credentials".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1tv5oq1o5cscgu4hfx8c.png)

Por padrão, a AWS irá criar o "User name" como "ses-smtp-user.YYYYMMDD-HHMMSS", caso você queira, poderá alterar o nome do "User name", abaixo irá mostrar qual a permissão o usuário possui.

Basicamente a AWS cria um usuário IAM com uma Policy de Allow para ses:SendRawEmail, ela gera uma Access keys e executa um script para gerar uma credencial SMTP.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a33v0i0zn1xoi4fm9v83.png)

Eu alterei o nome do meu usuário para "ses-smtp-alfredo", clique em "Create user".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m5ygbhpjrqx982jdci26.png)

Copie os dados exibidos na tela e salve em um local seguro o "SMTP username" e "SMTP password" é a nossa credencial de autenticação no Amazon SES para envio de e-mails. Clique em "Return to SES console".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u4cw9nxs3kaa3wdu2y02.png)

Retornando à guia "SMTP settings", encontraremos as informações essenciais para a configuração da nossa aplicação, incluindo o "SMTP endpoint", as configurações de "TLS" e "Port".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nv5srdbjjzthx7o8fx48.png)

## Etapa 05 - Criando credencial SMTP via credencial programática
Nesta etapa irei demonstrar como gerar uma credencial SMTP via credencial programática, para isso é necessário executar um script para transformar a Secret Key em uma credencial SMTP.
>NOTA: A credencial SMTP é gerada por região e só funciona para o Amazon SES daquela região, você pode utilizar a mesma Secret Key para gerar credencial SMTP para outras regiões.

Acesse a console AWS e acesse o serviço "IAM".

No menu lateral a esquerda, clique em "Users".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b6obgiw67w1kt0uk1io6.png)

Clique em "Create user".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qckcn6d81st55fwmh1nq.png)

Em "User name", defina um nome para o seu usuário e clique em "Next".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w2uhqbva8qcqtvuqm86s.png)

Iremos definir as permissões depois, apenas clique em "Next".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2078w9c40fzr5xyw604n.png)

Clique em "Create user".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5l34ad8ounev4r1fs1vp.png)

Clique no usuário que acabamos de criar.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3ox74jsgbela4nlf8qcg.png)

Clique em "Add permissions" e em seguida clique em "Create inline policy".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0frolv8ziaqc4uxjulu1.png)

Altere o "Policy editor" para "JSON".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mbms49j1kpqx0u01mn7u.png)

Cole o seguinte JSON no "Policy editor" e clique em "Next".
```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ses:SendRawEmail",
            "Resource": "*"
        }
    ]
}
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/14v6j2k0whx8bwlb4f5q.png)

Defina um nome para a Policy e clique em "Create policy".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i463nkdhc2h5pmmhtkmp.png)

Clique na aba "Security credentials".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kfnfn1q3n65m0v2qi65v.png)

Em "Access keys", clique em "Create access key".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mjne03zab19nkhu0zk2d.png)

Escolha a "Use case" como "Other" e clique em "Next".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t6updyn7grzgjpkzfqja.png)

Clique em "Create access key".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9qu603zwscjg54or8obd.png)

Salve a "Access key" e a "Secret access key" gerada em um local seguro, clique em "Done".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/una25w9lqabcgk0a6m43.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tt7yp54on1vg6ilv8nx3.png)

Agora, precisamos converter nossa "Secret access key" em uma credencial SMTP.

Utilizei um Linux com Ubuntu 22.04. Primeiro, instalei o python3 e, em seguida, criei o arquivo com o script em python.
Ao executar o script, forneça a "Secret access key" e, em seguida, indique a região para a qual deseja gerar a credencial SMTP. Neste tutorial, estamos usando a região us-east-1.
```bash
apt-get update
apt-get install python3 -y
vim /tmp/ses.py
```

Script:
```python
#!/usr/bin/env python3

import hmac
import hashlib
import base64
import argparse

SMTP_REGIONS = [
    "us-east-2",  # US East (Ohio)
    "us-east-1",  # US East (N. Virginia)
    "us-west-2",  # US West (Oregon)
    "ap-south-1",  # Asia Pacific (Mumbai)
    "ap-northeast-2",  # Asia Pacific (Seoul)
    "ap-southeast-1",  # Asia Pacific (Singapore)
    "ap-southeast-2",  # Asia Pacific (Sydney)
    "ap-northeast-1",  # Asia Pacific (Tokyo)
    "ca-central-1",  # Canada (Central)
    "eu-central-1",  # Europe (Frankfurt)
    "eu-west-1",  # Europe (Ireland)
    "eu-west-2",  # Europe (London)
    "eu-south-1",  # Europe (Milan)
    "eu-north-1",  # Europe (Stockholm)
    "sa-east-1",  # South America (Sao Paulo)
    "us-gov-west-1",  # AWS GovCloud (US)
]

# These values are required to calculate the signature. Do not change them.
DATE = "11111111"
SERVICE = "ses"
MESSAGE = "SendRawEmail"
TERMINAL = "aws4_request"
VERSION = 0x04


def sign(key, msg):
    return hmac.new(key, msg.encode("utf-8"), hashlib.sha256).digest()


def calculate_key(secret_access_key, region):
    if region not in SMTP_REGIONS:
        raise ValueError(f"The {region} Region doesn't have an SMTP endpoint.")

    signature = sign(("AWS4" + secret_access_key).encode("utf-8"), DATE)
    signature = sign(signature, region)
    signature = sign(signature, SERVICE)
    signature = sign(signature, TERMINAL)
    signature = sign(signature, MESSAGE)
    signature_and_version = bytes([VERSION]) + signature
    smtp_password = base64.b64encode(signature_and_version)
    return smtp_password.decode("utf-8")


def main():
    parser = argparse.ArgumentParser(
        description="Convert a Secret Access Key to an SMTP password."
    )
    parser.add_argument("secret", help="The Secret Access Key to convert.")
    parser.add_argument(
        "region",
        help="The AWS Region where the SMTP password will be used.",
        choices=SMTP_REGIONS,
    )
    args = parser.parse_args()
    print(calculate_key(args.secret, args.region))


if __name__ == "__main__":
    main()
```

Executando o script:
>NOTA: A saída do script será a sua credencial SMTP.

```bash
python3 /tmp/ses.py AedgghOlpaoKFYZ+5w/aoAo/BEBb/1z9RQ2V4N9W us-east-1
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dgprh8ar0sm1jjh23ki5.png)

## Etapa 06 - Testando envio de e-mail via AWS Console
Agora vamos realizar um teste de envio de e-mail utilizando a própria Console da AWS.

Acesse a console AWS e acesse o serviço "Amazon Simple Email Service".

No menu lateral a esquerda, clique em "Verified identities".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d5kemny2whkuk1reyace.png)

Clique no seu domínio.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/51njz5er1rjbzuhqaogo.png)

Clique no botão "Send test email".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kchuedze9xrb0i02n9pz.png)

Em "Email format", selecione "Formatted".

Em "From-address", digite o nome do email que irá enviar a mensagem.

Em "Scenario", selecione "Custom".

Em "Custom recipient", digite o e-mail do destinatário, quem irá receber o nosso e-mail de teste.

Em "Subject", digite um assunto para o e-mail.

Em "Body", digite uma mensagem de teste.

Clique em "Send test email".
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8iomg037v9ah0a6xfqqp.png)

Veja as informações extraida do e-mail de teste que acabamos de enviar:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l49l17pmg8l8wu1ao3ih.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pv10mmofh77jkuriyscl.png)

Nosso e-mail foi enviado com sucesso!

## Etapa 07 - Testando envio de e-mail via script
Agora vamos realizar um teste de envio de e-mail utilizando um script bash utilizando a nossa credencial SMTP gerada na etapa 05.

Utilizei o mesmo Linux com Ubuntu 22.04, primeiro instalei o sendemail e em seguida criei o arquivo com o script em bash com permissão de execução.
Antes de executar o script, altere as variáveis conforme o seu ambiente.

```bash
apt-get update
apt-get install sendemail -y
vim /tmp/email.sh
```

Script:
```bash
#!/bin/bash

# STMP endpoint
SMTP_HOST="email-smtp.us-east-1.amazonaws.com"
# STARTTLS Port
SMTP_PORT="587"
# Access key
SMTP_USER="AKIAR3YIWCET3TYHQR6T"
# Credencial SMTP
SMTP_PASS="BHqSfD7stBQJf55FGQ9RoSeNK5h2E0LvOaQFl0DmZs2Z"
# Remetente
EMAIL_FROM="contato2@alfredocastro.com.br"
# Destinatário
EMAIL_TO="alfredotavio@gmail.com"
# Assunto
SUBJECT="Teste de Envio 2"
# Mensagem
echo "E-mail de teste 2" | \
        sendemail -o tls=yes -f ${EMAIL_FROM} -u ${SUBJECT} -t ${EMAIL_TO} -s ${SMTP_HOST}:${SMTP_PORT} -xu ${SMTP_USER} -xp ${SMTP_PASS}
```

Executando o script:
```bash
chmod +x /tmp/email.sh
/tmp/email.sh
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f58j5gx7su9c1ws5vr1q.png)

Veja as informações extraida do e-mail de teste que acabamos de enviar utilizando nosso script em bash:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/29qwqoj5qcgmh9l62yp2.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xovjopih7bqc7dp491sc.png)

Espero tê-lo ajudado! Se houver alguma dúvida, não hesite em entrar em contato.