Configurar el acceso de clientes a MySQL en Compute Engine a través de una dirección IP privada

En este tutorial se explica cómo ejecutar una base de datos MySQL en una red privada de Google Cloud para permitir el acceso remoto seguro a la base de datos mediante Compute Engine.

Sigue este tutorial si quieres instalar tu propia base de datos MySQL en Compute Engine, pero quieres restringir el acceso solo a los clientes de MySQL autorizados que también se ejecuten en Compute Engine. Puede que quieras gestionar tu propia instancia de MySQL en lugar de usar el servicio gestionado debido a las instancias entre regiones, el uso avanzado de parámetros y las necesidades de rendimiento específicas.

En este tutorial se describe cómo configurar tu aplicación de servidor MySQL para que acepte tráfico remoto de un cliente MySQL instalado en una instancia de Compute Engine en la misma red privada.

Para obtener información sobre cómo elegir la opción de implementación de MySQL adecuada, consulta el artículo Cómo instalar MySQL en Compute Engine.

En este tutorial se da por hecho que conoces los siguientes conceptos:

  • Comandos básicos de Linux
  • Ubuntu Server 18.04
  • MySQL 5.7
  • Compute Engine

Arquitectura

En este tutorial, desplegarás dos instancias de Compute Engine. Una instancia es el servidor y la otra es el cliente, tal como se muestra en el siguiente diagrama:

Arquitectura de dos instancias implementadas

Crear instancias de Compute Engine

Crea dos instancias de MySQL: una de cliente y otra de servidor.

Crear una instancia de cliente de Compute Engine

  • Create a Compute Engine instance. Configure the instance as follows:
    • Name the instance my-client.
    • Define la marca --zone en la zona en la que quieras crear la instancia.
    • Asigna el valor ubuntu-os-cloud a la marca --image-project.
    • Asigna el valor ubuntu-1804-lts a la marca --image-family.
    • Define la marca --scopes como https://www.googleapis.com/auth/cloud-platform.
    • gcloud compute instances create my-client --zone=ZONE --image-project=ubuntu-os-cloud --image-family=ubuntu-1804-lts --scopes=https://www.googleapis.com/auth/cloud-platform

      Crear una instancia de servidor de Compute Engine

    • Create a Compute Engine instance. Configure the instance as follows:
      • Name the instance my-server.
      • Define la marca --zone en la zona en la que quieras crear la instancia.
      • Asigna el valor ubuntu-os-cloud a la marca --image-project.
      • Asigna el valor ubuntu-1804-lts a la marca --image-family.
      • Define la marca --scopes como https://www.googleapis.com/auth/cloud-platform.
      • gcloud compute instances create my-server --zone=ZONE --image-project=ubuntu-os-cloud --image-family=ubuntu-1804-lts --scopes=https://www.googleapis.com/auth/cloud-platform

        Instalar el cliente de MySQL

        En los siguientes pasos se describe cómo instalar MySQL en una instancia de Compute Engine.

        1. Para conectarte a la instancia my-client, usa el comando ssh.
        2. Actualiza el gestor de paquetes apt-get.
          sudo apt-get update
          
        3. Instala el paquete de cliente de MySQL.
          sudo apt-get -y install mysql-client-5.7

        Instalar el servidor MySQL

        En los siguientes pasos se describe cómo instalar MySQL en una instancia de Compute Engine.

        1. Para conectarte a la instancia my-server, usa el comando ssh.
        2. Actualiza el gestor de paquetes apt-get.
          sudo apt-get update
          
        3. Instala el paquete del servidor MySQL.
          sudo apt-get -y install mysql-server-5.7

        Mejorar la seguridad de la instalación de MySQL

        Debes establecer una contraseña raíz para MySQL y realizar tareas básicas de mantenimiento de seguridad en la configuración del servidor MySQL. Para obtener más información, consulta la documentación de MySQL sobre mysql_secure_installation.

        1. En la sesión SSH de tu instancia my-server, usa el siguiente comando para mejorar la seguridad de tu instalación de MySQL.

          sudo mysql_secure_installation
          
        2. Pulsa enter para saltarte la configuración del complemento VALIDATE PASSWORD.

        3. Introduce una nueva contraseña de administrador dos veces.

        4. Para quitar a los usuarios anónimos, introduce Y y pulsa enter.

        5. Para evitar el inicio de sesión root remoto, introduce Y y pulsa enter.

        6. Para eliminar la base de datos de prueba, introduce Y y pulsa enter.

        7. Para volver a cargar las tablas de privilegios, introduce Y y pulsa enter.

        Configurar el servidor MySQL

        Para poder conectarte de forma remota al servidor MySQL, debes configurarlo para que escuche en su dirección IP interna. A continuación, crea una cuenta de usuario no root para que el cliente MySQL se conecte al servidor.

        Todos los comandos de cliente de MySQL deben incluir determinadas marcas de línea de comandos (por ejemplo, para autenticar). Los comandos de MySQL de esta sección incluyen las siguientes marcas: --user para el nombre de usuario, -p para la contraseña y -e para ejecutar la instrucción dada y salir inmediatamente. Para obtener más información, consulta la referencia de las opciones de comandos de MySQL 5.7.

        1. En Cloud Shell, usa SSH para conectarte a la instancia my-server.

        2. Actualiza el archivo de configuración /etc/mysql/mysql.conf.d/mysqld.cnf con la siguiente información:

          LOCAL_IP=$(curl  http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip \
              -H "Metadata-Flavor: Google")
          sudo sed -i "s|bind-address.*|bind-address = $LOCAL_IP|" /etc/mysql/mysql.conf.d/mysqld.cnf
          
        3. Reinicia el servicio MySQL para aplicar los cambios al servidor en ejecución.

          sudo service mysql restart
          
        4. Comprueba que el servidor se esté ejecutando de forma local. Sustituye [ROOT_PASSWORD] por la contraseña raíz del servidor MySQL que has establecido en un paso anterior.

          sudo mysql --user=root -p[ROOT_PASSWORD] -e "show databases"
          

          El resultado será similar al siguiente:

          +--------------------+
          | Database           |
          +--------------------+
          | information_schema |
          | mysql              |
          | performance_schema |
          | sys                |
          +--------------------+
          

        Crear un usuario de MySQL

        La conexión remota como usuario root se ha inhabilitado con el comando mysql_secure_installation anterior. Debes crear un usuario con los permisos necesarios para permitir las conexiones remotas.

        1. En Cloud Shell, crea una variable de entorno para la dirección IP interna my-client.

          CLIENT_IP=$(gcloud compute instances describe my-client \
              --zone=ZONE \
              --format='value(networkInterfaces[0].networkIP)')
          
        2. Crea un usuario de MySQL con una contraseña. Sustituye [MY_PASSWORD] por tu contraseña y [ROOT_PASSWORD] por la contraseña del usuario raíz de MySQL.

          sudo mysql -uroot -p[ROOT_PASSWORD] \
              -e "CREATE USER 'TESTUSER'@'${CLIENT_IP}' IDENTIFIED BY '[MY_PASSWORD]';"
          
        3. Concede al nuevo usuario de MySQL permiso para iniciar sesión en el servidor desde la dirección IP interna de my-client.

          sudo mysql -uroot -p[ROOT_PASSWORD] -e \
              "GRANT ALL PRIVILEGES ON *.* TO 'TESTUSER'@'${CLIENT_IP}' \
              IDENTIFIED BY '[MY_PASSWORD]';"
          

        Quitar la dirección IP externa de my-server

        La instancia my-server no necesita una dirección IP externa porque el cliente puede acceder a my-server a través de una dirección IP interna.

        • Para quitar la dirección IP externa, actualiza los ajustes de configuración en Cloud Shell. Sustituye [ZONE] por tu Google Cloud zona.

          gcloud compute instances delete-access-config my-server \
              --access-config-name "external-nat" \
              --zone="ZONE"
          

        Verificar el acceso remoto de un cliente a una instancia de servidor

        En los pasos que se indican a continuación se describe cómo conectarse al servidor MySQL de my-server desde tu instancia de my-client.

        1. En Cloud Shell, usa SSH para conectarte a la instancia my-client.
        2. Prueba la conexión enumerando las bases de datos.

          sudo mysql --host=my-server --user=TESTUSER \
              --password=[MY_PASSWORD] -e "SHOW DATABASES;"
          

          La salida tiene un aspecto similar al siguiente:

          +--------------------+
          | Database           |
          +--------------------+
          | information_schema |
          | mysql              |
          | performance_schema |
          | sys                |
          +--------------------+
          

        Con estos pasos se verifica que tu cliente MySQL puede conectarse correctamente al servidor MySQL a través de la dirección IP interna.

        Consideraciones sobre el cortafuegos en entornos de producción

        La configuración de red predeterminada de Google Cloud incluye una regla de cortafuegosdefault-allow-internal que permite el tráfico interno entre instancias de Compute Engine en una amplia gama de puertos, incluido el puerto de MySQL, el puerto 3306. En entornos no predeterminados con una superficie de seguridad establecida, es posible que tengas que crear una regla de cortafuegos para permitir que tu instancia de my-client se comunique con tu instancia de my-server a través de la red. De lo contrario, las dos instancias no podrán comunicarse entre sí.

        Puedes basar las reglas de cortafuegos en intervalos de direcciones IP o etiquetas. Los intervalos de direcciones IP son útiles si quieres conceder acceso a un amplio intervalo de direcciones IP internas. Por otro lado, si quieres conceder acceso a instancias específicas de tu red, las etiquetas ofrecen una solución más flexible. Las etiquetas facilitan la incorporación de nuevos clientes sin conceder acceso a una amplia gama de direcciones IP. Solo tienes que asignar la etiqueta adecuada a la nueva instancia de cliente de MySQL. Por ejemplo, puedes crear una regla de cortafuegos que permita el tráfico de todas las instancias de cliente etiquetadas con mysql-client.

        Para admitir reglas de cortafuegos que usen etiquetas, puedes asignar las etiquetas adecuadas a las VMs my-client y my-server en Cloud Shell.

        gcloud compute instances add-tags my-client --tags mysql-client --zone=ZONE
        
        gcloud compute instances add-tags my-server --tags mysql-server --zone=ZONE
        

        Añadir una nueva regla de cortafuegos

        En los pasos siguientes se describe cómo crear una regla de cortafuegos para permitir que las instancias con la etiqueta my-client se comuniquen con las instancias que tienen la etiqueta my-server mediante el puerto 3306.

        • En Cloud Shell, crea una regla de cortafuegos para permitir las comunicaciones de mysql-client a mysql-server.

          gcloud compute firewall-rules create "mysql-remote-access" \
              --allow tcp:3306 --source-tags "mysql-client" \
              --target-tags "mysql-server"
          

        Ahora puede conectarse a MySQL desde my-client.

        Consideraciones sobre el acceso de clientes externos

        En este tutorial se explica cómo acceder desde clientes MySQL a servidores MySQL que se ejecutan en Compute Engine. Permitir el acceso desde un cliente que no se ejecuta en Compute Engine queda fuera del ámbito de este tutorial. Si necesitas permitir el acceso que no sea de Compute Engine, modifica lo siguiente:

        • Añade una dirección IP externa a my-server para permitir la conectividad externa.
        • Añade la dirección IP de origen de tu cliente externo a las reglas de cortafuegos.
        • Modifica la cuenta TESTUSER o crea una cuenta de usuario vinculada a la dirección IP de origen de tu cliente externo.