Como configuro minha instância do Amazon RDS for Oracle para enviar e-mails?

Data da última atualização: 16/11/2021

Quero configurar meu Amazon Relational Database Service (Amazon RDS) para que a instância de banco de dados Oracle envie e-mails.

Breve descrição

Para enviar um e-mail de uma instância do Amazon RDS for Oracle, você pode usar pacotes UTL_MAIL ou UTL_SMTP.

  • Para usar UTL_MAIL com o RDS for Oracle, você deve adicionar a opção UTL_MAIL no grupo de opções não padrão anexado à instância. Para obter mais informações sobre como configurar o UTL_MAIL, consulte ORACLE UTL_MAIL.
  • Para usar o UTL_SMTP com o RDS for Oracle, é necessário configurar um servidor SMTP em uma máquina on-premises ou instância do Amazon Elastic Compute Cloud (Amazon EC2) usando o Amazon Simple Email Service (Amazon SES). Nesse caso, certifique-se de que a conectividade do RDS for Oracle com o servidor SMTP esteja configurada corretamente.

Este artigo se concentra na configuração da instância de banco de dados para enviar e-mails por meio do pacote UTL_SMTP usando o Amazon SES.

Como pré-requisito, certifique-se de que o endpoint do Amazon SES esteja acessível a partir da instância do RDS. Se a instância do RDS for executada em uma sub-rede privada, você deverá adicionar um gateway NAT à tabela de rotas da sub-rede. Isso é necessário para que a sub-rede se comunique com o endpoint do Amazon SES. Para verificar a tabela de rotas da sub-rede, abra o console da Amazon VPC e escolha Route Tables (Tabela de rotas) no painel de navegação.

Para configurar sua instância de banco de dados para enviar e-mails, faça o seguinte:

  1. Configure o servidor de e-mail SMTP. Neste artigo, o Amazon SES é usado para configurar o servidor de e-mail SMTP.
  2. Crie uma instância do Amazon EC2. Em seguida, configure o cliente e a carteira Oracle usando o certificado apropriado.
  3. Carregue a carteira para um bucket do Amazon Simple Storage Service (Amazon S3).
  4. Baixe a carteira do bucket do Amazon S3 para o servidor RDS usando a integração do S3.
  5. Conceda os privilégios necessários ao usuário (se o usuário não for um usuário mestre) e crie as listas de controle de acesso (ACLs) necessárias.
  6. Envie o e-mail usando as credenciais do Amazon SES e o procedimento fornecido neste artigo.

Resolução

Configurar o servidor de e-mail SMTP usando o Amazon SES

Crie uma instância do Amazon EC2 e configure o cliente e a carteira Oracle

1.    Crie uma instância Linux do Amazon EC2.

2.    Instale o cliente Oracle, de preferência da mesma versão da instância do Amazon RDS. Neste artigo, é utilizado o Oracle versão 19c. Para baixar o cliente Oracle 19c, consulte Oracle Database 19c (19.3). Essa versão também vem com o utilitário orapki.

3.    Instale a AWS Command Line Interface (AWS CLI).

4.    Permita a conexão na porta do banco de dados no grupo de segurança do RDS a partir da instância do EC2. Se ambas as instâncias usarem a mesma VPC, permita a conexão por meio de seus endereços IP privados.

5.    Conecte-se à instância do EC2.

6.    Execute o seguinte comando para baixar o certificado AmazonRootCA1.

wget https://www.amazontrust.com/repository/AmazonRootCA1.pem

7.    Execute os seguintes comandos para criar a carteira:

orapki wallet create -wallet . -auto_login_only
orapki wallet add -wallet . -trusted_cert -cert AmazonRootCA1.pem -auto_login_only

Carregue a carteira para o Amazon S3

1.    Execute o seguinte comando para carregar a carteira para um bucket do Amazon S3:

Observação: certifique-se de que o bucket do S3 esteja na mesma região que a instância do RDS para que a integração do S3 funcione.

aws s3 cp cwallet.sso s3://testbucket/
2.    Execute o seguinte comando para verificar se o arquivo foi carregado com êxito:
aws s3 ls testbucket

Baixe a carteira para o servidor RDS usando a integração do S3

1.    Crie um grupo de opções usando o console do Amazon RDS.

2.    Adicione a opção S3_INTEGRATION ao grupo de opções que você criou. Isso é necessário para baixar o arquivo da carteira do Amazon S3 para a instância do RDS.

3.    Crie uma instância do RDS for Oracle com o grupo de opções que você criou.

4.    Prepare-se para a integração do S3 criando uma política e uma função do AWS Identity and Access Management (IAM). Para obter mais informações, consulte Pré-requisitos para integração do Amazon RDS for Oracle com o Amazon S3.

5.    Execute os seguintes comandos para baixar a carteira no RDS a partir do bucket do S3:

SQL> exec rdsadmin.rdsadmin_util.create_directory('S3_WALLET');

PL/SQL procedure successfully completed.

SQL> SELECT OWNER,DIRECTORY_NAME,DIRECTORY_PATH FROM DBA_DIRECTORIES WHERE DIRECTORY_NAME='S3_WALLET';

OWNER             DIRECTORY_NAME            DIRECTORY_PATH
-------------------- ------------------------------ ----------------------------------------------------------------------
SYS             S3_WALLET                /rdsdbdata/userdirs/01

SQL> SELECT
rdsadmin.rdsadmin_s3_tasks.download_from_s3(
p_bucket_name => 'testbucket',
p_directory_name => 'S3_WALLET',
P_S3_PREFIX => 'cwallet.sso')  AS TASK_ID FROM DUAL;

TASK_ID
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1625291989577-52

SQL> SELECT filename FROM table(RDSADMIN.RDS_FILE_UTIL.LISTDIR('S3_WALLET'));

FILENAME
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
01/
cwallet.sso

Conceda os privilégios necessários ao usuário e crie as ACLs necessárias

Observação: você precisará desta etapa se não estiver usando o usuário mestre do RDS for Oracle.

Execute o seguinte comando para conceder os privilégios necessários ao usuário não mestre:

begin
    rdsadmin.rdsadmin_util.grant_sys_object(
        p_obj_name  => 'DBA_DIRECTORIES',
        p_grantee   => 'example-username',
        p_privilege => 'SELECT');
end;
/

Execute os seguintes comandos para criar as ACLs necessárias:

BEGIN
DBMS_NETWORK_ACL_ADMIN.CREATE_ACL (
acl => 'ses_1.xml',
description => 'AWS SES ACL 1',
principal => 'TEST',
is_grant => TRUE,
privilege => 'connect');
COMMIT;
END;
/
BEGIN
DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL (
acl => 'ses_1.xml',
host => 'example-host');
COMMIT;
END;
/

Enviar o e-mail

Execute o seguinte procedimento para enviar o e-mail:

Observação: certifique-se de substituir os seguintes valores no procedimento:

  • example-server pelo nome do seu servidor de e-mail SMTP
  • example-sender-email pelo endereço de e-mail do remetente
  • example-receiver-email pelo endereço de e-mail do destinatário
  • example-SMTP-username por seu nome de usuário
  • example-SMTP-password por sua senha

Se você estiver usando on-premises ou o Amazon EC2 como o servidor SMTP, certifique-se de usar as informações relacionadas ao servidor on-premises ou do EC2 em vez do Amazon SES.

declare
l_smtp_server varchar2(1024) := 'example-server';
l_smtp_port number := 587;
l_wallet_dir varchar2(128) := 'S3_WALLET';
l_from varchar2(128) := 'example-sender-email';
l_to varchar2(128)  := 'example-receiver-email';
l_user varchar2(128) := 'example-SMTP-username';
l_password varchar2(128) := 'example-SMTP-password';
l_subject varchar2(128) := 'Test mail from RDS Oracle';
l_wallet_path varchar2(4000);
l_conn utl_smtp.connection;
l_reply utl_smtp.reply;
l_replies utl_smtp.replies;
begin
select 'file:/' || directory_path into l_wallet_path from dba_directories where directory_name=l_wallet_dir;
--open a connection
l_reply := utl_smtp.open_connection(
host => l_smtp_server,
port => l_smtp_port,
c => l_conn,
wallet_path => l_wallet_path,
secure_connection_before_smtp => false);
dbms_output.put_line('opened connection, received reply ' || l_reply.code || '/' || l_reply.text);
--get supported configs from server
l_replies := utl_smtp.ehlo(l_conn, 'localhost');
for r in 1..l_replies.count loop
dbms_output.put_line('ehlo (server config) : ' || l_replies(r).code || '/' || l_replies(r).text);
end loop;
--STARTTLS
l_reply := utl_smtp.starttls(l_conn);
dbms_output.put_line('starttls, received reply ' || l_reply.code || '/' || l_reply.text);
--
l_replies := utl_smtp.ehlo(l_conn, 'localhost');
for r in 1..l_replies.count loop
dbms_output.put_line('ehlo (server config) : ' || l_replies(r).code || '/' || l_replies(r).text);
end loop;
utl_smtp.auth(l_conn, l_user, l_password, utl_smtp.all_schemes);
utl_smtp.mail(l_conn, l_from);
utl_smtp.rcpt(l_conn, l_to);
utl_smtp.open_data (l_conn);
utl_smtp.write_data(l_conn, 'Date: ' || to_char(SYSDATE, 'DD-MON-YYYY HH24:MI:SS') || utl_tcp.crlf);
utl_smtp.write_data(l_conn, 'From: ' || l_from || utl_tcp.crlf);
utl_smtp.write_data(l_conn, 'To: ' || l_to || utl_tcp.crlf);
utl_smtp.write_data(l_conn, 'Subject: ' || l_subject || utl_tcp.crlf);
utl_smtp.write_data(l_conn, '' || utl_tcp.crlf);
utl_smtp.write_data(l_conn, 'Test message.' || utl_tcp.crlf);
utl_smtp.close_data(l_conn);

l_reply := utl_smtp.quit(l_conn);
exception
when others then
utl_smtp.quit(l_conn);
raise;
end;
/

Solucionar problemas

ORA-29279: o erro a seguir poderá ser exibido se o seu nome de usuário ou senha do SMTP estiver incorreto

ORA-29279: SMTP permanent error: 535 Authentication Credentials Invalid

Para resolver esse problema, verifique se as credenciais SMTP estão corretas.

ORA-00942: o seguinte erro poderá ocorrer se o pacote de e-mail for executado por um usuário não mestre:

PL/SQL: ORA-00942: table or view does not exist

Para resolver esse problema, conceda as permissões necessárias ao usuário executando o seguinte procedimento:

begin
    rdsadmin.rdsadmin_util.grant_sys_object(
        p_obj_name  => 'DBA_DIRECTORIES',
        p_grantee   => 'example-username',
        p_privilege => 'SELECT');
end;
/

ORA-24247: o seguinte erro poderá ocorrer se uma ACL não estiver atribuída ao host de destino ou o usuário não tiver os privilégios necessários para acessar o host de destino:

ORA-24247: network access denied by access control list (ACL)

Para resolver esse problema, crie uma ACL e a atribua ao host executando o seguinte procedimento:

BEGIN
DBMS_NETWORK_ACL_ADMIN.CREATE_ACL (
acl => 'ses_1.xml',
description => 'AWS SES ACL 1',
principal => 'TEST',
is_grant => TRUE,
privilege => 'connect');
COMMIT;
END;
/

BEGIN
DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL (
acl => 'ses_1.xml',
host => 'example-host');
COMMIT;
END;
/

Documentação da Oracle referente à Visão geral do serviço de entrega de e-mail

Este artigo ajudou?


Precisa de ajuda com faturamento ou suporte técnico?