暗号化された接続を使用して Azure Database for MySQL - フレキシブル サーバーに接続する
適用対象: Azure Database for MySQL - フレキシブル サーバー
Azure Database for MySQL フレキシブル サーバーは、トランスポート層セキュリティ (TLS) 暗号化による Secure Sockets Layer (SSL) を使用して、クライアント アプリケーションを Azure Database for MySQL フレキシブル サーバー インスタンスに接続することをサポートしています。 TLS は、データベース サーバーとクライアント アプリケーションの間の暗号化されたネットワーク接続を保証する業界標準のプロトコルであり、ユーザーがコンプライアンス要件に準拠できるようにします。
Azure Database for MySQL フレキシブル サーバーでは、トランスポート層セキュリティ (TLS 1.2) を使用する暗号化された接続が既定でサポートされ、TLS 1.0 と TLS 1.1 を使用する受信接続はすべて既定で拒否されます。 フレキシブル サーバーでの暗号化された接続の強制または TLS のバージョンの構成は、この記事で説明されているように変更できます。
Azure Database for MySQL フレキシブル サーバー インスタンスで使用できる SSL および TLS 設定のさまざまな構成を次に示します。
重要
TLS 1.0 および TLS 1.1 プロトコルのサポートの変更により、2024 年 9 月上旬以降、新しいサーバーでは TLS 1.0 または 1.1 の使用が許可されなくなり、既存のサーバーはこれらのバージョンにダウングレードできなくなります。 2024 年 9 月中旬から、現在 TLS 1.0 または 1.1 を使っているすべてのサーバーの TLS 1.2 への必須のアップグレードが開始されます。 このアップグレード プロセスは、2024 年 9 月末までに完了する予定です。 お客様には、9 月末までにアプリケーションが TLS 1.2 と完全に互換性があることを確認することを強くお勧めします。
シナリオ | サーバー パラメーターの設定 | 説明 |
---|---|---|
SSL 強制を無効にする | require_secure_transport = OFF | レガシ アプリケーションが Azure Database for MySQL フレキシブル サーバーへの暗号化された接続をサポートしていない場合は、require_secure_transport=OFF と設定して、Azure Database for MySQL フレキシブル サーバー インスタンスへの暗号化された接続の強制を無効にできます。 |
TLS バージョン < 1.2 で SSL を強制する (2024 年 9 月に非推奨になる予定) | require_secure_transport = ON および tls_version = TLS 1.0 または TLS 1.1 | レガシ アプリケーションで暗号化された接続がサポートされているが、TLS バージョン < 1.2 が必要な場合は、暗号化された接続を有効にできますが、アプリケーションでサポートされている TLS バージョン (1.0 または 1.1) での接続を許可するように Azure Database for MySQL フレキシブル サーバー インスタンスを構成します。 Azure Database for MySQL フレキシブル サーバー バージョン v5.7 でのみサポートされます |
TLS バージョン 1.2 で SSL を強制する (既定の構成) | require_secure_transport = ON および tls_version = TLS 1.2 | これは、Azure Database for MySQL フレキシブル サーバーに推奨される既定の構成です。 |
TLS バージョン = 1.3 で SSL を強制する | require_secure_transport = ON および tls_version = TLS 1.3 | これは、新しいアプリケーションの開発に便利であり、推奨されます。 Azure Database for MySQL フレキシブル サーバー バージョン v8.0 でのみサポートされます |
Note
Azure Database for MySQL フレキシブル サーバーでの SSL 暗号の変更はサポートされていません。 tls_version が TLS バージョン 1.2 に設定されている場合、FIPS 暗号スイートが既定で強制されます。 バージョン 1.2 以外の TLS の場合、SSL 暗号は、MySQL Community のインストールに付随する既定値に設定されます。
この記事では、次のことについて説明します。
- Azure Database for MySQL フレキシブル サーバー インスタンスの構成
- SSL を無効にする
- TLS バージョンで SSL を強制した場合
- mysql コマンドラインを使用して Azure Database for MySQL フレキシブル サーバー インスタンスに接続する
- 暗号化された接続を無効にする
- 暗号化された接続を有効にする
- 接続の暗号化の状態を確認する
- さまざまなアプリケーション フレームワークを使用して、暗号化された接続で Azure Database for MySQL フレキシブル サーバー インスタンスに接続する
Azure Database for MySQL フレキシブル サーバー インスタンスで SSL の強制を無効にする
クライアント アプリケーションが暗号化された接続をサポートしていない場合は、Azure Database for MySQL フレキシブル サーバー インスタンスで暗号化された接続の強制を無効にする必要があります。 暗号化された接続の強制を無効にするには、スクリーンショットに示されているように require_secure_transport サーバー パラメーターを OFF に設定し、このサーバー パラメーターの構成を保存して反映します。 require_secure_transport は、ただちに有効になる動的サーバー パラメーターであるため、有効にするためにサーバーを再起動する必要はありません。
SSL を無効にした mysql コマンド ライン クライアントを使用して接続する
次の例は、mysql コマンド ライン インターフェイスを使用してサーバーに接続する方法を示しています。 --ssl-mode=DISABLED
接続文字列設定を使用して、mysql クライアントからの TLS/SSL 接続を無効にします。 値を実際のサーバー名とパスワードに置き換えてください。
mysql.exe -h mydemoserver.mysql.database.azure.com -u myadmin -p --ssl-mode=DISABLED
重要
require_secure_transport を OFF に設定しても、暗号化された接続がサーバー側でサポートされないわけではありません。 Azure Database for MySQL フレキシブル サーバー インスタンスで require_secure_transport を OFF に設定しても、クライアントが暗号化された接続で接続する場合は、引き続き受け入れられます。 require_secure_transport=OFF で構成された Azure Database for MySQL フレキシブル サーバー インスタンスへの mysql クライアントを使用した次の接続も、以下のように機能します。
mysql.exe -h mydemoserver.mysql.database.azure.com -u myadmin -p --ssl-mode=REQUIRED
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 17
Server version: 5.7.29-log MySQL Community Server (GPL)
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show global variables like '%require_secure_transport%';
+--------------------------+-------+
| Variable_name | Value |
| +--------------------------+-------+ |
| require_secure_transport | OFF |
| +--------------------------+-------+ |
| 1 row in set (0.02 sec) |
まとめると、require_secure_transport=OFF を設定すると、Azure Database for MySQL フレキシブル サーバーでの暗号化された接続の強制が緩和され、クライアントからサーバーへの暗号化されていない接続も、暗号化された接続に加えて許可されます。
TLS バージョンで SSL を強制する
Azure Database for MySQL フレキシブル サーバー インスタンスで TLS バージョンを設定するには、*tls_version- サーバー パラメーターを設定する必要があります。 TLS プロトコルのデフォルトの設定は TLS 1.2 です。 アプリケーションで SSL を使用した MySQL サーバーへの接続がサポートされているが、TLS 1.2 以外のプロトコルが必要な場合は、サーバー パラメーターで TLS バージョンを設定する必要があります。 *tls_version- は静的サーバー パラメーターであるため、パラメーターを反映するにはサーバーを再起動する必要があります。 Azure Database for MySQL フレキシブル サーバーの使用可能なバージョンでサポートされているプロトコルは次のとおりです。
Azure Database for MySQL フレキシブル サーバーのバージョン | tls_versionのサポートされる値 | 既定の設定 |
---|---|---|
MySQL 5.7 | TLS 1.0、TLS 1.1 (2024 年 9 月に非推奨になります) TLS 1.2 | TLS 1.2 |
MySQL 8.0 | TLS 1.2、TLS 1.3 | TLS 1.2 |
TLS/SSL で mysql コマンド ライン クライアントを使用して接続する
パブリック SSL 証明書をダウンロードする
クライアント アプリケーションで暗号化された接続を使用するには、パブリック SSL 証明書をダウンロードする必要があります。これは、以下のスクリーンショットに示すように、Azure portal の [ネットワーク] ペインでも入手できます。
Note
この SSL 証明書は、Azure Government クラウド内のサーバー用にダウンロードする必要があります。
証明書ファイルをダウンロードし、希望の場所に保存します。 たとえば、このチュートリアルでは、ローカル環境、またはアプリケーションがホストされているクライアント環境の c:\ssl
または \var\www\html\bin
を使用しています。 これにより、アプリケーションから SSL 経由で安全にデータベースに接続できるようになります。
"プライベート アクセス (VNet 統合)" を使用して Azure Database for MySQL フレキシブル サーバー インスタンスを作成した場合、サーバーと同じ VNet 内のリソースからサーバーに接続する必要があります。 仮想マシンを作成し、Azure Database for MySQL フレキシブル サーバー インスタンスで作成した VNet に追加できます。
"パブリック アクセス (許可された IP アドレス)" を使用して Azure Database for MySQL フレキシブル サーバー インスタンスを作成した場合、サーバーのファイアウォール規則のリストにローカル IP アドレスを追加できます。
ローカル環境からサーバーに接続するには、mysql.exe または Azure Database for MySQL - フレキシブル サーバーで MySQL Workbench を使用する--> のいずれかを選択できます。
次の例は、mysql コマンド ライン インターフェイスを使用してサーバーに接続する方法を示しています。 --ssl-mode=REQUIRED
接続文字列設定を使用して、TLS/SSL 証明書の検証を適用します。 ローカルの証明書ファイルのパスを --ssl-ca
パラメーターに渡します。 値を実際のサーバー名とパスワードに置き換えてください。
sudo apt-get install mysql-client
wget --no-check-certificate https://dl.cacerts.digicert.com/DigiCertGlobalRootCA.crt.pem
mysql -h mydemoserver.mysql.database.azure.com -u mydemouser -p --ssl-mode=REQUIRED --ssl-ca=DigiCertGlobalRootCA.crt.pem
Note
--ssl-ca
に渡された値が、保存済みの証明書のファイル パスと一致することを確認します。
SSL を使用して Azure Database for MySQL フレキシブル サーバーに接続しており、証明書のサブジェクト名を使用して完全な検証 (sslmode=VERTIFY_IDENTITY) を実行するオプションを使用している場合、接続文字列には <servername>.mysql.database.azure.com を使用します。
暗号化されていない接続を使用してサーバーに接続しようとすると、セキュリティで保護されていないトランスポートを使用した接続が禁止されていることを示す、下のようなエラーが表示されます。
ERROR 3159 (HY000): Connections using insecure transport are prohibited while --require_secure_transport=ON.
TLS/SSL 接続を確認する
TLS/SSL を使用して MySQL サーバーに接続していることを確認するには、MySQL の status コマンドを実行します。
mysql> status
接続が暗号化されていることを確認します。そのために、出力に "SSL: Cipher in use is" (SSL: 使用中の暗号) と表示されていることを確認します。 この暗号スイートは例を示しており、クライアントによっては別の暗号スイートが表示されることがあります。
サーバーで構成されている TLS プロトコルを識別する方法
コマンド SHOW GLOBAL VARIABLES LIKE 'tls_version' を実行できます。そして、すべてのプロトコルが構成されているかを理解するために値を確認します。
mysql> SHOW GLOBAL VARIABLES LIKE 'tls_version';
自分のクライアントがサーバーへの接続に使用している TLS プロトコルを見つける方法
以下のコマンドを実行し、セッションの tls_version を確認して、接続に使用されている TLS バージョンを特定できます。
SELECT sbt.variable_value AS tls_version, t2.variable_value AS cipher,
processlist_user AS user, processlist_host AS host
FROM performance_schema.status_by_thread AS sbt
JOIN performance_schema.threads AS t ON t.thread_id = sbt.thread_id
JOIN performance_schema.status_by_thread AS t2 ON t2.thread_id = t.thread_id
WHERE sbt.variable_name = 'Ssl_version' and t2.variable_name = 'Ssl_cipher' ORDER BY tls_version;
さまざまなアプリケーション フレームワークを使用して、暗号化された接続で Azure Database for MySQL フレキシブル サーバー インスタンスに接続する
Azure portal でサーバーに使用できる [接続文字列] ページで事前定義されている接続文字列には、TLS/SSL を使用してデータベース サーバーに接続するための一般的な言語の必須のパラメーターが含まれています。 TLS/SSL パラメーターは、コネクタによって異なります。 たとえば、"useSSL=true"、"sslmode=required"、または "ssl_verify_cert=true" などのバリエーションがあります。
アプリケーションから TLS/SSL 経由で Azure Database for MySQL フレキシブル サーバー インスタンスへの暗号化された接続を確立するには、次のコード サンプルを参照してください。
WordPress
SSL パブリック証明書をダウンロードして、wp-config.php 内で // **MySQL settings - You can get this info from your web host** //
行の後に次の行を追加します。
//** Connect with SSL ** //
define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL);
//** SSL CERT **//
define('MYSQL_SSL_CERT','/FULLPATH/on-client/to/DigiCertGlobalRootCA.crt.pem');
PHP
$conn = mysqli_init();
mysqli_ssl_set($conn,NULL,NULL, "/var/www/html/DigiCertGlobalRootCA.crt.pem", NULL, NULL);
mysqli_real_connect($conn, 'mydemoserver.mysql.database.azure.com', 'myadmin', 'yourpassword', 'quickstartdb', 3306, MYSQLI_CLIENT_SSL);
if (mysqli_connect_errno()) {
die('Failed to connect to MySQL: '.mysqli_connect_error());
}
PHP (PDO を使用)
$options = array(
PDO::MYSQL_ATTR_SSL_CA => '/var/www/html/DigiCertGlobalRootCA.crt.pem'
);
$db = new PDO('mysql:host=mydemoserver.mysql.database.azure.com;port=3306;dbname=databasename', 'myadmin', 'yourpassword', $options);
Python (MySQLConnector Python)
try:
conn = mysql.connector.connect(user='myadmin',
password='<password>',
database='quickstartdb',
host='mydemoserver.mysql.database.azure.com',
ssl_ca='/var/www/html/DigiCertGlobalRootCA.crt.pem')
except mysql.connector.Error as err:
print(err)
Python (PyMySQL)
conn = pymysql.connect(user='myadmin',
password='<password>',
database='quickstartdb',
host='mydemoserver.mysql.database.azure.com',
ssl={'ca': '/var/www/html/DigiCertGlobalRootCA.crt.pem'})
Django (PyMySQL)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'quickstartdb',
'USER': 'myadmin',
'PASSWORD': 'yourpassword',
'HOST': 'mydemoserver.mysql.database.azure.com',
'PORT': '3306',
'OPTIONS': {
'ssl': {'ca': '/var/www/html/DigiCertGlobalRootCA.crt.pem'}
}
}
}
Ruby
client = Mysql2::Client.new(
:host => 'mydemoserver.mysql.database.azure.com',
:username => 'myadmin',
:password => 'yourpassword',
:database => 'quickstartdb',
:sslca => '/var/www/html/DigiCertGlobalRootCA.crt.pem'
)
Golang
rootCertPool := x509.NewCertPool()
pem, _ := ioutil.ReadFile("/var/www/html/DigiCertGlobalRootCA.crt.pem")
if ok := rootCertPool.AppendCertsFromPEM(pem); !ok {
log.Fatal("Failed to append PEM.")
}
mysql.RegisterTLSConfig("custom", &tls.Config{RootCAs: rootCertPool})
var connectionString string
connectionString = fmt.Sprintf("%s:%s@tcp(%s:3306)/%s?allowNativePasswords=true&tls=custom",'myadmin' , 'yourpassword', 'mydemoserver.mysql.database.azure.com', 'quickstartdb')
db, _ := sql.Open("mysql", connectionString)
Java (MySQL Connector for Java)
# generate truststore and keystore in code
String importCert = " -import "+
" -alias mysqlServerCACert "+
" -file " + ssl_ca +
" -keystore truststore "+
" -trustcacerts " +
" -storepass password -noprompt ";
String genKey = " -genkey -keyalg rsa " +
" -alias mysqlClientCertificate -keystore keystore " +
" -storepass password123 -keypass password " +
" -dname CN=MS ";
sun.security.tools.keytool.Main.main(importCert.trim().split("\\s+"));
sun.security.tools.keytool.Main.main(genKey.trim().split("\\s+"));
# use the generated keystore and truststore
System.setProperty("javax.net.ssl.keyStore","path_to_keystore_file");
System.setProperty("javax.net.ssl.keyStorePassword","password");
System.setProperty("javax.net.ssl.trustStore","path_to_truststore_file");
System.setProperty("javax.net.ssl.trustStorePassword","password");
url = String.format("jdbc:mysql://%s/%s?serverTimezone=UTC&useSSL=true", 'mydemoserver.mysql.database.azure.com', 'quickstartdb');
properties.setProperty("user", 'myadmin');
properties.setProperty("password", 'yourpassword');
conn = DriverManager.getConnection(url, properties);
Java (MariaDB Connector for Java)
# generate truststore and keystore in code
String importCert = " -import "+
" -alias mysqlServerCACert "+
" -file " + ssl_ca +
" -keystore truststore "+
" -trustcacerts " +
" -storepass password -noprompt ";
String genKey = " -genkey -keyalg rsa " +
" -alias mysqlClientCertificate -keystore keystore " +
" -storepass password123 -keypass password " +
" -dname CN=MS ";
sun.security.tools.keytool.Main.main(importCert.trim().split("\\s+"));
sun.security.tools.keytool.Main.main(genKey.trim().split("\\s+"));
# use the generated keystore and truststore
System.setProperty("javax.net.ssl.keyStore","path_to_keystore_file");
System.setProperty("javax.net.ssl.keyStorePassword","password");
System.setProperty("javax.net.ssl.trustStore","path_to_truststore_file");
System.setProperty("javax.net.ssl.trustStorePassword","password");
url = String.format("jdbc:mariadb://%s/%s?useSSL=true&trustServerCertificate=true", 'mydemoserver.mysql.database.azure.com', 'quickstartdb');
properties.setProperty("user", 'myadmin');
properties.setProperty("password", 'yourpassword');
conn = DriverManager.getConnection(url, properties);
.NET (MySqlConnector)
var builder = new MySqlConnectionStringBuilder
{
Server = "mydemoserver.mysql.database.azure.com",
UserID = "myadmin",
Password = "yourpassword",
Database = "quickstartdb",
SslMode = MySqlSslMode.VerifyCA,
SslCa = "DigiCertGlobalRootCA.crt.pem",
};
using (var connection = new MySqlConnection(builder.ConnectionString))
{
connection.Open();
}
Node.js
var fs = require('fs');
var mysql = require('mysql');
const serverCa = [fs.readFileSync("/var/www/html/DigiCertGlobalRootCA.crt.pem", "utf8")];
var conn=mysql.createConnection({
host:"mydemoserver.mysql.database.azure.com",
user:"myadmin",
password:"yourpassword",
database:"quickstartdb",
port:3306,
ssl: {
rejectUnauthorized: true,
ca: serverCa
}
});
conn.connect(function(err) {
if (err) throw err;
});