

# 新しい SSL/TLS 証明書を使用して MySQL DB インスタンスに接続するようにアプリケーションを更新する
<a name="ssl-certificate-rotation-mysql"></a>

2023 年 1 月 13 日に Amazon RDS は、Secure Socket Layer または Transport Layer Security (SSL/TLS) を使用して RDS DB インスタンスに接続するための新しい認証局 (CA) 証明書を公開しました。ここでは、新しい証明書を使用するためのアプリケーションの更新について説明します。

このトピックでは、クライアントアプリケーションが SSL/TLS を使用して DB インスタンスに接続されているかどうかを判断できます。該当する場合はさらに、それらのアプリケーションの接続に証明書の検証が必要かどうかを確認できます。

**注記**  
一部のアプリケーションは、サーバー上の証明書を正常に検証できる場合にのみ、MySQL DB インスタンスに接続されるように設定されています。そのようなアプリケーションの場合は、新しい CA 証明書を含むように、クライアントアプリケーションの信頼ストアを更新する必要があります。  
`disabled`、`preferred`、および `required` の SSL モードを指定できます。`preferred` SSL モードを使用し、CA 証明書が存在しないか、最新でない場合、接続は SSL を使用しない状態にフォールバックし、暗号化なしで接続が行われます。  
`preferred` モードの使用を避けることをお勧めします。`preferred` モードでは、接続時に無効な証明書が検出されると、暗号化の使用が停止し、暗号化せずに続行されます。

クライアントアプリケーションの信頼ストアで CA 証明書を更新した後、DB インスタンスで証明書をローテーションできます。これらの手順を開発環境またはステージング環境でテストしてから、本番環境で実装することを強くお勧めします。

証明書のローテーションの詳細については、「[SSL/TLS 証明書のローテーション](UsingWithRDS.SSL-certificate-rotation.md)」を参照してください。証明書のダウンロードの詳細については、[SSL/TLS を使用した DB インスタンスまたはクラスターへの接続の暗号化](UsingWithRDS.SSL.md) を参照してください。MySQL DB インスタンスで SSL/TLS を使用する方法については、「[Amazon RDS 上の MySQL DB インスタンスの SSL/TLS サポート](MySQL.Concepts.SSLSupport.md)」を参照してください。

**Topics**
+ [SSL を使用して MySQL DB インスタンスに接続しているアプリケーションがあるかどうかの確認](#ssl-certificate-rotation-mysql.determining-server)
+ [クライアントが接続するために証明書の検証が必要かどうかの確認](#ssl-certificate-rotation-mysql.determining-client)
+ [アプリケーション信頼ストアの更新](#ssl-certificate-rotation-mysql.updating-trust-store)
+ [SSL 接続を確立するための Java コードの例](#ssl-certificate-rotation-mysql.java-example)

## SSL を使用して MySQL DB インスタンスに接続しているアプリケーションがあるかどうかの確認
<a name="ssl-certificate-rotation-mysql.determining-server"></a>

Amazon RDS for MySQL バージョン 5.7、8.0、または 8.4 を使用しており、Performance Schema が有効になっている場合は、次のクエリを実行すると、接続で SSL/TLS が使用されているかどうかを確認できます。Performance Schemaを有効にする方法については、MySQL ドキュメントの「[Performance Schemaクイックスタート](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-quick-start.html)」を参照してください。

```
mysql> SELECT id, user, host, connection_type 
       FROM performance_schema.threads pst 
       INNER JOIN information_schema.processlist isp 
       ON pst.processlist_id = isp.id;
```

この出力例では、`admin` で SSL が使用されているため、独自のセッション (`webapp1`) と、ログインしているアプリケーションの両方を確認できます。

```
+----+-----------------+------------------+-----------------+
| id | user            | host             | connection_type |
+----+-----------------+------------------+-----------------+
|  8 | admin           | 10.0.4.249:42590 | SSL/TLS         |
|  4 | event_scheduler | localhost        | NULL            |
| 10 | webapp1         | 159.28.1.1:42189 | SSL/TLS         |
+----+-----------------+------------------+-----------------+
3 rows in set (0.00 sec)
```

## クライアントが接続するために証明書の検証が必要かどうかの確認
<a name="ssl-certificate-rotation-mysql.determining-client"></a>

JDBC クライアントおよび MySQL クライアントを接続するために証明書の検証が必要かどうかを確認できます。

### JDBC
<a name="ssl-certificate-rotation-mysql.determining-client.jdbc"></a>

MySQL Connector/J 8.0 を使用した次の例では、アプリケーションの JDBC 接続プロパティをチェックして、正常な接続に有効な証明書が必要かどうかを確認する 1 つの方法を示します。MySQL のすべての JDBC 接続オプションの詳細については、MySQL ドキュメントの「[設定プロパティ](https://dev.mysql.com/doc/connector-j/en/connector-j-reference-configuration-properties.html)」を参照してください。

MySQL Connector/J 8.0 を使用する場合、次の例のように、接続プロパティで `sslMode` が `VERIFY_CA` または `VERIFY_IDENTITY` に設定されている場合、SSL 接続では DB サーバー証明書に対する検証が必要です。

```
Properties properties = new Properties();
properties.setProperty("sslMode", "VERIFY_IDENTITY");
properties.put("user", DB_USER);
properties.put("password", DB_PASSWORD);
```

**注記**  
MySQL Java Connector v5.1.38 以降または MySQL Java Connector v8.0.9 以降を使用してデータベースに接続する場合、データベースへの接続時に SSL/TLS を使用するようにアプリケーションを明示的に設定しなくても、これらのクライアントドライバーはデフォルトで SSL/TLS を使用します。また、SSL/TLS の使用時に証明書検証が部分的に実行され、データベースサーバー証明書の有効期限が切れていると、接続に失敗します。

### MySQL
<a name="ssl-certificate-rotation-mysql.determining-client.mysql"></a>

MySQL クライアントの以下の例では、スクリプトの MySQL 接続をチェックして、正常な接続に有効な証明書が必要かどうかを確認する 2 つの方法を示します。MySQL クライアントで使用するすべての接続オプションの詳細については、MySQL ドキュメントの「[ Client-Side Configuration for Encrypted Connections](https://dev.mysql.com/doc/refman/8.0/en/using-encrypted-connections.html#using-encrypted-connections-client-side-configuration)」を参照してください。

MySQL Client バージョン 5.7 以降を使用する場合に、次の例のように、`--ssl-mode` オプションに `VERIFY_CA` または `VERIFY_IDENTITY` を指定している場合は、SSL 接続にサーバー CA 証明書に対する検証が必要です。

```
mysql -h mysql-database.rds.amazonaws.com -uadmin -ppassword --ssl-ca=/tmp/ssl-cert.pem --ssl-mode=VERIFY_CA                
```

## アプリケーション信頼ストアの更新
<a name="ssl-certificate-rotation-mysql.updating-trust-store"></a>

MySQL アプリケーションの信頼ストアの更新については、MySQL ドキュメントの「[Installing SSL Certificates](https://dev.mysql.com/doc/mysql-monitor/8.0/en/mem-ssl-installation.html)」を参照してください。

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

証明書をインポートするサンプルスクリプトについては、[証明書を信頼ストアにインポートするためのサンプルスクリプト](UsingWithRDS.SSL-certificate-rotation.md#UsingWithRDS.SSL-certificate-rotation-sample-script) を参照してください。

**注記**  
信頼ストアを更新するとき、新しい証明書を追加できるだけでなく、古い証明書を保持できます。

アプリケーションで mysql JDBC ドライバーを使用している場合は、アプリケーションで以下のプロパティを設定します。

```
System.setProperty("javax.net.ssl.trustStore", certs);
System.setProperty("javax.net.ssl.trustStorePassword", "password");
```

アプリケーションを起動するとき、以下のプロパティを設定します。

```
java -Djavax.net.ssl.trustStore=/path_to_trust_store/MyTruststore.jks -Djavax.net.ssl.trustStorePassword=my_trust_store_password com.companyName.MyApplication        
```

**注記**  
セキュリティ上のベストプラクティスとして、ここに示されているプロンプト以外のパスワードを指定してください。

## SSL 接続を確立するための Java コードの例
<a name="ssl-certificate-rotation-mysql.java-example"></a>

次のコード例では、JDBC を使用してサーバー証明書を検証する SSL 接続のセットアップ方法を示します。

```
public class MySQLSSLTest {
     
        private static final String DB_USER = "username";
        private static final String DB_PASSWORD = "password";
        // This trust store has only the prod root ca.
        private static final String TRUST_STORE_FILE_PATH = "file-path-to-trust-store";
        private static final String TRUST_STORE_PASS = "trust-store-password";
            
        public static void test(String[] args) throws Exception {
            Class.forName("com.mysql.jdbc.Driver");
                    
            System.setProperty("javax.net.ssl.trustStore", TRUST_STORE_FILE_PATH);
            System.setProperty("javax.net.ssl.trustStorePassword", TRUST_STORE_PASS);
            
            Properties properties = new Properties();
            properties.setProperty("sslMode", "VERIFY_IDENTITY");
            properties.put("user", DB_USER);
            properties.put("password", DB_PASSWORD);
            
     
            Connection connection = null;
            Statement stmt = null;
            ResultSet rs = null;
            try {
                connection = DriverManager.getConnection("jdbc:mysql://mydatabase.123456789012.us-east-1.rds.amazonaws.com:3306",properties);
                stmt = connection.createStatement();
                rs=stmt.executeQuery("SELECT 1 from dual");
            } finally {
                if (rs != null) {
                    try {
                        rs.close();
                    } catch (SQLException e) {
                    }
                }
                if (stmt != null) {
                   try {
                        stmt.close();
                    } catch (SQLException e) {
                   }
                }
                if (connection != null) {
                    try {
                        connection.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
            return;
        }
    }
```

**重要**  
データベース接続で SSL/TLS を使用することを決定し、アプリケーションの信頼ストアを更新したら、rds-ca-rsa2048-g1 証明書を使用するようにデータベースを更新できます。ステップについては、「[DB インスタンスまたはクラスターの変更による CA 証明書の更新](UsingWithRDS.SSL-certificate-rotation.md#UsingWithRDS.SSL-certificate-rotation-updating)」のステップ 3 を参照してください。  
セキュリティ上のベストプラクティスとして、ここに示されているプロンプト以外のパスワードを指定してください。