Oracle 安全套接字层 - Amazon Relational Database Service

Oracle 安全套接字层

要为 RDS for Oracle 数据库实例启用 SSL 加密,请向与数据库实例关联的选项组添加 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 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 选项设置。

可以为 SQLNET.CIPHER_SUITE 指定多个值。如果数据库实例之间具有数据库链接并且您决定更新密码套件,则此技术很有用。

下表总结了所有版本的 Oracle Database 19c 和 21c 中对 RDS for Oracle 的 SSL 支持。

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

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 版本

    例如,以下 AWS 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/19.0.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. 下载适用于所有 AWS 区域的证书捆绑 .pem 文件并将此文件放在 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
  8. 使用操作系统实用程序将 .pem 捆绑文件中的每个证书解压缩到单独的 .pem 文件中。

  9. 使用单独的 orapki 命令将每个证书添加到 Wallet 中,将 certificate-pem-file 替换为 .pem 文件的绝对文件名。

    prompt>orapki wallet add -wallet $ORACLE_HOME/ssl_wallet -trusted_cert -cert certificate-pem-file -auto_login_only

    有关更多信息,请参阅 轮换 SSL/TLS 证书

使用 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 文档中的创建 keystore。有关参考信息,请参阅《Java Platform, Standard Edition Tools Reference》中的 keytool

keytool -genkey -alias client -validity 365 -keyalg RSA -keystore clientkeystore

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

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

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

  2. 使用操作系统实用程序将 .pem 文件中的每个证书解压缩到单独的文件中。

  3. 使用单独的 openssl 命令将每个证书转换为 .der 格式,同时将证书 certificate-pem-file 替换为证书 .pem 文件的名称(不带 .pem 扩展名)。

    openssl x509 -outform der -in certificate-pem-file.pem -out certificate-pem-file.der
  4. 使用以下命令将每个证书导入 keystore。

    keytool -import -alias rds-root -keystore clientkeystore.jks -file certificate-pem-file.der

    有关更多信息,请参阅 轮换 SSL/TLS 证书

  5. 确认成功创建了密钥存储。

    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