Amazon RDS for Oracle 인스턴스가 이메일을 전송하록 구성하려면 어떻게 해야 합니까?

최종 업데이트 날짜: 2021년 11월 16일

Amazon Relational Database Service(Amazon RDS) for Oracle DB 인스턴스가 이메일을 전송하도록 구성하려고 합니다.

간략한 설명

Amazon RDS for Oracle 인스턴스에서 이메일을 전송하려면 UTL_MAIL 또는 UTL_SMTP 패키지를 사용할 수 있습니다.

  • RDS for Oracle과 함께 UTL_MAIL을 사용하려면 인스턴스와 연결된 기본이 아닌 옵션 그룹에 UTL_MAIL 옵션을 추가해야 합니다. UTL_MAIL 구성에 대한 자세한 내용은 ORACLE UTL_MAIL을 참조하세요.
  • RDS for Oracle과 함께 UTL_SMTP를 사용하려면 Amazon Simple Email Service(Amazon SES)를 사용하여 온프레미스 머신이나 Amazon Elastic Compute Cloud(Amazon EC2) 인스턴스에서 SMTP 서버를 구성해야 합니다. 이 경우 RDS for Oracle에서 SMTP 서버로의 연결이 올바르게 구성되어 있는지 확인합니다.

이 문서에서는 Amazon SES를 사용하여 UTL_SMTP 패키지를 통해 이메일을 전송하도록 DB 인스턴스를 구성하는 방법을 중점적으로 다룹니다.

사전 요구 사항으로 RDS 인스턴스에서 Amazon SES 엔드포인트에 액세스할 수 있어야 합니다. RDS 인스턴스가 프라이빗 서브넷에서 실행되는 경우 서브넷의 라우팅 테이블에 NAT 게이트웨이를 추가해야 합니다. 이는 서브넷이 Amazon SES 엔드포인트와 통신하는 데 필요합니다. 서브넷의 라우팅 테이블을 확인하려면 Amazon VPC 콘솔을 열고 탐색 창에서 라우팅 테이블(Route Tables)을 선택합니다.

DB 인스턴스가 이메일을 전송하도록 구성하려면 다음을 수행합니다.

  1. SMTP 메일 서버를 설정합니다. 이 문서에서는 SMTP 메일 서버를 설정하는 데 Amazon SES를 사용합니다.
  2. Amazon EC2 인스턴스를 생성합니다. 그런 다음 적절한 인증서를 사용하여 Oracle 클라이언트와 전자 지갑을 구성합니다.
  3. 지갑을 Amazon Simple Storage Service(Amazon S3) 버킷에 업로드합니다.
  4. S3 통합을 사용하여 Amazon S3 버킷에서 RDS 서버로 지갑을 다운로드합니다.
  5. 사용자에게 필요한 권한을 부여하고(사용자가 마스터가 아닌 경우) 필요한 액세스 제어 목록(ACL)을 생성합니다.
  6. Amazon SES 자격 증명과 이 문서에 제공된 절차를 사용하여 이메일을 전송합니다.

해결 방법

Amazon SES를 사용하여 SMTP 메일 서버 설정

Amazon EC2 인스턴스를 생성하고 Oracle 클라이언트와 지갑 구성

1.    Amazon EC2 Linux 인스턴스를 생성합니다.

2.    Oracle 클라이언트를 설치합니다. Amazon RDS 인스턴스와 동일한 버전을 사용하는 것이 바람직합니다. 이 문서에서는 Oracle 버전 19c를 사용합니다. Oracle 19c 클라이언트를 다운로드할 수 있습니다. Oracle 데이터베이스 19c(19.3)를 참조하세요. 이 버전에는 orapki 유틸리티도 함께 제공됩니다.

3.    AWS Command Line Interface(AWS CLI)를 설치합니다.

4.    EC2 인스턴스의 RDS 보안 그룹에서 데이터베이스 포트에 대한 연결을 허용합니다. 두 인스턴스가 모두 동일한 VPC를 사용하는 경우 프라이빗 IP 주소를 통한 연결을 허용합니다.

5.    EC2 인스턴스에 연결합니다.

6.    다음 명령을 실행하여 AmazonRootCA1 인증서를 다운로드합니다.

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

7.    다음 명령을 실행하여 지갑을 생성합니다.

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

지갑을 Amazon S3에 업로드

1.    다음 명령을 실행하여 지갑을 Amazon S3 버킷에 업로드합니다.

참고: S3 통합이 작동하려면 S3 버킷이 RDS 인스턴스와 동일한 리전에 있어야 합니다.

aws s3 cp cwallet.sso s3://testbucket/
2.    다음 명령을 실행하여 파일이 업로드되었는지 확인합니다.
aws s3 ls testbucket

S3 통합을 사용하여 RDS 서버로 지갑 다운로드

1.    Amazon RDS 콘솔을 사용하여 옵션 그룹을 생성합니다.

2.    생성한 옵션 그룹에 S3_INTEGRATION 옵션을 추가합니다. 이 작업은 Amazon S3에서 RDS 인스턴스로 지갑 파일을 다운로드하는 데 필요합니다.

3.    생성한 옵션 그룹을 사용하여 RDS for Oracle 인스턴스를 생성합니다.

4.    AWS Identity and Access Management(IAM) 정책 및 역할을 생성하여 S3 통합을 준비합니다. 자세한 내용은 Amazon RDS for Oracle을 Amazon S3와 통합하기 위한 사전 요구 사항을 참조하세요.

5.    다음 명령을 실행하여 S3 버킷에서 RDS로 지갑을 다운로드합니다.

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

사용자에게 필요한 권한을 부여하고 필요한 ACL을 생성합니다.

참고: RDS for Oracle에 대해 마스터가 아닌 사용자를 사용하는 경우 이 단계가 필요합니다.

다음 명령을 실행하여 마스터가 아닌 사용자에게 필요한 권한을 부여합니다.

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

다음 명령을 실행하여 필요한 ACL을 생성합니다.

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;
/

이메일 전송

다음 절차를 실행하여 이메일을 전송합니다.

참고: 절차에서 다음과 같이 값을 변경합니다.

  • example-server를 사용자의 SMTP 메일 서버 이름으로 변경
  • example-sender-email을 발신자 이메일 주소로 변경
  • example-receiver-email을 수신자 이메일 주소로 변경
  • example-SMTP-username을 자신의 사용자 이름으로 변경
  • example-SMTP-password를 자신의 암호로 변경

온프레미스 또는 Amazon EC2를 SMTP 서버로 사용하는 경우 Amazon SES 대신 온프레미스 또는 EC2 서버와 관련된 정보를 사용해야 합니다.

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;
/

오류 문제 해결

ORA-29279: SMTP 사용자 이름 또는 암호가 정확하지 않으면 다음 오류가 발생할 수 있습니다.

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

이 문제를 해결하려면 SMTP 자격 증명이 정확한지 확인하세요.

ORA-00942: 이메일 패키지를 마스터가 아닌 사용자가 실행하는 경우 다음 오류가 발생할 수 있습니다.

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

이 문제를 해결하려면 다음 절차를 실행하여 사용자에게 필요한 권한을 부여합니다.

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

ORA-24247: ACL이 대상 호스트에 할당되지 않았거나 사용자에게 대상 호스트에 액세스하는 데 필요한 권한이 없는 경우 다음 오류가 발생할 수 있습니다.

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

이 문제를 해결하려면 다음 절차를 실행하여 ACL을 생성하고 호스트에 ACL을 할당합니다.

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;
/

Oracle 설명서의 이메일 전송 서비스 개요

이 문서가 도움이 되었나요?


결제 또는 기술 지원이 필요하세요?