Oracle 安全套接字层 - Amazon Relational Database Service
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

Oracle 安全套接字层

通过向与数据库实例关联的选项组添加 Oracle SSL 选项,可实现针对 RDS for Oracle 数据库实例的 SSL 加密。根据 Oracle 的要求,Amazon RDS 使用另一个端口连接 SSL。此方法允许数据库实例与 SQL*Plus 之间能够同时进行明文通信和 SSL 加密通信。例如,您可以使用用于明文通信的端口与 VPC 内的其他资源通信,同时使用用于 SSL 加密通信的端口与 VPC 外部的资源通信。

注意

您可以在同一 RDS for Oracle 数据库实例上使用 SSL 或原生网络加密(NNE),但不能同时使用两者。如果您使用 SSL 加密,则必须禁用任何其他连接加密。有关更多信息,请参阅Oracle 本机网络加密

SSL/TLS 和 NNE 不再是 Oracle 高级安全的一部分。在 RDS for Oracle 中,您可以对以下数据库版本的所有许可版本使用 SSL 加密:

  • Oracle Database 21c (21.0.0)

  • Oracle Database 19c(19.0.0)

  • Oracle Database 12c 第 2 版(12.2)– 不再支持此版本

  • Oracle Database 12c 第 1 版(12.1)– 不再支持此版本

Oracle SSL 选项的 TLS 版本

Amazon RDS for Oracle 支持传输层安全性 (TLS) 版本 1.0 和 1.2。在添加新的 Oracle SSL 选项时,请显式将 SQLNET.SSL_VERSION 设置为有效值。下面是该选项设置允许的值:

  • "1.0" – 客户端只能使用 TLS 版本 1.0 连接到数据库实例。对于现有 Oracle SSL 选项,SQLNET.SSL_VERSION 自动设置为 "1.0"。您可以根据需要更改设置。

  • "1.2" – 客户端只能使用 TLS 1.2 连接到数据库实例。

  • "1.2 or 1.0" – 客户端只能使用 TLS 1.2 或 1.0 连接到数据库实例。

Oracle SSL 选项的密码套件

Amazon RDS for Oracle 支持多个 SSL 密码套件。默认情况下,Oracle SSL 选项配置为使用 SSL_RSA_WITH_AES_256_CBC_SHA 密码套件。要指定不同的密码套件以在 SSL 连接中使用,请使用 SQLNET.CIPHER_SUITE 选项设置。

下表总结了 RDS for Oracle 的 SSL 支持。指定的 Oracle Database 版本支持所有版本。

密码套件(SQLNET.CIPHER_SUITE) TLS 版本支持(SQLNET.SSL_VERSION) 支持的 Oracle Database 版本 FIPS 支持 符合 FedRAMP 要求
SSL_RSA_WITH_AES_256_CBC_SHA(原定设置) 1.0 和 1.2 12c、19c、21c
SSL_RSA_WITH_AES_256_CBC_SHA256 1.2 12c、19c、21c
SSL_RSA_WITH_AES_256_GCM_SHA384 1.2 12c、19c、21c
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 1.2 19c、21c
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 1.2 19c、21c
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 1.2 19c、21c
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 1.2 19c、21c
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 1.2 19c、21c
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 1.2 19c、21c

FIPS 支持

RDS for Oracle 使您能够使用 140-2 联邦信息处理标准(FIPS)。FIPS 140-2 是一项美国政府标准,它定义了密码模块的安全要求。您可以通过针对 Oracle SSL 选项将 FIPS.SSLFIPS_140 设置为 TRUE 来开启 FIPS 标准。为 SSL 配置 FIPS 140-2 时,加密库会加密客户端与 RDS for Oracle 数据库实例之间的数据。

客户端必须使用符合 FIPS 条件的密码套件。建立连接时,客户端和 RDS for Oracle 数据库实例协商为来回传输消息使用的密码套件。Oracle SSL 选项的密码套件中的表显示了适用于各个 TLS 版本的符合 FIPS 条件的 SSL 密码套件。有关更多信息,请参阅 Oracle 数据库文档中的 Oracle 数据库 FIPS 140-2 设置

添加 SSL 选项

要使用 SSL,您的 RDS for Oracle 数据库实例必须与包括 SSL 选项的选项组关联。

将 SSL 选项添加到选项组
  1. 创建新选项组或识别现有选项组,然后您可以将 SSL 选项添加到其中。

    有关创建选项组的信息,请参阅 创建选项组

  2. SSL 选项添加到该选项组。

    如果要为 SSL 连接仅使用 FIPS 验证的密码套件,请将选项 FIPS.SSLFIPS_140 设置为 TRUE。有关 FIPS 标准的信息,请参阅 FIPS 支持

    有关向选项组添加选项的信息,请参阅 将选项添加到选项组

  3. 创建新的 RDS for Oracle 数据库实例并将选项组与其关联,或者修改要将选项组与其关联的 RDS for Oracle 数据库实例。

    有关创建数据库实例的信息,请参阅 创建 Amazon RDS 数据库实例

    有关修改数据库实例的信息,请参阅 修改 Amazon RDS 数据库实例

将 SSL 选项添加到选项组
  1. 创建新选项组或识别现有选项组,然后您可以将 SSL 选项添加到其中。

    有关创建选项组的信息,请参阅 创建选项组

  2. SSL 选项添加到该选项组。

    指定以下选项设置:

    • Port – SSL 端口号

    • VpcSecurityGroupMemberships – 为其启用此选项的 VPC 安全组

    • SQLNET.SSL_VERSION – 客户端可用来连接到数据库实例的 TLS 版本

    例如,以下 Amazon CLI 命令将 SSL 选项添加到名为 ora-option-group 的选项组。

    对于 Linux、macOS 或 Unix:

    aws rds add-option-to-option-group --option-group-name ora-option-group \ --options 'OptionName=SSL,Port=2484,VpcSecurityGroupMemberships="sg-68184619",OptionSettings=[{Name=SQLNET.SSL_VERSION,Value=1.0}]'

    对于 Windows:

    aws rds add-option-to-option-group --option-group-name ora-option-group ^ --options 'OptionName=SSL,Port=2484,VpcSecurityGroupMemberships="sg-68184619",OptionSettings=[{Name=SQLNET.SSL_VERSION,Value=1.0}]'
  3. 创建新的 RDS for Oracle 数据库实例并将选项组与其关联,或者修改要将选项组与其关联的 RDS for Oracle 数据库实例。

    有关创建数据库实例的信息,请参阅 创建 Amazon RDS 数据库实例

    有关修改数据库实例的信息,请参阅 修改 Amazon RDS 数据库实例

配置 SQL*Plus 以将 SSL 用于 RDS for Oracle 数据库实例

在连接到使用 Oracle SSL 选项的 RDS for Oracle 数据库实例之前,您必须先配置 SQL*Plus。

注意

若要允许从适当的客户端访问数据库实例,请确保已正确配置安全组。有关更多信息,请参阅“使用安全组控制访问权限”。另外,这些说明适用于 SQL*Plus 和其他直接使用 Oracle 主目录的客户端。有关 JDBC 连接,请参阅设置通过 JDBC 的 SSL 连接

将 SQL*Plus 配置为使用 SSL 连接到 RDS for Oracle 数据库实例
  1. ORACLE_HOME 环境变量设置为 Oracle 主目录的位置。

    Oracle 主目录的路径取决于您的安装。以下示例设置 ORACLE_HOME 环境变量。

    prompt>export ORACLE_HOME=/home/user/app/user/product/12.1.0/dbhome_1

    有关设置 Oracle 环境变量的信息,请参阅 Oracle 文档中的 SQL*Plus 环境变量,另请参阅适用于您的操作系统的 Oracle 安装指南。

  2. $ORACLE_HOME/lib 追加到 LD_LIBRARY_PATH 环境变量。

    下面是一个设置 LD_LIBRARY_PATH 环境变量的示例。

    prompt>export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/lib
  3. $ORACLE_HOME/ssl_wallet 处的 Oracle wallet 创建一个目录。

    下面是一个创建 Oracle wallet 目录的示例。

    prompt>mkdir $ORACLE_HOME/ssl_wallet
  4. 下载适用于所有 Amazon 区域的根证书并将此文件放在 ssl_wallet 目录中。

    有关下载根证书的信息,请参阅 使用 SSL/TLS 加密与数据库实例的连接

  5. $ORACLE_HOME/network/admin 目录中,修改或创建 tnsnames.ora 文件并包含下列条目。

    net_service_name = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCPS) (HOST = endpoint) (PORT = ssl_port_number) ) ) (CONNECT_DATA = (SID = database_name) ) (SECURITY = (SSL_SERVER_CERT_DN = "C=US,ST=Washington,L=Seattle,O=Amazon.com,OU=RDS,CN=endpoint") ) )
  6. 在同一目录中,修改或创建 sqlnet.ora 文件并包含下列参数。

    注意

    要通过 TLS 安全连接与实体进行通信,Oracle 需要包含身份验证所需证书的钱夹。您可以使用 Oracle 的 ORAPKI 实用工具来创建和维护 Oracle 钱夹,如步骤 7 中所示。有关更多信息,请参阅 Oracle 文档中的使用 ORAPKI 设置 Oracle 钱夹

    WALLET_LOCATION = (SOURCE = (METHOD = FILE) (METHOD_DATA = (DIRECTORY = $ORACLE_HOME/ssl_wallet))) SSL_CLIENT_AUTHENTICATION = FALSE SSL_VERSION = 1.0 SSL_CIPHER_SUITES = (SSL_RSA_WITH_AES_256_CBC_SHA) SSL_SERVER_DN_MATCH = ON
    注意

    您可以将 SSL_VERSION 设置为较高值(如果您的数据库实例支持它)。

  7. 运行下列命令以创建 Oracle wallet。

    prompt>orapki wallet create -wallet $ORACLE_HOME/ssl_wallet -auto_login_only   prompt>orapki wallet add -wallet $ORACLE_HOME/ssl_wallet -trusted_cert -cert $ORACLE_HOME/ssl_wallet/rds-ca-2019-root.pem -auto_login_only

    将文件名替换为您下载的文件名。

使用 SSL 连接到 RDS for Oracle 数据库实例

在如前所述将 SQL*Plus 配置为使用 SSL 之后,您可以使用 SSL 选项连接到 RDS for Oracle 数据库实例。您也可以选择首先导出指向包含 tnsnames.ora 和 sqlnet.ora 文件的目录的 TNS_ADMIN 值。这样做可确保 SQL*Plus 可始终找到这些文件。以下示例导出 TNS_ADMIN 值。

export TNS_ADMIN = ${ORACLE_HOME}/network/admin

连接到数据库实例。例如,您可以使用 SQL*Plus,通过 tnsnames.ora 文件中的 <net_service_name> 进行连接。

sqlplus mydbuser@net_service_name

您还可以通过以下命令,使用 SQL*Plus 连接到数据库实例,而无需使用 tnsnames.ora 文件。

sqlplus 'mydbuser@(DESCRIPTION = (ADDRESS = (PROTOCOL = TCPS)(HOST = endpoint) (PORT = ssl_port_number))(CONNECT_DATA = (SID = database_name)))'

您还可在不使用 SSL 的情况下连接到 RDS for Oracle 数据库实例。例如,以下命令通过不带 SSL 加密的明文端口连接到数据库实例。

sqlplus 'mydbuser@(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = endpoint) (PORT = port_number))(CONNECT_DATA = (SID = database_name)))'

如果要关闭传输控制协议 (TCP) 端口访问,请创建一个没有 IP 地址入口的安全组并将此组添加到实例。添加此组将会关闭通过 TCP 端口的连接,同时仍然允许从 SSL 选项安全组允许的范围内的 IP 地址通过 SSL 端口进行指定的连接。

设置通过 JDBC 的 SSL 连接

要使用通过 JDBC 的 SSL 连接,您必须创建密钥存储,信任 Amazon RDS 根 CA 证书并使用下面指定的代码段。

要创建 JKS 格式的 keystore,请使用以下命令。有关创建 keystore 的更多信息,请参阅 Oracle 文档

keytool -keystore clientkeystore -genkey -alias client

接着,按照下列步骤信任 Amazon RDS 根 CA 证书。

信任 Amazon RDS 根 CA 证书
  1. 下载适用于所有 Amazon 区域的根证书并将此文件放在 ssl_wallet 目录中。

    有关下载根证书的信息,请参阅 使用 SSL/TLS 加密与数据库实例的连接

  2. 使用以下命令将证书转换为 .der 格式。

    openssl x509 -outform der -in rds-ca-2019-root.pem -out rds-ca-2019-root.der

    将文件名替换为您下载的文件名。

  3. 使用以下命令将证书导入密钥存储。

    keytool -import -alias rds-root -keystore clientkeystore.jks -file rds-ca-2019-root.der
  4. 确认成功创建了密钥存储。

    keytool -list -v -keystore clientkeystore.jks

    在出现提示时,输入密钥存储密码。

以下代码说明如何设置使用 JDBC 的 SSL 连接。

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 } }
注意

作为安全最佳实践,请指定除此处所示提示以外的密码。

使用 SSL 连接强制执行 DN 匹配

您可以使用 Oracle 参数 SSL_SERVER_DN_MATCH 强制数据库服务器的可分辨名称 (DN) 与其服务名称匹配。如果您强制执行匹配验证,则 SSL 将确保证书来自服务器。如果您未强制执行匹配验证,则 SSL 将执行检查,但允许连接,而不管是否存在匹配项。如果您未强制执行匹配,则会允许服务器潜在的伪造标识行为。

要强制执行 DN 匹配,请添加 DN 匹配属性并使用下面指定的连接字符串。

将属性添加到客户端连接以强制执行 DN 匹配。

properties.put("oracle.net.ssl_server_dn_match", "TRUE");

使用 SSL 时使用以下连接字符串强制执行 DN 匹配。

final String connectionString = String.format( "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCPS)(HOST=%s)(PORT=%d))" + "(CONNECT_DATA=(SID=%s))" + "(SECURITY = (SSL_SERVER_CERT_DN = \"C=US,ST=Washington,L=Seattle,O=Amazon.com,OU=RDS,CN=%s\")))", DB_SERVER_NAME, SSL_PORT, DB_SID, DB_SERVER_NAME);

排查 SSL 连接问题

您可能会查询数据库并收到 ORA-28860 错误。

ORA-28860: Fatal SSL error 28860. 00000 - "Fatal SSL error" *Cause: An error occurred during the SSL connection to the peer. It is likely that this side sent data which the peer rejected. *Action: Enable tracing to determine the exact cause of this error.

当客户端尝试使用服务器不支持的 TLS 版本进行连接时,就会发生此错误。要避免此错误,请编辑 sqlnet.ora 并将 SSL_VERSION 设置为正确的 TLS 版本。有关更多信息,请参阅 My Oracle Support 中的 Oracle 支持文档 2748438.1