Conexión al servidor flexible de Azure Database for MySQL con conexiones cifradas

SE APLICA A: Azure Database for MySQL: Servidor flexible

El servidor flexible de Azure Database for MySQL admite la conexión de las aplicaciones cliente a la instancia del servidor flexible de Azure Database for MySQL mediante el cifrado de la Capa de sockets seguros (SSL) con la Seguridad de la capa de transporte (TLS). TLS es un protocolo estándar del sector que garantiza conexiones de red cifradas entre el servidor de bases de datos y las aplicaciones cliente, lo que le permite ajustarse a los requisitos de cumplimiento.

De manera predeterminada, el servidor flexible de Azure Database for MySQL admite conexiones cifradas mediante la Seguridad de la capa de transporte (TLS 1.2), y todas las conexiones entrantes con TLS 1.0 y TLS 1.1 se deniegan de manera predeterminada. La obligatoriedad de conexiones cifradas o la configuración de versiones de TLS en el servidor flexible se pueden cambiar como se indica en este artículo.

A continuación se muestran las distintas configuraciones de SSL y TLS que puede tener para la instancia de servidor flexible de Azure Database for MySQL:

Escenario Configuración de parámetros del servidor Descripción
Deshabilitación de la aplicación de SSL require_secure_transport = OFF Si la aplicación heredada no admite conexiones cifradas al servidor flexible de Azure Database for MySQL, puede deshabilitar la obligatoriedad de conexiones cifradas a la instancia del servidor flexible de Azure Database for MySQL estableciendo require_secure_transport=OFF.
Exigir SSL con la versión de TLS < 1.2 require_secure_transport = ON y tls_version = TLS 1.0 o TLS 1.1 Si la aplicación heredada admite conexiones cifradas, pero necesita la versión de TLS < 1.2, puede permitir conexiones cifradas, pero debe configurar la instancia del servidor flexible de Azure Database for MySQL para permitir conexiones con la versión de TLS (1.0 o 1.1) admitida por la aplicación. Solo se admite con la versión 5.7 del servidor flexible de Azure Database for MySQL.
Exigir SSL con la versión de TLS = 1.2 (configuración predeterminada) require_secure_transport = ON y tls_version = TLSV 1.2 Esta es la configuración recomendada y predeterminada del servidor flexible de Azure Database for MySQL.
Exigir SSL con la versión de TLS = 1.3 require_secure_transport = ON y tls_version = TLS 1.3 Esta configuración es útil y recomendada para el desarrollo de nuevas aplicaciones. Solo se admite con la versión 8.0 del servidor flexible de Azure Database for MySQL.

Nota:

  • No se admiten cambios en el cifrado SSL en el servidor flexible de Azure Database for MySQL. Los conjuntos de cifrado FIPS se aplican de forma predeterminada cuando tls_version está establecido en la versión de TLS 1.2. En el caso de versiones de TLS distintas de la versión 1.2, el cifrado SSL se establece en la configuración predeterminada que se incluye con la instalación de la comunidad de MySQL.
  • En las ediciones de la comunidad de código abierto de MySQL a partir de las versiones 8.0.26 y 5.7.35, los protocolos en la versión de TLS 1.0 y versión de TLS 1.1 están en desuso. Estos protocolos publicados en 1996 y 2006 respectivamente para cifrar datos en movimiento se consideran débiles, obsoletos y vulnerables a las amenazas de seguridad. Para más información, consulte Eliminación de compatibilidad con los protocolos TLS 1.0 y TLS 1.1. El servidor flexible de Azure Database for MySQL también deja de admitir versiones de TLS una vez que la comunidad suspende la compatibilidad con el protocolo, con el fin de alinearse con los estándares de seguridad modernos.

En este artículo aprenderá a:

  • Configurar la instancia del servidor flexible de Azure Database for MySQL.
    • Con SSL deshabilitado
    • Con SSL exigido con la versión de TLS
  • Conectar la instancia del servidor flexible de Azure Database for MySQL mediante la línea de comandos de mysql.
    • Con conexiones cifradas deshabilitadas
    • Con conexiones cifradas habilitadas
  • Comprobar el estado de cifrado de la conexión
  • Conectar la instancia del servidor flexible de Azure Database for MySQL con conexiones cifradas mediante varios marcos de trabajo de aplicaciones

Deshabilitar la obligatoriedad de SSL en la instancia del servidor flexible de Azure Database for MySQL.

Si la aplicación cliente no admite conexiones cifradas, tiene que deshabilitar la obligatoriedad de conexiones cifradas en la instancia del servidor flexible de Azure Database for MySQL. Para deshabilitar la obligatoriedad de conexiones cifradas, debe establecer el parámetro de servidor require_secure_transport en OFF, tal y como se muestra en la captura de pantalla, y guardar la configuración para que surta efecto. require_secure_transport es un parámetro de servidor dinámico que surte efecto inmediatamente sin necesidad de reiniciar el servidor.

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

Conexión mediante el cliente de la línea de comandos de MySQL con SSL deshabilitado

En el ejemplo siguiente se muestra cómo conectarse al servidor mediante la interfaz de la línea de comandos mysql. Use la configuración de cadena de conexión --ssl-mode=DISABLED para deshabilitar la conexión TLS/SSL del cliente de MySQL. Reemplace los valores por el nombre real del servidor y la contraseña.

 mysql.exe -h mydemoserver.mysql.database.azure.com -u myadmin -p --ssl-mode=DISABLED

Importante

Establecer el require_secure_transport en OFF no significa que las conexiones cifradas no se admitan en el lado del servidor. Si establece require_secure_transport en OFF en la instancia del servidor flexible de Azure Database for MySQL, pero el cliente se conecta con la conexión cifrada, se sigue aceptando. La siguiente conexión mediante el cliente mysql a una instancia del servidor flexible de Azure Database for MySQL configurada con require_secure_transport=OFF también funciona como se muestra a continuación.

 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)

En resumen, la configuración de require_secure_transport=OFF reduce la obligatoriedad de conexiones cifradas en el servidor flexible de Azure Database for MySQL y permite conexiones no cifradas al servidor desde el cliente además de conexiones cifradas.

Exigir SSL con la versión de TLS

Para establecer versiones de TLS en la instancia del servidor flexible de Azure Database for MySQL, debe establecer el parámetro *tls_version- server. La configuración predeterminada para el protocolo TLS es TLS 1.2. Si la aplicación admite conexiones al servidor MySQL con SSL, pero requiere un protocolo que no es la versión 1.2 de TLS, debe establecer las versiones de TLS en el parámetro de servidor. *tls_version- es un parámetro de servidor estático que requerirá un reinicio del servidor para que surta efecto. A continuación, se muestran los protocolos admitidos para las versiones disponibles del servidor flexible de Azure Database for MySQL.

Versión del servidor flexible de Azure Database for MySQL Valores admitidos de tls_version Valor predeterminado
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

Conexión mediante el cliente de línea de comandos mysql con TLS/SSL

Descarga del certificado SSL público

Para usar conexiones cifradas con las aplicaciones cliente, debe descargar el certificado SSL público, que también está disponible en el panel Redes de Azure Portal, como se muestra en la captura de pantalla siguiente.

Screenshot showing how to download public SSL certificate from Azure portal.

Nota:

Debe descargar este certificado SSL de los servidores en la nube de Azure Government.

Guarde el archivo de certificado en la ubicación que prefiera. Por ejemplo, en este tutorial se usa c:\ssl o \var\www\html\bin en el entorno local o en el entorno cliente donde se hospeda la aplicación. Esto permite que las aplicaciones se conecten de forma segura a la base de datos a través de SSL.

Si ha creado la instancia del servidor flexible de Azure Database for MySQL con Acceso privado (integración con red virtual), debe conectarse al servidor desde un recurso que se encuentre en la misma red virtual que el servidor. Puede crear una máquina virtual y agregarla a la red virtual creada con la instancia del servidor flexible de Azure Database for MySQL.

Si ha creado la instancia del servidor flexible de Azure Database for MySQL con Acceso público (direcciones IP permitidas), puede agregar la dirección IP local a la lista de reglas de firewall del servidor.

Puede elegir mysql.exe o MySQL Workbench--> para conectarse al servidor desde su entorno local.

En el ejemplo siguiente se muestra cómo conectarse al servidor mediante la interfaz de la línea de comandos mysql. Use la configuración de la cadena de conexión --ssl-mode=REQUIRED para aplicar la comprobación del certificado TLS/SSL. Pase la ruta de acceso al archivo del certificado local al parámetro --ssl-ca. Reemplace los valores por el nombre real del servidor y la contraseña.

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

Nota

Confirme que el valor pasado a --ssl-ca coincide con la ruta de acceso al archivo del certificado que guardó. Si se va a conectar al servidor flexible de Azure Database for MySQL con SSL y usa una opción para realizar la comprobación completa (sslmode=VERTIFY_IDENTITY) con el nombre de sujeto del certificado, use <servername>.mysql.database.azure.com en la cadena de conexión.

Si intenta conectarse al servidor con conexiones no cifradas, verá un error parecido al siguiente, que indica que las conexiones que usan transporte no seguro están prohibidas:

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

Comprobación de la conexión TLS/SSL

Ejecute el comando status de MySQL para comprobar que se ha conectado al servidor de MySQL mediante TLS/SSL:

mysql> status

Confirme que la conexión está cifrada; para ello, revise la salida, que debe mostrar: SSL: el cifrado en uso es. Este conjunto de cifrado muestra un ejemplo; en función del cliente, puede ver otro conjunto de cifrado.

¿Cómo identificar los protocolos TLS configurados en el servidor?

Puede ejecutar el comando SHOW GLOBAL VARIABLES LIKE 'tls_version'; y comprobar el valor para comprender qué protocolos están configurados.

mysql> SHOW GLOBAL VARIABLES LIKE 'tls_version';

Cómo saber qué protocolo TLS utilizan mis clientes para conectarse al servidor

Puede ejecutar el comando siguiente y examinar tls_version de la sesión para identificar qué versión de TLS usan para conectarse.

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;

Conectar la instancia del servidor flexible de Azure Database for MySQL con conexiones cifradas mediante varios marcos de trabajo de aplicaciones

Las cadenas de conexión que están predefinidas en la página "Cadenas de conexión", disponible para el servidor en Azure Portal, incluyen los parámetros necesarios de lenguajes comunes para conectarse a su servidor de bases de datos mediante TLS/SSL. El parámetro TLS/SSL varía en función del conector. Por ejemplo, puede ser "useSSL=true", "sslmode=required" o "ssl_verify_cert=true", entre otras variables.

Para establecer una conexión cifrada a la instancia del servidor flexible de Azure Database for MySQL a través de TLS/SSL desde la aplicación, consulte los ejemplos de código siguientes:

WordPress

Descargue el certificado SSL público y agregue las siguientes líneas en wp-config.php después de la línea // **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 (mediante 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 (conector de MySQL para 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 (conector de MariaDB para 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;
});

Pasos siguientes