Práctica 7
Implantación de Aplicaciones Web
Curso 2023/2024
1 Arquitectura de una aplicación web LAMP en dos niveles
En esta práctica deberá automatizar la instalación y configuración de una aplicación web LAMP en dos máquinas virtuales EC2 de Amazon Web Services (AWS), con la última versión de Ubuntu Server. En una de las máquinas deberá instalar Apache HTTP Server y los módulos necesarios de PHP y en la otra máquina deberá instalar MySQL Server.
Ahora vamos a tener la pila LAMP repartida en dos máquinas virtuales, una se encargará de gestionar las peticiones web y la otra de gestionar la base de datos.
Una vez que hayas comprobado que todos los servicios de la pila LAMP están funcionando correctamente en las dos máquinas, instala y configura la aplicación propuesta.
Ten en cuenta que tendrás que modificar la configuración de MySQL Server para que permita conexiones remotas y también tendrás que revisar los privilegios del usuario que se conecta a la base de datos de la aplicación.
La arquitectura estará formada por:
- Una capa de front-end, formada por un servidor web con Apache HTTP Server.
- Una capa de back-end, formada por un servidor MySQL.
1.1 Arquitectura de red ideal
1.2 Repositorio del proyecto de ejemplo
1.3 Configuración de MySQL
Edita el siguiente archivo de configuración:
/etc/mysql/mysql.conf.d/mysqld.cnf
Busca la directiva de configuración bind-address
dentro
del bloque de [mysqld]
:
[mysqld]
bind-address = 127.0.0.1
En la configuración por defecto, MySQL sólo permite conexiones desde localhost (127.0.0.1). Habrá que modificar este valor por la dirección IP de la máquina donde se está ejecutando el servicio de MySQL.
[mysqld]
bind-address = IP_SERVIDOR_MYSQL
El valor de IP_SERVIDOR_MYSQL
indica desde que interfaz
de red del servidor de MySQL se van a permitir conexiones. En nuestro
caso, los valores que podemos poner aquí son:
- IP pública de AWS: Permitimos el acceso a cualquier máquina que envíe una petición de conexión desde la red pública de AWS.
- IP privada de AWS: Sólo permitimos el acceso desde máquinas que estén en la misma red privada de AWS.
127.0.0.1
: No permitimos conexiones remotas, sólo se permiten conexiones dentro de la misma máquina.0.0.0.0
: Indica que permitimos conexiones desde cualquier interfaz de red que tenga la máquina.
Si nuestra máquina dispone más de una interfaz de red podemos poner la dirección IP 0.0.0.0 para permitir que se puedan conectar a MySQL desde cualquiera de las interfaces de red disponibles.
[mysqld]
bind-address = 0.0.0.0
Una vez hecho esto tenemos que reiniciar el servicio de MySQL:
sudo systemctl restart mysql
1.4 Asignando privilegios a los
usuarios de MySQL con GRANT
Para asignar privilegios utilizaremos la sentencia GRANT
de SQL. La sintaxis es la siguiente:
GRANT [permiso] ON [nombre_base_de_datos].[nombre_tabla] TO 'nombre_usuario'@'localhost';
Por ejemplo:
GRANT ALL PRIVILEGES ON *.* TO 'nombre_usuario'@'localhost';
En este comando, los asteriscos indican que estamos aplicando el
permiso ALL PRIVILEGES
al usuario
nombre_usuario
para todas las tablas de cada una de las
bases de datos.
A partir de la versión 8.0 de MySQL no es posible crear un
usuario con la sentencia GRANT
de SQL. Por lo tanto, sólo
usaremos GRANT para aquellos usuarios que ya han sido creados
previamente. Puede encontrar más
información en la documentación oficial.
En esta práctica tenemos que asignar privilegios al usuario de MySQL que vamos a utilizar para conectarnos desde la máquina donde está corriendo el servicio de Apache HTTP.
Paso 1. Creación de un usuario
CREATE USER 'nombre_usuario'@'IP_MÁQUINA_CLIENTE' IDENTIFIED BY 'contraseña';
Donde el valor de IP_MÁQUINA_CLIENTE
indica que el
usuario nombre_usuario
sólo podrá conectarse al servidor de
MySQL desde esa dirección IP. Los valores que podemos utilizar para
IP_MÁQUINA_CLIENTE
son los siguientes:
localhost
: No permitimos conexiones remotas, sólo se permiten conexiones dentro de la misma máquina.%
: Este comodín indica que permitimos conexiones desde cualquier máquina.- Una dirección IP desde la máquina que ese usuario puede conectarse al servidor de MySQL.
Tenga en cuenta que tendrá que reemplazar los valores
nombre_usuario
, contraseña
y
IP_MÁQUINA_CLIENTE
por los valores que necesite.
Paso 2. Asignación de privilegios
Una vez que hemos creado el usuario le asignamos los privilegios que
sean necesarios sobre la base de datos de la aplicación. En este caso le
vamos a asignar todos los privilegios con
ALL PRIVILEGES
.
GRANT ALL PRIVILEGES ON 'base_de_datos'.* TO 'nombre_usuario'@'IP_MÁQUINA_CLIENTE';
Tenga en cuenta que tendrá que reemplazar los valores
base_de_datos
, nombre_usuario
y
IP_MÁQUINA_CLIENTE
por los valores que necesite.
Los diferentes tipos de permisos que podemos aplicar son los siguientes:
ALL PRIVILEGES
: permite a un usuario de MySQL acceder a todas las bases de datos asignadas en el sistema.CREATE
: permite crear nuevas tablas o bases de datos.DROP
: permite eliminar tablas o bases de datosDELETE
: permite eliminar registros de tablas.INSERT
: permite insertar registros en tablas.SELECT
: permite leer registros en las tablas.UPDATE
: permite actualizar registros seleccionados en tablas.GRANT OPTION
: permite asignar privilegios a otros usuarios.
Paso 3. Actualizamos las tablas de privilegios
Para que los cambios que hemos realizado sobre los privilegios de los usuarios se apliquen de forma inmediata, tendremos que ejecutar el siguiente comando.
FLUSH PRIVILEGES;
Ejemplo
Por ejemplo, si queremos permitir que un usuario se pueda conectar
desde cualquier dirección IP podemos utilizar el comodín %
.
De modo que tendríamos que realizar lo siguiente:
CREATE USER 'nombre_usuario'@'%' IDENTIFIED BY 'contraseña';
GRANT ALL PRIVILEGES ON 'base_de_datos'.* TO 'nombre_usuario'@'%';
FLUSH PRIVILEGES;
1.5 Comprobamos la lista de usuarios de MySQL
Los usuarios de MySQL se almacenan en la tabla
mysql.user
. La clave primaria de esta tabla está formada
por los valores user
y host
, de modo que cada
fila vendrá identificada por un nombre de usuario y el host desde el que
puede conectarse.
La siguiente consulta nos devuelve el listado de usuarios que tenemos en MySQL y desde qué host pueden conectarse:
SELECT user,host FROM mysql.user;
En nuestra caso la consulta anterior devuelve el siguiente resultado:
+------------------+--------------+
| user | host |
+------------------+--------------+
| root | % |
| root | localhost |
| lamp_user | % |
| lamp_user | localhost |
| debian-sys-maint | localhost |
| phpmyadmin | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
+------------------+--------------+
El siguiente diagrama muestra un ejemplo de dos usuarios que se están
conectando a una máquina con MySQL Server. El usuario
root@localhost
es un usuario que sólo puede conectarse
desde la máquina local y el usuario root@'%'
es un usuario
que se puede conectar desde una máquina remota.
También podemos consultar qué permisos específicos tiene un
determinado usuario. La siguiente consulta nos devuelve los permisos que
tiene el usuario root
:
FOR root; SHOW GRANTS
+------------------------------------------------+
| Grants for root@% |
+------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' |
+------------------------------------------------+
1.6 Comprobamos que podemos conectarnos a MySQL
Ahora vamos a comprobar que podemos conectarnos con MySQL desde la
máquina donde está corriendo el servicio de Apache HTTP. Podemos
comprobarlo conectando con el shell de mysql
:
mysql -u USERNAME -p -h IP-SERVIDOR-MYSQL
O haciendo un telnet al puerto donde está corriendo el servicio de MySQL:
telnet IP-SERVIDOR-MYSQL 3306
Si no podemos conectarnos a MySQL revisaremos que el servicio está activo y que no tenemos ningún firewall que nos esté filtrando el puerto del servicio donde se ejecuta MySQL.
1.7 Configuración de la aplicación web para conectar a MySQL
Una vez que has realizado los pasos anteriores debes configurar la aplicación web para que pueda conectar a MySQL.
El repositorio de la aplicación web que tendrás que poner en producción es el siguiente:
En esta aplicación web el archivo de configuración que tendrás que
editar y configurar se llama config.php
.
El contenido del archivo config.php
es el siguiente:
<?php
define('DB_HOST', 'localhost');
define('DB_NAME', 'lamp_db');
define('DB_USER', 'lamp_user');
define('DB_PASSWORD', 'lamp_password');
$mysqli = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
?>
En este archivo se definen las constantes DB_HOST
,
DB_NAME
, DB_USER
y DB_PASSWORD
.
Por lo tanto, estos son los valores que tendrás que configurar para que
tu aplicación web pueda conectarse a MySQL.
1.8 ¿Qué puedo hacer si desde la máquina de front-end (Apache HTTP Server) no puedo conectar a la máquina de back-end (MySQL)?
A continuación se describe una secuencia de pasos que se pueden realizar para detectar posibles errores cuando desde la máquina de front-end (Apache HTTP Server) no puedo conectar con la máquina de back-end (MySQL).
Lo primero que deberíamos hacer sería comprobar que las dos instancias están en ejecución.
Una vez que hemos comprobado que las dos instancias están en ejecución, deberíamos comprobar que están en la misma subred y que pueden verse entre sí haciendo uso de la utilidad
ping
.Si las máquinas están en la misma subred y pueden verse entre sí, debemos comprobar que el puerto
3306
de la máquina donde se ejecuta MySQL está abierto. Revisa la configuración del firewall para verificar que el puerto3306
está abierto.Una vez que hemos verificado que el puerto
3306
está abierto en el firewall, podemos comprobar si el servicio de MySQL está en ejecución en ese puerto. Para comprobarlo podemos hacer untelnet
al puerto3306
desde la máquina de front-end, donde se ejecuta Apache HTTP Server. Ejemplo:telnet IP-SERVIDOR-MYSQL 3306
.Si el puerto está abierto recibirás algún mensaje de respuesta al hacer un
telnet
. Si no recibes ninguna respuesta comprueba que el parámetrobind-address
está bien configurado en el archivo de configuración de MySQL, para que pueda aceptar conexiones desde la subred donde está la máquina de front-end donde se ejecuta Apache HTTP Server.Si el puerto
3306
está abierto, podemos comprobar que el usuario de MySQL de la aplicación web puede conectarse desde la máquina de front-end donde se ejecuta Apache HTTP Server. Recuerda que el usuario que se conecta desde otra máquina tiene que crearse con el comodín%
en el valor del host. En la máquina de Apache puedes instalar el cliente de MySQL conapt install mysql-client
y comprobar que puedes conectarte a MySQL con el usuario de la aplicación web. Ejemplo:mysql -u USERNAME -p -h IP-SERVIDOR-MYSQL
.Comprueba que has configurado correctamente el archivo de configuración de la aplicación web para que pueda conectarse a MySQL.
1.9 Entregables
En esta práctica habrá que entregar un documento técnico con la descripción de los pasos que se han llevado a cabo.
El documento debe incluir como mínimo los siguientes contenidos:
URL del repositorio de GitHub donde se ha alojado el documento técnico escrito en Markdown.
Scripts de bash utilizados para realizar el aprovisionamiento de las máquinas virtuales.
Tenga en cuenta que el aprovisionamiento de las máquinas virtuales se realizará mediante un script de bash. Cada máquina usará su propio script. El contenido de cada uno de los scripts deberá ser incluido en el documento y deberá describir qué acciones se han ido realizando en cada uno de ellos.
2 Referencias
- Amazon Web Services
- Ubuntu Server
- LAMP Stack
- PHP
- Apache HTTP Server
- MySQL Server
- Move MySQL to a Separate Cloud Database Server
- Markdown
3 Licencia
Esta
página forma parte del curso
Implantación de Aplicaciones
Web de José Juan Sánchez
Hernández y su contenido se distribuye bajo una
licencia
Creative Commons Reconocimiento-NoComercial-CompartirIgual 4.0
Internacional.