SSL 接続を使用して Amazon RDS インスタンスに正常に接続する方法を教えてください。
Secure Socket Layer (SSL) 接続を使用して Amazon Relational Database Service (Amazon RDS) DB インスタンスに接続したいです。
簡単な説明
MySQL、MariaDB、Microsoft SQL Server、Oracle、PostgreSQL を実行する DB インスタンスへの接続を暗号化するには、アプリケーションで SSL または Transport Layer Security (TLS) を使用します。SSL/TLS 接続は、クライアントと DB インスタンスの間で転送されるデータを暗号化することで、単一レイヤーのセキュリティを実現します。サーバー証明書は、Amazon RDS DB インスタンスへの接続が確立されていることを検証することで、追加のセキュリティレイヤーとなります。
DB インスタンスをプロビジョニングすると、Amazon RDS は SSL 証明書を作成し、その証明書をインスタンスにインストールします。これらの証明書は、認証機関 (CA) によって署名されています。SSL 証明書には、なりすまし攻撃からインスタンスを保護するために、SSL 証明書の共通名として DB インスタンスのエンドポイントが含まれています。Amazon RDS によって作成された SSL 証明書は信頼されたルートエンティティであり、ほとんどのケースで機能します。ただし、アプリケーションが証明書チェーンを受け入れない場合、証明書が失敗する場合があります。このような場合は、中間証明書を使用して AWS リージョンに接続します。たとえば、SSL を使用して AWS GovCloud (米国) リージョンに接続する場合は、中間証明書を使用する必要があります。
すべてのリージョン用の中間証明書およびルート証明書を含む証明書バンドルは、AWS Trust Services からダウンロードできます。アプリケーションが Microsoft Windows 上にあり、PKCS7 ファイルが必要な場合は、Amazon Trust Services から PKCS7 証明書バンドルをダウンロードします。このバンドルには、中間証明書とルート証明書の両方が含まれています。
解決策
各データベースエンジンは、独自のプロセスで SSL/TLS を実装しています。DB クラスターに SSL/TLS 接続を実装するには、データベースエンジンに応じて次のいずれかの方法を使用します。
Amazon RDS for Oracle
Amazon RDS for Oracle インスタンスで SSL モードを有効にするには、カスタムオプショングループに SSL オプションを追加します。
RDS for Oracle は TLS バージョン 1.0 と 1.2 をサポートしています。Oracle SSL オプションを使用するには、オプショングループで SQLNET.SSL_VERSION オプション設定を使用します。このオプション設定には次の値を使用できます。
- "1.0" - クライアントは TLS 1.0 のみを使用して DB インスタンスに接続できます。
- "1.2" - クライアントは TLS 1.2 のみを使用して DB インスタンスに接続できます。
- "1.2 or 1.0" - クライアントは TLS 1.2 または 1.0 を使用して DB インスタンスに接続できます。
既存の Oracle SSL オプションでは、SQLNET.SSL_VERSION は自動的に "1.0" に設定されています。この設定は必要に応じて変更できます。
Oracle SSL オプションを使用する Oracle DB インスタンスに接続する前に、SQL*Plus クライアントでSSL を使用するように設定する必要があります。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 を使用して 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 を使用するため、サーバーのみが認証の対象です。したがって、認証は一方向でのみ可能です。ただし、暗号化は両方向で行うことができます。詳細については、MariaDB のウェブサイトで「MariaDB クライアントで片方向 TLS を有効化する」を参照してください。
サーバー証明書の検証により、クライアントは証明書がサーバーに属していることを確認します。詳細については、MariaDB のウェブサイトで「サーバー証明書の検証」を参照してください。
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;
Performance Schema が有効であり、アプリケーションがデータベースインスタンスに接続されている RDS for MariaDB バージョン 10.5 以降で、SSL/TLS を使用している接続を確認します。
MariaDB> SELECT id, user, host, connection_type FROM performance_schema.threads pst INNER JOIN information_schema.processlist isp ON pst.processlist_id = isp.id;
注: Performance Schema の詳細については、MariaDB のウェブサイトで「Performance Schema」を参照してください。
Amazon RDS for MySQL
MySQL は OpenSSL を使用して接続を保護します。詳細については、「Amazon RDS における MySQL DB インスタンス用 SSL/TLS サポート」を参照してください。
デフォルトでは、MySQL クライアントプログラムは、サーバーが暗号化された接続をサポートしている場合は暗号化された接続を確立しようとします。--ssl-ca パラメータを使用して、DB インスタンスのエンドポイントを共通名として含む 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;
Performance Schema が有効であり、アプリケーションがデータベースインスタンスに接続されている RDS for MySQL バージョン 5.7 または 8.0 で、SSL/TLS を使用している接続を確認します。
mysql> SELECT id, user, host, connection_type FROM performance_schema.threads pst INNER JOIN information_schema.processlist isp ON pst.processlist_id = isp.id;
注: Performance Schema の詳細については、MariaDB のウェブサイトで「Performance Schema」を参照してください。
Amazon RDS for Microsoft SQL Server
SSL を使用して RDS for Microsoft SQL Server DB インスタンスに接続するには、すべての接続に SSL を強制するか、特定の接続を暗号化します。
他の SQL クライアントからの接続を暗号化するには、接続文字列に encrypt=true を追加します。この文字列は、GUI ツールの接続ページでオプションまたはプロパティとして使用できる場合があります。
接続が暗号化されていることを確認するには、次のクエリを実行します。
SELECT ENCRYPT_OPTION FROM SYS.DM_EXEC_CONNECTIONS WHERE SESSION_ID = @@SPID;
クエリが encrypt_option に対して true を返すことを確認します。
注: 接続に JDBC を使用するクライアントで SSL 暗号化を有効化するには、Java CA 証明書 (cacerts) ストアに RDS SQL 証明書を追加する必要がある場合があります。keytool ユーティリティを使用して行うことができます。
Amazon RDS for PostgreSQL
Amazon RDS は PostgreSQL DB インスタンスでの SSL 暗号化をサポートしています。詳細については、「PostgreSQL DB インスタンスで SSL を使用する」を参照してください。
SSL 経由で RDS for PostgreSQL DB インスタンスに接続する前に、次の手順を完了します。
- 証明書をダウンロードします。
- 証明書をオペレーティングシステムにインポートします。
詳細については、「SSL 経由で PostgreSQL DB インスタンスに接続する」を参照してください。
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"
SSL を使用するように RDS for PostgreSQL インスタンスへの接続を構成するには、カスタムパラメータグループで rds.force_ssl を 1 (有効) に設定します。デフォルトでは、この値は 0 (無効) に設定されています。
rds.force_ssl を 1 (有効) に設定すると、新しい SSL 設定をサポートするために、DB インスタンスの pg_hba.conf ファイルが変更されます。pg_hba.conf ファイルの内容の概要を確認するには、pg_hba_file_rules ビューを使用します。詳細については、PostgreSQL のウェブサイトで pg_hba_file_rules を参照してください。
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 (有効) に設定すると、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

