Diferència entre revisions de la pàgina «WoSeBerry - Manual técnico»
(Hi ha 247 revisions intermèdies del mateix usuari que no es mostren) | |||
Línia 1: | Línia 1: | ||
− | + | En esta página se explicará la instalación y configuración del software necesario para llevar a cabo el proyecto Woseberry. | |
− | |||
− | |||
== Configuración de las Raspberry Pi == | == Configuración de las Raspberry Pi == | ||
− | === Instalación del sistema | + | === Instalación del sistema operativo === |
− | Todas las Raspberry Pi de nuestro proyecto cuentan con | + | Todas las Raspberry Pi de nuestro proyecto cuentan con el sistema operativo [https://www.raspberrypi.org/documentation/raspbian/ Raspbian]. Este sistema es la adaptación de la distribución Debian adaptada al hardware de una Raspberry. A excepción del resto de Raspberry, la Raspberry con función de firewall (BERRY-01) llevará instalada la versión con interfaz gráfica. |
− | + | Una vez instalado el sistema operativo Raspbian en cada una de las Raspberry, procederemos a la configuración básica con la ejecución del siguiente comando: | |
<pre>$ sudo raspi-config</pre> | <pre>$ sudo raspi-config</pre> | ||
− | + | [[File:Raspi-config.png|frame|none|Opciones de configuración al ejecutar el comando raspi-config]] | |
+ | |||
+ | === Asignación del direccionamiento IP === | ||
+ | Dado que el proyecto está montado bajo una LAN, se creó una red independiente con IPs de clase privada de tipo C. Para configurar la IP estática en las Raspberry deberemos editar el siguiente fichero: | ||
− | + | <pre>$ sudo nano /etc/dhcpcd.conf</pre> | |
+ | En éste asignaremos el direccionamiento correspondiente a cada Raspberry: | ||
− | === | + | {| class="wikitable" |
+ | ! scope="row" colspan="2"|BERRY-01 | ||
+ | ! scope="row" colspan="2"|BERRY-02 | ||
+ | ! scope="row" colspan="2"|BERRY-03 | ||
+ | |- | ||
+ | |[[File:berry01-logo.png|center|150px]] | ||
+ | | | ||
+ | * '''IP (eth0):''' 192.168.30.254/24 | ||
+ | * '''IP (eth1):''' 192.168.3.123/24 | ||
+ | * '''DNS:''' 192.168.30.254 10.27.100.1 | ||
+ | |[[File:berry02-logo.png|center|150px]] | ||
+ | | | ||
+ | * '''IP (eth0):''' 192.168.30.2/24 | ||
+ | * '''DNS:''' 192.168.30.254 | ||
+ | |[[File:berry02-logo.png|center|150px]] | ||
+ | | | ||
+ | * '''IP (eth0):''' 192.168.30.3/24 | ||
+ | * '''DNS:''' 192.168.30.254 | ||
+ | |- | ||
+ | ! scope="row" colspan="2"|BERRY-04 | ||
+ | ! scope="row" colspan="2"|BERRY-05 | ||
+ | ! scope="row" colspan="2"|BERRY-06 | ||
+ | |- | ||
+ | |[[File:berry03-logo.png|180px]] | ||
+ | | | ||
+ | * '''IP (eth0):''' 192.168.30.4/24 | ||
+ | * '''DNS:''' 192.168.30.254 10.27.100.1 | ||
+ | |[[File:berry03-logo.png|180px]] | ||
+ | | | ||
+ | * '''IP (eth0):''' 192.168.30.5/24 | ||
+ | * '''DNS:''' 192.168.30.254 | ||
+ | |[[File:berry03-logo.png|180px]] | ||
+ | | | ||
+ | * '''IP (eth0):''' 192.168.30.6/24 | ||
+ | * '''DNS:''' 192.168.30.254 | ||
+ | |} | ||
Línia 22: | Línia 59: | ||
Dado que todo el escenario estará montado bajo una LAN, deberemos configurar en la Raspberry con función de firewall (BERRY-01) aspectos como: | Dado que todo el escenario estará montado bajo una LAN, deberemos configurar en la Raspberry con función de firewall (BERRY-01) aspectos como: | ||
− | * Servidor DNS: Nos proporcionará la asignación de un dominio para la tienda online. | + | * '''Servidor DNS''': Nos proporcionará la asignación de un dominio para la tienda online. |
− | * Enrutamiento: Permitirá la circulación de tráfico. | + | * '''Enrutamiento''': Permitirá la circulación de tráfico. |
− | * Enmascaramiento: Permitirá enmascarar el tráfico de la red LAN con la IP de la interfaz ''"eth1"''. | + | * '''Enmascaramiento''': Permitirá enmascarar el tráfico de la red LAN con la IP de la interfaz ''"eth1"''. |
=== Servidor DNS === | === Servidor DNS === | ||
Línia 32: | Línia 69: | ||
Una vez instalado, realizaremos una copia de seguridad de los archivos de configuración. De esta manera, en caso de tener un error podremos restaurar la configuración por defecto: | Una vez instalado, realizaremos una copia de seguridad de los archivos de configuración. De esta manera, en caso de tener un error podremos restaurar la configuración por defecto: | ||
− | < | + | |
− | pi@BERRY-01:~$ sudo cp /etc/bind/named.conf.local /etc/bind/named.conf.local.bak | + | <b>pi@BERRY-01:~$</b> sudo cp /etc/bind/named.conf.local /etc/bind/named.conf.local.bak |
− | pi@BERRY-01:~$ sudo cp /etc/bind/db.local /etc/bind/db.woseberry | + | <b>pi@BERRY-01:~$</b> sudo cp /etc/bind/db.local /etc/bind/db.woseberry |
− | + | ||
Seguidamente editaremos el archivo ''/etc/bind/'''named.conf.local''''' para crear la zona directa e indicar cual es el archivo que contiene su configuración: | Seguidamente editaremos el archivo ''/etc/bind/'''named.conf.local''''' para crear la zona directa e indicar cual es el archivo que contiene su configuración: | ||
+ | |||
+ | <b>pi@BERRY-01:~$</b> sudo nano /etc/bind/named.conf.local | ||
<pre> | <pre> | ||
− | |||
zone "woseberry.tk" { | zone "woseberry.tk" { | ||
type master; | type master; | ||
Línia 44: | Línia 82: | ||
}; | }; | ||
</pre> | </pre> | ||
− | Por último, crearemos la zona directa editando el fichero /etc/bind/db.woseberry: | + | |
+ | Por último, crearemos la zona directa editando el fichero ''/etc/bind/'''db.woseberry''''' | ||
+ | |||
+ | <b>pi@BERRY-01:~$</b> sudo nano /etc/bind/db.woseberry | ||
<pre> | <pre> | ||
− | |||
; | ; | ||
; BIND reverse data file for local loopback interface | ; BIND reverse data file for local loopback interface | ||
; | ; | ||
$TTL 604800 | $TTL 604800 | ||
− | @ | + | @ IN SOA woseberry.tk. root.woseberry.tk. ( |
− | + | 2 ; Serial | |
604800 ; Refresh | 604800 ; Refresh | ||
86400 ; Retry | 86400 ; Retry | ||
Línia 58: | Línia 98: | ||
604800 ) ; Negative Cache TTL | 604800 ) ; Negative Cache TTL | ||
; | ; | ||
− | @ | + | @ IN NS woseberry.tk |
− | 192.168.3. | + | @ IN A 192.168.30.123 |
+ | BERRY-01 IN A 192.168.30.254 | ||
+ | BERRY-02 IN A 192.168.30.2 | ||
+ | BERRY-03 IN A 192.168.30.3 | ||
+ | BERRY-04 IN A 192.168.30.4 | ||
+ | BERRY-05 IN A 192.168.30.5 | ||
+ | BERRY-06 IN A 192.168.30.6 | ||
+ | |||
</pre> | </pre> | ||
=== Enrutamiento y enmascaramiento === | === Enrutamiento y enmascaramiento === | ||
− | + | Dado que la BERRY-01 es la encargada de dar acceso a Internet a la LAN, es primordial activar la directiva de enrutamiento además de enmascarar las IP de la LAN por la IP de la interfaz eth1. Para ello, editaremos el archivo ''/etc/'''rc.local''''' con la finalidad de que dichas directivas se ejecuten en el inicio del sistema. | |
<b>pi@BERRY-01:~$</b> sudo nano /etc/rc.local | <b>pi@BERRY-01:~$</b> sudo nano /etc/rc.local | ||
Línia 77: | Línia 124: | ||
exit 0 | exit 0 | ||
</pre> | </pre> | ||
+ | |||
+ | |||
== Instalación y configuración WordPress == | == Instalación y configuración WordPress == | ||
+ | |||
+ | Ahora que tenemos salida a Internet desde la LAN procederemos a realizar la instalación del los servidores de base de datos y los gestores de contenido WordPress. | ||
=== Instalación servidor base de datos MySQL === | === Instalación servidor base de datos MySQL === | ||
− | + | Instalaremos el paquete mysql-server en las BERRY-04, BERRY-05 y BERRY-06, las cuales son las encargadas de almacenar todos los datos que se generarán en la tienda virtual. Para ello ejecutaremos el siguiente comando en las tres Raspberry: | |
+ | |||
+ | <b>$</b> sudo apt install mysql-server mysql-client phpmyadmin | ||
+ | |||
+ | Finalizada la instalación, generaremos un usuario llamado ''pi'' que tendrá todos los privilegios en cualquier base de datos y desde cualquier máquina. Realizaremos la siguiente operación en las tres Raspberry: | ||
− | |||
<b>pi@BERRY-04:~$</b> sudo su | <b>pi@BERRY-04:~$</b> sudo su | ||
<b>root@BERRY-04:/home/pi#</b> mysql -u root | <b>root@BERRY-04:/home/pi#</b> mysql -u root | ||
Línia 92: | Línia 146: | ||
<b>MariaDB [(none)]></b> exit; | <b>MariaDB [(none)]></b> exit; | ||
− | + | Aprovechando que estamos gestionando las bases de datos y los usuarios, crearemos una base de datos llamada ''wordpress'' y un usuario con el mismo nombre con permisos sobre esa base de datos. | |
− | + | ||
− | + | <b>MariaDB [(none)]></b> CREATE DATABASE wordpress; | |
− | <b>MariaDB [(none)]></b> CREATE | + | <b>MariaDB [(none)]></b> GRANT ALL ON wordpress.* TO 'wordpress'@'%' IDENTIFIED BY 'woseberry'; |
− | <b>MariaDB [(none)]></b> GRANT ALL | ||
<b>MariaDB [(none)]></b> FLUSH PRIVILEGES; | <b>MariaDB [(none)]></b> FLUSH PRIVILEGES; | ||
<b>MariaDB [(none)]></b> exit; | <b>MariaDB [(none)]></b> exit; | ||
− | + | === Instalación servidor web apache === | |
+ | |||
+ | Con los servidores de base de datos ya en marcha en las BERRY-04, BERRY-05 y BERRY-06, procederemos a la instalación de los servidores web en las BERRY-02 y BERRY-03. | ||
+ | Para que WordPress funcione correctamente, necesitamos instalar los siguientes paquetes en ambas Raspberry: | ||
+ | |||
+ | <b>$</b> sudo apt-get install apache2 php7.0 libapache2-mod-php7.0 php7.0-mysql php7.0-curl php7.0-gd php7.0-imap php7.0-mcrypt php7.0-recode php7.0-tidy php7.0-xmlrpc | ||
+ | |||
+ | === Descarga, instalación y configuración WordPress === | ||
+ | |||
+ | '''¡Importante! Todos estos pasos deberán realizarse en las BERRY-02 y BERRY-03 de manera idéntica. Excepto en el archivo de configuración ''wp-config.php'', el cual se indicarán IP distintas en la base de datos''' | ||
+ | |||
+ | Una vez tenemos operativo el servicio de ''apache2'' junto al resto de dependencias necesarias, procederemos con la instalación y configuración de WordPress. Por tal de mejorar la seguridad en la tienda virtual, nos descargaremos la última versión estable, la cual corrige todos los errores encontrados hasta la fecha. | ||
+ | |||
+ | Para ello, ejecutaremos el siguiente comando en las BERRY-02 y BERRY-03: | ||
+ | |||
+ | <b>$</b> <nowiki>wget https://es.wordpress.org/wordpress-4.9.5-es_ES.zip</nowiki> | ||
+ | |||
+ | Seguidamente, descomprimiremos el gestor de contenido y lo copiaremos en el directorio ''/var/www/html'': | ||
+ | |||
+ | <b>$</b> unzip wordpress-4.9.5-es_ES.zip | ||
+ | <b>$</b> sudo cp -R wordpress/* /var/www/html | ||
+ | |||
+ | Dado que en la instalación de ''apache2'' nos genera un archivo ''index.html'' en el que podemos ver que el servicio está funcionando correctamente, procederemos a eliminarlo para que no haya conflicto con el resto de archivos de WordPress: | ||
+ | |||
+ | <b>$</b> sudo rm /var/www/html/index.html | ||
+ | |||
+ | Una vez hecho esto, copiaremos el archivo de configuración de WordPress para proceder a su configuración más adelante: | ||
+ | |||
+ | <b>$</b> sudo cp /var/www/html/wp-config-sample.php /var/www/html/wp-config.php | ||
+ | |||
+ | Modificaremos los permisos de los archivos de WordPress por tal de que no estén asignados al usuario ''root'': | ||
+ | |||
+ | <b>$</b> sudo chown -R www-data:www-data /var/www/html/ | ||
+ | <b>$</b> sudo chmod -R 755 /var/www/html/ | ||
+ | |||
+ | Por último, activaremos dos módulos de ''apache2'' esenciales para el funcionamiento correcto de WordPress: | ||
+ | |||
+ | <b>$</b> sudo a2enmod headers | ||
+ | <b>$</b> sudo a2enmod rewrite | ||
+ | |||
+ | Finalizados todos los pasos, reiniciaremos ''apache2'' para aplicar los cambios: | ||
+ | |||
+ | <b>$</b> sudo service apache2 restart | ||
+ | |||
+ | El siguiente paso será configurar WordPress indicandole la ubicación de la base de datos, junto al usuario y contraseña que la administrarán. Por ahora, la BERRY-02 apuntará a la base de datos BERRY-04. Por otro lado, la BERRY-03 apuntará a la BERRY-05. | ||
+ | |||
+ | Modificamos el archivo de configuración ''wp-config.php'' para vincularlo con la base de datos correspondiente. | ||
+ | |||
+ | <b>pi@BERRY-02:~$</b> sudo nano /var/www/html/wp-config.php | ||
+ | |||
+ | // ** MySQL settings - You can get this info from your web host ** // | ||
+ | /** The name of the database for WordPress */ | ||
+ | define('DB_NAME', ''''wordpres'''s'); | ||
+ | |||
+ | /** MySQL database username */ | ||
+ | define('DB_USER', ''''wordpress''''); | ||
+ | |||
+ | /** MySQL database password */ | ||
+ | define('DB_PASSWORD', ''''woseberry''''); | ||
+ | |||
+ | /** MySQL hostname */ | ||
+ | define('DB_HOST', ''''192.168.30.4''''); | ||
+ | |||
+ | /** Database Charset to use in creating database tables. */ | ||
+ | define('DB_CHARSET', 'utf8'); | ||
+ | |||
+ | /** The Database Collate type. Don't change this if in doubt. */ | ||
+ | define('DB_COLLATE', ''); | ||
+ | |||
+ | Y para la BERRY-03 su configuración será la siguiente: | ||
+ | |||
+ | <b>pi@BERRY-03:~$</b> sudo nano /var/www/html/wp-config.php | ||
+ | |||
+ | // ** MySQL settings - You can get this info from your web host ** // | ||
+ | /** The name of the database for WordPress */ | ||
+ | define('DB_NAME', ''''wordpress''''); | ||
+ | |||
+ | /** MySQL database username */ | ||
+ | define('DB_USER', ''''wordpress''''); | ||
+ | |||
+ | /** MySQL database password */ | ||
+ | define('DB_PASSWORD', ''''woseberry''''); | ||
+ | |||
+ | /** MySQL hostname */ | ||
+ | define('DB_HOST', ''''192.168.30.5''''); | ||
+ | |||
+ | /** Database Charset to use in creating database tables. */ | ||
+ | define('DB_CHARSET', 'utf8'); | ||
+ | |||
+ | /** The Database Collate type. Don't change this if in doubt. */ | ||
+ | define('DB_COLLATE', ''); | ||
+ | |||
+ | |||
+ | Ahora solo nos falta completar el proceso de instalación desde la interfaz web. Para ello, en la barra de direcciones de un navegador web, escribimos el dominio o la dirección IP del servidor de la siguiente forma ''<nowiki>http://dominio_o_IP</nowiki>'' | ||
+ | |||
+ | En nuestro caso, accederemos mediante el dominio: | ||
+ | <pre>http://woseberry.tk</pre> | ||
+ | |||
+ | [[File:Instalacion_wordpress.png|500px|Instalación Wordpress]] | ||
+ | |||
+ | |||
+ | == Certificados SSL - HTTPS == | ||
+ | |||
+ | Dado que la finalidad es conseguir una tienda online que sea operativa, es primordial que cuente con unos certificados SSL que acrediten que la tienda es segura y se puede comprar en ella sin miedo a que nuestros datos se vean comprometidos por falta de seguridad. Para ello, las empresas suelen pagar por unos certificados validados por entidades certificadoras que acreditan la autenticidad de los certificados. Sin embargo, también existe la posibilidad de hacerlo de manera gratuita completando unos formularios y cumpliendo determinados requisitos. Paralelamente, también debemos realizar las configuraciones oportunas para que nuestro site funcione de forma segura a través del puerto 443 con el protocolo HTTPS. | ||
+ | |||
+ | === Crear, configurar e instalar certificados - Let's Encrypt === | ||
+ | |||
+ | Podemos utilizar la página web [https://gethttpsforfree.com/ Get HTTPS for free] para conseguir unos certificados válidos acreditados por esta entidad. Para ello se deben siguir ciertos pasos que detallamos a continuación. | ||
+ | |||
+ | ==== Generar clave privada y solicitud de firma de certificado ==== | ||
+ | |||
+ | Para generar una clave privada ejecutamos el siguiente comando en una de las Raspberry Pi. | ||
+ | '''$''' openssl genrsa 4096 > Certificados/domain.key | ||
+ | |||
+ | Seguidamente generamos una petición de firma de certificado (CSR) con el dominio, en nuestro caso ''woseberry.tk'' | ||
+ | '''$''' openssl req -new -sha256 -key Certificados/domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:woseberry.tk")) | ||
+ | |||
+ | ==== Firmar la petición API ==== | ||
+ | |||
+ | Para que la entidad Let’s Encrypt pueda validar que somos realmente nosotros quienes solicitamos los certificados y los que disponemos del servidor donde queremos instalarlos, deberemos ir generando unas claves a partir de nuestra clave privada. De este modo, devolviendo el HASH resultante podrán acreditar nuestra identidad y propiedad del dominio. | ||
+ | Uno de los pasos a realizar es la configuración de un registro TXT en los DNS de nuestro proveedor de dominio que apunten al dominio ''woseberry.tk''. Por esta razón, es primordial tener registrado dicho dominio y apuntarlo a un servidor público en Internet. De esta manera, al configurar el registro TXT en el DNS, '''Let’s Encrypt''' podrá validar correctamente nuestra identidad. | ||
+ | |||
+ | ==== Instalación de certificados ==== | ||
+ | |||
+ | Una vez finalizados los pasos anteriores, dispondremos de 3 claves: | ||
+ | *domain.key | ||
+ | *domain.crt | ||
+ | *intermediate.pem | ||
+ | |||
+ | Estas claves las utilizaremos tanto en los servidores Apache de las Raspberry BERRY-02 y BERRY-03 como para la BERRY-01 con HAProxy. Por lo tanto, es primordial disponer de estos tres archivos en las tres Raspberry. Para ello, podemos copiarlos mediante el siguiente comando en la Raspberry correspondiente. | ||
+ | '''$''' scp Certificados/* pi@BERRY-01:/home/pi/Certificados | ||
+ | '''$''' scp Certificados/* pi@BERRY-02:/home/pi/Certificados | ||
+ | '''$''' scp Certificados/* pi@BERRY-03:/home/pi/Certificados | ||
+ | |||
+ | Creamos la misma carpeta en las tres Raspberry para almacenar las claves. | ||
+ | <b>$</b> sudo mkdir /etc/apache2/ssl | ||
+ | |||
+ | Una vez hayamos transferido los certificados y tengamos la carpeta ''/etc/apache2/ssl'' creada en las tres Raspberry, moveremos las claves a dicha carpeta mediante el siguiente comando. | ||
+ | <b>$</b> sudo mv Certificados/* /etc/apache2/ssl | ||
+ | |||
+ | === Configuración de los servidores web con los certificados === | ||
+ | |||
+ | '''¡Importante! Esta configuración deberá realizarse en las BERRY-02 y BERRY-03.''' | ||
+ | |||
+ | En primer lugar activamos el modulo SSL de apache2. | ||
+ | |||
+ | <b>$</b> sudo a2enmod ssl | ||
+ | |||
+ | Antes de modificar el archivo de configuración ''default-ssl.conf'', hacemos una copia de seguridad del site SSL. | ||
+ | |||
+ | <b>$</b> sudo cp /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-available/default-ssl.conf.bak | ||
+ | |||
+ | Ahora ya podemos modificar el archivo del site SSL y especificar las rutas al certificado y clave privada. | ||
+ | |||
+ | <b>$</b> sudo nano /etc/apache2/sites-available/default-ssl.conf | ||
+ | |||
+ | <IfModule mod_ssl.c> | ||
+ | <VirtualHost _default_:443> | ||
+ | ServerAdmin [email protected] | ||
+ | DocumentRoot /var/www/html | ||
+ | ErrorLog ${APACHE_LOG_DIR}/error.log | ||
+ | CustomLog ${APACHE_LOG_DIR}/access.log combined | ||
+ | '''SSLEngine on''' | ||
+ | '''SSLCertificateFile /etc/apache2/ssl/domain.crt''' | ||
+ | '''SSLCertificateKeyFile /etc/apache2/ssl/domain.key''' | ||
+ | <FilesMatch "\.(cgi|shtml|phtml|php)$"> | ||
+ | SSLOptions +StdEnvVars | ||
+ | </FilesMatch> | ||
+ | <Directory /usr/lib/cgi-bin> | ||
+ | SSLOptions +StdEnvVars | ||
+ | </Directory> | ||
+ | </VirtualHost> | ||
+ | </IfModule> | ||
+ | |||
+ | Habilitamos el site con SSL. | ||
+ | <b>$</b> sudo a2ensite default-ssl.conf | ||
+ | |||
+ | Para aplicar los cambios debemos reiniciar el servicio de apache2. | ||
+ | <b>$</b> sudo service apache2 restart | ||
+ | |||
+ | |||
+ | == Balanceo de las páginas web - HAProxy == | ||
+ | |||
+ | === Instalación y configuración === | ||
+ | |||
+ | Con los gestores de contenido ya operativos, el siguiente paso será configurar el balanceo de carga hacia ellos. Para ello instalaremos el paquete ''HAProxy'' ejecutando el siguiente comando en la BERRY-01: | ||
+ | |||
+ | <b>pi@BERRY-01:~$</b> sudo apt install haproxy | ||
+ | |||
+ | Para poder iniciar el balanceador de carga, debemos entrar en el archivo ''/etc/default/'''haproxy''''' y modificar el valor por defecto de la línea "ENABLED" por el valor 1 | ||
+ | |||
+ | <b>pi@BERRY-01:~$</b> sudo nano /etc/default/haproxy | ||
+ | |||
+ | ... | ||
+ | |||
+ | ENABLED='''1''' | ||
+ | |||
+ | En el archivo de configuración de HAProxy disponemos de los apartados generales con los que el servicio comprueba el estado de los servidores, los logs donde guarda cada suceso, el modo de conexión que realiza para cada chequeo, etc. | ||
+ | |||
+ | Un parámetro importante a cambiar es el tiempo en el que HAProxy realiza el chequeo para comprobar el estado de los servidores. Por defecto, su valor está a 30 segundos. Si queremos mejorar la alta disponibilidad, deberemos bajar este valor, sin embargo, hay que tener en cuenta que al bajar este valor se generará más tráfico en la red por culpa de los chequeos. | ||
+ | |||
+ | En nuestro caso reduciremos este valor a 10 segundos: | ||
+ | |||
+ | <b>pi@BERRY-01:~$</b> sudo nano /etc/haproxy/haproxy.cfg | ||
+ | |||
+ | global | ||
+ | log /dev/log local0 | ||
+ | log /dev/log local1 notice | ||
+ | chroot /var/lib/haproxy | ||
+ | stats socket /run/haproxy/admin.sock mode 660 level admin | ||
+ | '''stats timeout 10s''' | ||
+ | user haproxy | ||
+ | group haproxy | ||
+ | daemon | ||
+ | |||
+ | Para balancear el tráfico hacia los diferentes servidores web, editaremos el archivo de configuración ''/etc/haproxy/'''haproxy.cfg'''''. Al final del fichero crearemos un nuevo ''frontend'' el cual permite escuchar peticiones tanto por el puerto 80 como por el puerto 443 en cualquiera de las interfaces de la BERRY-01. Estas peticiones las reedirigirá hacia los servidores web indicados por el puerto 443. Además, también deberá conservar las sesiones pertinentes para que un usuario pueda iniciar sesión y no la pierda mientras navega por las diferentes páginas o realiza una compra. | ||
+ | |||
+ | <b>pi@BERRY-01:~$</b> sudo nano /etc/haproxy/haproxy.cfg | ||
+ | |||
+ | frontend woseberry | ||
+ | bind *:80 | ||
+ | bind *:443 ssl crt /etc/apache2/ssl/intermediate.pem | ||
+ | default_backend apaches | ||
+ | |||
+ | backend apaches | ||
+ | balance leastconn | ||
+ | cookie SRVNAME insert | ||
+ | server BERRY-02 192.168.30.2:443 check cookie BERRY-02 check ssl verify none | ||
+ | server BERRY-03 192.168.30.3:443 check cookie BERRY-03 check ssl verify none | ||
+ | |||
+ | Una vez realizada toda la configuración, reiniciaremos el servicio de HAProxy para aplicar los cambios: | ||
+ | <b>pi@BERRY-01:~$</b> sudo service haproxy restart | ||
+ | |||
+ | Gracias a HAProxy habremos conseguido el balanceo de carga entre ambos WordPress consiguiendo un esquema como el siguiente: | ||
+ | |||
+ | {|{| class="wikitable" | ||
+ | |[[File:Esquema2-apaches.jpg|center|400px]] | ||
+ | |- | ||
+ | |Esquema del balanceo con HAProxy entre ambos WordPress | ||
+ | |} | ||
+ | |||
+ | === Visualizar el log === | ||
+ | |||
+ | Para visualizar cada comprobación que hace el servicio HAProxy en la BERRY-01, disponemos de un log general situado en la carpeta ''/var/log/''. Este log registra cada operación de comprobación realizada y también queda registrado cuando uno de los nodos falla. | ||
+ | |||
+ | Si queremos disponer por un log independiente por cada ''frontend'' configurado, podemos activarlo con la siguiente directiva: | ||
+ | |||
+ | log /var/log/haproxy_frontend | ||
+ | |||
+ | Sin embargo, tenemos que considerar que cada comprobación que realice HAProxy quedará registrada en este log, por lo que el archivo aumentará de tamaño poco a poco y podría provocar que nos quedáramos sin espacio en disco. | ||
+ | |||
+ | En el siguiente ejemplo, podemos comprobar como el servicio se ha iniciado: | ||
+ | |||
+ | May 17 17:05:04 BERRY-01 haproxy[2309]: Proxy woseberry started. | ||
+ | May 17 17:05:04 BERRY-01 haproxy[2309]: Proxy woseberry started. | ||
+ | May 17 17:05:04 BERRY-01 haproxy[2309]: Proxy apaches started. | ||
+ | May 17 17:05:04 BERRY-01 haproxy[2309]: Proxy apaches started. | ||
+ | May 17 17:05:04 BERRY-01 haproxy[2309]: Proxy mysql started. | ||
+ | May 17 17:05:04 BERRY-01 haproxy[2309]: Proxy mysql started. | ||
+ | May 17 17:05:04 BERRY-01 haproxy[2309]: Proxy databases started. | ||
+ | May 17 17:05:04 BERRY-01 haproxy[2309]: Proxy databases started. | ||
+ | |||
+ | En este ejemplo podemos observar como la conexión con la BERRY-03 se ha perdido y unos minutos más tarde se restablece: | ||
+ | May 17 17:05:06 BERRY-01 haproxy[2313]: Server apaches/BERRY-03 is '''DOWN''', reason: Layer4 timeout, check duration: 2000ms. 1 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue. | ||
+ | May 17 17:18:11 BERRY-01 haproxy[2313]: Server apaches/BERRY-03 is '''UP''', reason: Layer6 check passed, check duration: 250ms. 2 active and 0 backup servers online. 0 sessions requeued, 0 total in queue. | ||
+ | |||
+ | |||
+ | == Replicación bases de datos - Galera == | ||
+ | |||
+ | === Instalación y configuración de Galera === | ||
+ | |||
+ | Para poder utilizar el software Galera, debemos asegurarnos de tener instalados los siguientes paquetes en todos los servidores MySQL. En nuestro caso en las BERRY-04, BERRY-05 y BERRY-06: | ||
+ | |||
+ | * mysql-server | ||
+ | * mariadb-server | ||
+ | * mariadb-server-10.1 | ||
+ | * rsync | ||
+ | * python3-software-properties | ||
+ | |||
+ | El siguiente paso será editar el archivo ''/etc/mysql/mariadb.conf.d/'''50-server.cnf'''''. En este fichero deberemos buscar la línea con el parámetro ''bind-address'' y comentarla: | ||
+ | <b>$</b> sudo nano /etc/mysql/mariadb.conf/50-server.cnf | ||
+ | |||
+ | ... | ||
+ | '''#''' bind-address = 127.0.0.1 | ||
+ | ... | ||
+ | |||
+ | === Configuración del nodo principal === | ||
+ | Deberemos tener claro con que nodo vamos a iniciar el cluster, ya que el archivo de configuración de Galera variará con respecto al resto de nodos. En nuestro caso, el nodo principal y creador del cluster será la BERRY-04. | ||
+ | |||
+ | Por defecto, Galera no dispone de ningún archivo de configuración de ejemplo, por lo que deberemos crearlo manualmente. El único requisito fundamental será que este archivo esté ubicado en el directorio ''/etc/mysql/conf.d'' y tenga como extensión ''.cnf'' | ||
+ | |||
+ | Crearemos el fichero en el nodo principal: | ||
+ | |||
+ | '''pi@BERRY-04:~$''' sudo touch /etc/mysql/conf.d/galera.cnf | ||
− | + | En él, configuraremos los siguientes parámetros: | |
− | |||
− | |||
− | |||
− | |||
− | + | [galera] | |
− | + | # Mandatory settings | |
− | + | wsrep_on=ON | |
− | + | wsrep_provider=/usr/lib/galera/libgalera_smm.so | |
− | + | binlog_format=row | |
+ | default_storage_engine=InnoDB | ||
+ | innodb_autoinc_lock_mode=2 | ||
+ | wsrep_sst_method=rsync | ||
+ | |||
+ | # Node configuration | ||
+ | wsrep_cluster_address='''"gcomm://"''' | ||
+ | wsrep_node_address='''192.168.30.4''' | ||
+ | wsrep_node_name='''"NODO_1"''' | ||
+ | |||
+ | # Custom settings | ||
+ | wsrep_cluster_name="Cluster_galera" | ||
+ | bind-address='''192.168.30.4''' | ||
− | + | La información resaltada es aquella que deberemos cambiar en cada archivo de configuración de cada nodo. Dado que la BERRY-04 la hemos establecido como nodo principal, el apartado ''wsrep_cluster_address'' deberá permanecer tal y como se muestra. Sin embargo, veremos que en el resto de nodos deberemos especificar la IP de cada nodo. | |
− | + | En los apartados ''wsrep_node_address'' y ''bind-address'' deberemos indicar la dirección IP o nombre DNS del nodo donde se está aplicando la configuración. El apartado ''wsrep_node_name'' nos proporcionará un nombre identificativo por cada nodo. Podemos personalizarlo al igual que el apartado ''wsrep_cluster_name'', el cual solo define un nombre común para el clúster. | |
− | + | Finalizada la configuración pararemos el servicio de MySQL: | |
− | |||
− | |||
− | |||
− | + | '''pi@BERRY-04:~$''' sudo systemctl stop mysql | |
− | |||
− | |||
− | |||
+ | Una vez detenido, iniciaremos el cluster con el siguiente comando: | ||
− | === | + | '''pi@BERRY-04:~$''' sudo galera_new_cluster |
+ | |||
+ | Por último, iniciaremos el servicio de MySQL: | ||
+ | |||
+ | '''pi@BERRY-04:~$''' sudo systemctl start mysql | ||
+ | |||
+ | === Configuración para el resto de nodos === | ||
+ | Al igual que en el nodo principal, deberemos crear el fichero de configuración en el directorio correspondiente: | ||
+ | |||
+ | '''$''' sudo touch /etc/mysql/conf.d/galera.cnf | ||
+ | |||
+ | En él, configuraremos los siguientes parámetros (BERRY-05): | ||
+ | |||
+ | [galera] | ||
+ | # Mandatory settings | ||
+ | wsrep_on=ON | ||
+ | wsrep_provider=/usr/lib/galera/libgalera_smm.so | ||
+ | binlog_format=row | ||
+ | default_storage_engine=InnoDB | ||
+ | innodb_autoinc_lock_mode=2 | ||
+ | wsrep_sst_method=rsync | ||
+ | |||
+ | # Node configuration | ||
+ | wsrep_cluster_address='''"gcomm://192.168.30.4,192.168.30.5,192.168.30.6"''' | ||
+ | wsrep_node_address='''192.168.30.5''' | ||
+ | wsrep_node_name='''"NODO_2"''' | ||
+ | |||
+ | # Custom settings | ||
+ | wsrep_cluster_name="Cluster_galera" | ||
+ | bind-address='''192.168.30.5''' | ||
+ | |||
+ | Y en el caso de la BERRY-06: | ||
+ | |||
+ | [galera] | ||
+ | # Mandatory settings | ||
+ | wsrep_on=ON | ||
+ | wsrep_provider=/usr/lib/galera/libgalera_smm.so | ||
+ | binlog_format=row | ||
+ | default_storage_engine=InnoDB | ||
+ | innodb_autoinc_lock_mode=2 | ||
+ | wsrep_sst_method=rsync | ||
+ | |||
+ | # Node configuration | ||
+ | wsrep_cluster_address='''"gcomm://192.168.30.4,192.168.30.5,192.168.30.6"''' | ||
+ | wsrep_node_address='''192.168.30.6''' | ||
+ | wsrep_node_name='''"NODO_3"''' | ||
+ | |||
+ | # Custom settings | ||
+ | wsrep_cluster_name="Cluster_galera" | ||
+ | bind-address='''192.168.30.6''' | ||
+ | |||
+ | Como podemos observar, las BERRY-05 y BERRY-06 contienen la misma información. Los únicos parámetros que hay que variar por cada nodo son ''wsrep_node_address'', ''wsrep_node_name'' y ''bind-address''. | ||
+ | |||
+ | Una vez tengamos los archivos de configuración de Galera en el resto de nodos reiniciaremos el servicio MySQL en cada uno de ellos. '''¡Importante! Hay que reiniciar el servicio uno a uno, esperando a que finalice el de un servidor para poder reiniciar el del otro''': | ||
+ | |||
+ | '''$''' sudo systemctl restart mysql | ||
+ | |||
+ | Podremos comprobar que todos los nodos se han unido al clúster ejecutando la siguiente sentencia SQL en cualquiera de ellos: | ||
+ | |||
+ | '''$''' sudo mysql -u root -p -e 'SELECT VARIABLE_VALUE as "Núm. nodos" FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME="wsrep_cluster_size"' | ||
+ | |||
+ | +-------------+ | ||
+ | | Núm. nodos | | ||
+ | +-------------+ | ||
+ | | 3 | | ||
+ | +-------------+ | ||
+ | |||
+ | Gracias a Galera, habremos conseguido la replicación entre bases de datos y tendremos un esquema parecido al siguiente: | ||
+ | |||
+ | {|{| class="wikitable" | ||
+ | |[[File:Esquema2-db.jpg|center|800px]] | ||
+ | |- | ||
+ | |Esquema de la replicación de Galera con el balanceo de HAProxy | ||
+ | |} | ||
+ | |||
+ | === Usuario de chequeo === | ||
+ | Por tal de que HAProxy sea capaz de comprobar que nodo MariaDB está operativo y cual está caído, deberemos crear un usuario sin contraseña. HAProxy utilizará este usuario para establecer una conexión y así mantener el nodo operativo. Para crear este usuario entraremos en la consola de MySQL en cualquiera de los nodos, como por ejemplo la BERRY-04: | ||
+ | <b>pi@BERRY-04:~$</b> mysql -u pi -p | ||
+ | |||
+ | Una vez hayamos entrado en la consola, crearemos el usuario ejecutando el siguiente comando. '''¡Importante! El usuario no debe tener contraseña definida ni permisos sobre otras bases de datos, ya que únicamente se utilizará para establecer una conexión a modo de chequeo''': | ||
+ | |||
+ | <b>MariaDB [(none)]></b> CREATE USER 'haproxy'@'192.168.30.254'; | ||
+ | |||
+ | El usuario se llamará ''haproxy'' para ser más identificativo y solo permitirá conectarse desde la IP donde está instalado HAProxy. | ||
+ | |||
+ | Dado que las bases de datos están replicadas, tan solo deberemos crearlo en uno de los nodos. Ejecutando la siguiente sentencia SQL en el resto de nodos podremos comprobar que el usuario se ha replicado correctamente: | ||
+ | |||
+ | <b>MariaDB [(none)]></b> SELECT haproxy from mysql.user; | ||
+ | |||
+ | Donde podremos ver toda la información del usuario haproxy: | ||
+ | |||
+ | |||
+ | == Balanceo de las bases de datos - HAProxy == | ||
+ | |||
+ | === Configuración del balanceo === | ||
+ | Ahora que ya tenemos las bases de datos funcionando con el software ''Galera'', es decir, funcionando en cluster y replicadas, balancearemos el tráfico hacia ellas para conseguir el mayor rendimiento posible. Para ello editaremos la configuración de HAProxy en el fichero ''/etc/haproxy/'''haproxy.cfg''''': | ||
+ | |||
+ | <b>pi@BERRY-01:~$</b> sudo nano /etc/haproxy/haproxy.cfg | ||
+ | |||
+ | Añadiendo las siguientes líneas al final del fichero: | ||
+ | |||
+ | <pre> | ||
+ | frontend mysql | ||
+ | bind 192.168.30.254:3306 | ||
+ | mode tcp | ||
+ | default_backend databases | ||
+ | |||
+ | backend databases | ||
+ | balance roundrobin | ||
+ | mode tcp | ||
+ | option tcpka | ||
+ | option mysql-check user haproxy | ||
+ | server BERRY-04 192.168.30.4:3306 check weight 1 | ||
+ | server BERRY-05 192.168.30.5:3306 check weight 1 | ||
+ | server BERRY-06 192.168.30.6:3306 check weight 1 | ||
+ | </pre> | ||
+ | |||
+ | Como podemos observar, hemos creado un nuevo ''frontend'' encargado de escuchar peticiones a la IP 192.168.30.254 por el puerto 3306. Cuando estas peticiones se realicen redireccionará el tráfico hacia el ''backend'' llamado ''databases''. | ||
+ | Este ''backend'' balancea con el algoritmo ''roundrobin'' hacia los servidores MySQL de las BERRY-04, BERRY-05 y BERRY-06. Para comprobar que el servicio está operativo y sigue funcionando, realizará una conexión hacia la base de datos con el usuario ''haproxy'', el cual creamos en el apartado anterior. | ||
+ | |||
+ | Finalizada esta configuración reiniciaremos el servicio de HAProxy para aplicar los cambios: | ||
+ | |||
+ | <b>pi@BERRY-01:~$</b> sudo service haproxy restart | ||
+ | |||
+ | === Configuración de los servidores web === | ||
+ | |||
+ | Hasta ahora, cada servidor web estaba configurado para realizar peticiones a una base de datos en concreto. Sin embargo, ahora que tenemos un sistema de replicas y balanceado, conviene que todos los servidores web soliciten la petición de la base de datos al HAProxy. De esta manera, él será el encargado de indicar a que base de datos realizar la consulta. | ||
+ | |||
+ | Para ello, deberemos editar el archivo ''/var/www/html/'''wp-config.php''''' en los servidores web e indicar la nueva IP de la base de datos: | ||
+ | |||
+ | <b>$</b> sudo nano /var/www/html/wp-config.php | ||
+ | |||
+ | // ** MySQL settings - You can get this info from your web host ** // | ||
+ | /** The name of the database for WordPress */ | ||
+ | define('DB_NAME', 'wordpress'); | ||
+ | |||
+ | /** MySQL database username */ | ||
+ | define('DB_USER', 'wordpress'); | ||
+ | |||
+ | /** MySQL database password */ | ||
+ | define('DB_PASSWORD', 'woseberry'); | ||
+ | |||
+ | /** MySQL hostname */ | ||
+ | define('DB_HOST', ''''192.168.30.254''''); | ||
+ | |||
+ | /** Database Charset to use in creating database tables. */ | ||
+ | define('DB_CHARSET', 'utf8'); | ||
+ | |||
+ | /** The Database Collate type. Don't change this if in doubt. */ | ||
+ | define('DB_COLLATE', ''); | ||
+ | |||
+ | |||
+ | |||
+ | == Sincronizacíon de las uploads en WordPress - Rsync == | ||
+ | Ahora que ya tenemos la replicación en las bases de datos, debemos tener en cuenta que WordPress almacena todas las imágenes de manera local, es decir, en el mismo servidor web. Para solucionar esta inconcurrencia de datos disponemos de dos mecanismos como: | ||
+ | * Creación de un directorio compartido entre los servidores web: NFS | ||
+ | * Sincronización del directorio ''wp-content'': Rsync | ||
+ | |||
+ | En nuestro caso, hemos elegido la opción de sincronización de los directorios, ya que de esta manera nos ahorraremos la instalación de un nuevo servicio como es NFS. Simplemente con la utilización del paquete ''rsync'' conseguiremos mantener el directorio ''wp-content'' en ambos servidores web de manera idéntica. | ||
+ | Esta sincronización la programaremos para que se realice cada 15 minutos, comprobando aquellos ficheros que son diferentes y realizando la copia mediante el uso de ''SSH''. Para poder programar esta sincronización utilizaremos la herramienta del sistema ''crontab'': | ||
+ | <b>pi@BERRY-02:~$</b> crontab -e | ||
+ | |||
+ | Añadiendo la siguiente línea al final del fichero: | ||
+ | |||
+ | # m h dom mon dow command | ||
+ | */15 * * * * rsync -ahvrz /var/www/html/wp-content/uploads/* pi@'''192.168.30.3''':/var/www/html/wp-content/uploads | ||
+ | |||
+ | Dado que la copia se realiza con el uso de ''SSH'', cuando se establezca la conexión nos pedirá la contraseña del usuario. Si queremos evitar esta acción y que se realice la sincronización sin interacción del usuario deberemos generar una clave pública y una clave privada para el usuario ''pi'' en la BERRY-02: | ||
+ | <b>pi@BERRY-02:~$</b> ssh-keygen | ||
+ | |||
+ | Seguidamente copiaremos la clave pública en la BERRY-03 para que permanezca en la lista de claves autorizadas: | ||
+ | <b>pi@BERRY-02:~$</b> ssh-copy-id pi@'''192.168.30.3''' | ||
+ | |||
+ | Finalizada esta operación, la BERRY-02 se conectará automáticamente por ''SSH'' a la BERRY-03 y realizará una sincronización del directorio ''wp-content'' en caso de que haya ficheros o directorios distintos. | ||
− | + | Realizaremos la misma operación en la BERRY-03, indicando al IP de la BERRY-02 en la conexión por ''SSH''. | |
− | |||
− | + | == Envío de correos en caso de error en MySQL - SSMTP == | |
+ | Para el administrador de todo este escenario, es primordial tener constancia cuanto antes siempre que falle uno de los servidores. De esta manera, se puede aplicar solución al problema y seguir ofreciendo un servicio de alta disponibilidad al usuario. Es por ello que la creación de pequeños chequeos que revisen el funcionamiento correcto de servicios como ''apache2'' o ''mysql'', sea primordial. | ||
− | + | En cada uno de los servidores se creará un script que monitorice el servicio correspondiente. En el caso de las BERRY-02 o BERRY-03 se monitorizará el servicio ''apache2''. En cuanto a las BERRY-04, BERRY-05 y BERRY-06 se monitorizará el servicio de ''mysql''. | |
− | + | === Instalación y configuración de ssmtp === | |
− | + | '''¡Importante! Está configuración debe realizarse en las BERRY-04, BERRY-05 y BERRY-06''' | |
− | + | El paquete ''ssmtp'' nos permite enviar correos a través de la terminal GNU/Linux. De esta manera, en el momento que el sistema se de cuenta de que el servicio que se estaba monitorizando cae, enviará un correo a la cuenta del administrador. | |
+ | Para instalar este paquete ejecutaremos el siguiente comando todas las Raspberry: | ||
− | + | '''$''' sudo apt install ssmtp | |
− | + | Seguidamente, editaremos el archivo de configuración '''''/etc/ssmtp/ssmtp.conf''''': | |
− | |||
− | + | '''$''' sudo nano /etc/ssmtp/ssmtp.conf | |
− | |||
+ | # Config file for sSMTP sendmail | ||
+ | |||
+ | # Correo utilizado para enviar mensajes | ||
+ | |||
+ | |||
+ | # Servidor de correo utilizado | ||
+ | mailhub=smtp.gmail.com:465 | ||
+ | |||
+ | # Dominio de correo | ||
+ | rewriteDomain=gmail.com | ||
+ | |||
+ | # Credenciales cuenta de correo | ||
+ | AuthUser=woseberry | ||
+ | AuthPass=woseberryP@ssw0rd | ||
+ | |||
+ | FromLineOverride=YES | ||
+ | UseTLS=YES | ||
+ | |||
+ | # The full hostname | ||
+ | hostname=DEBIAN-VM | ||
− | + | === Script de monitorizaje === | |
+ | En el caso de las BERRY-04, BERRY-05 y BERRY-06 que son las encargadas de almacenar las bases de datos. El script se encargará de revisar que el servicio esté en marcha constantemente. En el momento en el que falle, se ejecutará la orden de enviar un correo al administrador con información como la hora, el estado actual del servicio y el log de errores: | ||
− | + | #!/bin/bash | |
+ | |||
+ | servicio=mysql | ||
+ | fecha=$(date) | ||
+ | maquina=$(hostname) | ||
+ | estadoServicio=$(service mysql status) | ||
+ | logError=$(tail -n 20 /var/log/mysql/error.log) | ||
+ | mensajeError="Al parecer se ha detenido $servicio en la $maquina aproximadamente. Hora aproximada: $fecha" | ||
+ | |||
+ | if (( $(ps -ef | grep -v grep | grep $servicio | wc -l) == 0 )); then | ||
+ | echo -e "Subject: ERROR - MySQL\n\n$mensajeError\n\n$estadoServicio\n\n$logError" | ssmtp woseberry@gmail.com | ||
+ | fi | ||
− | + | Una vez creado el script, deberemos añadirlo en el demonio crontab para que se ejecute cada cierto tiempo, como por ejemplo, cada 10 minutos. | |
+ | Dado que este script contiene comandos de superusuario o de root, deberemos añadirlo al crontab con privilegios: | ||
+ | '''$''' sudo crontab -e | ||
− | + | Y añadiremos al final del archivo las siguientes líneas: | |
− | + | # Revisar el funcionamiento de MySQL | |
+ | */10 * * * * bash /home/pi/Scripts/mailMySQL_cron.sh | ||
− | |||
+ | == Realizar copias de seguridad en la base de datos - MySQLdump == | ||
− | + | Aunque tengamos nuestras bases de datos replicadas y eso ya nos proporcione cierto nivel de seguridad, siempre es recomendable realizar copias de seguridad periódicamente. | |
− | + | Con el siguiente script, podemos crear un backup de la base de datos ''wordpress'' en cualquier momento, ya que el comando '''mysqldump''' antes de proceder a realizar el backup bloquea las tablas de la base de datos para que no se pueda escribir durante la copia y así obtener un backup fiable con integridad de sus datos. Como resultado, obtendremos un archivo con extensión ''.sql'' con el nombre especificado más la fecha y hora del instante de la realización de dicho backup. | |
− | |||
− | + | #!/bin/bash | |
− | |||
+ | mysqldump --user=pi --password=woseberry wordpress > backup_wordpress_$(date "+%d-%m-%Y_%H:%M:%S").sql | ||
− | + | echo "Copia de seguridad de la base de datos wordpress realizada." | |
− | + | Pero al margen de poder realizar el backup en cualquier momento, es importante programarlo para que éste se ejecute automáticamente. | |
− | |||
− | + | En esta ocasión configuraremos el demonio ''crontab'' en las BERRY-04, BERRY-05 y BERRY-06 para que ejecute el script creado, cada día a las 4 en punto de la madrugada, ya que es la hora con menos actividad de la página en España, y realice un backup de la base de datos ''wordpress''. | |
− | |||
+ | Ejecutamos el crontab del usuario root: | ||
− | + | '''$''' sudo crontab -e | |
− | + | Añadimos las siguientes líneas al final del archivo: | |
− | + | # Realizar backup de la base de datos wordpress | |
+ | 00 4 * * * bash /home/pi/Scripts/backup_wordpressdb.sh | ||
− | + | == Configuración del firewall - IPtables == | |
− | + | Ahora que tenemos todo el esquema montado, es conveniente denegar algunos accesos malintencionados que intenten vulnerar la seguridad de la tienda virtual. Para ello se ejecutará un script al inicio del sistema en la BERRY-01: | |
<pre> | <pre> | ||
− | // | + | #!/bin/bash |
− | + | ||
− | + | # Borrar toda las reglas | |
+ | iptables -F | ||
+ | iptables -X | ||
+ | iptables -Z | ||
+ | |||
+ | # Definir las políticas por defecto | ||
+ | iptables -P INPUT DROP | ||
+ | iptables -P OUTPUT ACCEPT | ||
+ | |||
+ | # Permitir las conexiones SSH en ambas interfaces | ||
+ | iptables -A INPUT -i eth1 -p tcp --dport 22 -j ACCEPT | ||
+ | iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT | ||
+ | |||
+ | # Permitir las conexiones DNS en ambas interfaces | ||
+ | iptables -A INPUT -i eth1 -p tcp --dport 53 -j ACCEPT | ||
+ | iptables -A INPUT -i eth1 -p udp --dport 53 -j ACCEPT | ||
+ | iptables -A INPUT -i eth0 -p tcp --dport 53 -j ACCEPT | ||
+ | iptables -A INPUT -i eth0 -p udp --dport 53 -j ACCEPT | ||
− | + | # Permitir las peticiones HTTP y HTTPS en ambas interfaces | |
− | + | iptables -A INPUT -i eth1 -p tcp --dport 80 -j ACCEPT | |
+ | iptables -A INPUT -i eth1 -p tcp --dport 443 -j ACCEPT | ||
+ | iptables -A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT | ||
+ | iptables -A INPUT -i eth0 -p tcp --dport 443 -j ACCEPT | ||
− | + | # Permitir las peticiones MySQL en la interfaz interna | |
− | + | iptables -A INPUT -i eth0 -p tcp --dport 3306 -j ACCEPT | |
+ | iptables -A INPUT -i eth0 -p udp --dport 3306 -j ACCEPT | ||
− | + | # Permitir las conexiones preestablecidas | |
− | + | iptables -A INPUT -i eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT | |
+ | iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT | ||
− | / | + | # Habilitar el enrutamiento |
− | + | echo 1 > /proc/sys/net/ipv4/ip_forward | |
− | + | # Enmascarar la red LAN con la interfaz eth1 (Internet) | |
− | + | iptables -t nat -A POSTROUTING -s 192.168.30.0/24 -o eth1 -j MASQUERADE | |
</pre> | </pre> | ||
+ | Seguidamente, añadiremos la ejecucción de este script en el archivo /etc/rc.local: | ||
+ | |||
+ | '''pi@BERRY-01:~$''' sudo nano /etc/rc.local | ||
+ | |||
+ | … | ||
+ | |||
+ | '''# Ejecutar las reglas del firewall''' | ||
+ | '''bash /home/pi/Scripts/firewall.sh''' | ||
+ | |||
+ | exit 0 | ||
+ | |||
+ | |||
+ | == Pruebas de rendimiento - Apache Bench == | ||
+ | |||
+ | Como suele ser habitual en cualquier proyecto, una vez tenemos la infraestructura funcionando, es conveniente realizar las correspondientes pruebas de rendimiento. En nuestro caso, realizaremos pruebas principalmente sobre el servidor web apache y registraremos sus resultados. | ||
+ | |||
+ | Para realizar dichas pruebas de rendimiento utilizaremos el programa Apache Bench, y para instalarlo deberemos ejecutar el siguiente comando: | ||
− | + | '''$''' sudo apt-get install apache2-utils | |
+ | |||
+ | Para realizar una prueba de rendimiento de por ejemplo 200 peticiones, ejecutándose con una concurrencia de 20 peticiones simultáneas, sobre la página web woseberry.tk y guardando los resultados en un archivo, el comando a ejecutar sería el siguiente: | ||
+ | |||
+ | '''$''' ab -g resultados.tsv -n 200 -c 20 <nowiki>https://woseberry.tk/</nowiki> | ||
+ | |||
+ | '''ab''' es Apache Bench | ||
+ | |||
+ | '''-g resultados.tsv''' guarda los resultados en el archivo resultados.tsv | ||
+ | |||
+ | '''-n 200''' indica que se harán 200 peticiones | ||
+ | |||
+ | '''-c 20''' indica que se harán 20 peticiones concurrentes | ||
+ | |||
+ | '''<nowiki>https://woseberry.tk/</nowiki>''' es la URL que vamos a testear | ||
+ | |||
+ | |||
+ | Resultado de la ejecución del comando anterior: | ||
<pre> | <pre> | ||
− | // | + | This is ApacheBench, Version 2.3 <$Revision: 1706008 $> |
− | / | + | Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ |
− | + | Licensed to The Apache Software Foundation, http://www.apache.org/ | |
− | + | Benchmarking woseberry.tk (be patient) | |
− | + | Completed 100 requests | |
+ | Completed 200 requests | ||
+ | Finished 200 requests | ||
− | |||
− | |||
− | / | + | Server Software: Apache/2.4.25 |
− | + | Server Hostname: woseberry.tk | |
+ | Server Port: 443 | ||
+ | SSL/TLS Protocol: TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,4096,256 | ||
− | + | Document Path: / | |
− | + | Document Length: 48189 bytes | |
− | / | + | Concurrency Level: 20 |
− | + | Time taken for tests: 62.257 seconds | |
+ | Complete requests: 200 | ||
+ | Failed requests: 0 | ||
+ | Total transferred: 9700200 bytes | ||
+ | HTML transferred: 9637800 bytes | ||
+ | Requests per second: 3.21 [#/sec] (mean) | ||
+ | Time per request: 6225.711 [ms] (mean) | ||
+ | Time per request: 311.286 [ms] (mean, across all concurrent requests) | ||
+ | Transfer rate: 152.16 [Kbytes/sec] received | ||
+ | |||
+ | Connection Times (ms) | ||
+ | min mean[+/-sd] median max | ||
+ | Connect: 198 893 1055.8 587 3969 | ||
+ | Processing: 1483 5251 1276.6 5368 9083 | ||
+ | Waiting: 1449 5052 1286.8 5090 9034 | ||
+ | Total: 1869 6144 1484.3 6149 10674 | ||
+ | |||
+ | Percentage of the requests served within a certain time (ms) | ||
+ | 50% 6149 | ||
+ | 66% 6502 | ||
+ | 75% 6807 | ||
+ | 80% 7039 | ||
+ | 90% 7920 | ||
+ | 95% 9012 | ||
+ | 98% 9675 | ||
+ | 99% 9880 | ||
+ | 100% 10674 (longest request) | ||
</pre> | </pre> | ||
+ | === Interpretación de resultados === | ||
+ | |||
+ | Como podemos ver en el resultado de la prueba de rendimiento, obtenemos una gran cantidad de datos, y aunque la mayoría de ellos tienen una gran importancia para poder medir determinados aspectos, los que podemos considerar como genéricamente más relevantes son los siguientes: | ||
+ | |||
+ | |||
+ | * '''Peticiones completadas:''' 200 | ||
+ | |||
+ | * '''Peticiones fallidas:''' 0 | ||
+ | |||
+ | * '''Peticiones por segundo:''' 3.21 (promedio) | ||
+ | |||
+ | * '''Velocidad de transferencia (Kbytes/sec):''' 152.16 recibidos | ||
+ | |||
+ | |||
+ | '''<u>Promedio tiempos de conexión (segundos):</u>''' | ||
− | + | * '''Conectar:''' 0.89 (tiempo que tarda en conectarse con el servidor web) | |
− | + | * '''Proceso:''' 5.25 (tiempo que tarda el server en procesar la petición y enviar la respuesta) | |
− | |||
− | + | * '''Total:''' 6,14 (suma tiempo de conexión más tiempo de proceso) |
Revisió de 14:49, 25 maig 2018
En esta página se explicará la instalación y configuración del software necesario para llevar a cabo el proyecto Woseberry.
Configuración de las Raspberry Pi
Instalación del sistema operativo
Todas las Raspberry Pi de nuestro proyecto cuentan con el sistema operativo Raspbian. Este sistema es la adaptación de la distribución Debian adaptada al hardware de una Raspberry. A excepción del resto de Raspberry, la Raspberry con función de firewall (BERRY-01) llevará instalada la versión con interfaz gráfica.
Una vez instalado el sistema operativo Raspbian en cada una de las Raspberry, procederemos a la configuración básica con la ejecución del siguiente comando:
$ sudo raspi-config
Asignación del direccionamiento IP
Dado que el proyecto está montado bajo una LAN, se creó una red independiente con IPs de clase privada de tipo C. Para configurar la IP estática en las Raspberry deberemos editar el siguiente fichero:
$ sudo nano /etc/dhcpcd.conf
En éste asignaremos el direccionamiento correspondiente a cada Raspberry:
Configuración básica para la Raspberry firewall
Dado que todo el escenario estará montado bajo una LAN, deberemos configurar en la Raspberry con función de firewall (BERRY-01) aspectos como:
- Servidor DNS: Nos proporcionará la asignación de un dominio para la tienda online.
- Enrutamiento: Permitirá la circulación de tráfico.
- Enmascaramiento: Permitirá enmascarar el tráfico de la red LAN con la IP de la interfaz "eth1".
Servidor DNS
Para configurar un servidor DNS en Raspbian necesitaremos instalar el paquete "bind9", para ello ejecutaremos el siguiente comando:
pi@BERRY-01:~$ sudo apt install bind9
Una vez instalado, realizaremos una copia de seguridad de los archivos de configuración. De esta manera, en caso de tener un error podremos restaurar la configuración por defecto:
pi@BERRY-01:~$ sudo cp /etc/bind/named.conf.local /etc/bind/named.conf.local.bak pi@BERRY-01:~$ sudo cp /etc/bind/db.local /etc/bind/db.woseberry
Seguidamente editaremos el archivo /etc/bind/named.conf.local para crear la zona directa e indicar cual es el archivo que contiene su configuración:
pi@BERRY-01:~$ sudo nano /etc/bind/named.conf.local
zone "woseberry.tk" { type master; file "/etc/bind/db.woseberry"; };
Por último, crearemos la zona directa editando el fichero /etc/bind/db.woseberry
pi@BERRY-01:~$ sudo nano /etc/bind/db.woseberry
; ; BIND reverse data file for local loopback interface ; $TTL 604800 @ IN SOA woseberry.tk. root.woseberry.tk. ( 2 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL ; @ IN NS woseberry.tk @ IN A 192.168.30.123 BERRY-01 IN A 192.168.30.254 BERRY-02 IN A 192.168.30.2 BERRY-03 IN A 192.168.30.3 BERRY-04 IN A 192.168.30.4 BERRY-05 IN A 192.168.30.5 BERRY-06 IN A 192.168.30.6
Enrutamiento y enmascaramiento
Dado que la BERRY-01 es la encargada de dar acceso a Internet a la LAN, es primordial activar la directiva de enrutamiento además de enmascarar las IP de la LAN por la IP de la interfaz eth1. Para ello, editaremos el archivo /etc/rc.local con la finalidad de que dichas directivas se ejecuten en el inicio del sistema.
pi@BERRY-01:~$ sudo nano /etc/rc.local
… # Activar el enrutamiento echo 1 > /proc/sys/net/ipv4/ip_forward # Enmascarar el tráfico de la LAN con la IP de la interfaz que nos proporciona salida a Internet iptables -t nat -A POSTROUTING -s 192.168.30.0/24 -o eth1 -j MASQUERADE exit 0
Instalación y configuración WordPress
Ahora que tenemos salida a Internet desde la LAN procederemos a realizar la instalación del los servidores de base de datos y los gestores de contenido WordPress.
Instalación servidor base de datos MySQL
Instalaremos el paquete mysql-server en las BERRY-04, BERRY-05 y BERRY-06, las cuales son las encargadas de almacenar todos los datos que se generarán en la tienda virtual. Para ello ejecutaremos el siguiente comando en las tres Raspberry:
$ sudo apt install mysql-server mysql-client phpmyadmin
Finalizada la instalación, generaremos un usuario llamado pi que tendrá todos los privilegios en cualquier base de datos y desde cualquier máquina. Realizaremos la siguiente operación en las tres Raspberry:
pi@BERRY-04:~$ sudo su root@BERRY-04:/home/pi# mysql -u root MariaDB [(none)]> CREATE USER 'pi'@'%' IDENTIFIED BY 'woseberry'; MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 'pi'@'%'; MariaDB [(none)]> FLUSH PRIVILEGES; MariaDB [(none)]> exit;
Aprovechando que estamos gestionando las bases de datos y los usuarios, crearemos una base de datos llamada wordpress y un usuario con el mismo nombre con permisos sobre esa base de datos.
MariaDB [(none)]> CREATE DATABASE wordpress; MariaDB [(none)]> GRANT ALL ON wordpress.* TO 'wordpress'@'%' IDENTIFIED BY 'woseberry'; MariaDB [(none)]> FLUSH PRIVILEGES; MariaDB [(none)]> exit;
Instalación servidor web apache
Con los servidores de base de datos ya en marcha en las BERRY-04, BERRY-05 y BERRY-06, procederemos a la instalación de los servidores web en las BERRY-02 y BERRY-03. Para que WordPress funcione correctamente, necesitamos instalar los siguientes paquetes en ambas Raspberry:
$ sudo apt-get install apache2 php7.0 libapache2-mod-php7.0 php7.0-mysql php7.0-curl php7.0-gd php7.0-imap php7.0-mcrypt php7.0-recode php7.0-tidy php7.0-xmlrpc
Descarga, instalación y configuración WordPress
¡Importante! Todos estos pasos deberán realizarse en las BERRY-02 y BERRY-03 de manera idéntica. Excepto en el archivo de configuración wp-config.php, el cual se indicarán IP distintas en la base de datos
Una vez tenemos operativo el servicio de apache2 junto al resto de dependencias necesarias, procederemos con la instalación y configuración de WordPress. Por tal de mejorar la seguridad en la tienda virtual, nos descargaremos la última versión estable, la cual corrige todos los errores encontrados hasta la fecha.
Para ello, ejecutaremos el siguiente comando en las BERRY-02 y BERRY-03:
$ wget https://es.wordpress.org/wordpress-4.9.5-es_ES.zip
Seguidamente, descomprimiremos el gestor de contenido y lo copiaremos en el directorio /var/www/html:
$ unzip wordpress-4.9.5-es_ES.zip $ sudo cp -R wordpress/* /var/www/html
Dado que en la instalación de apache2 nos genera un archivo index.html en el que podemos ver que el servicio está funcionando correctamente, procederemos a eliminarlo para que no haya conflicto con el resto de archivos de WordPress:
$ sudo rm /var/www/html/index.html
Una vez hecho esto, copiaremos el archivo de configuración de WordPress para proceder a su configuración más adelante:
$ sudo cp /var/www/html/wp-config-sample.php /var/www/html/wp-config.php
Modificaremos los permisos de los archivos de WordPress por tal de que no estén asignados al usuario root:
$ sudo chown -R www-data:www-data /var/www/html/ $ sudo chmod -R 755 /var/www/html/
Por último, activaremos dos módulos de apache2 esenciales para el funcionamiento correcto de WordPress:
$ sudo a2enmod headers $ sudo a2enmod rewrite
Finalizados todos los pasos, reiniciaremos apache2 para aplicar los cambios:
$ sudo service apache2 restart
El siguiente paso será configurar WordPress indicandole la ubicación de la base de datos, junto al usuario y contraseña que la administrarán. Por ahora, la BERRY-02 apuntará a la base de datos BERRY-04. Por otro lado, la BERRY-03 apuntará a la BERRY-05.
Modificamos el archivo de configuración wp-config.php para vincularlo con la base de datos correspondiente.
pi@BERRY-02:~$ sudo nano /var/www/html/wp-config.php
// ** MySQL settings - You can get this info from your web host ** // /** The name of the database for WordPress */ define('DB_NAME', 'wordpress'); /** MySQL database username */ define('DB_USER', 'wordpress'); /** MySQL database password */ define('DB_PASSWORD', 'woseberry'); /** MySQL hostname */ define('DB_HOST', '192.168.30.4'); /** Database Charset to use in creating database tables. */ define('DB_CHARSET', 'utf8'); /** The Database Collate type. Don't change this if in doubt. */ define('DB_COLLATE', );
Y para la BERRY-03 su configuración será la siguiente:
pi@BERRY-03:~$ sudo nano /var/www/html/wp-config.php
// ** MySQL settings - You can get this info from your web host ** // /** The name of the database for WordPress */ define('DB_NAME', 'wordpress'); /** MySQL database username */ define('DB_USER', 'wordpress'); /** MySQL database password */ define('DB_PASSWORD', 'woseberry'); /** MySQL hostname */ define('DB_HOST', '192.168.30.5'); /** Database Charset to use in creating database tables. */ define('DB_CHARSET', 'utf8'); /** The Database Collate type. Don't change this if in doubt. */ define('DB_COLLATE', );
Ahora solo nos falta completar el proceso de instalación desde la interfaz web. Para ello, en la barra de direcciones de un navegador web, escribimos el dominio o la dirección IP del servidor de la siguiente forma http://dominio_o_IP
En nuestro caso, accederemos mediante el dominio:
http://woseberry.tk
Certificados SSL - HTTPS
Dado que la finalidad es conseguir una tienda online que sea operativa, es primordial que cuente con unos certificados SSL que acrediten que la tienda es segura y se puede comprar en ella sin miedo a que nuestros datos se vean comprometidos por falta de seguridad. Para ello, las empresas suelen pagar por unos certificados validados por entidades certificadoras que acreditan la autenticidad de los certificados. Sin embargo, también existe la posibilidad de hacerlo de manera gratuita completando unos formularios y cumpliendo determinados requisitos. Paralelamente, también debemos realizar las configuraciones oportunas para que nuestro site funcione de forma segura a través del puerto 443 con el protocolo HTTPS.
Crear, configurar e instalar certificados - Let's Encrypt
Podemos utilizar la página web Get HTTPS for free para conseguir unos certificados válidos acreditados por esta entidad. Para ello se deben siguir ciertos pasos que detallamos a continuación.
Generar clave privada y solicitud de firma de certificado
Para generar una clave privada ejecutamos el siguiente comando en una de las Raspberry Pi.
$ openssl genrsa 4096 > Certificados/domain.key
Seguidamente generamos una petición de firma de certificado (CSR) con el dominio, en nuestro caso woseberry.tk
$ openssl req -new -sha256 -key Certificados/domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:woseberry.tk"))
Firmar la petición API
Para que la entidad Let’s Encrypt pueda validar que somos realmente nosotros quienes solicitamos los certificados y los que disponemos del servidor donde queremos instalarlos, deberemos ir generando unas claves a partir de nuestra clave privada. De este modo, devolviendo el HASH resultante podrán acreditar nuestra identidad y propiedad del dominio. Uno de los pasos a realizar es la configuración de un registro TXT en los DNS de nuestro proveedor de dominio que apunten al dominio woseberry.tk. Por esta razón, es primordial tener registrado dicho dominio y apuntarlo a un servidor público en Internet. De esta manera, al configurar el registro TXT en el DNS, Let’s Encrypt podrá validar correctamente nuestra identidad.
Instalación de certificados
Una vez finalizados los pasos anteriores, dispondremos de 3 claves:
- domain.key
- domain.crt
- intermediate.pem
Estas claves las utilizaremos tanto en los servidores Apache de las Raspberry BERRY-02 y BERRY-03 como para la BERRY-01 con HAProxy. Por lo tanto, es primordial disponer de estos tres archivos en las tres Raspberry. Para ello, podemos copiarlos mediante el siguiente comando en la Raspberry correspondiente.
$ scp Certificados/* pi@BERRY-01:/home/pi/Certificados $ scp Certificados/* pi@BERRY-02:/home/pi/Certificados $ scp Certificados/* pi@BERRY-03:/home/pi/Certificados
Creamos la misma carpeta en las tres Raspberry para almacenar las claves.
$ sudo mkdir /etc/apache2/ssl
Una vez hayamos transferido los certificados y tengamos la carpeta /etc/apache2/ssl creada en las tres Raspberry, moveremos las claves a dicha carpeta mediante el siguiente comando.
$ sudo mv Certificados/* /etc/apache2/ssl
Configuración de los servidores web con los certificados
¡Importante! Esta configuración deberá realizarse en las BERRY-02 y BERRY-03.
En primer lugar activamos el modulo SSL de apache2.
$ sudo a2enmod ssl
Antes de modificar el archivo de configuración default-ssl.conf, hacemos una copia de seguridad del site SSL.
$ sudo cp /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-available/default-ssl.conf.bak
Ahora ya podemos modificar el archivo del site SSL y especificar las rutas al certificado y clave privada.
$ sudo nano /etc/apache2/sites-available/default-ssl.conf
<IfModule mod_ssl.c> <VirtualHost _default_:443> ServerAdmin [email protected] DocumentRoot /var/www/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined SSLEngine on SSLCertificateFile /etc/apache2/ssl/domain.crt SSLCertificateKeyFile /etc/apache2/ssl/domain.key <FilesMatch "\.(cgi|shtml|phtml|php)$"> SSLOptions +StdEnvVars </FilesMatch> <Directory /usr/lib/cgi-bin> SSLOptions +StdEnvVars </Directory> </VirtualHost> </IfModule>
Habilitamos el site con SSL.
$ sudo a2ensite default-ssl.conf
Para aplicar los cambios debemos reiniciar el servicio de apache2.
$ sudo service apache2 restart
Balanceo de las páginas web - HAProxy
Instalación y configuración
Con los gestores de contenido ya operativos, el siguiente paso será configurar el balanceo de carga hacia ellos. Para ello instalaremos el paquete HAProxy ejecutando el siguiente comando en la BERRY-01:
pi@BERRY-01:~$ sudo apt install haproxy
Para poder iniciar el balanceador de carga, debemos entrar en el archivo /etc/default/haproxy y modificar el valor por defecto de la línea "ENABLED" por el valor 1
pi@BERRY-01:~$ sudo nano /etc/default/haproxy
... ENABLED=1
En el archivo de configuración de HAProxy disponemos de los apartados generales con los que el servicio comprueba el estado de los servidores, los logs donde guarda cada suceso, el modo de conexión que realiza para cada chequeo, etc.
Un parámetro importante a cambiar es el tiempo en el que HAProxy realiza el chequeo para comprobar el estado de los servidores. Por defecto, su valor está a 30 segundos. Si queremos mejorar la alta disponibilidad, deberemos bajar este valor, sin embargo, hay que tener en cuenta que al bajar este valor se generará más tráfico en la red por culpa de los chequeos.
En nuestro caso reduciremos este valor a 10 segundos:
pi@BERRY-01:~$ sudo nano /etc/haproxy/haproxy.cfg
global log /dev/log local0 log /dev/log local1 notice chroot /var/lib/haproxy stats socket /run/haproxy/admin.sock mode 660 level admin stats timeout 10s user haproxy group haproxy daemon
Para balancear el tráfico hacia los diferentes servidores web, editaremos el archivo de configuración /etc/haproxy/haproxy.cfg. Al final del fichero crearemos un nuevo frontend el cual permite escuchar peticiones tanto por el puerto 80 como por el puerto 443 en cualquiera de las interfaces de la BERRY-01. Estas peticiones las reedirigirá hacia los servidores web indicados por el puerto 443. Además, también deberá conservar las sesiones pertinentes para que un usuario pueda iniciar sesión y no la pierda mientras navega por las diferentes páginas o realiza una compra.
pi@BERRY-01:~$ sudo nano /etc/haproxy/haproxy.cfg
frontend woseberry bind *:80 bind *:443 ssl crt /etc/apache2/ssl/intermediate.pem default_backend apaches backend apaches balance leastconn cookie SRVNAME insert server BERRY-02 192.168.30.2:443 check cookie BERRY-02 check ssl verify none server BERRY-03 192.168.30.3:443 check cookie BERRY-03 check ssl verify none
Una vez realizada toda la configuración, reiniciaremos el servicio de HAProxy para aplicar los cambios:
pi@BERRY-01:~$ sudo service haproxy restart
Gracias a HAProxy habremos conseguido el balanceo de carga entre ambos WordPress consiguiendo un esquema como el siguiente:
Esquema del balanceo con HAProxy entre ambos WordPress |
Visualizar el log
Para visualizar cada comprobación que hace el servicio HAProxy en la BERRY-01, disponemos de un log general situado en la carpeta /var/log/. Este log registra cada operación de comprobación realizada y también queda registrado cuando uno de los nodos falla.
Si queremos disponer por un log independiente por cada frontend configurado, podemos activarlo con la siguiente directiva:
log /var/log/haproxy_frontend
Sin embargo, tenemos que considerar que cada comprobación que realice HAProxy quedará registrada en este log, por lo que el archivo aumentará de tamaño poco a poco y podría provocar que nos quedáramos sin espacio en disco.
En el siguiente ejemplo, podemos comprobar como el servicio se ha iniciado:
May 17 17:05:04 BERRY-01 haproxy[2309]: Proxy woseberry started. May 17 17:05:04 BERRY-01 haproxy[2309]: Proxy woseberry started. May 17 17:05:04 BERRY-01 haproxy[2309]: Proxy apaches started. May 17 17:05:04 BERRY-01 haproxy[2309]: Proxy apaches started. May 17 17:05:04 BERRY-01 haproxy[2309]: Proxy mysql started. May 17 17:05:04 BERRY-01 haproxy[2309]: Proxy mysql started. May 17 17:05:04 BERRY-01 haproxy[2309]: Proxy databases started. May 17 17:05:04 BERRY-01 haproxy[2309]: Proxy databases started.
En este ejemplo podemos observar como la conexión con la BERRY-03 se ha perdido y unos minutos más tarde se restablece:
May 17 17:05:06 BERRY-01 haproxy[2313]: Server apaches/BERRY-03 is DOWN, reason: Layer4 timeout, check duration: 2000ms. 1 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue. May 17 17:18:11 BERRY-01 haproxy[2313]: Server apaches/BERRY-03 is UP, reason: Layer6 check passed, check duration: 250ms. 2 active and 0 backup servers online. 0 sessions requeued, 0 total in queue.
Replicación bases de datos - Galera
Instalación y configuración de Galera
Para poder utilizar el software Galera, debemos asegurarnos de tener instalados los siguientes paquetes en todos los servidores MySQL. En nuestro caso en las BERRY-04, BERRY-05 y BERRY-06:
- mysql-server
- mariadb-server
- mariadb-server-10.1
- rsync
- python3-software-properties
El siguiente paso será editar el archivo /etc/mysql/mariadb.conf.d/50-server.cnf. En este fichero deberemos buscar la línea con el parámetro bind-address y comentarla:
$ sudo nano /etc/mysql/mariadb.conf/50-server.cnf
... # bind-address = 127.0.0.1 ...
Configuración del nodo principal
Deberemos tener claro con que nodo vamos a iniciar el cluster, ya que el archivo de configuración de Galera variará con respecto al resto de nodos. En nuestro caso, el nodo principal y creador del cluster será la BERRY-04.
Por defecto, Galera no dispone de ningún archivo de configuración de ejemplo, por lo que deberemos crearlo manualmente. El único requisito fundamental será que este archivo esté ubicado en el directorio /etc/mysql/conf.d y tenga como extensión .cnf
Crearemos el fichero en el nodo principal:
pi@BERRY-04:~$ sudo touch /etc/mysql/conf.d/galera.cnf
En él, configuraremos los siguientes parámetros:
[galera] # Mandatory settings wsrep_on=ON wsrep_provider=/usr/lib/galera/libgalera_smm.so binlog_format=row default_storage_engine=InnoDB innodb_autoinc_lock_mode=2 wsrep_sst_method=rsync # Node configuration wsrep_cluster_address="gcomm://" wsrep_node_address=192.168.30.4 wsrep_node_name="NODO_1" # Custom settings wsrep_cluster_name="Cluster_galera" bind-address=192.168.30.4
La información resaltada es aquella que deberemos cambiar en cada archivo de configuración de cada nodo. Dado que la BERRY-04 la hemos establecido como nodo principal, el apartado wsrep_cluster_address deberá permanecer tal y como se muestra. Sin embargo, veremos que en el resto de nodos deberemos especificar la IP de cada nodo.
En los apartados wsrep_node_address y bind-address deberemos indicar la dirección IP o nombre DNS del nodo donde se está aplicando la configuración. El apartado wsrep_node_name nos proporcionará un nombre identificativo por cada nodo. Podemos personalizarlo al igual que el apartado wsrep_cluster_name, el cual solo define un nombre común para el clúster.
Finalizada la configuración pararemos el servicio de MySQL:
pi@BERRY-04:~$ sudo systemctl stop mysql
Una vez detenido, iniciaremos el cluster con el siguiente comando:
pi@BERRY-04:~$ sudo galera_new_cluster
Por último, iniciaremos el servicio de MySQL:
pi@BERRY-04:~$ sudo systemctl start mysql
Configuración para el resto de nodos
Al igual que en el nodo principal, deberemos crear el fichero de configuración en el directorio correspondiente:
$ sudo touch /etc/mysql/conf.d/galera.cnf
En él, configuraremos los siguientes parámetros (BERRY-05):
[galera] # Mandatory settings wsrep_on=ON wsrep_provider=/usr/lib/galera/libgalera_smm.so binlog_format=row default_storage_engine=InnoDB innodb_autoinc_lock_mode=2 wsrep_sst_method=rsync # Node configuration wsrep_cluster_address="gcomm://192.168.30.4,192.168.30.5,192.168.30.6" wsrep_node_address=192.168.30.5 wsrep_node_name="NODO_2" # Custom settings wsrep_cluster_name="Cluster_galera" bind-address=192.168.30.5
Y en el caso de la BERRY-06:
[galera] # Mandatory settings wsrep_on=ON wsrep_provider=/usr/lib/galera/libgalera_smm.so binlog_format=row default_storage_engine=InnoDB innodb_autoinc_lock_mode=2 wsrep_sst_method=rsync # Node configuration wsrep_cluster_address="gcomm://192.168.30.4,192.168.30.5,192.168.30.6" wsrep_node_address=192.168.30.6 wsrep_node_name="NODO_3" # Custom settings wsrep_cluster_name="Cluster_galera" bind-address=192.168.30.6
Como podemos observar, las BERRY-05 y BERRY-06 contienen la misma información. Los únicos parámetros que hay que variar por cada nodo son wsrep_node_address, wsrep_node_name y bind-address.
Una vez tengamos los archivos de configuración de Galera en el resto de nodos reiniciaremos el servicio MySQL en cada uno de ellos. ¡Importante! Hay que reiniciar el servicio uno a uno, esperando a que finalice el de un servidor para poder reiniciar el del otro:
$ sudo systemctl restart mysql
Podremos comprobar que todos los nodos se han unido al clúster ejecutando la siguiente sentencia SQL en cualquiera de ellos:
$ sudo mysql -u root -p -e 'SELECT VARIABLE_VALUE as "Núm. nodos" FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME="wsrep_cluster_size"'
+-------------+ | Núm. nodos | +-------------+ | 3 | +-------------+
Gracias a Galera, habremos conseguido la replicación entre bases de datos y tendremos un esquema parecido al siguiente:
Esquema de la replicación de Galera con el balanceo de HAProxy |
Usuario de chequeo
Por tal de que HAProxy sea capaz de comprobar que nodo MariaDB está operativo y cual está caído, deberemos crear un usuario sin contraseña. HAProxy utilizará este usuario para establecer una conexión y así mantener el nodo operativo. Para crear este usuario entraremos en la consola de MySQL en cualquiera de los nodos, como por ejemplo la BERRY-04:
pi@BERRY-04:~$ mysql -u pi -p
Una vez hayamos entrado en la consola, crearemos el usuario ejecutando el siguiente comando. ¡Importante! El usuario no debe tener contraseña definida ni permisos sobre otras bases de datos, ya que únicamente se utilizará para establecer una conexión a modo de chequeo:
MariaDB [(none)]> CREATE USER 'haproxy'@'192.168.30.254';
El usuario se llamará haproxy para ser más identificativo y solo permitirá conectarse desde la IP donde está instalado HAProxy.
Dado que las bases de datos están replicadas, tan solo deberemos crearlo en uno de los nodos. Ejecutando la siguiente sentencia SQL en el resto de nodos podremos comprobar que el usuario se ha replicado correctamente:
MariaDB [(none)]> SELECT haproxy from mysql.user;
Donde podremos ver toda la información del usuario haproxy:
Balanceo de las bases de datos - HAProxy
Configuración del balanceo
Ahora que ya tenemos las bases de datos funcionando con el software Galera, es decir, funcionando en cluster y replicadas, balancearemos el tráfico hacia ellas para conseguir el mayor rendimiento posible. Para ello editaremos la configuración de HAProxy en el fichero /etc/haproxy/haproxy.cfg:
pi@BERRY-01:~$ sudo nano /etc/haproxy/haproxy.cfg
Añadiendo las siguientes líneas al final del fichero:
frontend mysql bind 192.168.30.254:3306 mode tcp default_backend databases backend databases balance roundrobin mode tcp option tcpka option mysql-check user haproxy server BERRY-04 192.168.30.4:3306 check weight 1 server BERRY-05 192.168.30.5:3306 check weight 1 server BERRY-06 192.168.30.6:3306 check weight 1
Como podemos observar, hemos creado un nuevo frontend encargado de escuchar peticiones a la IP 192.168.30.254 por el puerto 3306. Cuando estas peticiones se realicen redireccionará el tráfico hacia el backend llamado databases. Este backend balancea con el algoritmo roundrobin hacia los servidores MySQL de las BERRY-04, BERRY-05 y BERRY-06. Para comprobar que el servicio está operativo y sigue funcionando, realizará una conexión hacia la base de datos con el usuario haproxy, el cual creamos en el apartado anterior.
Finalizada esta configuración reiniciaremos el servicio de HAProxy para aplicar los cambios:
pi@BERRY-01:~$ sudo service haproxy restart
Configuración de los servidores web
Hasta ahora, cada servidor web estaba configurado para realizar peticiones a una base de datos en concreto. Sin embargo, ahora que tenemos un sistema de replicas y balanceado, conviene que todos los servidores web soliciten la petición de la base de datos al HAProxy. De esta manera, él será el encargado de indicar a que base de datos realizar la consulta.
Para ello, deberemos editar el archivo /var/www/html/wp-config.php en los servidores web e indicar la nueva IP de la base de datos:
$ sudo nano /var/www/html/wp-config.php
// ** MySQL settings - You can get this info from your web host ** // /** The name of the database for WordPress */ define('DB_NAME', 'wordpress'); /** MySQL database username */ define('DB_USER', 'wordpress'); /** MySQL database password */ define('DB_PASSWORD', 'woseberry'); /** MySQL hostname */ define('DB_HOST', '192.168.30.254'); /** Database Charset to use in creating database tables. */ define('DB_CHARSET', 'utf8'); /** The Database Collate type. Don't change this if in doubt. */ define('DB_COLLATE', );
Sincronizacíon de las uploads en WordPress - Rsync
Ahora que ya tenemos la replicación en las bases de datos, debemos tener en cuenta que WordPress almacena todas las imágenes de manera local, es decir, en el mismo servidor web. Para solucionar esta inconcurrencia de datos disponemos de dos mecanismos como:
- Creación de un directorio compartido entre los servidores web: NFS
- Sincronización del directorio wp-content: Rsync
En nuestro caso, hemos elegido la opción de sincronización de los directorios, ya que de esta manera nos ahorraremos la instalación de un nuevo servicio como es NFS. Simplemente con la utilización del paquete rsync conseguiremos mantener el directorio wp-content en ambos servidores web de manera idéntica. Esta sincronización la programaremos para que se realice cada 15 minutos, comprobando aquellos ficheros que son diferentes y realizando la copia mediante el uso de SSH. Para poder programar esta sincronización utilizaremos la herramienta del sistema crontab:
pi@BERRY-02:~$ crontab -e
Añadiendo la siguiente línea al final del fichero:
# m h dom mon dow command */15 * * * * rsync -ahvrz /var/www/html/wp-content/uploads/* pi@192.168.30.3:/var/www/html/wp-content/uploads
Dado que la copia se realiza con el uso de SSH, cuando se establezca la conexión nos pedirá la contraseña del usuario. Si queremos evitar esta acción y que se realice la sincronización sin interacción del usuario deberemos generar una clave pública y una clave privada para el usuario pi en la BERRY-02:
pi@BERRY-02:~$ ssh-keygen
Seguidamente copiaremos la clave pública en la BERRY-03 para que permanezca en la lista de claves autorizadas:
pi@BERRY-02:~$ ssh-copy-id pi@192.168.30.3
Finalizada esta operación, la BERRY-02 se conectará automáticamente por SSH a la BERRY-03 y realizará una sincronización del directorio wp-content en caso de que haya ficheros o directorios distintos.
Realizaremos la misma operación en la BERRY-03, indicando al IP de la BERRY-02 en la conexión por SSH.
Envío de correos en caso de error en MySQL - SSMTP
Para el administrador de todo este escenario, es primordial tener constancia cuanto antes siempre que falle uno de los servidores. De esta manera, se puede aplicar solución al problema y seguir ofreciendo un servicio de alta disponibilidad al usuario. Es por ello que la creación de pequeños chequeos que revisen el funcionamiento correcto de servicios como apache2 o mysql, sea primordial.
En cada uno de los servidores se creará un script que monitorice el servicio correspondiente. En el caso de las BERRY-02 o BERRY-03 se monitorizará el servicio apache2. En cuanto a las BERRY-04, BERRY-05 y BERRY-06 se monitorizará el servicio de mysql.
Instalación y configuración de ssmtp
¡Importante! Está configuración debe realizarse en las BERRY-04, BERRY-05 y BERRY-06
El paquete ssmtp nos permite enviar correos a través de la terminal GNU/Linux. De esta manera, en el momento que el sistema se de cuenta de que el servicio que se estaba monitorizando cae, enviará un correo a la cuenta del administrador.
Para instalar este paquete ejecutaremos el siguiente comando todas las Raspberry:
$ sudo apt install ssmtp
Seguidamente, editaremos el archivo de configuración /etc/ssmtp/ssmtp.conf:
$ sudo nano /etc/ssmtp/ssmtp.conf
# Config file for sSMTP sendmail # Correo utilizado para enviar mensajes [email protected] # Servidor de correo utilizado mailhub=smtp.gmail.com:465 # Dominio de correo rewriteDomain=gmail.com # Credenciales cuenta de correo AuthUser=woseberry AuthPass=woseberryP@ssw0rd FromLineOverride=YES UseTLS=YES # The full hostname hostname=DEBIAN-VM
Script de monitorizaje
En el caso de las BERRY-04, BERRY-05 y BERRY-06 que son las encargadas de almacenar las bases de datos. El script se encargará de revisar que el servicio esté en marcha constantemente. En el momento en el que falle, se ejecutará la orden de enviar un correo al administrador con información como la hora, el estado actual del servicio y el log de errores:
#!/bin/bash servicio=mysql fecha=$(date) maquina=$(hostname) estadoServicio=$(service mysql status) logError=$(tail -n 20 /var/log/mysql/error.log) mensajeError="Al parecer se ha detenido $servicio en la $maquina aproximadamente. Hora aproximada: $fecha" if (( $(ps -ef | grep -v grep | grep $servicio | wc -l) == 0 )); then echo -e "Subject: ERROR - MySQL\n\n$mensajeError\n\n$estadoServicio\n\n$logError" | ssmtp [email protected] fi
Una vez creado el script, deberemos añadirlo en el demonio crontab para que se ejecute cada cierto tiempo, como por ejemplo, cada 10 minutos. Dado que este script contiene comandos de superusuario o de root, deberemos añadirlo al crontab con privilegios:
$ sudo crontab -e
Y añadiremos al final del archivo las siguientes líneas:
# Revisar el funcionamiento de MySQL */10 * * * * bash /home/pi/Scripts/mailMySQL_cron.sh
Realizar copias de seguridad en la base de datos - MySQLdump
Aunque tengamos nuestras bases de datos replicadas y eso ya nos proporcione cierto nivel de seguridad, siempre es recomendable realizar copias de seguridad periódicamente.
Con el siguiente script, podemos crear un backup de la base de datos wordpress en cualquier momento, ya que el comando mysqldump antes de proceder a realizar el backup bloquea las tablas de la base de datos para que no se pueda escribir durante la copia y así obtener un backup fiable con integridad de sus datos. Como resultado, obtendremos un archivo con extensión .sql con el nombre especificado más la fecha y hora del instante de la realización de dicho backup.
#!/bin/bash
mysqldump --user=pi --password=woseberry wordpress > backup_wordpress_$(date "+%d-%m-%Y_%H:%M:%S").sql
echo "Copia de seguridad de la base de datos wordpress realizada."
Pero al margen de poder realizar el backup en cualquier momento, es importante programarlo para que éste se ejecute automáticamente.
En esta ocasión configuraremos el demonio crontab en las BERRY-04, BERRY-05 y BERRY-06 para que ejecute el script creado, cada día a las 4 en punto de la madrugada, ya que es la hora con menos actividad de la página en España, y realice un backup de la base de datos wordpress.
Ejecutamos el crontab del usuario root:
$ sudo crontab -e
Añadimos las siguientes líneas al final del archivo:
# Realizar backup de la base de datos wordpress 00 4 * * * bash /home/pi/Scripts/backup_wordpressdb.sh
Configuración del firewall - IPtables
Ahora que tenemos todo el esquema montado, es conveniente denegar algunos accesos malintencionados que intenten vulnerar la seguridad de la tienda virtual. Para ello se ejecutará un script al inicio del sistema en la BERRY-01:
#!/bin/bash # Borrar toda las reglas iptables -F iptables -X iptables -Z # Definir las políticas por defecto iptables -P INPUT DROP iptables -P OUTPUT ACCEPT # Permitir las conexiones SSH en ambas interfaces iptables -A INPUT -i eth1 -p tcp --dport 22 -j ACCEPT iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT # Permitir las conexiones DNS en ambas interfaces iptables -A INPUT -i eth1 -p tcp --dport 53 -j ACCEPT iptables -A INPUT -i eth1 -p udp --dport 53 -j ACCEPT iptables -A INPUT -i eth0 -p tcp --dport 53 -j ACCEPT iptables -A INPUT -i eth0 -p udp --dport 53 -j ACCEPT # Permitir las peticiones HTTP y HTTPS en ambas interfaces iptables -A INPUT -i eth1 -p tcp --dport 80 -j ACCEPT iptables -A INPUT -i eth1 -p tcp --dport 443 -j ACCEPT iptables -A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT iptables -A INPUT -i eth0 -p tcp --dport 443 -j ACCEPT # Permitir las peticiones MySQL en la interfaz interna iptables -A INPUT -i eth0 -p tcp --dport 3306 -j ACCEPT iptables -A INPUT -i eth0 -p udp --dport 3306 -j ACCEPT # Permitir las conexiones preestablecidas iptables -A INPUT -i eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT # Habilitar el enrutamiento echo 1 > /proc/sys/net/ipv4/ip_forward # Enmascarar la red LAN con la interfaz eth1 (Internet) iptables -t nat -A POSTROUTING -s 192.168.30.0/24 -o eth1 -j MASQUERADE
Seguidamente, añadiremos la ejecucción de este script en el archivo /etc/rc.local:
pi@BERRY-01:~$ sudo nano /etc/rc.local
… # Ejecutar las reglas del firewall bash /home/pi/Scripts/firewall.sh exit 0
Pruebas de rendimiento - Apache Bench
Como suele ser habitual en cualquier proyecto, una vez tenemos la infraestructura funcionando, es conveniente realizar las correspondientes pruebas de rendimiento. En nuestro caso, realizaremos pruebas principalmente sobre el servidor web apache y registraremos sus resultados.
Para realizar dichas pruebas de rendimiento utilizaremos el programa Apache Bench, y para instalarlo deberemos ejecutar el siguiente comando:
$ sudo apt-get install apache2-utils
Para realizar una prueba de rendimiento de por ejemplo 200 peticiones, ejecutándose con una concurrencia de 20 peticiones simultáneas, sobre la página web woseberry.tk y guardando los resultados en un archivo, el comando a ejecutar sería el siguiente:
$ ab -g resultados.tsv -n 200 -c 20 https://woseberry.tk/
ab es Apache Bench
-g resultados.tsv guarda los resultados en el archivo resultados.tsv
-n 200 indica que se harán 200 peticiones
-c 20 indica que se harán 20 peticiones concurrentes
https://woseberry.tk/ es la URL que vamos a testear
Resultado de la ejecución del comando anterior:
This is ApacheBench, Version 2.3 <$Revision: 1706008 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking woseberry.tk (be patient) Completed 100 requests Completed 200 requests Finished 200 requests Server Software: Apache/2.4.25 Server Hostname: woseberry.tk Server Port: 443 SSL/TLS Protocol: TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,4096,256 Document Path: / Document Length: 48189 bytes Concurrency Level: 20 Time taken for tests: 62.257 seconds Complete requests: 200 Failed requests: 0 Total transferred: 9700200 bytes HTML transferred: 9637800 bytes Requests per second: 3.21 [#/sec] (mean) Time per request: 6225.711 [ms] (mean) Time per request: 311.286 [ms] (mean, across all concurrent requests) Transfer rate: 152.16 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 198 893 1055.8 587 3969 Processing: 1483 5251 1276.6 5368 9083 Waiting: 1449 5052 1286.8 5090 9034 Total: 1869 6144 1484.3 6149 10674 Percentage of the requests served within a certain time (ms) 50% 6149 66% 6502 75% 6807 80% 7039 90% 7920 95% 9012 98% 9675 99% 9880 100% 10674 (longest request)
Interpretación de resultados
Como podemos ver en el resultado de la prueba de rendimiento, obtenemos una gran cantidad de datos, y aunque la mayoría de ellos tienen una gran importancia para poder medir determinados aspectos, los que podemos considerar como genéricamente más relevantes son los siguientes:
- Peticiones completadas: 200
- Peticiones fallidas: 0
- Peticiones por segundo: 3.21 (promedio)
- Velocidad de transferencia (Kbytes/sec): 152.16 recibidos
Promedio tiempos de conexión (segundos):
- Conectar: 0.89 (tiempo que tarda en conectarse con el servidor web)
- Proceso: 5.25 (tiempo que tarda el server en procesar la petición y enviar la respuesta)
- Total: 6,14 (suma tiempo de conexión más tiempo de proceso)