

# Securing Oracle DB instance connections
<a name="Oracle.Concepts.RestrictedDBAPrivileges"></a>

Amazon RDS for Oracle supports SSL/TLS encrypted connections and also the Oracle Native Network Encryption (NNE) option to encrypt connections between your application and your Oracle DB instance. For more information about the Oracle Native Network Encryption option, see [Oracle native network encryption](Appendix.Oracle.Options.NetworkEncryption.md). 

**Topics**
+ [Using SSL with an RDS for Oracle DB instance](Oracle.Concepts.SSL.md)
+ [Updating applications to connect to Oracle DB instances using new SSL/TLS certificates](ssl-certificate-rotation-oracle.md)
+ [Using native network encryption with an RDS for Oracle DB instance](Oracle.Concepts.NNE.md)
+ [Configuring Kerberos authentication for Amazon RDS for Oracle](oracle-kerberos.md)
+ [Configuring UTL\$1HTTP access using certificates and an Oracle wallet](Oracle.Concepts.ONA.md)

# Using SSL with an RDS for Oracle DB instance
<a name="Oracle.Concepts.SSL"></a>

Secure Sockets Layer (SSL) is an industry-standard protocol for securing network connections between client and server. After SSL version 3.0, the name was changed to Transport Layer Security (TLS), but we still often refer to the protocol as SSL. Amazon RDS supports SSL encryption for Oracle DB instances. Using SSL, you can encrypt a connection between your application client and your Oracle DB instance. SSL support is available in all AWS Regions for Oracle.

To enable SSL encryption for an Oracle DB instance, add the Oracle SSL option to the option group associated with the DB instance. Amazon RDS uses a second port, as required by Oracle, for SSL connections. Doing this allows both clear text and SSL-encrypted communication to occur at the same time between a DB instance and an Oracle client. For example, you can use the port with clear text communication to communicate with other resources inside a VPC while using the port with SSL-encrypted communication to communicate with resources outside the VPC. 

For more information, see [Oracle Secure Sockets Layer](Appendix.Oracle.Options.SSL.md). 

**Note**  
You can't use both SSL and Oracle native network encryption (NNE) on the same DB instance. Before you can use SSL encryption, you must disable any other connection encryption. 

# Updating applications to connect to Oracle DB instances using new SSL/TLS certificates
<a name="ssl-certificate-rotation-oracle"></a>

As of January 13, 2023, Amazon RDS has published new Certificate Authority (CA) certificates for connecting to your RDS DB instances using Secure Socket Layer or Transport Layer Security (SSL/TLS). Following, you can find information about updating your applications to use the new certificates.

This topic can help you to determine whether any client applications use SSL/TLS to connect to your DB instances. 

**Important**  
When you change the certificate for an Amazon RDS for Oracle DB instance, only the database listener is restarted. The DB instance isn't restarted. Existing database connections are unaffected, but new connections will encounter errors for a brief period while the listener is restarted.  
We recommend that you restart your Oracle DB to prevent any connection errors.

**Note**  
For client applications that use SSL/TLS to connect to your DB instances, you must update your client application trust stores to include the new CA certificates. 

After you update your CA certificates in the client application trust stores, you can rotate the certificates on your DB instances. We strongly recommend testing these procedures in a development or staging environment before implementing them in your production environments.

For more information about certificate rotation, see [Rotating your SSL/TLS certificate](UsingWithRDS.SSL-certificate-rotation.md). For more information about downloading certificates, see [Using SSL/TLS to encrypt a connection to a DB instance or cluster ](UsingWithRDS.SSL.md). For information about using SSL/TLS with Oracle DB instances, see [Oracle Secure Sockets Layer](Appendix.Oracle.Options.SSL.md).

**Topics**
+ [Finding out whether applications connect using SSL](#ssl-certificate-rotation-oracle.determining)
+ [Updating your application trust store](#ssl-certificate-rotation-oracle.updating-trust-store)
+ [Example Java code for establishing SSL connections](#ssl-certificate-rotation-oracle.java-example)

## Finding out whether applications connect using SSL
<a name="ssl-certificate-rotation-oracle.determining"></a>

If your Oracle DB instance uses an option group with the `SSL` option added, you might be using SSL. Check this by following the instructions in [Listing the options and option settings for an option group](USER_WorkingWithOptionGroups.md#USER_WorkingWithOptionGroups.ListOption). For information about the `SSL` option, see [Oracle Secure Sockets Layer](Appendix.Oracle.Options.SSL.md).

Check the listener log to determine whether there are SSL connections. The following is sample output in a listener log.

```
date time * (CONNECT_DATA=(CID=(PROGRAM=program)
(HOST=host)(USER=user))(SID=sid)) * 
(ADDRESS=(PROTOCOL=tcps)(HOST=host)(PORT=port)) * establish * ORCL * 0
```

When `PROTOCOL` has the value `tcps` for an entry, it shows an SSL connection. However, when `HOST` is `127.0.0.1`, you can ignore the entry. Connections from `127.0.0.1` are a local management agent on the DB instance. These connections aren't external SSL connections. Therefore, you have applications connecting using SSL if you see listener log entries where `PROTOCOL` is `tcps` and `HOST` is *not* `127.0.0.1`.

To check the listener log, you can publish the log to Amazon CloudWatch Logs. For more information, see [Publishing Oracle logs to Amazon CloudWatch Logs](USER_LogAccess.Concepts.Oracle.md#USER_LogAccess.Oracle.PublishtoCloudWatchLogs).

## Updating your application trust store
<a name="ssl-certificate-rotation-oracle.updating-trust-store"></a>

You can update the trust store for applications that use SQL\$1Plus or JDBC for SSL/TLS connections.

### Updating your application trust store for SQL\$1Plus
<a name="ssl-certificate-rotation-oracle.updating-trust-store.sqlplus"></a>

You can update the trust store for applications that use SQL\$1Plus for SSL/TLS connections.

**Note**  
When you update the trust store, you can retain older certificates in addition to adding the new certificates.

**To update the trust store for SQL\$1Plus applications**

1. Download the new root certificate that works for all AWS Regions and put the file in the `ssl_wallet` directory.

   For information about downloading the root certificate, see [Using SSL/TLS to encrypt a connection to a DB instance or cluster ](UsingWithRDS.SSL.md).

1. Run the following command to update the Oracle wallet.

   ```
   prompt>orapki wallet add -wallet $ORACLE_HOME/ssl_wallet -trusted_cert -cert
         $ORACLE_HOME/ssl_wallet/ssl-cert.pem -auto_login_only
   ```

   Replace the file name with the one that you downloaded.

1. Run the following command to confirm that the wallet was updated successfully.

   ```
   prompt>orapki wallet display -wallet $ORACLE_HOME/ssl_wallet                     
   ```

   Your output should contain the following.

   ```
   Trusted Certificates: 
   Subject: CN=Amazon RDS Root 2019 CA,OU=Amazon RDS,O=Amazon Web Services\, Inc.,L=Seattle,ST=Washington,C=US
   ```

### Updating your application trust store for JDBC
<a name="ssl-certificate-rotation-oracle.updating-trust-store.jdbc"></a>

You can update the trust store for applications that use JDBC for SSL/TLS connections.

For information about downloading the root certificate, see [Using SSL/TLS to encrypt a connection to a DB instance or cluster ](UsingWithRDS.SSL.md).

For sample scripts that import certificates, see [Sample script for importing certificates into your trust store](UsingWithRDS.SSL-certificate-rotation.md#UsingWithRDS.SSL-certificate-rotation-sample-script).

## Example Java code for establishing SSL connections
<a name="ssl-certificate-rotation-oracle.java-example"></a>

The following code example shows how to set up the SSL connection using JDBC.

```
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
 
public class OracleSslConnectionTest {
    private static final String DB_SERVER_NAME = "<dns-name-provided-by-amazon-rds>";
    private static final Integer SSL_PORT = "<ssl-option-port-configured-in-option-group>";
    private static final String DB_SID = "<oracle-sid>";
    private static final String DB_USER = "<user name>";
    private static final String DB_PASSWORD = "<password>";
    // This key store has only the prod root ca.
    private static final String KEY_STORE_FILE_PATH = "<file-path-to-keystore>";
    private static final String KEY_STORE_PASS = "<keystore-password>";
 
    public static void main(String[] args) throws SQLException {
        final Properties properties = new Properties();
        final String connectionString = String.format(
                "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCPS)(HOST=%s)(PORT=%d))(CONNECT_DATA=(SID=%s)))",
                DB_SERVER_NAME, SSL_PORT, DB_SID);
        properties.put("user", DB_USER);
        properties.put("password", DB_PASSWORD);
        properties.put("oracle.jdbc.J2EE13Compliant", "true");
        properties.put("javax.net.ssl.trustStore", KEY_STORE_FILE_PATH);
        properties.put("javax.net.ssl.trustStoreType", "JKS");
        properties.put("javax.net.ssl.trustStorePassword", KEY_STORE_PASS);
        final Connection connection = DriverManager.getConnection(connectionString, properties);
        // If no exception, that means handshake has passed, and an SSL connection can be opened
    }
}
```

**Important**  
After you have determined that your database connections use SSL/TLS and have updated your application trust store, you can update your database to use the rds-ca-rsa2048-g1 certificates. For instructions, see step 3 in [Updating your CA certificate by modifying your DB instance or cluster](UsingWithRDS.SSL-certificate-rotation.md#UsingWithRDS.SSL-certificate-rotation-updating).

# Using native network encryption with an RDS for Oracle DB instance
<a name="Oracle.Concepts.NNE"></a>

Oracle Database offers two ways to encrypt data over the network: native network encryption (NNE) and Transport Layer Security (TLS). NNE is a proprietary Oracle security feature, whereas TLS is an industry standard. RDS for Oracle supports NNE for all editions of Oracle Database.

NNE has the following advantages over TLS:
+ You can control NNE on the client and server using settings in the NNE option:
  + `SQLNET.ALLOW_WEAK_CRYPTO_CLIENTS` and `SQLNET.ALLOW_WEAK_CRYPTO`
  + `SQLNET.CRYPTO_CHECKSUM_CLIENT` and `SQLNET.CRYPTO_CHECKSUM_SERVER`
  + `SQLNET.CRYPTO_CHECKSUM_TYPES_CLIENT` and `SQLNET.CRYPTO_CHECKSUM_TYPES_SERVER`
  + `SQLNET.ENCRYPTION_CLIENT` and `SQLNET.ENCRYPTION_SERVER`
  + `SQLNET.ENCRYPTION_TYPES_CLIENT` and `SQLNET.ENCRYPTION_TYPES_SERVER`
+ In most cases, you don't need to configure your client or server. In contrast, TLS requires you to configure both client and server.
+ No certificates are required. In TLS, the server requires a certificate (which eventually expires), and the client requires a trusted root certificate for the certificate authority that issued the server’s certificate.

To enable NNE encryption for an Oracle DB instance, add the Oracle NNE option to the option group associated with the DB instance. For more information, see [Oracle native network encryption](Appendix.Oracle.Options.NetworkEncryption.md). 

**Note**  
You can't use both NNE and TLS on the same DB instance.

# Configuring Kerberos authentication for Amazon RDS for Oracle
<a name="oracle-kerberos"></a>

You can use Kerberos authentication to authenticate users when they connect to your Amazon RDS for Oracle DB instance. In this configuration, your DB instance works with AWS Directory Service for Microsoft Active Directory, also called AWS Managed Microsoft AD. When users authenticate with an RDS for Oracle DB instance joined to the trusting domain, authentication requests are forwarded to the directory that you create with Directory Service.

Keeping all of your credentials in the same directory can save you time and effort. You have a centralized place for storing and managing credentials for multiple database instances. A directory can also improve your overall security profile.

# Region and version availability
<a name="oracle-kerberos-setting-up.RegionVersionAvailability"></a>

Feature availability and support varies across specific versions of each database engine, and across AWS Regions. For more information on version and Region availability of RDS for Oracle with Kerberos authentication, see [Supported Regions and DB engines for Kerberos authentication in Amazon RDS](Concepts.RDS_Fea_Regions_DB-eng.Feature.KerberosAuthentication.md).

**Note**  
Kerberos authentication isn't supported for DB instance classes that are deprecated for RDS for Oracle DB instances. For more information, see [RDS for Oracle DB instance classes](Oracle.Concepts.InstanceClasses.md).

**Topics**
+ [Region and version availability](oracle-kerberos-setting-up.RegionVersionAvailability.md)
+ [Setting up Kerberos for Oracle DB instances](oracle-kerberos-setting-up.md)
+ [Managing a DB instance in a domain](oracle-kerberos-managing.md)
+ [Connecting to Oracle with Kerberos authentication](oracle-kerberos-connecting.md)

# Setting up Kerberos for Oracle DB instances
<a name="oracle-kerberos-setting-up"></a>

Use AWS Directory Service for Microsoft Active Directory, also called AWS Managed Microsoft AD, to set up Kerberos authentication for an Oracle DB instance. To set up Kerberos authentication, complete the following steps:
+ [Step 1: Create a directory using the AWS Managed Microsoft AD](#oracle-kerberos.setting-up.create-directory)
+ [Step 2: Create a trust](#oracle-kerberos.setting-up.create-forest-trust)
+ [Step 3: Configure IAM permissions for Amazon RDS](#oracle-kerberos.setting-up.CreateIAMRole)
+ [Step 4: Create and configure users](#oracle-kerberos.setting-up.create-users)
+ [Step 5: Enable cross-VPC traffic between the directory and the DB instance](#oracle-kerberos.setting-up.vpc-peering)
+ [Step 6: Create or modify an Oracle DB instance](#oracle-kerberos.setting-up.create-modify)
+ [Step 7: Create Kerberos authentication Oracle logins](#oracle-kerberos.setting-up.create-logins)
+ [Step 8: Configure an Oracle client](#oracle-kerberos.setting-up.configure-oracle-client)

**Note**  
During the setup, RDS creates an Oracle database user named *managed\$1service\$1user*@*example.com* with the `CREATE SESSION` privilege, where *example.com* is your domain name. This user corresponds to the user that Directory Service creates inside your Managed Active Directory. Periodically, RDS uses the credentials provided by the Directory Service to log in to your Oracle database. Afterwards, RDS immediately destroys the ticket cache.

## Step 1: Create a directory using the AWS Managed Microsoft AD
<a name="oracle-kerberos.setting-up.create-directory"></a>

Directory Service creates a fully managed Active Directory in the AWS Cloud. When you create an AWS Managed Microsoft AD directory, Directory Service creates two domain controllers and Domain Name System (DNS) servers on your behalf. The directory servers are created in different subnets in a VPC. This redundancy helps make sure that your directory remains accessible even if a failure occurs. 

When you create an AWS Managed Microsoft AD directory, Directory Service performs the following tasks on your behalf: 
+ Sets up an Active Directory within the VPC. 
+ Creates a directory administrator account with the user name Admin and the specified password. You use this account to manage your directory. 
**Note**  
Be sure to save this password. Directory Service doesn't store it. You can reset it, but you can't retrieve it. 
+ Creates a security group for the directory controllers. 

When you launch an AWS Managed Microsoft AD, AWS creates an Organizational Unit (OU) that contains all of your directory's objects. This OU has the NetBIOS name that you typed when you created your directory and is located in the domain root. The domain root is owned and managed by AWS. 

The Admin account that was created with your AWS Managed Microsoft AD directory has permissions for the most common administrative activities for your OU: 
+ Create, update, or delete users 
+ Add resources to your domain such as file or print servers, and then assign permissions for those resources to users in your OU 
+ Create additional OUs and containers 
+ Delegate authority 
+ Restore deleted objects from the Active Directory Recycle Bin 
+ Run AD and DNS Windows PowerShell modules on the Active Directory Web Service 

The Admin account also has rights to perform the following domain-wide activities: 
+ Manage DNS configurations (add, remove, or update records, zones, and forwarders) 
+ View DNS event logs 
+ View security event logs 

To create the directory, use the AWS Management Console, the AWS CLI, or the Directory Service API. Make sure to open the relevant outbound ports on the directory security group so that the directory can communicate with the Oracle DB instance.

**To create a directory with AWS Managed Microsoft AD**

1. Sign in to the AWS Management Console and open the Directory Service console at [https://console.aws.amazon.com/directoryservicev2/](https://console.aws.amazon.com/directoryservicev2/).

1. In the navigation pane, choose **Directories** and choose **Set up Directory**. 

1. Choose **AWS Managed Microsoft AD**. AWS Managed Microsoft AD is the only option that you can currently use with Amazon RDS. 

1.  Enter the following information:   
**Directory DNS name**  
The fully qualified name for the directory, such as **corp.example.com**.   
**Directory NetBIOS name**  
The short name for the directory, such as **CORP**.   
**Directory description**  
(Optional) A description for the directory.   
**Admin password**  
The password for the directory administrator. The directory creation process creates an administrator account with the user name Admin and this password.   
The directory administrator password and can't include the word "admin." The password is case-sensitive and must be 8–64 characters in length. It must also contain at least one character from three of the following four categories:   
   + Lowercase letters (a–z) 
   + Uppercase letters (A–Z) 
   + Numbers (0–9) 
   + Non-alphanumeric characters (\$1\$1@\$1\$1%^&\$1\$1-\$1=`\$1\$1()\$1\$1[]:;"'<>,.?/)   
**Confirm password**  
The administrator password retyped. 

1. Choose **Next**.

1.  Enter the following information in the **Networking** section and then choose **Next**:   
**VPC**  
The VPC for the directory. Create the Oracle DB instance in this same VPC.   
**Subnets**  
Subnets for the directory servers. The two subnets must be in different Availability Zones. 

1.  Review the directory information and make any necessary changes. When the information is correct, choose **Create directory**.   
![\[Directory details page during creation\]](http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/images/WinAuth2.png)

It takes several minutes for the directory to be created. When it has been successfully created, the **Status** value changes to **Active**. 

To see information about your directory, choose the directory name in the directory listing. Note the **Directory ID** value because you need this value when you create or modify your Oracle DB instance. 

![\[Directory details page\]](http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/images/WinAuth3.png)


## Step 2: Create a trust
<a name="oracle-kerberos.setting-up.create-forest-trust"></a>

If you plan to use AWS Managed Microsoft AD only, move on to [Step 3: Configure IAM permissions for Amazon RDS](#oracle-kerberos.setting-up.CreateIAMRole).

To enable Kerberos authentication using your self-managed Active Directory, you must create a forest trust relationship between your self-managed Active Directory and the AWS Managed Microsoft AD created in the previous step. The trust can be one-way, where the AWS Managed Microsoft AD trusts the self-managed Active Directory. The trust can also be two-way, where both Active Directories trust each other. For more information about setting up forest trusts using Directory Service, see [When to create a trust relationship](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_setup_trust.html) in the *Directory Service Administration Guide*.

## Step 3: Configure IAM permissions for Amazon RDS
<a name="oracle-kerberos.setting-up.CreateIAMRole"></a>

To call Directory Service for you, Amazon RDS requires an IAM role that uses the managed IAM policy `AmazonRDSDirectoryServiceAccess`. This role allows Amazon RDS to make calls to the Directory Service.

**Note**  
For the role to allow access, the AWS Security Token Service (AWS STS) endpoint must be activated in the correct AWS Region for your AWS account. AWS STS endpoints are active by default in all AWS Regions, and you can use them without any further actions. For more information, see [Activating and deactivating AWS STS in an AWS Region](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html#sts-regions-activate-deactivate) in the *IAM User Guide*.

### Creating an IAM role
<a name="oracle-kerberos.setting-up.CreateIAMRole.create-role"></a>

When you create a DB instance using the AWS Management Console, and the console user has the `iam:CreateRole` permission, the console creates `rds-directoryservice-kerberos-access-role` automatically. Otherwise, you must create the IAM role manually. When you create an IAM role manually, choose `Directory Service`, and attach the AWS managed policy `AmazonRDSDirectoryServiceAccess` to it. 

For more information about creating IAM roles for a service, see [Creating a role to delegate permissions to an AWS service](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html) in the *IAM User Guide*.

**Note**  
The IAM role used for Windows Authentication for RDS for Microsoft SQL Server can't be used for RDS for Oracle.

### Creating an IAM trust policy manually
<a name="oracle-kerberos.setting-up.CreateIAMRole.trust-policy"></a>

Optionally, you can create resource policies with the required permissions instead of using the managed IAM policy `AmazonRDSDirectoryServiceAccess`. Specify both `directoryservice.rds.amazonaws.com` and `rds.amazonaws.com` as principals.

To limit the permissions that Amazon RDS gives another service for a specific resource, we recommend using the [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn) and [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount) global condition context keys in resource policies. The most effective way to protect against the confused deputy problem is to use the `aws:SourceArn` global condition context key with the full ARN of an Amazon RDS resource. For more information, see [Preventing cross-service confused deputy problems](cross-service-confused-deputy-prevention.md).

The following example shows how you can use the `aws:SourceArn` and `aws:SourceAccount` global condition context keys in Amazon RDS to prevent the confused deputy problem.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "directoryservice.rds.amazonaws.com",
          "rds.amazonaws.com"
        ]
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "ArnLike": {
          "aws:SourceArn": "arn:aws:rds:us-east-1:123456789012:db:mydbinstance"
        },
        "StringEquals": {
          "aws:SourceAccount": "123456789012"
        }
      }
    }
  ]
}
```

------

For opt-in Regions, you must also include a service principal for that Region in the form of `directoryservice.rds.region_name.amazonaws.com`. For example, in the Africa (Cape Town) Region, use the following trust policy:

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "directoryservice.rds.amazonaws.com",
          "directoryservice.rds.af-south-1.amazonaws.com",
          "rds.amazonaws.com"
        ]
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "ArnLike": {
          "aws:SourceArn": "arn:aws:rds:af-south-1:123456789012:db:mydbinstance"
        },
        "StringEquals": {
          "aws:SourceAccount": "123456789012"
        }
      }
    }
  ]
}
```

------

The role must also have the following IAM policy.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Action": [
        "ds:DescribeDirectories",
        "ds:AuthorizeApplication",
        "ds:UnauthorizeApplication",
        "ds:GetAuthorizedApplicationDetails"
      ],
    "Effect": "Allow",
    "Resource": "*"
    }
  ]
}
```

------

## Step 4: Create and configure users
<a name="oracle-kerberos.setting-up.create-users"></a>

 You can create users with the Active Directory Users and Computers tool, which is one of the Active Directory Domain Services and Active Directory Lightweight Directory Services tools. In this case, *users* are individual people or entities that have access to your directory. 

To create users in an Directory Service directory, you must be connected to a Windows-based Amazon EC2 instance that is a member of the Directory Service directory. At the same time, you must be logged in as a user that has privileges to create users. For more information about creating users in your Microsoft Active Directory, see [Manage users and groups in AWS Managed Microsoft AD](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_manage_users_groups.html) in the *Directory Service Administration Guide*.

## Step 5: Enable cross-VPC traffic between the directory and the DB instance
<a name="oracle-kerberos.setting-up.vpc-peering"></a>

If you plan to locate the directory and the DB instance in the same VPC, skip this step and move on to [Step 6: Create or modify an Oracle DB instance](#oracle-kerberos.setting-up.create-modify).

If you plan to locate the directory and the DB instance in different AWS accounts or VPCs, configure cross-VPC traffic using VPC peering or [AWS Transit Gateway](https://docs.aws.amazon.com/vpc/latest/tgw/what-is-transit-gateway.html). The following procedure enables traffic between VPCs using VPC peering. Follow the instructions in [What is VPC peering?](https://docs.aws.amazon.com/vpc/latest/peering/Welcome.html) in the *Amazon Virtual Private Cloud Peering Guide*.

**To enable cross-VPC traffic using VPC peering**

1. Set up appropriate VPC routing rules to ensure that network traffic can flow both ways.

1. Ensure that the DB instance's security group can receive inbound traffic from the directory's security group. For more information, see [ Best practices for AWS Managed Microsoft AD](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_best_practices.html) in the *Directory Service Administration Guide*.

1. Ensure that there is no network access control list (ACL) rule to block traffic.

If a different AWS account owns the directory, you must share the directory.

**To share the directory between AWS accounts**

1. Start sharing the directory with the AWS account that the DB instance will be created in by following the instructions in [Tutorial: Sharing your AWS Managed Microsoft AD directory for seamless EC2 Domain-join](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_tutorial_directory_sharing.html) in the *Directory Service Administration Guide*.

1. Sign in to the Directory Service console using the account for the DB instance, and ensure that the domain has the `SHARED` status before proceeding.

1. While signed into the Directory Service console using the account for the DB instance, note the **Directory ID** value. You use this directory ID to join the DB instance to the domain.

## Step 6: Create or modify an Oracle DB instance
<a name="oracle-kerberos.setting-up.create-modify"></a>

Create or modify an Oracle DB instance for use with your directory. You can use the console, CLI, or RDS API to associate a DB instance with a directory. You can do this in one of the following ways:
+ Create a new Oracle DB instance using the console, the [ create-db-instance](https://docs.aws.amazon.com/cli/latest/reference/rds/create-db-instance.html) CLI command, or the [CreateDBInstance](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_CreateDBInstance.html) RDS API operation.

  For instructions, see [Creating an Amazon RDS DB instance](USER_CreateDBInstance.md).
+ Modify an existing Oracle DB instance using the console, the [modify-db-instance](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-instance.html) CLI command, or the [ModifyDBInstance](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_ModifyDBInstance.html) RDS API operation.

  For instructions, see [Modifying an Amazon RDS DB instance](Overview.DBInstance.Modifying.md).
+ Restore an Oracle DB instance from a DB snapshot using the console, the [ restore-db-instance-from-db-snapshot](https://docs.aws.amazon.com/cli/latest/reference/rds/restore-db-instance-from-db-snapshot.html) CLI command, or the [ RestoreDBInstanceFromDBSnapshot](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_RestoreDBInstanceFromDBSnapshot.html) RDS API operation.

  For instructions, see [Restoring to a DB instance](USER_RestoreFromSnapshot.md).
+ Restore an Oracle DB instance to a point-in-time using the console, the [ restore-db-instance-to-point-in-time](https://docs.aws.amazon.com/cli/latest/reference/rds/restore-db-instance-to-point-in-time.html) CLI command, or the [ RestoreDBInstanceToPointInTime](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_RestoreDBInstanceToPointInTime.html) RDS API operation.

  For instructions, see [Restoring a DB instance to a specified time for Amazon RDS](USER_PIT.md).

Kerberos authentication is only supported for Oracle DB instances in a VPC. The DB instance can be in the same VPC as the directory, or in a different VPC. When you create or modify the DB instance, do the following:
+ Provide the domain identifier (`d-*` identifier) that was generated when you created your directory.
+ Provide the name of the IAM role that you created.
+ Ensure that the DB instance security group can receive inbound traffic from the directory security group and send outbound traffic to the directory.

When you use the console to create a DB instance, choose **Password and Kerberos authentication** in the **Database authentication** section. Choose **Browse Directory** and then select the directory, or choose **Create a new directory**.

![\[Kerberos authentication setting when creating a DB instance\]](http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/images/kerberos-authentication.png)


When you use the console to modify or restore a DB instance, choose the directory in the **Kerberos authentication** section, or choose **Create a new directory**.

![\[Kerberos authentication setting when modifying or restoring a DB instance\]](http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/images/kerberos-auth-modify-restore.png)


When you use the AWS CLI, the following parameters are required for the DB instance to be able to use the directory that you created:
+ For the `--domain` parameter, use the domain identifier ("d-\$1" identifier) generated when you created the directory.
+ For the `--domain-iam-role-name` parameter, use the role you created that uses the managed IAM policy `AmazonRDSDirectoryServiceAccess`.

For example, the following CLI command modifies a DB instance to use a directory.

For Linux, macOS, or Unix:

```
aws rds modify-db-instance \
    --db-instance-identifier mydbinstance \
    --domain d-ID \
    --domain-iam-role-name role-name
```

For Windows:

```
aws rds modify-db-instance ^
    --db-instance-identifier mydbinstance ^
    --domain d-ID ^
    --domain-iam-role-name role-name
```

**Important**  
If you modify a DB instance to enable Kerberos authentication, reboot the DB instance after making the change.

**Note**  
*MANAGED\$1SERVICE\$1USER* is a service account whose name is randomly generated by Directory Service for RDS. During the Kerberos authentication setup, RDS for Oracle creates a user with the same name and assigns it the `CREATE SESSION` privilege. The Oracle DB user is identified externally as *MANAGED\$1SERVICE\$1USER@EXAMPLE.COM*, where *EXAMPLE.COM* is the name of your domain. Periodically, RDS uses the credentials provided by the Directory Service to log in to your Oracle database. Afterward, RDS immediately destroys the ticket cache.

## Step 7: Create Kerberos authentication Oracle logins
<a name="oracle-kerberos.setting-up.create-logins"></a>

Use the Amazon RDS master user credentials to connect to the Oracle DB instance as you do any other DB instance. The DB instance is joined to the AWS Managed Microsoft AD domain. Thus, you can provision Oracle logins and users from the Microsoft Active Directory users in your domain. To manage database permissions, you grant and revoke standard Oracle permissions to these logins.

**To allow a Microsoft Active Directory user to authenticate with Oracle**

1. Connect to the Oracle DB instance using your Amazon RDS master user credentials.

1. Create an externally authenticated user in Oracle database.

   In the following example, replace `KRBUSER@CORP.EXAMPLE.COM` with the user name and domain name.

   ```
   CREATE USER "KRBUSER@CORP.EXAMPLE.COM" IDENTIFIED EXTERNALLY; 
   GRANT CREATE SESSION TO "KRBUSER@CORP.EXAMPLE.COM";
   ```

   Users (both humans and applications) from your domain can now connect to the Oracle DB instance from a domain joined client machine using Kerberos authentication. 

## Step 8: Configure an Oracle client
<a name="oracle-kerberos.setting-up.configure-oracle-client"></a>

To configure an Oracle client, meet the following requirements:
+ Create a configuration file named krb5.conf (Linux) or krb5.ini (Windows) to point to the domain. Configure the Oracle client to use this configuration file.
+ Verify that traffic can flow between the client host and Directory Service over DNS port 53 over TCP/UDP, Kerberos ports (88 and 464 for managed Directory Service) over TCP, and LDAP port 389 over TCP.
+ Verify that traffic can flow between the client host and the DB instance over the database port.

Following is sample content for AWS Managed Microsoft AD.

```
[libdefaults]
 default_realm = EXAMPLE.COM
[realms]
 EXAMPLE.COM = {
  kdc = example.com
  admin_server = example.com
 }
[domain_realm]
 .example.com = CORP.EXAMPLE.COM
 example.com = CORP.EXAMPLE.COM
```

Following is sample content for on-premise Microsoft AD. In your krb5.conf or krb5.ini file, replace *on-prem-ad-server-name* with the name of your on-premises AD server.

```
[libdefaults]
 default_realm = ONPREM.COM
[realms]
 AWSAD.COM = {
  kdc = awsad.com
  admin_server = awsad.com
 }
 ONPREM.COM = {
  kdc = on-prem-ad-server-name
  admin_server = on-prem-ad-server-name
 }
[domain_realm]
 .awsad.com = AWSAD.COM
 awsad.com= AWSAD.COM
 .onprem.com = ONPREM.COM
 onprem.com= ONPREM.COM
```

**Note**  
After you configure your krb5.ini or krb5.conf file, we recommend that you reboot the server.

The following is sample sqlnet.ora content for a SQL\$1Plus configuration:

```
SQLNET.AUTHENTICATION_SERVICES=(KERBEROS5PRE,KERBEROS5)
SQLNET.KERBEROS5_CONF=path_to_krb5.conf_file
```

For an example of a SQL Developer configuration, see [Document 1609359.1](https://support.oracle.com/epmos/faces/DocumentDisplay?id=1609359.1) from Oracle Support.

# Managing a DB instance in a domain
<a name="oracle-kerberos-managing"></a>

You can use the console, the CLI, or the RDS API to manage your DB instance and its relationship with your Microsoft Active Directory. For example, you can associate a Microsoft Active Directory to enable Kerberos authentication. You can also disassociate a Microsoft Active Directory to disable Kerberos authentication. You can also move a DB instance to be externally authenticated by one Microsoft Active Directory to another.

For example, using the CLI, you can do the following: 
+ To reattempt enabling Kerberos authentication for a failed membership, use the [modify-db-instance](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-instance.html) CLI command and specify the current membership's directory ID for the `--domain` option.
+ To disable Kerberos authentication on a DB instance, use the [modify-db-instance](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-instance.html) CLI command and specify `none` for the `--domain` option.
+ To move a DB instance from one domain to another, use the [modify-db-instance](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-instance.html) CLI command and specify the domain identifier of the new domain for the `--domain` option.

## Viewing the status of domain membership
<a name="oracle-kerberos-managing.understanding"></a>

After you create or modify your DB instance, the DB instance becomes a member of the domain. You can view the status of the domain membership for the DB instance in the console or by running the [describe-db-instances](https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-instances.html) CLI command. The status of the DB instance can be one of the following: 
+ `kerberos-enabled` – The DB instance has Kerberos authentication enabled.
+ `enabling-kerberos` – AWS is in the process of enabling Kerberos authentication on this DB instance.
+ `pending-enable-kerberos` – Enabling Kerberos authentication is pending on this DB instance.
+ `pending-maintenance-enable-kerberos` – AWS will attempt to enable Kerberos authentication on the DB instance during the next scheduled maintenance window.
+ `pending-disable-kerberos` – Disabling Kerberos authentication is pending on this DB instance.
+ `pending-maintenance-disable-kerberos` – AWS will attempt to disable Kerberos authentication on the DB instance during the next scheduled maintenance window.
+ `enable-kerberos-failed` – A configuration problem has prevented AWS from enabling Kerberos authentication on the DB instance. Correct the configuration problem before reissuing the command to modify the DB instance.
+ `disabling-kerberos` – AWS is in the process of disabling Kerberos authentication on this DB instance.

A request to enable Kerberos authentication can fail because of a network connectivity issue or an incorrect IAM role. If the attempt to enable Kerberos authentication fails when you create or modify a DB instance, make sure that you're using the correct IAM role. Then modify the DB instance to join the domain.

**Note**  
Only Kerberos authentication with Amazon RDS for Oracle sends traffic to the domain's DNS servers. All other DNS requests are treated as outbound network access on your DB instances running Oracle. For more information about outbound network access with Amazon RDS for Oracle, see [Setting up a custom DNS server](Appendix.Oracle.CommonDBATasks.System.md#Appendix.Oracle.CommonDBATasks.CustomDNS).

## Force-rotating Kerberos keys
<a name="oracle-kerberos-managing.rotation"></a>

A secret key is shared between AWS Managed Microsoft AD and Amazon RDS for Oracle DB instance. This key is rotated automatically every 45 days. You can use the following Amazon RDS procedure to force the rotation of this key.

```
SELECT rdsadmin.rdsadmin_kerberos_auth_tasks.rotate_kerberos_keytab AS TASK_ID FROM DUAL;
```

**Note**  
In a read replica configuration, this procedure is available only on the source DB instance and not on the read replica.

The `SELECT` statement returns the ID of the task in a `VARCHAR2` data type. You can view the status of an ongoing task in a bdump file. The bdump files are located in the `/rdsdbdata/log/trace` directory. Each bdump file name is in the following format.

```
dbtask-task-id.log
```

You can view the result by displaying the task's output file.

```
SELECT text FROM table(rdsadmin.rds_file_util.read_text_file('BDUMP','dbtask-task-id.log'));
```

Replace *`task-id`* with the task ID returned by the procedure.

**Note**  
Tasks are executed asynchronously.

# Connecting to Oracle with Kerberos authentication
<a name="oracle-kerberos-connecting"></a>

This section assumes that you have set up your Oracle client as described in [Step 8: Configure an Oracle client](oracle-kerberos-setting-up.md#oracle-kerberos.setting-up.configure-oracle-client). To connect to the Oracle DB with Kerberos authentication, log in using the Kerberos authentication type. For example, after launching Oracle SQL Developer, choose **Kerberos Authentication** as the authentication type, as shown in the following example. 

![\[Shows the New/Select Database Connection dialog box in Oracle SQL Developer. The Kerberos Authentication checkbox is selected.\]](http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/images/ora-kerberos-auth.png)


To connect to Oracle with Kerberos authentication with SQL\$1Plus:

1. At a command prompt, run the following command:

   ```
   kinit username
   ```

   Replace *`username`* with the user name and, at the prompt, enter the password stored in the Microsoft Active Directory for the user.

1. Open SQL\$1Plus and connect using the DNS name and port number for the Oracle DB instance.

   For more information about connecting to an Oracle DB instance in SQL\$1Plus, see [Connecting to your DB instance using SQL\$1Plus](USER_ConnectToOracleInstance.SQLPlus.md).

**Tip**  
If you are using a native Windows cache, you can also set the `SQLNET.KERBEROS5_CC_NAME` parameter to `OSMSFT://` or `MSLSA` in the sqlnet.ora file to use the credentials stored in the Microsoft Active Directory.

# Configuring UTL\$1HTTP access using certificates and an Oracle wallet
<a name="Oracle.Concepts.ONA"></a>

Amazon RDS supports outbound network access on your RDS for Oracle DB instances. To connect your DB instance to the network, you can use the following PL/SQL packages:

`UTL_HTTP`  
This package makes HTTP calls from SQL and PL/SQL. You can use it to access data on the Internet over HTTP. For more information, see [UTL\$1HTTP](https://docs.oracle.com/en/database/oracle/oracle-database/19/arpls/UTL_HTTP.html#GUID-A85D2D1F-90FC-45F1-967F-34368A23C9BB) in the Oracle documentation.

`UTL_TCP`  
This package provides TCP/IP client-side access functionality in PL/SQL. This package is useful to PL/SQL applications that use Internet protocols and email. For more information, see [UTL\$1TCP](https://docs.oracle.com/en/database/oracle/oracle-database/19/arpls/UTL_TCP.html#GUID-348AFFE8-78B2-4217-AE73-384F46A1D292) in the Oracle documentation.

`UTL_SMTP`  
This package provides interfaces to the SMTP commands that enable a client to dispatch emails to an SMTP server. For more information, see [UTL\$1SMTP](https://docs.oracle.com/en/database/oracle/oracle-database/19/arpls/UTL_SMTP.html#GUID-F0065C52-D618-4F8A-A361-7B742D44C520) in the Oracle documentation.

By completing the following tasks, you can configure `UTL_HTTP.REQUEST` to work with websites that require client authentication certificates during the SSL handshake. You can also configure password authentication for `UTL_HTTP` access to websites by modifying the Oracle wallet generation commands and the `DBMS_NETWORK_ACL_ADMIN.APPEND_WALLET_ACE` procedure. For more information, see [ DBMS\$1NETWORK\$1ACL\$1ADMIN](https://docs.oracle.com/en/database/oracle/oracle-database/21/arpls/DBMS_NETWORK_ACL_ADMIN.html) in the Oracle Database documentation.

**Note**  
You can adapt the following tasks for `UTL_SMTP`, which enables you to send emails over SSL/TLS (including [Amazon Simple Email Service](https://aws.amazon.com/ses/)).

**Topics**
+ [Considerations when configuring UTL\$1HTTP access](#utl_http-considerations)
+ [Step 1: Get the root certificate for a website](#website-root-certificate)
+ [Step 2: Create an Oracle wallet](#create-oracle-wallet)
+ [Step 3: Download your Oracle wallet to your RDS for Oracle instance](#upload-wallet-to-instance)
+ [Step 4: Grant user permissions for the Oracle wallet](#config-oracle-wallet-user)
+ [Step 5: Configure access to a website from your DB instance](#config-website-access)
+ [Step 6: Test connections from your DB instance to a website](#test_utl_http)

## Considerations when configuring UTL\$1HTTP access
<a name="utl_http-considerations"></a>

Before configuring access, consider the following:
+ You can use SMTP with the UTL\$1MAIL option. For more information, see [Oracle UTL\$1MAIL](Oracle.Options.UTLMAIL.md).
+ The Domain Name Server (DNS) name of the remote host can be any of the following: 
  + Publicly resolvable.
  + The endpoint of an Amazon RDS DB instance.
  + Resolvable through a custom DNS server. For more information, see [Setting up a custom DNS server](Appendix.Oracle.CommonDBATasks.System.md#Appendix.Oracle.CommonDBATasks.CustomDNS). 
  + The private DNS name of an Amazon EC2 instance in the same VPC or a peered VPC. In this case, make sure that the name is resolvable through a custom DNS server. Alternatively, to use the DNS provided by Amazon, you can enable the `enableDnsSupport` attribute in the VPC settings and enable DNS resolution support for the VPC peering connection. For more information, see [DNS support in your VPC](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html#vpc-dns-support) and [Modifying your VPC peering connection](https://docs.aws.amazon.com/vpc/latest/peering/working-with-vpc-peering.html#modify-peering-connections). 
  + To connect securely to remote SSL/TLS resources, we recommend that you create and upload customized Oracle wallets. By using the Amazon S3 integration with Amazon RDS for Oracle feature, you can download a wallet from Amazon S3 into Oracle DB instances. For information about Amazon S3 integration for Oracle, see [Amazon S3 integration](oracle-s3-integration.md).
+ You can establish database links between Oracle DB instances over an SSL/TLS endpoint if the Oracle SSL option is configured for each instance. No further configuration is required. For more information, see [Oracle Secure Sockets Layer](Appendix.Oracle.Options.SSL.md).

## Step 1: Get the root certificate for a website
<a name="website-root-certificate"></a>

For the RDS for Oracle DB instance to make secure connections to a website, add the root CA certificate. Amazon RDS uses the root certificate to sign the website certificate to the Oracle wallet.

You can get the root certificate in various ways. For example, you can do the following:

1. Use a web server to visit the website secured by the certificate.

1. Download the root certificate that was used for signing.

For AWS services, root certificates typically reside in the [Amazon trust services repository](https://www.amazontrust.com/repository/).

## Step 2: Create an Oracle wallet
<a name="create-oracle-wallet"></a>

Create an Oracle wallet that contains both the web server certificates and the client authentication certificates. The RDS Oracle instance uses the web server certificate to establish a secure connection to the website. The website needs the client certificate to authenticate the Oracle database user.

You might want to configure secure connections without using client certificates for authentication. In this case, you can skip the Java keystore steps in the following procedure.

**To create an Oracle wallet**

1. Place the root and client certificates in a single directory, and then change into this directory.

1. Convert the .p12 client certificate to the Java keystore.
**Note**  
If you're not using client certificates for authentication, you can skip this step.

   The following example converts the client certificate named *client\$1certificate.p12* to the Java keystore named *client\$1keystore.jks*. The keystore is then included in the Oracle wallet. The keystore password is *P12PASSWORD*.

   ```
   orapki wallet pkcs12_to_jks -wallet ./client_certificate.p12 -jksKeyStoreLoc ./client_keystore.jks -jksKeyStorepwd P12PASSWORD
   ```

1. Create a directory for your Oracle wallet that is different from the certificate directory.

   The following example creates the directory `/tmp/wallet`.

   ```
   mkdir -p /tmp/wallet
   ```

1. Create an Oracle wallet in your wallet directory.

   The following example sets the Oracle wallet password to *P12PASSWORD*, which is the same password used by the Java keystore in a previous step. Using the same password is convenient, but not necessary. The `-auto_login` parameter turns on the automatic login feature, so that you don’t need to specify a password every time you want to access it.
**Note**  
Specify a password other than the prompt shown here as a security best practice.

   ```
   orapki wallet create -wallet /tmp/wallet -pwd P12PASSWORD -auto_login
   ```

1. Add the Java keystore to your Oracle wallet.
**Note**  
If you're not using client certificates for authentication, you can skip this step.

   The following example adds the keystore *client\$1keystore.jks* to the Oracle wallet named */tmp/wallet*. In this example, you specify the same password for the Java keystore and the Oracle wallet.

   ```
   orapki wallet jks_to_pkcs12 -wallet /tmp/wallet -pwd P12PASSWORD -keystore ./client_keystore.jks -jkspwd P12PASSWORD
   ```

1. Add the root certificate for your target website to the Oracle wallet.

   The following example adds a certificate named *Root\$1CA.cer*.

   ```
   orapki wallet add -wallet /tmp/wallet -trusted_cert -cert ./Root_CA.cer -pwd P12PASSWORD
   ```

1. Add any intermediate certificates.

   The following example adds a certificate named *Intermediate.cer*. Repeat this step as many times as need to load all intermediate certificates.

   ```
   orapki wallet add -wallet /tmp/wallet -trusted_cert -cert ./Intermediate.cer -pwd P12PASSWORD
   ```

1. Confirm that your newly created Oracle wallet has the required certificates.

   ```
   orapki wallet display -wallet /tmp/wallet -pwd P12PASSWORD
   ```

## Step 3: Download your Oracle wallet to your RDS for Oracle instance
<a name="upload-wallet-to-instance"></a>

In this step, you upload your Oracle wallet to Amazon S3, and then download the wallet from Amazon S3 to your RDS for Oracle instance.

**To download your Oracle wallet to your RDS for Oracle DB instance**

1. Complete the prerequisites for Amazon S3 integration with Oracle, and add the `S3_INTEGRATION` option to your Oracle DB instance. Ensure that the IAM role for the option has access to the Amazon S3 bucket you are using.

   For more information, see [Amazon S3 integration](oracle-s3-integration.md).

1. Log in to your DB instance as the master user, and then create an Oracle directory to hold the Oracle wallet.

   The following example creates an Oracle directory named *WALLET\$1DIR*.

   ```
   EXEC rdsadmin.rdsadmin_util.create_directory('WALLET_DIR');
   ```

   For more information, see [Creating and dropping directories in the main data storage space](Appendix.Oracle.CommonDBATasks.Misc.md#Appendix.Oracle.CommonDBATasks.NewDirectories).

1. Upload the Oracle wallet to your Amazon S3 bucket.

   You can use any supported upload technique.

1. If you're re-uploading an Oracle wallet, delete the existing wallet. Otherwise, skip to the next step.

   The following example removes the existing wallet, which is named *cwallet.sso*.

   ```
   EXEC UTL_FILE.FREMOVE ('WALLET_DIR','cwallet.sso');
   ```

1. Download the Oracle wallet from your Amazon S3 bucket to the Oracle DB instance.

   The following example downloads the wallet named *cwallet.sso* from the Amazon S3 bucket named *my\$1s3\$1bucket* to the DB instance directory named *WALLET\$1DIR*.

   ```
   SELECT rdsadmin.rdsadmin_s3_tasks.download_from_s3(
         p_bucket_name    =>  'my_s3_bucket', 
         p_s3_prefix      =>  'cwallet.sso', 
         p_directory_name =>  'WALLET_DIR') 
      AS TASK_ID FROM DUAL;
   ```

1. (Optional) Download a password-protected Oracle wallet.

   Download this wallet only if you want to require a password for every use of the wallet. The following example downloads password-protected wallet *ewallet.p12*.

   ```
   SELECT rdsadmin.rdsadmin_s3_tasks.download_from_s3(
         p_bucket_name    =>  'my_s3_bucket', 
         p_s3_prefix      =>  'ewallet.p12', 
         p_directory_name =>  'WALLET_DIR') 
      AS TASK_ID FROM DUAL;
   ```

1. Check the status of your DB task.

   Substitute the task ID returned from the preceding steps for *dbtask-1234567890123-4567.log* in the following example.

   ```
   SELECT TEXT FROM TABLE(rdsadmin.rds_file_util.read_text_file('BDUMP','dbtask-1234567890123-4567.log'));
   ```

1. Check the contents of the directory that you're using to store the Oracle wallet.

   ```
   SELECT * FROM TABLE(rdsadmin.rds_file_util.listdir(p_directory => 'WALLET_DIR'));
   ```

   For more information, see [Listing files in a DB instance directory](Appendix.Oracle.CommonDBATasks.Misc.md#Appendix.Oracle.CommonDBATasks.ListDirectories).

## Step 4: Grant user permissions for the Oracle wallet
<a name="config-oracle-wallet-user"></a>

You can either create a new database user or configure an existing user. In either case, you must configure the user to access the Oracle wallet for secure connections and client authentication using certificates.

**To grant user permissions for the Oracle wallet**

1. Log in your RDS for Oracle DB instance as the master user.

1. If you don't want to configure an existing database user, create a new user. Otherwise, skip to the next step.

   The following example creates a database user named *my-user*.

   ```
   CREATE USER my-user IDENTIFIED BY my-user-pwd;
   GRANT CONNECT TO my-user;
   ```

1. Grant permission to your database user on the directory containing your Oracle wallet.

   The following example grants read access to user *my-user* on directory *WALLET\$1DIR*.

   ```
   GRANT READ ON DIRECTORY WALLET_DIR TO my-user;
   ```

1. Grant permission to your database user to use the `UTL_HTTP` package.

   The following PL/SQL program grants `UTL_HTTP` access to user *my-user*.

   ```
   BEGIN 
     rdsadmin.rdsadmin_util.grant_sys_object('UTL_HTTP', UPPER('my-user')); 
     END;
   /
   ```

1. Grant permission to your database user to use the `UTL_FILE` package.

   The following PL/SQL program grants `UTL_FILE` access to user *my-user*.

   ```
   BEGIN 
     rdsadmin.rdsadmin_util.grant_sys_object('UTL_FILE', UPPER('my-user')); 
     END;
   /
   ```

## Step 5: Configure access to a website from your DB instance
<a name="config-website-access"></a>

In this step, you configure your Oracle database user so that it can connect to your target website using `UTL_HTTP`, your uploaded Oracle Wallet, and the client certificate. For more information, see [Configuring Access Control to an Oracle Wallet ](https://docs.oracle.com/en/database/oracle/oracle-database/19/dbseg/managing-fine-grained-access-in-pl-sql-packages-and-types.html#GUID-0BCB5925-A40F-4507-95F9-5DA4A1919EBD) in the Oracle Database documentation.

**To configure access to a website from your RDS for Oracle DB instance**

1. Log in your RDS for Oracle DB instance as the master user.

1. Create a Host Access Control Entry (ACE) for your user and the target website on a secure port.

   The following example configures *my-user* to access *secret.encrypted-website.com* on secure port 443.

   ```
   BEGIN
     DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
       host       => 'secret.encrypted-website.com', 
       lower_port => 443,
       upper_port => 443,
       ace        => xs$ace_type(privilege_list => xs$name_list('http'),
                                 principal_name => 'my-user',
                                 principal_type => xs_acl.ptype_db)); 
                              -- If the program unit results in PLS-00201, set
                              -- the principal_type parameter to 2 as follows:
                              -- principal_type => 2));
   END;
   /
   ```
**Important**  
The preceding program unit can result in the following error: `PLS-00201: identifier 'XS_ACL' must be declared`. If this error is returned, replace the line that assigns a value to `principal_type` with the following line, and then rerun the program unit:  

   ```
   principal_type => 2));
   ```
For more information about constants in the PL/SQL package `XS_ACL`, see [https://docs.oracle.com/en/database/oracle/oracle-database/19/dbfsg/XS_ACL-package.html#GUID-A157FB28-FE23-4D30-AAEB-8224230517E7](https://docs.oracle.com/en/database/oracle/oracle-database/19/dbfsg/XS_ACL-package.html#GUID-A157FB28-FE23-4D30-AAEB-8224230517E7) in the Oracle Database documentation.

   For more information, see [Configuring Access Control for External Network Services ](https://docs.oracle.com/en/database/oracle/oracle-database/19/dbseg/managing-fine-grained-access-in-pl-sql-packages-and-types.html#GUID-3D5B66BC-0277-4887-9CD1-97DB44EB5213) in the Oracle Database documentation.

1. (Optional) Create an ACE for your user and target website on the standard port. 

   You might need to use the standard port if some web pages are served from the standard web server port (80) instead of the secure port (443).

   ```
   BEGIN
     DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
       host       => 'secret.encrypted-website.com', 
       lower_port => 80,
       upper_port => 80,
       ace        => xs$ace_type(privilege_list => xs$name_list('http'),
                                 principal_name => 'my-user',
                                 principal_type => xs_acl.ptype_db)); 
                              -- If the program unit results in PLS-00201, set
                              -- the principal_type parameter to 2 as follows:
                              -- principal_type => 2));
   END;
   /
   ```

1. Confirm that the access control entries exist.

   ```
   SET LINESIZE 150
   COLUMN HOST FORMAT A40
   COLUMN ACL FORMAT A50
   
   SELECT HOST, LOWER_PORT, UPPER_PORT, ACL
     FROM DBA_NETWORK_ACLS
   ORDER BY HOST;
   ```

1. Grant permission to your database user to use the `UTL_HTTP` package.

   The following PL/SQL program grants `UTL_HTTP` access to user *my-user*.

   ```
   BEGIN 
     rdsadmin.rdsadmin_util.grant_sys_object('UTL_HTTP', UPPER('my-user')); 
     END;
   /
   ```

1. Confirm that related access control lists exist.

   ```
   SET LINESIZE 150
   COLUMN ACL FORMAT A50
   COLUMN PRINCIPAL FORMAT A20
   COLUMN PRIVILEGE FORMAT A10
   
   SELECT ACL, PRINCIPAL, PRIVILEGE, IS_GRANT,
          TO_CHAR(START_DATE, 'DD-MON-YYYY') AS START_DATE,
          TO_CHAR(END_DATE, 'DD-MON-YYYY') AS END_DATE
     FROM DBA_NETWORK_ACL_PRIVILEGES
   ORDER BY ACL, PRINCIPAL, PRIVILEGE;
   ```

1. Grant permission to your database user to use certificates for client authentication and your Oracle wallet for connections.
**Note**  
If you're not using client certificates for authentication, you can skip this step.

   ```
   DECLARE
     l_wallet_path all_directories.directory_path%type;
   BEGIN
     SELECT DIRECTORY_PATH 
       INTO l_wallet_path 
       FROM ALL_DIRECTORIES
      WHERE UPPER(DIRECTORY_NAME)='WALLET_DIR';
     DBMS_NETWORK_ACL_ADMIN.APPEND_WALLET_ACE(
       wallet_path => 'file:/' || l_wallet_path,
       ace         =>  xs$ace_type(privilege_list => xs$name_list('use_client_certificates'),
                                   principal_name => 'my-user',
                                   principal_type => xs_acl.ptype_db));
   END;
   /
   ```

## Step 6: Test connections from your DB instance to a website
<a name="test_utl_http"></a>

In this step, you configure your database user so that it can connect to the website using `UTL_HTTP`, your uploaded Oracle Wallet, and the client certificate.

**To configure access to a website from your RDS for Oracle DB instance**

1. Log in your RDS for Oracle DB instance as a database user with `UTL_HTTP` permissions.

1. Confirm that a connection to your target website can resolve the host address.

   The following example gets the host address from *secret.encrypted-website.com*.

   ```
   SELECT UTL_INADDR.GET_HOST_ADDRESS(host => 'secret.encrypted-website.com')
     FROM DUAL;
   ```

1. Test a failed connection.

   The following query fails because `UTL_HTTP` requires the location of the Oracle wallet with the certificates.

   ```
   SELECT UTL_HTTP.REQUEST('secret.encrypted-website.com') FROM DUAL;
   ```

1. Test website access by using `UTL_HTTP.SET_WALLET` and selecting from `DUAL`.

   ```
   DECLARE
     l_wallet_path all_directories.directory_path%type;
   BEGIN
     SELECT DIRECTORY_PATH
       INTO l_wallet_path 
       FROM ALL_DIRECTORIES
      WHERE UPPER(DIRECTORY_NAME)='WALLET_DIR';
     UTL_HTTP.SET_WALLET('file:/' || l_wallet_path);
   END;
   /
   
   SELECT UTL_HTTP.REQUEST('secret.encrypted-website.com') FROM DUAL;
   ```

1. (Optional) Test website access by storing your query in a variable and using `EXECUTE IMMEDIATE`.

   ```
   DECLARE
     l_wallet_path all_directories.directory_path%type;
     v_webpage_sql VARCHAR2(1000);
     v_results     VARCHAR2(32767);
   BEGIN
     SELECT DIRECTORY_PATH
       INTO l_wallet_path 
       FROM ALL_DIRECTORIES
      WHERE UPPER(DIRECTORY_NAME)='WALLET_DIR';
     v_webpage_sql := 'SELECT UTL_HTTP.REQUEST(''secret.encrypted-website.com'', '''', ''file:/' ||l_wallet_path||''') FROM DUAL';
     DBMS_OUTPUT.PUT_LINE(v_webpage_sql);
     EXECUTE IMMEDIATE v_webpage_sql INTO v_results;
     DBMS_OUTPUT.PUT_LINE(v_results);
   END;
   /
   ```

1. (Optional) Find the file system location of your Oracle wallet directory.

   ```
   SELECT * FROM TABLE(rdsadmin.rds_file_util.listdir(p_directory => 'WALLET_DIR'));
   ```

   Use the output from the previous command to make an HTTP request. For example, if the directory is *rdsdbdata/userdirs/01*, run the following query.

   ```
   SELECT UTL_HTTP.REQUEST('https://secret.encrypted-website.com/', '', 'file://rdsdbdata/userdirs/01') 
   FROM   DUAL;
   ```