sql >> Base de Datos >  >> RDS >> Mysql

¿Las conexiones de mi servidor MySQL están cifradas y son seguras?

Uno de los mayores factores y fundamentos del gobierno de datos es la seguridad. Es una buena práctica tener implementada la seguridad de la base de datos siempre que tenga la administración de datos involucrada para la empresa o el consumo masivo.

La seguridad de los datos es uno de los aspectos más importantes de la administración de una base de datos. Desempeña un papel fundamental para el que toda gestión de base de datos debe implementar. Cuando se implementa y se hace correctamente, el resultado mejorará no solo la seguridad de sus datos, sino que también afectará la estabilidad del sistema, mejorará el ciclo de vida del desarrollo, impulsará el cumplimiento de sus datos y mejorará la conciencia de seguridad hasta el nivel de su equipo. Todo el mundo no quiere que sus datos acaben en las manos equivocadas. Si se violan los datos, no solo se pone en riesgo la confidencialidad y la integridad de sus datos, sino que también deja a su organización expuesta a importantes riesgos financieros. Incluso para una simple implementación de administración de base de datos, si descubre que alguien ya se ha entrometido en su sistema, la sensación de inseguridad y miedo sobre las consecuencias que le traerá es totalmente incómoda.

Determinar si la conexión de su servidor MySQL es segura depende de la seguridad con la que MySQL transmite los datos en tránsito. Con una conexión sin cifrar entre el cliente MySQL y el servidor, alguien con acceso a la red podría observar todo su tráfico e inspeccionar los datos que se envían o reciben entre el cliente y el servidor.

Cuando debe mover información a través de una red de manera segura, una conexión sin cifrar es inaceptable. Para hacer ilegible cualquier tipo de datos, utilice el cifrado. Los algoritmos de cifrado deben incluir elementos de seguridad para resistir muchos tipos de ataques conocidos, como cambiar el orden de los mensajes cifrados o reproducir los datos dos veces.

Pero mi MySQL es seguro, ¿verdad?

Creer que su MySQL es seguro sin determinar su estabilidad y controles de vulnerabilidad es como una religión. Tiendes a creer incluso sin verlo, incluso sin tocarlo. El problema es que MySQL es una tecnología y su existencia no se basa en pensamientos abstractos. Debe probarse, debe probarse y requiere seguridad y sigue las mejores prácticas que también han sido probadas por otros.

Determinar si las conexiones de su servidor MySQL, es decir, en tránsito, son seguras o si están encriptadas depende de "¿cómo configuró su base de datos?" o "¿quién configuró su base de datos?".

MySQL admite conexiones cifradas entre los clientes y el servidor utilizando el protocolo TLS (Seguridad de la capa de transporte). TLS a veces se conoce como SSL (Secure Sockets Layer), pero MySQL en realidad no usa el protocolo SSL para conexiones cifradas porque su cifrado es débil y SSL ya ha sido obsoleto a favor de TLS. TLS utiliza algoritmos de cifrado para garantizar que se pueda confiar en los datos recibidos a través de una red pública. Tiene mecanismos para detectar cambios, pérdidas o reproducciones de datos. TLS también incorpora algoritmos que proporcionan verificación de identidad utilizando el estándar X.509. SSL o TLS se usan indistintamente, pero para el contexto del cifrado con MySQL, se usa TLS para el cual MySQL admite conexiones cifradas mediante los protocolos TLSv1, TLSv1.1, TLSv1.2 y TLSv1.3.

X.509 permite identificar a alguien en Internet. En términos básicos, debería haber alguna entidad llamada “Autoridad de certificación” (o CA) que asigne certificados electrónicos a cualquier persona que los necesite. Los certificados se basan en algoritmos de cifrado asimétrico que tienen dos claves de cifrado (una clave pública y una clave secreta). El propietario de un certificado puede presentar el certificado a otra parte como prueba de identidad. Un certificado consta de la clave pública de su propietario. Todos los datos cifrados con esta clave pública se pueden descifrar solo con la clave secreta correspondiente, que está en poder del propietario del certificado.

Al igual que los espartanos usaban Scytale

Se sabe que Scytale se usa como una forma de cifrar y descifrar un mensaje que se usó alrededor del año 400 a.C. por los espartanos. Escribían un mensaje en una hoja de papiro (un tipo de papel) que se envolvía alrededor de un bastón. El destinatario solo puede descifrar el mensaje si el diámetro y el tamaño del personal son correctos. Sirve como una forma de cifrar y evitar la extracción no autorizada de mensajes o datos al destino de destino.

Al igual que con MySQL, el uso de cifrados y protocolos SSL/TLS es una forma de evitar que alguien extraiga sus datos o los secuestre mientras pasan por Internet o por cable.

De forma predeterminada, los programas MySQL intentan conectarse mediante cifrado si el servidor admite conexiones cifradas, recurriendo a una conexión no cifrada si no se puede establecer una conexión cifrada. Desde la versión MySQL>=5.7, se pueden crear o generar archivos TLS/SSL y RSA con el apoyo de variables. Para las distribuciones MySQL compiladas con OpenSSL, el servidor MySQL tiene la capacidad de generar automáticamente los archivos SSL y RSA faltantes al inicio. Las variables de sistema auto_generate_certs, sha256_password_auto_generate_rsa_keys y caching_sha2_password_auto_generate_rsa_keys (versión>=8.0) controlan la generación automática de estos archivos. Estas variables están habilitadas de forma predeterminada. Se pueden habilitar en el inicio e inspeccionar, pero no establecer en tiempo de ejecución.

De forma predeterminada, estas variables están activadas o habilitadas. De lo contrario, los usuarios pueden invocar la utilidad mysql_ssl_rsa_setup manualmente. Para algunos tipos de distribución, como paquetes RPM y DEB, la invocación de mysql_ssl_rsa_setup ocurre durante la inicialización del directorio de datos. En este caso, no es necesario que la distribución de MySQL se haya compilado con OpenSSL siempre que el comando openssl esté disponible.

Una vez que estos archivos estén disponibles y/o generados, MySQL seguirá sin usar conexiones de encriptación por las siguientes razones. Como se mencionó anteriormente, de forma predeterminada, los programas cliente de MySQL intentan establecer una conexión cifrada si el servidor admite conexiones cifradas, con control adicional disponible a través de --ssl-mode (o --ssl <=5.7.11 ya que esto ya está en desuso) opción:

  • De forma predeterminada, si la conexión MySQL no está marcada con --ssl-mode, el valor predeterminado se establece en --ssl-mode=PREFERIDO. Por lo tanto, los clientes intentan conectarse mediante el cifrado y recurren a una conexión no cifrada si no se puede establecer una conexión cifrada.

  • Con --ssl-mode=REQUIRED, los clientes requieren una conexión cifrada y fallan si no se puede establecer una.

  • Con --ssl-mode=DISABLED, los clientes utilizan una conexión sin cifrar.

  • Con --ssl-mode=VERIFY_CA o --ssl-mode=VERIFY_IDENTITY, los clientes requieren una conexión cifrada y también realice la verificación contra el certificado CA del servidor y (con VERIFY_IDENTITY) contra el nombre de host del servidor en su certificado.

Con el mecanismo predeterminado de MySQL para usar una conexión preferida, es probable que intente usar la conexión encriptada o segura, pero esto aún deja algunas cosas por hacer y por determinar.

Como se mencionó anteriormente, las variables auto_generate_certs, sha256_password_auto_generate_rsa_keys y caching_sha2_password_auto_generate_rsa_keys (versión>=8.0) ayudan a generar los archivos SSL/TLS y RSA requeridos, y el usuario normal sin tales requisitos durante la conexión seguirá siendo inseguro. Por ejemplo, creemos un usuario llamado dbadmin.

mysql> create user 'dbadmin'@'192.168.40.%' identified by '[email protected]';
Query OK, 0 rows affected (0.01 sec)

mysql> GRANT ALL PRIVILEGES ON *.* TO 'dbadmin'@'192.168.40.%';
Query OK, 0 rows affected (0.01 sec)

Luego verifique si las variables están configuradas correctamente, que deberían estar habilitadas como están por defecto:

mysql> show global variables where variable_name in ('auto_generate_certs','sha256_password_auto_generate_rsa_keys','caching_sha2_password_auto_generate_rsa_keys');
+----------------------------------------------+-------+
| Variable_name                                | Value |
+----------------------------------------------+-------+
| auto_generate_certs                          | ON    |
| caching_sha2_password_auto_generate_rsa_keys | ON    |
| sha256_password_auto_generate_rsa_keys       | ON    |
+----------------------------------------------+-------+
3 rows in set (0.00 sec)

Verificar si los archivos se generan correctamente en la ruta /var/lib/mysql/ (o la ruta de datadir para este MySQL):

$ find /var/lib/mysql -name "*.pem"
/var/lib/mysql/ca-key.pem
/var/lib/mysql/ca.pem
/var/lib/mysql/server-key.pem
/var/lib/mysql/server-cert.pem
/var/lib/mysql/client-key.pem
/var/lib/mysql/client-cert.pem
/var/lib/mysql/private_key.pem
/var/lib/mysql/public_key.pem

Luego verifique si los archivos SSL se cargaron correctamente:

mysql> show global variables like 'ssl%';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| ssl_ca        | ca.pem          |
| ssl_capath    |                 |
| ssl_cert      | server-cert.pem |
| ssl_cipher    |                 |
| ssl_crl       |                 |
| ssl_crlpath   |                 |
| ssl_fips_mode | OFF             |
| ssl_key       | server-key.pem  |
+---------------+-----------------+
8 rows in set (0.00 sec)

Determina la seguridad de tu conexión

Ahora, esto se ve bien. También significa que MySQL está listo para aceptar conexiones cifradas. Pero al conectarse a MySQL tal como está, como se indicó, utilizará --ssl-mode=PREFFERED de forma predeterminada, o si no se especifica --ssl-mode, aún se recuperará para usar una conexión sin cifrar. Ver a continuación:

$ mysql [email protected] -h 192.168.40.110 -udbadmin -e "estado;"|grep ssl -i

SSL:                    No está en uso

Esto revela que no está utilizando una conexión segura. Verificar las variables de estado de la sesión SSL si se usan cifrados revela vacío:

mysql> show global status like 'ssl%';
+--------------------------------+--------------------------+
| Variable_name                  | Value                    |
+--------------------------------+--------------------------+
| Ssl_accept_renegotiates        | 0                        |
| Ssl_accepts                    | 2                        |
| Ssl_callback_cache_hits        | 0                        |
| Ssl_cipher                     |                          |
| Ssl_cipher_list                |                          |
| Ssl_client_connects            | 0                        |
| Ssl_connect_renegotiates       | 0                        |
| Ssl_ctx_verify_depth           | 18446744073709551615     |
| Ssl_ctx_verify_mode            | 5                        |
| Ssl_default_timeout            | 0                        |
| Ssl_finished_accepts           | 2                        |
| Ssl_finished_connects          | 0                        |
| Ssl_server_not_after           | Aug 28 12:48:46 2031 GMT |
| Ssl_server_not_before          | Aug 30 12:48:46 2021 GMT |
| Ssl_session_cache_hits         | 0                        |
| Ssl_session_cache_misses       | 0                        |
| Ssl_session_cache_mode         | SERVER                   |
| Ssl_session_cache_overflows    | 0                        |
| Ssl_session_cache_size         | 128                      |
| Ssl_session_cache_timeouts     | 0                        |
| Ssl_sessions_reused            | 0                        |
| Ssl_used_session_cache_entries | 0                        |
| Ssl_verify_depth               | 0                        |
| Ssl_verify_mode                | 0                        |
| Ssl_version                    |                          |
+--------------------------------+--------------------------+
25 rows in set (0.002 sec)

Hacer cumplir una conexión segura 

Dado que revela que la conexión aún no está asegurada, MySQL introduce la variable require_secure_transport que requiere que todas las conexiones que se realicen estén encriptadas y aseguradas. Cualquier intento de conectarse para una conexión no segura falla. Por ejemplo, habilitándolo en el servidor:

mysql> set global require_secure_transport=1;
Query OK, 0 rows affected (0.00 sec)

Intentar conectarse como cliente utilizando una conexión sin cifrar fallará:

$ mysql [email protected] -h 192.168.40.110 -udbadmin
ERROR 3159 (HY000): Connections using insecure transport are prohibited while --require_secure_transport=ON.

Para conectarse correctamente y de forma segura, debe especificar las variables ssl-ca, ssl-cert, ssl-key. Ver a continuación:

$ mysql [email protected] -h 192.168.40.110 -udbadmin --ssl-ca=/tmp/pem/ca.pem --ssl-cert=/tmp/pem/server-cert.pem --ssl-key=/tmp/pem/server-key.pem -e "show global status like 'ssl%'\G"
*************************** 1. row ***************************
Variable_name: Ssl_accept_renegotiates
        Value: 0
*************************** 2. row ***************************
Variable_name: Ssl_accepts
        Value: 16
*************************** 3. row ***************************
Variable_name: Ssl_callback_cache_hits
        Value: 0
*************************** 4. row ***************************
Variable_name: Ssl_cipher
        Value: TLS_AES_256_GCM_SHA384
*************************** 5. row ***************************
Variable_name: Ssl_cipher_list
        Value: TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DHE-DSS-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-DSS-AES128-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES256-SHA:CAMELLIA256-SHA:CAMELLIA128-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA
*************************** 6. row ***************************
Variable_name: Ssl_client_connects
        Value: 0
*************************** 7. row ***************************
Variable_name: Ssl_connect_renegotiates
        Value: 0
*************************** 8. row ***************************
Variable_name: Ssl_ctx_verify_depth
        Value: 18446744073709551615
*************************** 9. row ***************************
Variable_name: Ssl_ctx_verify_mode
        Value: 5
*************************** 10. row ***************************
Variable_name: Ssl_default_timeout
        Value: 7200
*************************** 11. row ***************************
Variable_name: Ssl_finished_accepts
        Value: 11
*************************** 12. row ***************************
Variable_name: Ssl_finished_connects
        Value: 0
*************************** 13. row ***************************
Variable_name: Ssl_server_not_after
        Value: Aug 28 12:48:46 2031 GMT
*************************** 14. row ***************************
Variable_name: Ssl_server_not_before
        Value: Aug 30 12:48:46 2021 GMT
*************************** 15. row ***************************
Variable_name: Ssl_session_cache_hits
        Value: 0
*************************** 16. row ***************************
Variable_name: Ssl_session_cache_misses
        Value: 0
*************************** 17. row ***************************
Variable_name: Ssl_session_cache_mode
        Value: SERVER
*************************** 18. row ***************************
Variable_name: Ssl_session_cache_overflows
        Value: 0
*************************** 19. row ***************************
Variable_name: Ssl_session_cache_size
        Value: 128
*************************** 20. row ***************************
Variable_name: Ssl_session_cache_timeouts
        Value: 0
*************************** 21. row ***************************
Variable_name: Ssl_sessions_reused
        Value: 0
*************************** 22. row ***************************
Variable_name: Ssl_used_session_cache_entries
        Value: 0
*************************** 23. row ***************************
Variable_name: Ssl_verify_depth
        Value: 18446744073709551615
*************************** 24. row ***************************
Variable_name: Ssl_verify_mode
        Value: 5
*************************** 25. row ***************************
Variable_name: Ssl_version
        Value: TLSv1.3

Alternativamente, si un usuario se crea con SSL REQUERIDO, por ejemplo, también debería conectarse usando SSL sin importar que require_secure_transport esté deshabilitado, que es su valor predeterminado. Tenga en cuenta que, si require_secure_transport está habilitado, su capacidad complementa los requisitos de SSL por cuenta, que tienen prioridad. Por lo tanto, si una cuenta se define con REQUIRE SSL, habilitar require_secure_transport no hace posible usar la cuenta para conectarse usando un archivo de socket Unix.

Asegurarse de que las implementaciones del servidor MySQL estén cifradas y sean seguras

Sin complicaciones es lo que siempre esperamos para que no haya otros problemas ni preocupaciones de los que preocuparse. ClusterControl implementa bases de datos MySQL utilizando conexiones cifradas y genera los certificados SSL y RSA para usted. Por ejemplo, una captura de pantalla a continuación que muestra la actividad laboral de un comando Crear clúster de ClusterControl.

Configura los archivos SSL y RSA y los coloca en /etc/ mysql/certs/ ruta como a continuación:

mysql> show global variables like 'ssl%';
+---------------+--------------------------------+
| Variable_name | Value                          |
+---------------+--------------------------------+
| ssl_ca        | /etc/mysql/certs/server_ca.crt |
| ssl_capath    |                                |
| ssl_cert      | /etc/mysql/certs/server.crt    |
| ssl_cipher    |                                |
| ssl_crl       |                                |
| ssl_crlpath   |                                |
| ssl_key       | /etc/mysql/certs/server.key    |
+---------------+--------------------------------+
7 rows in set (0.00 sec)

Luego, ClusterControl también agrupa los archivos SSL y RSA generados de manera centralizada en el panel de navegación Administración de claves, como se muestra a continuación:

Una vez implementado, todo lo que tiene que hacer es crear usuarios con SSL REQUERIDO o tener require_secure_transport si desea aplicar una capa cifrada y segura para las conexiones de su servidor MySQL.