暗号化された接続を使用して Azure Database for MySQL - フレキシブル サーバーに接続する

適用対象: Azure Database for MySQL - フレキシブル サーバー

Azure Database for MySQL フレキシブル サーバーでは、Secure Sockets Layer (SSL) とトランスポート層セキュリティ (TLS) 暗号化を使用して、クライアント アプリケーションを 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 設定のさまざまな構成を次に示します:

シナリオ サーバー パラメーターの設定 説明
SSL 強制を無効にする require_secure_transport = OFF レガシ アプリケーションで Azure Database for MySQL フレキシブル サーバーへの暗号化された接続がサポートされていない場合、require_secure_transport=OFF を設定して、Azure Database for MySQL フレキシブル サーバーへの暗号化された接続の強制を無効にできます。
バージョン 1.2 より前の TLS で SSL を強制する 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 のインストールに付随する既定値に設定されます。
  • MySQL バージョン 8.0.26 および 5.7.35 のリリース以降の MySQL オープン ソース コミュニティ エディションでは、TLS 1.0. と TLS 1.1 プロトコルは非推奨です。 1996 年と 2006 年にリリースされたこれらのプロトコルは、動作中のデータを暗号化するためにそれぞれ、脆弱で古く、セキュリティ上の脅威に対して脆弱であると見なされます。 詳細については、「TLS 1.0 および TLS 1.1 プロトコルのサポートの削除」を参照してください。 また、Azure Database for MySQL フレキシブル サーバーは、コミュニティがプロトコルのサポートを停止すると、最TLS バージョンのサポートも停止して、最新のセキュリティ標準に合わせます。

この記事では、次のことについて説明します。

  • 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 は、ただちに有効になる動的サーバー パラメーターであるため、有効にするためにサーバーを再起動する必要はありません。

Screenshot showing how to disable SSL with Azure Database for MySQL flexible server.

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、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 の [ネットワーク] ペインでも入手できます。

Screenshot showing how to download public SSL certificate from 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 または 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='yourpassword',
                                   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='yourpassword',
                       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;
});

次のステップ