如何使用 SSL 連線成功連接至我的 Amazon RDS 執行個體?

上次更新日期:2021 年 10 月 25 日

我想要使用 Secure Socket Layer (SSL) 連線連接至我的 Amazon Relational Database Service (Amazon RDS) 資料庫執行個體。

簡短描述

您可以從應用程式使用 SSL 或 Transport Layer Security (TLS) 來加密與執行 MySQL、MariaDB、Microsoft SQL Server、Oracle 或 PostgreSQL 的資料庫執行個體的連線。SSL/TLS 連線會將在用戶端與資料庫執行個體之間傳輸的資料加密,提供一個安全保護層。伺服器憑證會驗證到 Amazon RDS 資料庫執行個體的連線,提供多一層的保護。

佈建資料庫執行個體時,Amazon RDS 會建立 SSL 憑證,並將憑證安裝到執行個體上。這些憑證由憑證授權單位簽署。SSL 憑證包含資料庫執行個體端點,並將之用作其一般名稱,以保護執行個體免遭詐騙攻擊。Amazon RDS 建立的 SSL 憑證是受信任的根實體,大多數情況下都可以使用。不過,如果您的應用程式不接受憑證鏈結,憑證可能會失敗。在這種情況下,您可能需要使用中繼憑證連線到 AWS 區域。例如,您必須使用中繼憑證,才能使用 SSL 連線到 AWS GovCloud (US) 區域。

您可以從 AWS Trust Services 下載包含所有 AWS 區域的中繼憑證和根憑證的憑證搭售。如果您的應用程式在 Microsoft Windows 中執行,並且需要一個 PKCS7 檔案,就可以從 Amazon Trust Services 下載 PKCS7 憑證搭售。此搭售中包含中繼憑證和根憑證。

解決方案

每個資料庫引擎都有自己實作 SSL/TLS 的過程。若要為您的資料庫叢集實作 SSL/TLS 連線,請根據資料庫引擎選擇下列選項之一。

Amazon RDS for Oracle

對於 Amazon RDS for Oracle 執行個體,您可以透過在自訂選項群組中新增 SSL 選項來開啟 SSL 模式。

Amazon RDS for Oracle 支援 Transport Layer Security (TLS) 版本 1.0 和 1.2。若要使用 Oracle SSL 選項,請使用選項群組中的 SQLNET.SSL_VERSION 選項設定。此選項設定允許使用下列值:

  • 「1.0」- 用戶端只能使用 TLS 1.0 連線到資料庫執行個體。
  • 「1.2」- 用戶端只能使用 TLS 1.2 連線到資料庫執行個體。
  • 「1.2 或 1.0」- 用戶端可以使用 TLS 1.2 或 1.0 連線到資料庫執行個體。

對於現有的 Oracle SSL 選項,SQLNET.SSL_VERSION 會自動設定為「1.0」。必要時可以變更設定。

您必須先將 SQL*Plus 用戶端設定為使用 SSL,才能連線到使用 Oracle SSL 選項的 Oracle 資料庫執行個體。若要透過 JDBC 使用 SSL 連線,您必須建立金鑰存放區、信任 Amazon RDS 根 CA 憑證,然後設定 SSL 連線。

使用 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 = "example-dns";
    private static final Integer SSL_PORT = "example-ssl-option-port-in-option-group";
    private static final String DB_SID = "example-oracle-sid";
    private static final String DB_USER = "example-username";
    private static final String DB_PASSWORD = "example-password";
    // This key store has only the prod root ca.
    private static final String KEY_STORE_FILE_PATH = "example-file-path-to-keystore";
    private static final String KEY_STORE_PASS = "example-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("example-username", DB_USER);
        properties.put("example-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 there is no exception, it means that an SSL connection can be opened
    }
}

在您使用 SSL 連線到 Amazon RDS for Oracle 執行個體之前,請務必確定下述事項:

  • RDS 根憑證會下載並新增至錢包檔案。這個檔案存放在 sqlnet.ora 檔案中的 WALLET_LOCATION 參數所指定的目錄中。
  • 您的 TNS 項目中有正確的 SSL 連接埠號碼。
  • Amazon RDS 安全群組設定為允許透過 SSL 連接埠從您的機器進行傳入連線。
  • 防火牆或安全政策已適當設定,允許來自 Amazon RDS 的流量通過 SSL 連接埠。

Amazon RDS for MariaDB

Amazon RDS for MariaDB 支援 TLS 版本 1.0、1.1、1.2 和 1.3。在單向 TLS 連線中,TLS 是在沒有用戶端憑證的情況下使用的,並且只能對伺服器進行身份驗證。因此,只能在一個方向進行身分驗證。但仍然可以進行雙向加密。透過伺服器憑證驗證,用戶端會驗證憑證是否屬於伺服器。

若要使用 RDS 憑證啟動 MySQL 5.7 用戶端或更高版本,請執行以下類似命令:

mysql -h myinstance.123456789012.rds-us-east-1.amazonaws.com -u testuser -p --ssl-ca=[full path]global-bundle.pem --ssl-mode=VERIFY_IDENTITY

若要使用 RDS 憑證啟動 MariaDB 用戶端,請執行以下類似命令:

mysql -h myinstance.123456789012.rds-us-east-1.amazonaws.com -u testuser -p --ssl-ca=[full path]global-bundle.pem --ssl-verify-server-cert

若要為特定使用者或帳戶要求 SSL 連線,請依您的 MariaDB 版本執行以下查詢:

ALTER USER 'test'@'%' REQUIRE SSL;

若要確認您的連線是否已加密,請執行下列查詢之一:

MariaDB > status;
MariaDB > SHOW VARIABLES LIKE 'have_ssl';

Amazon RDS for MySQL

Amazon RDS for MySQL 支援 TLS 版本 1.0、1.1 和 1.2。

Amazon RDS for MySQL 在以下版本中使用 yaSSL 進行安全連線:

  • MySQL 版本 5.7.19 及以下的 5.7 版本
  • MySQL 版本 5.6.37 及以下的 5.6 版本

MySQL 在以下版本中使用 OpenSSL 進行安全連線:

  • MySQL 版本 8.0
  • MySQL 版本 5.7.21 及以上的 5.7 版本
  • MySQL 版本 5.6.39 及以上的 5.6 版本

依據預設,如果伺服器支援加密連線,MySQL 用戶端程式會嘗試建立加密連線。如需與預設加密所提供的額外安全保護相關的資訊,請使用 --ssl-ca 參數來參考將資料庫執行個體端點作為一般名稱包含在內的 SSL 憑證。SSL 憑證可保護執行個體免遭詐騙攻擊。

若要為 MySQL 5.7 及以上版本使用 --ssl-ca 參數來啟動用戶端,請執行以下類似命令:

mysql -h myinstance.123456789012.rds-us-east-1.amazonaws.com -u testuser -p --ssl-ca=[full path]global-bundle.pem --ssl-mode=VERIFY_IDENTITY

若要為特定使用者或帳戶要求 SSL 連線,請依您的 MySQL 版本執行以下類似查詢:

mysql -h myinstance.123456789012.rds-us-east-1.amazonaws.com -u testuser -p --ssl-ca=[full path]global-bundle.pem --ssl-verify-server-cert

對於 MySQL 5.7 及以上版本:

ALTER USER 'testuser'@'%' REQUIRE SSL;

對於 MySQL 5.6 及以下版本:

GRANT USAGE ON *.* TO 'testuser'@'%' REQUIRE SSL;

若要確認您的連線是否已加密,請執行下列查詢之一:

mysql> status;
mysql> SHOW VARIABLES LIKE 'have_ssl';

Amazon RDS for Microsoft SQL Server

您可以透過以下方式之一,使用 SSL 連線到 SQL Server 資料庫執行個體:

  • 強制對所有連線使用 SSL:使用此方法時,連線對所有用戶端皆為透明,用戶端無需執行任何操作即可使用 SSL。若要使用此選項,請將 rds.force_ssl 參數設定為 1 (開啟)。預設情況下,rds.force_ssl 參數設定為 0 (關閉)。rds.force_ssl 參數是靜態的。因此,變更值之後,您必須重新啟動資料庫執行個體,變更才會生效。
  • 加密特定連線:此方法會從特定用戶端電腦設定 SSL 連線,而且您必須將該用戶端上的連線加密。

要加密來自其他 SQL 用戶端的連線,請將 encrypt=true 附加到連線字串。這個字串可能作為 GUI 工具中連線頁面上的選項或屬性提供。

執行下列查詢,以確認您的連線是否已加密:

SELECT ENCRYPT_OPTION FROM SYS.DM_EXEC_CONNECTIONS WHERE SESSION_ID = @@SPID;

對於 encrypt_option,驗證查詢是否傳回 true

注意:若要為使用 JDBC 連線的用戶端啟用 SSL 加密,您可能需要將 Amazon RDS SQL 憑證新增至 Java CA 憑證 (cacerts) 存放區。您可以使用 keytool 公用程式來完成此操作。

Amazon RDS for PostgreSQL

Amazon RDS 支援適用於 PostgreSQL 資料庫執行個體的 SSL 加密。您可以使用 SSL 加密應用程式與 PostgreSQL 資料庫執行個體之間的 PostgreSQL 連線。還可以強制與 PostgreSQL 資料庫執行個體的所有連線都使用 SSL。Amazon RDS for PostgreSQL 支援 TLS 版本 1.1 和 1.2。

在透過 SSL 連線至 Amazon RDS for PostgreSQL 資料庫執行個體之前,請執行以下操作:

  1. 下載憑證。
  2. 將憑證匯入您的作業系統。

如需詳細資訊,請參閱透過 SSL 連線到 PostgreSQL 資料庫執行個體

使用 sslrootcert 參數來參考憑證。例如 sslrootcert=rds-ssl-ca-cert.pem。

$ psql "host=myinstance.123456789012.rds-us-east-1.amazonaws.com port=5432 user=testuser dbname=testpg sslmode=verify-full sslrootcert=global-bundle.pem"

您還可以在自訂參數群組中將 rds.force_ssl 設為 1 (開啟),設定與 RDS for PostgreSQL 執行個體的連線使用 SSL。依預設,此值設定為 0 (關閉)

rds.force_ssl 設定為 1 (開啟) 時,資料庫執行個體的 pg_hba.conf 檔案將修改以支援新的 SSL 組態。您可以使用 pg_hba_file_rules 視圖來檢視 pg_hba.conf 檔案的內容摘要。

rds.force_ssl 設定為 0 (關閉) 時,pg_hba.conf 檔案內容將如下圖所示:

SELECT * FROM pg_hba_file_rules;

 line_number | type  |     database      | user_name  | address  | netmask | auth_method | options | error 
-------------+-------+-------------------+------------+----------+---------+-------------+---------+-------
           4 | local | {all}             | {all}      |          |         | md5         |         | 
          10 | host  | {all}             | {rdsadmin} | samehost |         | md5         |         | 
          11 | host  | {all}             | {rdsadmin} | all      |         | reject      |         | 
          12 | host  | {rdsadmin}        | {all}      | all      |         | reject      |         | 
          13 | host  | {all}             | {all}      | all      |         | md5         |         |
          14 | host  | {replication}     | {all}      | samehost |         | md5         |         | 
          15 | host  | {rds_replication} | {all}      | all      |         | md5         |         | 
(7 rows)

rds.force_ssl 設定為 1 (開啟) 時,pg_hba.conf 檔案內容將如下圖所示:

SELECT * FROM pg_hba_file_rules;

line_number |  type   |     database      | user_name  | address  | netmask | auth_method | options | error 
-------------+---------+-------------------+------------+----------+---------+-------------+---------+-------
          4 | local   | {all}             | {all}      |          |         | md5         |         |
         10 | host    | {all}             | {rdsadmin} | samehost |         | md5         |         |
         11 | host    | {all}             | {rdsadmin} | all      |         | reject      |         |
         12 | host    | {rdsadmin}        | {all}      | all      |         | reject      |         |
         13 | hostssl | {all}             | {all}      | all      |         | md5         |         |
         14 | host    | {replication}     | {all}      | samehost |         | md5         |         |
         15 | hostssl | {rds_replication} | {all}      | all      |         | md5         |         |

您可能會注意到,rds.force_ssl 設定為 1 (開啟) 之後,line_number (13) 的 type 值將更新為 hostssl

在執行個體上啟用 SSL 連線之後,當您啟動與 RDS for PostgreSQL 執行個體的連線時,會看到類似於下圖中的訊息:

$ psql "host=myinstance.123456789012.rds-us-east-1.amazonaws.com port=5432 user=testuser dbname=testpg"
. . .
SL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

所有非 SSL 連線都會被拒,並顯示下列訊息:

$ psql "host=myinstance.123456789012.rds-us-east-1.amazonaws.com port=5432 user=testuser dbname=testpg sslmode=disable"
psql: FATAL: no pg_hba.conf entry for host "host.ip", user "testuser", database "testpg", SSL off
$

此文章是否有幫助?


您是否需要帳單或技術支援?