

# PostgreSQL DB インスタンスで SSL を使用する
<a name="PostgreSQL.Concepts.General.SSL"></a>

Amazon RDS は、PostgreSQL DB インスタンスの Secure Socket Layer (SSL) 暗号化をサポートします。SSL を使用して、アプリケーションと PostgreSQL DB インスタンスとの PostgreSQL 接続を暗号化できます。デフォルトでは、RDS for PostgreSQL は SSL/TLS を使用し、すべてのクライアントが SSL/TLS を使用して接続することを想定していますが、必須にすることもできます。RDS for PostgreSQL は、Transport Layer Security (TLS) バージョン 1.1、1.2、および 1.3 をサポートしています。

SSL サポートおよび PostgreSQL データベースの一般情報については、PostgreSQL ドキュメントの「[SSL Support](https://www.postgresql.org/docs/11/libpq-ssl.html)」を参照してください。JDBC を介した SSL 接続の使用については、PostgreSQL ドキュメントの「[Configuring the Client](https://jdbc.postgresql.org/documentation/head/ssl-client.html)」を参照してください。

PostgreSQL 用の SSL は、すべての AWS リージョンで利用が可能です。インスタンスの作成時に、PostgreSQL DB インスタンス用の SSL 証明書が、Amazon RDS により作成されます。SSL 証明書認証を有効にした場合、SSL 証明書には、なりすまし攻撃から保護するために、SSL 証明書の共通名 (CN) として DB インスタンスのエンドポイントが含まれます。

**Topics**
+ [SSL 経由での PostgreSQL DB インスタンスへの接続](#PostgreSQL.Concepts.General.SSL.Connecting)
+ [PostgreSQL DB インスタンスへの SSL 接続を必須にする](#PostgreSQL.Concepts.General.SSL.Requiring)
+ [SSL 接続ステータスを確認する](#PostgreSQL.Concepts.General.SSL.Status)
+ [RDS for PostgreSQL の SSL 暗号スイート](#PostgreSQL.Concepts.General.SSL.Ciphers)

## SSL 経由での PostgreSQL DB インスタンスへの接続
<a name="PostgreSQL.Concepts.General.SSL.Connecting"></a>

**SSL を使用して PostgreSQL DB インスタンスに接続するには**

1. 証明書をダウンロードします。

   証明書のダウンロードについては、[SSL/TLS を使用した DB インスタンスまたはクラスターへの接続の暗号化](UsingWithRDS.SSL.md) を参照してください。

1. SSL 経由の PostgreSQL DB インスタンスへの接続

   SSL を使用して接続するとき、クライアントでは証明書チェーンを検証するかどうかを選択できます。接続パラメータで `sslmode=verify-ca` または `sslmode=verify-full` を指定すると、RDS CA 証明書が信頼ストアに存在するか、または接続 URL で参照されることをクライアントは要求します。この要求は、データベース証明書に署名する証明書チェーンを検証するためのものです。

   psql や JDBC など、クライアントに SSL サポートが設定されている場合、クライアントは初期にデフォルトで SSL を使用してデータベースへの接続を試みます。クライアントが SSL を使用して接続できない場合、SSL を使用しない接続に戻ります。使用されるデフォルトの `sslmode` モードは、libpq ベースのクライアント (psql など) と JDBC では異なります。libpq ベースのクライアントおよび JDBC クライアントはデフォルトで `prefer` に設定されます。

   `sslrootcert` パラメータを使用して証明書を参照します (`sslrootcert=rds-ssl-ca-cert.pem` など)。

以下は、証明書検証で SSL を使用して PostgreSQL DB インスタンスに接続するために `psql` を使用する例です。

```
$ 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"
```

## PostgreSQL DB インスタンスへの SSL 接続を必須にする
<a name="PostgreSQL.Concepts.General.SSL.Requiring"></a>

`rds.force_ssl` パラメータを使用することで、PostgreSQL DB インスタンスへの接続に SSL の使用を必須にすることができます。RDS for PostgreSQL バージョン 15 以降では、`rds.force_ssl` パラメータのデフォルト値は 1 (オン) です。その他すべての RDS for PostgreSQL メジャーバージョン 14 以前では、このパラメータのデフォルト値は 0 (オフ) です。`rds.force_ssl` パラメータを 1 (オン) に設定すれば、DB クラスターへの接続で SSL/TLS を必須にすることができます。`rds.force_ssl` パラメータを 1 に設定すれば、DB インスタンスへの接続に SSL を必須にすることができます。

このパラメータの値を変更するには、カスタム DB パラメータグループを作成する必要があります。次に、カスタム DB パラメータグループ内で `rds.force_ssl` の値を `1` に変更して、この機能をオンにします。RDS for PostgreSQL DB インスタンスを作成する前にカスタム DB パラメータグループを準備する場合は、作成プロセス中に (デフォルトのパラメータグループではなく) そのパラメータグループを選択できます。RDS for PostgreSQL DB インスタンスが既に実行された後でこれを行う場合は、インスタンスがカスタムパラメータグループを使用するようにインスタンスを再起動する必要があります。詳細については、「[Amazon RDS のパラメータグループ](USER_WorkingWithParamGroups.md)」を参照してください。

DB インスタンスで `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>

接続の暗号化ステータスは、DB インスタンスに接続するときにログオンバナーに表示されます。

```
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 DB インスタンスの 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 ドキュメント*の「[Database connection control functions](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\$1ciphers](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 コンソールまたは次の AWS CLI コマンドを使用します。

```
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.3 は パラメータで指定された暗号設定を使用しないため、この `ssl_ciphers` パラメータの値を TLS v1.2 に設定する必要があります。値を 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)」を参照してください。