

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 將 SSL 與 PostgreSQL 資料庫執行個體搭配使用
<a name="PostgreSQL.Concepts.General.SSL"></a>

對於 PostgreSQL 資料庫執行個體，Amazon RDS 支援 Secure Sockets Layer (SSL) 加密。您可以使用 SSL 將應用程式與 PostgreSQL 資料庫執行個體之間的 PostgreSQL 連線加密。依預設，RDS for PostgreSQL 使用並期望所有用戶端皆使用 SSL/TLS 進行連線，但您也可加以要求。RDS for PostgreSQL 支援 Transport Layer Security (TLS) 1.1、1.2 和 1.3 版。

如需 SSL 支援和 PostgreSQL 資料庫的一般資訊，請參閱 PostgreSQL 文件中的 [SSL 支援](https://www.postgresql.org/docs/11/libpq-ssl.html)。如需透過 JDBC 使用 SSL 連線的資訊，請參閱 PostgreSQL 文件中的[設定用戶端](https://jdbc.postgresql.org/documentation/head/ssl-client.html)。

SSL 支援適用於所有 PostgreSQL 的 AWS 區域。建立執行個體時，Amazon RDS 會為 PostgreSQL 資料庫執行個體建立 SSL 憑證。如果您啟用 SSL 憑證驗證，則 SSL 憑證會包含資料庫執行個體端點做為 SSL 憑證的一般名稱 (CN)，以防止詐騙攻擊。

**Topics**
+ [透過 SSL 連接至 PostgreSQL 資料庫執行個體](#PostgreSQL.Concepts.General.SSL.Connecting)
+ [需要以 SSL 連線至 PostgreSQL 資料庫執行個體](#PostgreSQL.Concepts.General.SSL.Requiring)
+ [判斷 SSL 連線狀態](#PostgreSQL.Concepts.General.SSL.Status)
+ [RDS for PostgreSQL 中的 SSL 密碼套件](#PostgreSQL.Concepts.General.SSL.Ciphers)

## 透過 SSL 連接至 PostgreSQL 資料庫執行個體
<a name="PostgreSQL.Concepts.General.SSL.Connecting"></a>

**透過 SSL 連接至 PostgreSQL 資料庫執行個體**

1. 下載憑證。

   如需有關下載憑證的詳細資訊，請參閱[使用 SSL/TLS 加密與資料庫執行個體或叢集的連線](UsingWithRDS.SSL.md)。

1. 透過 SSL 連接至 PostgreSQL 資料庫執行個體。

   當您使用 SSL 來連線時，用戶端可以選擇是否驗證憑證鏈。如果您的連線參數指定 `sslmode=verify-ca` 或 `sslmode=verify-full`，則用戶端在信任存放區必須有 RDS CA 憑證，或在連線 URL 中必須參考這些憑證。此需求是為了驗證用於簽署資料庫憑證的憑證鏈。

   當用戶端 (例如 psql 或 JDBC) 設有 SSL 支援時，依預設，用戶端會先嘗試以 SSL 連線至資料庫。如果用戶端無法以 SSL 連線，則回復為不以 SSL 來連線。以 libpq 為基礎的用戶端 (例如 psql) 和 JDBC 使用的預設 `sslmode` 模式不同。以 libpq 為基礎的用戶端和 JDBC 用戶端預設為 `prefer`。

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

下列是使用 `psql` 連線至使用具認證驗證 SSL 之 PostgreSQL 資料庫執行個體的範例。

```
$ psql "host=db-name.555555555555.ap-southeast-1.rds.amazonaws.com 
    port=5432 dbname=testDB user=testuser sslrootcert=rds-ca-rsa2048-g1.pem sslmode=verify-full"
```

## 需要以 SSL 連線至 PostgreSQL 資料庫執行個體
<a name="PostgreSQL.Concepts.General.SSL.Requiring"></a>

您可以使用 `rds.force_ssl` 參數來要求對 PostgreSQL 資料庫執行個體的連線使用 SSL。RDS for PostgreSQL 第 15 版和更新版本的 `rds.force_ssl` 參數預設值為 1 (開啟)。至於其他所有 RDS for PostgreSQL 主要版本 14 和較舊版本，此參數的預設值皆為 0 (關閉)。您可以將 `rds.force_ssl` 參數設為 1 (開啟)，以要求使用 SSL/TLS 連線至資料庫叢集。您可以將 `rds.force_ssl` 參數設為 1 (開啟)，以要求對資料庫執行個體的連線使用 SSL。

如要變更此參數值，您需要建立自訂資料庫參數群組。然後，您可變更您自訂資料庫參數群組中的 `rds.force_ssl` 值為 `1`，以開啟此功能。若於建立 RDS for PostgreSQL 資料庫執行個體之前準備了自訂資料庫參數群組，則可於建立程序期間加以選擇 (而非預設參數群組)。若您於 RDS for PostgreSQL 資料庫執行個體已執行之後進行此作業，則需要重新啟動執行個體，如此您的執行個體便可使用自訂參數群組。如需詳細資訊，請參閱[Amazon RDS 的參數群組](USER_WorkingWithParamGroups.md)。

當 `rds.force_ssl` 功能在資料庫執行個體上處於活動狀態時，未使用 SSL 的連線嘗試將遭到拒絕，並顯示下列訊息：

```
$ psql -h db-name.555555555555.ap-southeast-1.rds.amazonaws.com port=5432 dbname=testDB user=testuser
psql: error: FATAL: no pg_hba.conf entry for host "w.x.y.z", user "testuser", database "testDB", SSL off
```

## 判斷 SSL 連線狀態
<a name="PostgreSQL.Concepts.General.SSL.Status"></a>

當您連接至資料庫執行個體時，登入橫幅中會顯示連線的加密狀態：

```
Password for user master: 
psql (10.3) 
SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256) 
Type "help" for help.
postgres=>
```

您也可以載入 `sslinfo` 延伸，然後呼叫 `ssl_is_used()` 函數，以判斷是否正在使用 SSL。如果連線正在使用 SSL，此函數會傳回 `t`，否則傳回 `f`。

```
postgres=> CREATE EXTENSION sslinfo;
CREATE EXTENSION
postgres=> SELECT ssl_is_used();
ssl_is_used
---------
t
(1 row)
```

如需更多詳細資訊，您可使用下列查詢，從 `pg_settings` 取得資訊：

```
SELECT name as "Parameter name", setting as value, short_desc FROM pg_settings WHERE name LIKE '%ssl%';
             Parameter name             |                  value                  |                      short_desc
----------------------------------------+-----------------------------------------+-------------------------------------------------------
 ssl                                    | on                                      | Enables SSL connections.
 ssl_ca_file                            | /rdsdbdata/rds-metadata/ca-cert.pem     | Location of the SSL certificate authority file.
 ssl_cert_file                          | /rdsdbdata/rds-metadata/server-cert.pem | Location of the SSL server certificate file.
 ssl_ciphers                            | HIGH:!aNULL:!3DES                       | Sets the list of allowed SSL ciphers.
 ssl_crl_file                           |                                         | Location of the SSL certificate revocation list file.
 ssl_dh_params_file                     |                                         | Location of the SSL DH parameters file.
 ssl_ecdh_curve                         | prime256v1                              | Sets the curve to use for ECDH.
 ssl_key_file                           | /rdsdbdata/rds-metadata/server-key.pem  | Location of the SSL server private key file.
 ssl_library                            | OpenSSL                                 | Name of the SSL library.
 ssl_max_protocol_version               |                                         | Sets the maximum SSL/TLS protocol version to use.
 ssl_min_protocol_version               | TLSv1.2                                 | Sets the minimum SSL/TLS protocol version to use.
 ssl_passphrase_command                 |                                         | Command to obtain passphrases for SSL.
 ssl_passphrase_command_supports_reload | off                                     | Also use ssl_passphrase_command during server reload.
 ssl_prefer_server_ciphers              | on                                      | Give priority to server ciphersuite order.
(14 rows)
```

您還可使用下列查詢，依程序、用戶端和應用程式收集有關 RDS for PostgreSQL 資料庫執行個體之 SSL 使用情況的所有資訊：

```
SELECT datname as "Database name", usename as "User name", ssl, client_addr, application_name, backend_type
   FROM pg_stat_ssl
   JOIN pg_stat_activity
   ON pg_stat_ssl.pid = pg_stat_activity.pid
   ORDER BY ssl;
 Database name | User name | ssl |  client_addr   |    application_name    |         backend_type
---------------+-----------+-----+----------------+------------------------+------------------------------
               |           | f   |                |                        | autovacuum launcher
               | rdsadmin  | f   |                |                        | logical replication launcher
               |           | f   |                |                        | background writer
               |           | f   |                |                        | checkpointer
               |           | f   |                |                        | walwriter
 rdsadmin      | rdsadmin  | t   | 127.0.0.1      |                        | client backend
 rdsadmin      | rdsadmin  | t   | 127.0.0.1      | PostgreSQL JDBC Driver | client backend
 postgres      | postgres  | t   | 204.246.162.36 | psql                   | client backend
(8 rows)
```

如要識別用於 SSL 連線的密碼，可依如下方式查詢：

```
postgres=> SELECT ssl_cipher();
ssl_cipher
--------------------
DHE-RSA-AES256-SHA
(1 row)
```

若要進一步了解 `sslmode`，請參閱 *PostgreSQL 文件*中的[資料庫連線控制函數](https://www.postgresql.org/docs/11/libpq-connect.html#LIBPQ-CONNECT-SSLMODE)。

## RDS for PostgreSQL 中的 SSL 密碼套件
<a name="PostgreSQL.Concepts.General.SSL.Ciphers"></a>

PostgreSQL 組態參數 [ssl\$1cipher](https://www.postgresql.org/docs/current/runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SSL) 會指定在使用 TLS 1.2 和較低版本時，資料庫的 SSL 連線所允許的密碼套件類別。

 在 RDS for PostgreSQL 16 和更新版本中，您可以修改 `ssl_ciphers` 參數，以使用列入允許清單的密碼套件中的特定值。這是動態參數，不需要將資料庫執行個體重新開機。若要檢視列入允許清單的密碼套件，請使用 Amazon RDS 主控台或下列 CLI AWS 命令：

```
aws rds describe-db-parameters --db-parameter-group-name <your-parameter-group> --region <region> --endpoint-url <endpoint-url> --output json | jq '.Parameters[] | select(.ParameterName == "ssl_ciphers")'
```

下表列出支援自訂組態的版本允許的密碼套件和預設密碼套件。


| PostgreSQL 引擎版本 | 預設 ssl\$1cipher 套件值 | 列入允許清單的自訂 ssl\$1cipher 套件值 | 
| --- | --- | --- | 
| 18 | HIGH:\$1aNULL:\$13DES |  `TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384` `TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256` `TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256` `TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384` `TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256`  | 
| 17 | HIGH:\$1aNULL:\$13DES |  `TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384` `TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256` `TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256` `TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384` `TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256`  | 
| 16 | HIGH:\$1aNULL:\$13DES |  `TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384` `TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256` `TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256` `TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384` `TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256`  | 
| 15 | HIGH:\$1aNULL:\$13DES | 不支援自訂 ssl\$1ciphers | 
| 14 | HIGH:\$1aNULL:\$13DES | 不支援自訂 ssl\$1ciphers | 
| 13 | HIGH:\$1aNULL:\$13DES | 不支援自訂 ssl\$1ciphers | 
| 12 | HIGH:\$1aNULL:\$13DES | 不支援自訂 ssl\$1ciphers | 
| 11.4 及更高次要版本 | HIGH:MEDIUM:\$13DES:\$1aNULL:\$1RC4 | 不支援自訂 ssl\$1ciphers | 
| 11.1、11.2 | HIGH:MEDIUM:\$13DES:\$1aNULL | 不支援自訂 ssl\$1ciphers | 
| 10.9 及更高次要版本 | HIGH:MEDIUM:\$13DES:\$1aNULL:\$1RC4 | 不支援自訂 ssl\$1ciphers | 
| 10.7 及較低次要版本 | HIGH:MEDIUM:\$13DES:\$1aNULL | 不支援自訂 ssl\$1ciphers | 

若要將所有執行個體連線設定為使用 `TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384` 加密套件，請修改參數群組，如下列範例所示：

```
aws rds modify-db-parameter-group --db-parameter-group-name <your-parameter-group> --parameters "ParameterName='ssl_ciphers',ParameterValue='TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384',ApplyMethod=immediate"
```

此範例使用 ECDSA 密碼，因此您的執行個體必須使用具有橢圓曲線密碼編譯 (ECC) 的憑證授權機構來建立連線。若要了解 Amazon RDS 提供了哪些憑證授權機構，請參閱[憑證授權機構](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/singWithRDS.SSL.html#UsingWithRDS.SSL.RegionCertificateAuthorities)。

您可以透過[判斷 SSL 連線狀態](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/PostgreSQL.Concepts.General.SSL.html#PostgreSQL.Concepts.General.SSL.Status)中所述的方法，來驗證使用中的密碼。

密碼可能隨著內容而有不同的名稱：
+ 您可以在參數群組中設定的允許密碼，會以其 IANA 名稱來指稱。
+ `sslinfo` 和 `psql` 登入橫幅是指使用其 OpenSSL 名稱的密碼。

根據預設，RDS for PostgreSQL 16 和更新版本中的 `ssl_max_protocol_version` 值為 TLS v1.3。您必須將此參數的值設定為 TLS v1.2，因為 TLS v1.3 不使用 `ssl_ciphers` 參數中指定的密碼組態。該值設定為 TLS v1.2 時，連線只會使用您在 `ssl_ciphers` 中定義的密碼。

```
aws rds modify-db-parameter-group --db-parameter-group-name <your-parameter-group> --parameters "ParameterName='ssl_max_protocol_version',ParameterValue='TLSv1.2',ApplyMethod=immediate"
```

若要確保資料庫連線會使用 SSL，請在參數群組中將 `rds.force_ssl parameter` 設定為 1。如需參數和參數群組的詳細資訊，請參閱 [Amazon RDS 的參數群組](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_WorkingWithParamGroups.html)。