共用方式為


使用加密連線來連線到適用於 MySQL 的 Azure 資料庫 - 彈性伺服器

適用於:適用於 MySQL 的 Azure 資料庫 - 彈性伺服器

適用於 MySQL 的 Azure 資料庫彈性伺服器支援使用安全通訊端層 (SSL) 搭配傳輸層安全性 (TLS) 加密,將用戶端應用程式連線到適用於 MySQL 的 Azure 資料庫彈性伺服器執行個體。 TLS 為業界標準通訊協定,可確保資料庫伺服器與用戶端應用程式之間的網路連線經過加密,讓您遵守合規性需求。

適用於 MySQL 的 Azure 資料庫彈性伺服器預設支援使用傳輸層安全性 (TLS 1.2) 的加密連線,且預設會拒絕所有使用 TLS 1.0 和 TLS 1.1 的連入連線。 您可以如本文所述,變更彈性伺服器上的加密連線強制執行或 TLS 版本設定。

以下是適用於 MySQL 的 Azure 資料庫彈性伺服器執行個體可用 SSL 和 TLS 設定的不同設定:

重要事項

根據 移除 TLS 1.0 和 TLS 1.1 通訊協定的支持,我們先前計劃在 2024 年 9 月之前完全取代 TLS 1.0 和 1.1。 不過,由於某些客戶所識別的相依性,我們決定延長時程表。

  • 從 2025 年 8 月 31 日開始,我們將針對仍在使用 TLS 1.0 或 1.1 的所有伺服器開始強制升級。 在此日期之後,任何依賴 TLS 1.0 或 1.1 的連線隨時都可能會停止運作。 為避免潛在的服務中斷,我們強烈建議客戶在 2025 年 8 月 31 日之前完成移轉至 TLS 1.2。
  • 從 2024 年 9 月開始,將不再允許新伺服器使用 TLS 1.0 或 1.1,而且不允許現有伺服器降級至這些版本。

強烈建議客戶儘快更新其應用程式以支援 TLS 1.2,以避免服務中斷。

狀況 伺服器參數設定 描述
停用 SSL 強制執行 require_secure_transport = OFF 如果您的舊版應用程式不支援對適用於 MySQL 的 Azure 資料庫彈性伺服器的加密連線,則可藉由設定 require_secure_transport=OFF 來停用對適用於 MySQL 的 Azure 資料庫彈性伺服器執行個體的加密連線強制執行。
使用 TLS < 1.2 版 (將於 2024 年 9 月淘汰) 強制執行 SSL require_secure_transport = ON 以及 tls_version = TLS 1.0 或 TLS 1.1 如果您的舊版應用程式支援加密連線,但需要 TLS 版本 < 1.2 版,您可以啟用加密連線,但設定適用於 MySQL 的 Azure 資料庫彈性伺服器執行個體以允許與支援 TLS 版本 (1.0 或 1.1) 的連線。 僅支援適用於 MySQL 的 Azure 資料庫彈性伺服器 5.7 版
強制 SSL 使用 TLS 版本 = 1.2 (預設設定) require_secure_transport = ON 以及 tls_version = TLS 1.2 這是適用於 MySQL 的 Azure 資料庫彈性伺服器的建議和預設組態。
強制 SSL 使用 TLS 版本 = 1.3 require_secure_transport = ON 以及 tls_version = TLS 1.3 此設定對於新應用程式的開發很實用,建議使用。 僅支援適用於 MySQL 的 Azure 資料庫彈性伺服器 8.0 版

附註

不支援變更適用於 MySQL 的 Azure 資料庫彈性伺服器上的 SSL 加密。 當 tls_version 設定為 TLS 1.2 版時,預設會強制執行 FIPS 加密套件。 針對 1.2 版以外的 TLS 版本,SSL 加密會設定為 MySQL 社群安裝隨附的預設設定。

在本文中,您將學會如何:

  • 設定您的適用於 MySQL 的 Azure 資料庫彈性伺服器執行個體
    • 停用 SSL
    • 使用 TLS 版本強制執行 SSL
  • 使用 mysql 命令列連線到適用於 MySQL 的 Azure 資料庫彈性伺服器執行個體
    • 停用加密連線
    • 啟用加密連線
  • 確認連線的加密狀態
  • 使用各種應用程式架構,使用加密連線連接至適用於 MySQL 的 Azure 資料庫彈性伺服器執行個體

停用適用於 MySQL 的 Azure 資料庫彈性伺服器執行個體上的 SSL 強制執行

如果您的用戶端應用程式不支援加密連線,您必須停用適用於 MySQL 的 Azure 資料庫彈性伺服器執行個體上的加密連線強制執行。 若要停用加密連線強制執行,您必須如螢幕擷取畫面所示,將 require_secure_transport 伺服器參數設定為關閉,並儲存伺服器參數組態,使其生效。 require_secure_transport 是動態伺服器參數,會立即生效,而且不需要將伺服器重新開機,即會生效。

顯示如何使用適用於 MySQL 的 Azure 資料庫彈性伺服器來停用 SSL 的螢幕擷取畫面。

在 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 設定為關閉並不表示伺服器端不支援加密連線。 如果您在適用於 MySQL 的 Azure 資料庫彈性伺服器執行個體上將 require_secure_transport 設定為 [ OFF],但如果用戶端與加密連線連線,則仍會接受該連線。 下列使用 mysql 用戶端連線到使用 require_secure_transport=OFF 設定的適用於 MySQL 的 Azure 資料庫彈性伺服器執行個體也會運作,如下所示。

 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 設定會放寬適用於 MySQL 的 Azure 資料庫彈性伺服器上加密連線的強制執行,並允許從用戶端對伺服器的未加密連線。

強制 SSL 使用 TLS 版本

若要在適用於 MySQL 的 Azure 資料庫彈性伺服器執行個體上設定 TLS 版本,您必須設定 *tls_version- 伺服器參數。 TLS 通訊協定的預設設定為 TLS 1.2。 如果您的應用程式支援使用 SSL 連線到 MySQL 伺服器,但需要 TLS 1.2 以外的任何通訊協定,您必須在伺服器參數中設定 TLS 版本。 *tls_version- 是靜態伺服器參數,需要將伺服器重新啟動,參數才會生效。 以下是適用於 MySQL 的 Azure 資料庫 – 彈性伺服器可用版本的支援通訊協定。

適用於 MySQL 的 Azure 資料庫彈性伺服器版本 支援的 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

使用 mysql 命令列用戶端搭配 TLS/SSL 連線

下載公用 SSL 憑證

若要與用戶端應用程式建立加密連線,請下載 DigiCert 全域根目錄 G2 憑證Microsoft RSA 根憑證授權單位 2017 憑證。 在起始與伺服器的連線之前,請先合併這兩個憑證。 如需詳細步驟,請參閱如何 更新用戶端上的根憑證存放區

附註

您必須在 Azure 政府雲端中下載伺服器的 DigiCert 全域根目錄 G2 憑證

您必須在 Azure Mooncake 中下載伺服器的 DigiCert 全域根憑證

將憑證檔案儲存至您慣用的位置。 例如,本教學課程會在本地環境或託管應用程式所在的用戶端環境上使用 c:\ssl\var\www\html\bin。 這可讓應用程式透過 SSL 安全地連線到資料庫。

如果您使用私人存取 (VNet 整合) 建立適用於 MySQL 的 Azure 資料庫彈性伺服器執行個體,就必須從與伺服器相同的 VNet 中的資源連線到伺服器。 您可以建立虛擬機器,並新增至使用您適用於 MySQL 的 Azure 資料庫彈性伺服器執行個體建立的 VNet。

如果您使用公用存取 (允許的 IP 位址)建立適用於 MySQL 的 Azure 資料庫彈性伺服器執行個體,可以將本機 IP 位址新增至伺服器上的防火牆規則清單。

您可以選擇 mysql.exe使用 MySQL Workbench 搭配適用於 MySQL 的 Azure 資料庫 - 彈性伺服器--> 從本機環境連線到伺服器。

下列範例會示範如何使用 mysql 命令列介面來連接到伺服器。 使用 --ssl-mode=REQUIRED 連接字串設定來強制執行 TLS/SSL 憑證驗證。 將本地憑證檔案路徑傳遞至 --ssl-ca 參數。 以實際的伺服器名稱和密碼取代這些值。

sudo apt-get install mysql-client
wget --no-check-certificate https://cacerts.digicert.com/DigiCertGlobalRootG2.crt.pem
mysql -h mydemoserver.mysql.database.azure.com -u mydemouser -p --ssl-mode=REQUIRED --ssl-ca=DigiCertGlobalRootG2.crt.pem

附註

確認傳遞給 --ssl-ca 的值與您所儲存憑證的檔案路徑相符。 如果您要連線到適用於 MySQL 的 Azure 資料庫 - 彈性伺服器搭配 SSL 連線,並使用選項來執行憑證主體名稱的完整驗證 (sslmode=VERTIFY_IDENTITY),請在連接字串中使用 <servername>.mysql.database.azure.com。

如果您嘗試使用未加密的連線連接到伺服器,您會看到錯誤,指出使用不安全傳輸的連線是被禁止的,與以下類似:

ERROR 3159 (HY000): Connections using insecure transport are prohibited while --require_secure_transport=ON.

確認 TLS/SSL 連線

執行 mysql status 命令,確認您已使用 TLS/SSL 連線至 MySQL 伺服器︰

mysql> status

檢閱輸出來確認連線已加密,應該會顯示:使用中的 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;

使用各種應用程式架構,使用加密連線連接至適用於 MySQL 的 Azure 資料庫彈性伺服器執行個體

在 Azure 入口網站中,您的伺服器可用的 [連接字串] 頁面中所預先定義的連接字串,也包含通用語言使用 TLS/SSL 連線至資料庫伺服器所需的參數。 TLS/SSL 參數會根據連接器而有所不同。 例如,「useSSL=true」、「sslmode=required」或「ssl_verify_cert=true」和其他變化。

若要從透過 TLS/SSL 從應用程式建立與適用於 MySQL 的 Azure 資料庫彈性伺服器執行個體的加密連線,請參閱下列程式碼範例:

WordPress

下載 SSL 公開憑證,並在行 // **MySQL settings - You can get this info from your web host** // 之後於 wp-config.php 中新增下列幾行。

//** Connect with SSL ** //
define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL);
//** SSL CERT **//
define('MYSQL_SSL_CERT','/FULLPATH/on-client/to/DigiCertGlobalRootG2.crt.pem');

PHP

$conn = mysqli_init();
mysqli_ssl_set($conn,NULL,NULL, "/var/www/html/DigiCertGlobalRootG2.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/DigiCertGlobalRootG2.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/DigiCertGlobalRootG2.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/DigiCertGlobalRootG2.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/DigiCertGlobalRootG2.crt.pem'}
        }
    }
}

Ruby

client = Mysql2::Client.new(
        :host     => 'mydemoserver.mysql.database.azure.com',
        :username => 'myadmin',
        :password => 'yourpassword',
        :database => 'quickstartdb',
        :sslca => '/var/www/html/DigiCertGlobalRootG2.crt.pem'
    )

Golang

rootCertPool := x509.NewCertPool()
pem, _ := ioutil.ReadFile("/var/www/html/DigiCertGlobalRootG2.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 (適用於 Java 的 MySQL 連接器)

# 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 (適用於 Java 的 MariaDB 連接器)

# 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 = "DigiCertGlobalRootG2.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/DigiCertGlobalRootG2.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;
});