Se recomienda realizar una previa lectura del post Modificación del escenario OpenStack, pues en este artículo se tratarán con menor profundidad u obviarán algunos aspectos vistos con anterioridad.
El objetivo de esta tarea es el de continuar con la configuración del escenario de trabajo previamente generado en OpenStack, concretamente, llevando a cabo una instalación de un servidor DNS sobre la máquina Freston anteriormente creada, un servidor web sobre la máquina Quijote y un servidor de base de datos sobre la máquina Sancho, máquinas que se encuentran conectadas a las redes interna (10.0.1.0/24) en el caso de Freston y Sancho y a la red DMZ (10.0.2.0/24) en el caso de Quijote.
Servidor DNS
Se recomienda realizar una previa lectura del post Instalación de un servidor DNS, pues en este artículo se tratarán con menor profundidad u obviarán algunos aspectos vistos con anterioridad.
Hasta ahora hemos hecho uso de un mecanismo de resolución estática de nombres en las máquinas existentes en el escenario, que puede llegar a ser tedioso de gestionar conforme van aumentando las máquinas y los servicios existentes en la red, por lo que ha llegado la hora de solventarlo haciendo para ello uso de un servidor DNS bind9 ubicado en Freston.
Además, dicho servidor DNS será accesible desde el exterior (desde el instituto), ya que vamos a implementar una regla DNAT en Dulcinea para permitirlo, contando además con un subdominio delegado dentro del dominio principal gonzalonazareno.org, que tendrá, en este caso, el nombre alvaro.gonzalonazareno.org. Lo veremos con más detalle a continuación.
Todo está listo para llevar a cabo la instalación de bind9, no sin antes actualizar toda la paquetería existente en la máquina, ejecutando para ello el comando:
Una vez instalado, tendremos que proceder con la configuración inicial del servicio, que consta de varios archivos que se incluyen desde el archivo de configuración principal, de nombre named.conf. Los nombres de dichos archivos comienzan por named en relación al nombre del proceso que BIND ejecuta (abreviatura de “domain name daemon”).
El primer fichero de configuración que modificaremos será /etc/bind/named.conf.options, en el que estableceremos, mediante directivas, las opciones del servicio, haciendo para ello uso del comando:
Dentro del mismo, encontraremos una directiva principal de nombre options, en la cuál debemos introducir una serie de líneas:
Tras ello, guardaremos los cambios en el fichero y procederemos a modificar ahora el fichero /etc/bind/named.conf.local, en el que declararemos las vistas existentes y las zonas sobre las que tendrá autoridad, así como el fichero en el que están contenidas.
Si nos fijamos, acabo de hacer uso de un término que nunca antes habíamos utilizado, las vistas. Existen determinadas circunstancias en las que nos puede interesar que un mismo nombre que resuelve nuestro DNS devuelva direcciones IP distintas según en que red este conectada el cliente que realiza la consulta. Esto se entiende mucho mejor con un ejemplo gráfico:
Como se puede apreciar en la topología actualmente existente en el escenario de OpenStack, disponemos de un total de 3 redes que pueden consultar de forma potencial al servidor DNS ubicado en Freston (ya que descartamos las consultas procedentes de la red 10.0.0.0/24, al ser totalmente ajena al escenario).
Por ese mismo motivo, existen determinadas consultas que deberían ser resueltas a diferentes direcciones dependiendo de la procedencia del cliente, pues por ejemplo, desde el exterior no son accesibles las máquinas de la red DMZ o interna, ya que la única expuesta directamente al exterior es Dulcinea. Las resoluciones que deberían existir desde cada una de las redes son:
-
red interna de alvaro.vaca (interna):
- Dulcinea: 10.0.1.9
- Sancho: 10.0.1.4
- Quijote: 10.0.2.6
- Freston: 10.0.1.7
-
DMZ de alvaro.vaca (dmz):
- Dulcinea: 10.0.2.12
- Sancho: 10.0.1.4
- Quijote: 10.0.2.6
- Freston: 10.0.1.7
-
ext-net (externa):
- Dulcinea: 172.22.200.134
Además de la zona alvaro.gonzalonazareno.org, vamos a configurar otras dos de resolución inversa (para las redes 10.0.1.0/24 y 10.0.2.0/24), que serán únicamente visibles desde las redes interna y DMZ, ya que no tiene sentido resolver inversamente direcciones privadas desde el exterior.
Por último, antes de empezar a configurar, es importante pensar desde qué redes de origen se va a hacer de una vista u otra, quedando de la siguiente forma:
-
interna:
- 10.0.1.0/24: Aquellas máquinas existentes en la red interna de alvaro.vaca.
- localhost: Para que Freston, que se encuentra ubicado en la red anteriormente mencionada, también pueda hacer uso del servidor DNS.
-
dmz:
- 10.0.2.0/24: Aquellas máquinas existentes en la DMZ de alvaro.vaca.
-
externa:
- 172.22.0.0/15: Aquellas máquinas existentes en el instituto (172.22.0.0/16) y que accedan desde la VPN (172.23.0.0/16).
- 192.168.202.2: Para que el servidor DNS existente en el instituto pueda consultar al nuestro, necesario para la delegación de subdominio.
Como anteriormente hemos mencionado, vamos a proceder a modificar ahora el fichero /etc/bind/named.conf.local, en el que declararemos las vistas existentes y las zonas sobre las que tendrá autoridad, así como el fichero en el que están contenidas, ejecutando para ello el comando:
El resultado final del fichero sería:
Finalmente, y a modo de resumen, voy a aclarar dónde se encuentra contenida cada una de las tres zonas y desde dónde es accesible:
-
alvaro.gonzalonazareno.org:
- db.alvaro.interna: Vista interna (10.0.1.0/24 y localhost).
- db.alvaro.dmz: Vista dmz (10.0.2.0/24).
- db.alvaro.externa: Vista externa (172.22.0.0/15 y 192.168.202.2).
-
1.0.10.in-addr.arpa:
- db.1.0.10: Vista interna (10.0.1.0/24 y localhost) y Vista dmz (10.0.2.0/24).
-
2.0.10.in-addr.arpa:
- db.2.0.10: Vista interna (10.0.1.0/24 y localhost) y Vista dmz (10.0.2.0/24).
Un requisito indispensable a la hora de utilizar vistas es que debemos definir todas las zonas alcanzables desde la misma dentro de cada una de ellas, es por ello que hemos añadido un include de los ficheros /etc/bind/zones.rfc1918 y /etc/bind/named.conf.default-zones.
Por consecuencia, es importante comentar la línea referente al include del fichero /etc/bind/named.conf.default-zones en el fichero /etc/bind/named.conf, por lo que para modificarlo, haremos uso del comando:
Dentro del mismo, comentaremos la tercera de las líneas, quedando de la siguiente forma:
Cuando hayamos guardado los cambios en el mismo, habrá llegado la hora de definir el contenido de las tres zonas DNS con las que vamos a trabajar. Para una mayor facilidad, podemos hacer uso de una plantilla de nombre /etc/bind/db.empty para a partir de ahí, adaptarla a nuestras necesidades.
Vamos a comenzar con la configuración del fichero de la zona de resolución directa accesible desde la vista interna, así que copiaremos dicho fichero dentro de /var/cache/bind/, pues es donde se deben ubicar por defecto, con el nombre previamente asignado, db.alvaro.interna, haciendo para ello uso del comando:
El primer fichero de la zona DNS (vista interna) ya ha sido creado, aunque actualmente está vacío, de manera que vamos a proceder a modificarlo para añadir los registros correspondientes a la misma, ejecutando para ello los comandos:
El contenido de la plantilla es el siguiente:
Para el correcto funcionamiento será necesario llevar a cabo al menos tres modificaciones sobre la configuración presentada en la plantilla:
- SOA (Start of Authority): Es una de las directivas más importantes, en la que indicaremos el FQDN del servidor con autoridad maestro (es decir, el servidor con el que estamos trabajando, freston.alvaro.gonzalonazareno.org.), además del correo electrónico de la persona responsable de la zona DNS (por ejemplo, admin.alvaro.gonzalonazareno.org.).
- Serial: Identificador de la zona, que deberá ser incrementado después de cada cambio. Se recomienda que tenga la forma YYMMDDNN, por ejemplo, la primera modificación del día 15 de Diciembre de 2020 sería 20121501.
- NS (Name Server): Tendremos que indicar el FQDN del servidor con autoridad sobre la zona, que en este caso es el servidor con el que estamos trabajando, freston.alvaro.gonzalonazareno.org..
Esta sería la configuración base mínima para configurar la zona, de manera que a partir de ahora, tendremos que ir añadiendo registros para nombrar las máquinas y servicios existentes en dicha zona. A partir de aquí, la configuración se vuelve algo más “personal”, en el sentido de que puede variar según las necesidades de una persona u otra.
Para una mayor comodidad, estableceremos un registro $ORIGIN alvaro.gonzalonazareno.org., indicando que todos los registros definidos a partir de ahí serán autocompletados con el dominio especificado, evitándonos así tener que escribir todo el rato el nombre de dominio para escribir el FQDN de las máquinas o servicios. En mi caso, además de las 4 máquinas, he añadido un servicio web (www) y un servicio de base de datos (bd), para así evitar tener que hacerlo posteriormente, quedando de la siguiente forma:
La definición del primer fichero de la zona de resolución directa ha finalizado, de manera que para facilitar el trabajo, vamos a utilizar dicho fichero como plantilla base y a partir de ahí, lo adaptaremos a nuestras necesidades para los otros dos. Para copiar dicho fichero haremos uso del comando:
El segundo fichero de la zona DNS (vista dmz) ya ha sido creado, de manera que vamos a proceder a modificarlo para adaptarlo a nuestras necesidades, ejecutando para ello los comandos:
La única modificación que debemos llevar a cabo es referente a la dirección IP de Dulcinea, que pasa de ser 10.0.1.9 a ser 10.0.2.12, quedando de la siguiente forma:
La definición del segundo fichero de la zona de resolución directa ha finalizado, así que volveremos a utilizar el primer fichero como plantilla base y lo adaptaremos a nuestras necesidades para el último de ellos. Para copiar dicho fichero haremos uso del comando:
El tercer fichero de la zona DNS (vista externa) ya ha sido creado, de manera que vamos a proceder a modificarlo para adaptarlo a nuestras necesidades, ejecutando para ello los comandos:
Las modificaciones que debemos llevar a cabo consisten en:
- Eliminar todas las máquinas que no sean accesibles de forma directa desde el exterior, es decir, todas excepto Dulcinea.
- Cambiar la dirección IP de Dulcinea, que pasa de ser 10.0.1.9 a ser 172.22.200.134.
- Eliminar el nombre bd, ya que el servidor de base de datos no va a ser accesible desde el exterior.
- El CNAME del servicio www pasa a apuntar ahora a Dulcinea, que tendrá una regla DNAT para alcanzar a Quijote, que es donde estará alojado el servidor web.
El resultado final sería:
La definición de la zona de resolución directa para el subdominio alvaro.gonzalonazareno.org ha finalizado, así que volveremos a utilizar el primer fichero como plantilla base y lo adaptaremos a nuestras necesidades para las zonas de resolución inversa. Para copiar dicho fichero haremos uso del comando:
El fichero de la primera zona inversa ya ha sido creado, de manera que vamos a proceder a modificarlo para adaptarlo a nuestras necesidades, ejecutando para ello los comandos:
Las modificaciones que debemos llevar a cabo se resumen en modificar el valor del registro $ORIGIN a 1.0.10.in-addr.arpa., que será utilizado para autocompletar los registros que introduzcamos y en utilizar registros PTR para nombrar las máquinas, en lugar de registros A. No se nombrarán los servicios. El resultado final sería:
La definición de la zona de resolución inversa para la red 10.0.1.0/24 ha finalizado, así que vamos a utilizar dicho fichero como plantilla base y lo adaptaremos a nuestras necesidades para la segunda y última zona de resolución inversa. Para copiar dicho fichero haremos uso del comando:
El fichero de la segunda zona inversa ya ha sido creado, de manera que vamos a proceder a modificarlo para adaptarlo a nuestras necesidades, ejecutando para ello los comandos:
La modificaciones que debemos llevar a cabo se resumen en modificar el valor del registro $ORIGIN a 2.0.10.in-addr.arpa., que será utilizado para autocompletar los registros que introduzcamos y el nombrar con registros PTR las máquinas existentes en dicha red. El resultado final sería:
Una vez finalizada la definición de la zona DNS, vamos a proceder a comprobar que la sintaxis de los ficheros de configuración named sea correcta, antes proceder a cargar la nueva configuración en memoria, ejecutando para ello el comando:
La ejecución del comando no ha devuelto ninguna salida, por lo que podemos concluir que la sintaxis de los ficheros de configuración es correcta, por lo que podremos proceder a reiniciar el servicio para que así cargue la nueva configuración realizada, ejecutando para ello el comando:
El servicio ya se encuentra en ejecución con la nueva configuración cargada, sin embargo, la vista externa todavía no funciona como debería, ya que la máquina Freston no es accesible desde el exterior, sino que tendremos que añadir una regla DNAT a Dulcinea, que va a ser la que reciba las peticiones y las reenvíe al puerto 53 UDP de dicha máquina.
Para ello, tendremos que crear la cadena PREROUTING dentro de la tabla nat, es decir, aquella que permite modificar paquetes entrantes antes de que se tome una decisión de enrutamiento, permitiendo por tanto hacer Destination NAT (DNAT) para posteriormente alojar dentro de la misma, la regla que necesitamos. Para crear dicha cadena ejecutaremos el comando:
En este caso, hemos especificado que esta cadena sea muy prioritaria (a menor sea el número, mayor es la prioridad), de manera que las reglas albergadas en el interior de la cadena PREROUTING se ejecutarían antes que las de la cadena POSTROUTING. Vamos a verificar que dicha cadena se ha generado correctamente, ejecutando para ello el comando:
Efectivamente, así ha sido. Nos queda un último paso, añadir la regla necesaria a la cadena PREROUTING, de manera que nos permita hacer DNAT a la dirección de la máquina que actúa como servidor DNS, en este caso, la 10.0.1.7. Además, añadiremos reglas para los puertos 80 y 443 TCP, ya que posteriormente nos será necesario hacer DNAT a 10.0.1.4 para el servidor web. Para ello, ejecutaremos el comando:
En este caso, hemos especificado que se trata de reglas para la cadena prerouting (pues deben aplicarse justo antes de que se tome una decisión de enrutamiento), además, la interfaz (iifname) que debemos introducir será aquella por la que van a entrar los paquetes, es decir, la que está conectada a Internet, en este caso, eth0, además de indicar que esta regla la vamos a aplicar a todos aquellos paquetes que entren por los puertos:
- 53 UDP (udp dport).
- 80 TCP (tcp dport).
- 443 TCP (tcp dport).
Por último, para aquellos paquetes que cumplan dicha regla, vamos a contarlos (counter) y a hacer DNAT a la dirección IP de la máquina en cuestión (dnat to).
Posteriormente, vamos a verificar que dichas reglas se han añadido correctamente, ejecutando para ello el comando:
Efectivamente, así ha sido. Esta configuración se encuentra cargada en memoria, por lo que para conseguir que perdure en el tiempo, vamos a ejecutar el comando:
Gracias a ello, habremos guardado la configuración en un fichero en /etc/ de nombre nftables.conf que se importará de forma automática cuando reiniciemos la máquina gracias al daemon que se encuentra habilitado. En caso de que no cargase de nuevo la configuración, podríamos hacerlo manualmente con el comando nft -f /etc/nftables.conf
.
En mi caso, he decidido llevar a cabo algunas consultas al servidor DNS desde las diferentes máquinas pertenecientes al escenario, para así verificar que toda la configuración llevada a cabo hasta este momento, funciona como debería:
- Pruebas desde Dulcinea
- Pruebas desde Sancho
- Pruebas desde Quijote
- Pruebas desde Freston
- Pruebas desde el exterior
Dado que ya hemos configurado un servidor DNS, tendremos que eliminar la resolución estática de nombres en las máquinas, de manera que se conozcan entre ellas pero siempre haciendo uso del servidor DNS. Dicha información está almacenada en el fichero /etc/hosts, así que procederemos a realizar dicha modificación en las cuatro máquinas, quedando de la siguiente forma::
La resolución estática ha sido eliminada de todas las máquinas, de manera que actualmente no se conocen entre ellas. Para solucionarlo, tendremos que establecer en todas las máquinas el nuevo servidor DNS ubicado en Freston, para que así se haga uso del mismo de manera prioritaria a la hora de llevar a cabo una resolución. El procedimiento es diferente dependiendo de la distribución.
Dulcinea
Las instancias Debian Buster de OpenStack vienen con un fichero /etc/resolv.conf dinámico, lo que quiere decir que se genera dinámicamente en cada arranque. El contenido del mismo incluye los dos servidores DNS existentes en el instituto, situados en las direcciones 192.168.202.2 y 192.168.200.2, pero en este caso, es necesario añadir el servidor DNS ubicado en Freston de manera prioritaria. Al ser dinámico dicho fichero, no podemos modificarlo a mano ni tampoco indicar el servidor DNS en el /etc/network/interfaces, sino que tendremos que modificar los ficheros de configuración de resolvconf, el encargado de generar dicho fichero.
Para ello, modificaremos el fichero /etc/resolvconf/resolv.conf.d/head y lo indicaremos ahí, de manera que lo tendrá en cuenta para la siguiente ocasión y lo posicionará el primero en la lista, consiguiendo por tanto que tenga prioridad, ejecutando para ello el comando:
En este caso, el servidor DNS que necesito añadir es 10.0.1.7, por lo que la apariencia de dicho fichero sería:
Dado que en el primer artículo configuramos también el servidor 8.8.8.8 en el fichero /etc/resolvconf/resolv.conf.d/base, tendremos que eliminarlo para así no generar conflictos, haciendo para ello uso del comando:
Dentro del mismo, eliminaremos la línea nameserver 8.8.8.8 y añadiremos una directiva search, que nos permitirá autocompletar las consultas DNS que realicemos. Por ejemplo, cuando hagamos ping sancho
, autocompletará sancho con el nombre de dominio que introduzcamos, resultando ser sancho.alvaro.gonzalonazareno.org, y por tanto, evitaremos tener que introducir el nombre al completo cada vez que queramos comunicarnos con otra máquina. La apariencia final de dicho fichero sería:
Genial, todos los cambios necesarios se han llevado a cabo, pero para que surtan efecto y comprobar que perduran tras un reinicio, ejecutareremos el comando reboot
y cuando el reinicio finalice, visualizaremos el contenido del fichero /etc/resolv.conf, para así verificar que la nueva configuración se ha tenido en cuenta durante la generación dinámica de dicho fichero:
Como era de esperar, el servidor DNS 10.0.1.7 es el primero en la lista, de manera que será el primer servidor al que se envíen las consultas. De otro lado, la directiva search también se ha configurado como debería, de manera que cualquier consulta DNS será autocompletada con alvaro.gonzalonazareno.org, en caso de ser necesario.
Sancho
El fichero de configuración en el que debemos establecer la configuración de los servidores DNS en una máquina Ubuntu 20.04 es /etc/netplan/50-cloud-init.yaml, así que procederemos a modificarlo, ejecutando para ello el comando:
Dentro del mismo, modificaremos la directiva addresses, estableciendo de forma prioritaria el servidor DNS que hemos configurado. Al igual que en el caso anterior, añadiremos también una directiva search, que nos permitirá autocompletar las consultas DNS que realicemos. La apariencia final de dicho fichero sería:
Genial, todos los cambios necesarios se han llevado a cabo, pero para que surtan efecto y comprobar que perduran tras un reinicio, ejecutareremos el comando reboot
y cuando el reinicio finalice, visualizaremos el contenido del fichero /etc/resolv.conf, para así verificar que la nueva configuración se ha tenido en cuenta durante la generación dinámica de dicho fichero:
En este caso, el nuevo servidor DNS configurado no aparece reflejadoo en dicho fichero ya que Ubuntu implementa por defecto un servidor DNS local, capaz de cachear las respuestas, consiguiendo por tanto una navegación más rápida, pero que internamente, hará uso de los servidores DNS que le hemos especificado anteriormente para dichas peticiones. De otro lado, la directiva search se ha configurado como debería, de manera que cualquier consulta DNS será autocompletada con alvaro.gonzalonazareno.org, en caso de ser necesario.
Quijote
El fichero de configuración en el que debemos establecer la configuración de los servidores DNS en una máquina CentOS 8 es /etc/resolv.conf, así que procederemos a modificarlo, ejecutando para ello el comando:
Dentro del mismo, estableceremos de forma prioritaria en una directiva addresses el servidor DNS que hemos configurado. Al igual que en el caso anterior, modificaremos también la directiva search, que nos permitirá autocompletar las consultas DNS que realicemos. La apariencia final de dicho fichero sería:
Genial, todos los cambios necesarios se han llevado a cabo, pero para que surtan efecto y comprobar que perduran tras un reinicio, ejecutareremos el comando reboot
y cuando el reinicio finalice, visualizaremos el contenido del fichero /etc/resolv.conf, para así verificar que la nueva configuración se ha tenido en cuenta durante la generación dinámica de dicho fichero:
Como era de esperar, el servidor DNS 10.0.1.7 es el primero en la lista, de manera que será el primer servidor al que se envíen las consultas. De otro lado, la directiva search también se ha configurado como debería, de manera que cualquier consulta DNS será autocompletada con alvaro.gonzalonazareno.org, en caso de ser necesario.
Freston
Como anteriormente hemos mencionado, las instancias Debian Buster de OpenStack vienen con un fichero /etc/resolv.conf dinámico, por lo que no podemos modificarlo a mano ni tampoco indicar el servidor DNS en el /etc/network/interfaces, sino que tendremos que modificar los ficheros de configuración de resolvconf, el encargado de generar dicho fichero.
Para ello, modificaremos el fichero /etc/resolvconf/resolv.conf.d/head y lo indicaremos ahí, de manera que lo tendrá en cuenta para la siguiente ocasión y lo posicionará el primero en la lista, consiguiendo por tanto que tenga prioridad, ejecutando para ello el comando:
La apariencia final de dicho fichero sería:
Dado que en el artículo referente a la modificación del escenario configuramos también el servidor 8.8.8.8 en el fichero /etc/resolvconf/resolv.conf.d/base, tendremos que eliminarlo para así no generar conflictos, haciendo para ello uso del comando:
Dentro del mismo, eliminaremos la línea nameserver 8.8.8.8 y añadiremos una directiva search, que nos permitirá autocompletar las consultas DNS que realicemos. La apariencia final de dicho fichero sería:
Genial, todos los cambios necesarios se han llevado a cabo, pero para que surtan efecto y comprobar que perduran tras un reinicio, ejecutareremos el comando reboot
y cuando el reinicio finalice, visualizaremos el contenido del fichero /etc/resolv.conf, para así verificar que la nueva configuración se ha tenido en cuenta durante la generación dinámica de dicho fichero:
Como era de esperar, el servidor DNS 10.0.1.7 es el primero en la lista, de manera que será el primer servidor al que se envíen las consultas. De otro lado, la directiva search también se ha configurado como debería, de manera que cualquier consulta DNS será autocompletada con alvaro.gonzalonazareno.org, en caso de ser necesario.
Servidor Web
Tras ello, vamos a instalar un servidor web en Quijote que sea capaz de ejecutar código PHP, para posteriores aplicaciones que necesitemos desplegar en el escenario. Para ello, necesitamos llevar a cabo la instalación de httpd (el nombre que recibe Apache2 en esta distribución) y php-fpm, el servidor de aplicaciones que nos permitirá ejecutar código PHP, no sin antes actualizar toda la paquetería existente en la máquina, ejecutando para ello el comando:
Genial, los paquetes ya han sido instalados, sin embargo, los servicios no se encuentran actualmente activos ni mucho menos, habilitados para arrancar junto a la máquina. Por ello, tendremos que hacer uso de systemctl
para arrancarlos y habilitar su arranque durante el inicio de la máquina, ejecutando para ello los comandos:
Es importante mencionar que en CentOS 8 se utilizaba por defecto un firewall que de primeras es bastante restrictivo, de nombre firewalld. En el mismo, viene permitido poco más que el acceso por SSH, de manera que el puerto 80 se encuentra cerrado, bloqueando todas las peticiones entrantes al mismo. Para verificar el estado de dicho cortafuegos, ejecutaremos el comando:
Donde:
- –state: Indicamos que compruebe si el daemon firewalld se encuentra o no activo.
Efectivamente, el servicio se encuentra activo, por lo que vamos a proceder a listar todas aquellas reglas que se encuentran actualmente configuradas y habilitadas en el cortafuegos, haciendo uso del comando:
Donde:
- –list-all: Indicamos que muestre todas las reglas activas para la zona por defecto.
En esta ocasión, únicamente se encuentran permitidas las conexiones entrantes de 2 servicios, entre los que lógicamente, no se encuentra contemplado el puerto 80 (HTTP), por lo que procederemos a añadir dicha regla de forma manual, junto a otra para el puerto 443 (HTTPS), ya que nos será necesario posteriormente, ejecutando para ello los comandos:
Donde:
- –permanent: Indicamos que la regla perdure incluso tras un reinicio. El cambio no surtirá efecto inmediatamente.
- –add-port: Indicamos el puerto y el protocolo permitido en dicha regla.
Al parecer, las reglas se han añadido correctamente al cortafuegos de forma permanente, por lo que tal y como he mencionado, los cambios no surtirán efecto inmediatamente, de manera que tendremos que reiniciar el servicio. Para ello podemos hacer uso de systemctl
o bien de la propia opción que trae incluida firewall-cmd
:
Donde:
- –reload: Indicamos que reinicie el servicio de cortafuegos, consiguiendo así que las reglas permanentes se carguen en memoria.
Genial, en un principio las nuevas reglas ya han sido añadidas y se encuentran actualmente activas, por lo que volveremos a listar todas las reglas existentes para así verificarlo, ejecutando para ello el comando utilizado con anterioridad:
Como era de esperar, las reglas se han añadido correctamente y los puertos 80/TCP y 443/TCP se encuentran actualmente abiertos y con posibilidad de recibir peticiones.
Por defecto, httpd no crea los directorios /etc/httpd/sites-available y /etc/httpd/sites-enabled, que contendrán los ficheros de configuración para los VirtualHost que creemos, de manera que tendremos que hacerlo de forma manual, haciendo para ello uso del comando:
Cuando los nuevos directorios se encuentren generados, tendremos que modificar el fichero /etc/httpd/conf/httpd.conf para indicar la ruta del nuevo directorio que contendrá un enlace simbólico a los ficheros de configuración de los VirtualHost habilitados, ejecutando para ello el comando:
Dentro del mismo, tendremos que encontrar la siguiente directiva:
Y sustituir conf.d por sites-enabled, quedando de la siguiente forma:
Todo está listo para empezar a crear un VirtualHost en nuestro servidor web, pero dado que necesitamos ejecutar código PHP, tendremos que hacer que actúe como un proxy inverso, reenviando las peticiones necesarias a php-fpm, nuestro servidor de aplicaciones que interpretará el código PHP y lo transformará en HTML, para que pueda ser servido por httpd. Tenemos dos posibilidades para comunicar ambos servicios:
- Socket UNIX: Permiten un intercambio de datos eficiente entre procesos que se ejecutan y comunican de manera local (no-remota). Al fin y al cabo, es un tipo de fichero en el que un proceso escribe y el otro lee, actuando como pasarela, al que se le aplican los permisos de ficheros UNIX, de manera que se pueden restringir qué procesos pueden leer y escribir en el mismo. Es más seguro, al no estar expuestos a Internet y únicamente ser accesibles de manera local. Cuentan con un mayor rendimiento.
- Socket TCP/IP: Identifica un servidor basado en una dirección IP y un puerto, por ejemplo, cuando alojamos un servidor web y lo hacemos en la dirección 192.168.1.2 y en el puerto 80 y a dicha dirección y puerto se conecta una máquina cliente con dirección 192.168.1.3 a través de un puerto no privilegiado, como el 3412, entre los que existe una comunicación bidireccional, de manera que suele utilizarse para conexiones remotas. Es más inseguro, al ser accesible por cualquier persona, a no ser que se implemente un firewall o un método de autentificación. Cuentan con menor rendimiento.
En este caso, tras comparar ambas posibilidades, y dadas las circunstancias, haremos uso de un Socket UNIX, pues aumentaremos así la seguridad y el rendimiento. En realidad, también podríamos haber alojado un Socket TCP/IP en la dirección local (127.0.0.1), pero contaríamos con las desventajas del mismo.
El primer paso será configurar el método de escucha del servicio php-fpm, configuración que se llevará a cabo en un archivo del grupo de recursos, pues dicho servicio puede ejecutar múltiples grupos de procesos con diferentes configuraciones, pero en este caso, haremos uso del que viene por defecto, www.conf. Para comprobar qué configuración está usando actualmente, ejecutaremos el comando:
Como se puede apreciar, hemos leído el contenido de dicho fichero, filtrando por una cadena que se usa para establecer el método de escucha del servicio. En este caso, estamos usando por defecto un Socket UNIX alojado en /run/php-fpm/www.sock, por lo que no tendremos que llevar a cabo ninguna modificación a lo que respecta.
Ha llegado la hora de crear el VirtualHost en cuestión, fichero de configuración que debemos alojar en /etc/httpd/sites-available/, así que generaré uno de nombre sitioweb.conf, haciendo para ello uso del comando:
Dentro del mismo, en mi caso, estableceré el siguiente contenido:
Dentro del mismo, hemos establecido dos directivas totalmente necesarias:
- ServerName: Indicamos el nombre de dominio que se va a utilizar para acceder al VirtualHost en cuestión.
- DocumentRoot: Indicamos el directorio donde vamos a almacenar los ficheros que queremos que sean servidos.
Además de ellas, hemos indicado algunas directivas necesarias para hacer que el servidor web actúe como un proxy inverso, reenviando al servidor de aplicaciones php-fpm las peticiones de ficheros .php. De otro lado, hemos indicado un directorio en el que se van a almacenar los logs, que al igual que el DocumentRoot, también tendremos que crearlo.
Para crear el DocumentRoot y el directorio donde se almacenarán los logs, ejecutaremos el comando:
Donde:
- -p: Indicamos que se cree el directorio padre en caso de ser necesario. En este caso, generará el DocumentRoot /var/www/alvaro/.
Una vez realizadas todas las configuraciones oportunas, es hora de habilitar el VirtualHost. Para ello, a diferencia de apache2 que contaba con una utilidad para ello, tendremos crear el enlace simbólico al fichero de configuración ubicado en /etc/httpd/sites-available dentro de /etc/httpd/sites-enabled de forma manual. Para ello, ejecutamos el comando:
Al parecer, el sitio ha sido correctamente habilitado, sin embargo, en CentOS 8 viene habilitado por defecto SELinux, un módulo de seguridad para el kernel Linux que proporciona el mecanismo para implementar una políticas de control de acceso para las aplicaciones, los procesos y los archivos dentro de un sistema. Esto es un problema para nosotros, ya que por defecto está únicamente configurado para trabajar con los directorios que httpd crea por defecto, y nosotros hemos generado directorios adicionales.
Para solucionarlo, tendremos que modificar la política del mismo y permitir por tanto, el uso de dichos directorios, haciendo para ello uso del comando:
Para activar toda la nueva configuración llevada a cabo, tendremos que volver a cargar la configuración del servicio httpd, ejecutando para ello el comando:
Una vez que la configuración del servicio se ha vuelto a cargar, vamos a listar el contenido de /etc/nginx/sites-enabled para verificar que el correspondiente enlace simbólico ha sido correctamente creado. Para ello, ejecutaremos el comando:
Efectivamente, el sitio se encuentra actualmente activo, pero para comprobarlo, vamos a generar en el DocumentRoot un fichero PHP de nombre info.php que devuelva la información de PHP, ejecutando para ello el comando:
Tras ello, podremos solicitar dicho recurso desde el navegador, obteniendo el siguiente resultado:
Como se puede apreciar, el recurso ha sido correctamente generado y devuelto en HTML para su correspondiente visualización, por lo que podemos concluir que el servidor de apliciones php-fpm y el servidor web httpd tienen conectividad y están funcionando correctamente.
Servidor BBDD
Por último, vamos a instalar un gestor de bases de datos MariaDB en Sancho, para posteriores aplicaciones que necesitemos desplegar en el escenario. Para ello, necesitamos llevar a cabo la instalación de mariadb-server, no sin antes actualizar toda la paquetería existente en la máquina, ejecutando para ello el comando:
Una vez instalado, es recomendable aumentar la seguridad de dicha base de datos ya que se va a poner en producción, haciendo para ello uso de un script que proporciona MariaDB, que llevará a cabo una configuración inicial pensada para ello:
- Estableceremos una contraseña para el administrador de MariaDB.
- Eliminaremos el usuario anónimo que viene creado por defecto.
- Desactivaremos la conexión remota a root, es decir, únicamente se podrá llevar a cabo desde localhost.
- Eliminaremos la base de datos de pruebas que viene creada por defecto.
- Volveremos a cargar las tablas de privilegios, para que los cambios surtan efecto.
Lo primero que preguntará el script será la contraseña actual del usuario root de MariaDB. Lo dejaremos vacío y pulsaremos ENTER, ya que por ahora no tiene ninguna contraseña configurada. Tras ello, tendremos que ir introduciendo “Y” a las opciones que nos vayan saliendo, para así llevar a cabo toda la configuración anteriormente mencionada. Para ejecutar dicho script, haremos uso del comando:
Listo, la configuración inicial de MariaDB se habrá llevado a cabo gracias al script, aumentando así su seguridad.
Como curiosidad, me gustaría mencionar que la contraseña que hemos especificado para el usuario root de MariaDB no sirve “para nada”, lo pongo entre comillas ya que por defecto, la autentificación para dicho usuario se lleva a cabo mediante un Socket UNIX, es decir, mientras que te encuentres con sesión iniciada en root o bien antepongas sudo
al comando, podrás hacer uso de MariaDB sin conocer la contraseña que acabas de indicar.
Esto, puede ser bueno o malo, según se vea. En caso de querer autentificarte mediante Socket UNIX (opción por defecto), tendrás que asegurarte de proteger el acceso al usuario root del sistema, mientras que si deseas autentificarte con credenciales, tendrás que asegurarte de proteger el acceso al usuario root de MariaDB. En caso de considerar más oportuna la última opción, podrás encontrar aquí un artículo sobre cómo cambiar el método de autentificación.
Tras ello, accederemos al servidor mysql, ejecutando para ello el comando:
Vamos a realizar una prueba de conexión remota desde Quijote, de manera que necesitaremos crear un usuario que tenga el acceso permitido desde 10.0.2.6. En este caso, crearemos un usuario de nombre quijote, que tenga permitido el acceso desde la dirección anteriormente mencionada (si quisiéramos permitir el acceso desde cualquier dirección IP, se podría poder %), y cuya contraseña sea quijote.
Una vez llevada a cabo la creación del correspondiente usuario, podremos salir de mysql haciendo uso del comando:
Esto no es todo, ya que por defecto, mysql viene configurado para escuchar únicamente peticiones desde localhost, por lo que no escucharía aquellas peticiones que vengan del exterior. Para modificar esto, tenemos que editar el fichero /etc/mysql/mariadb.conf.d/50-server.cnf, haciendo uso de nano
:
Dentro del mismo, encontraremos una línea con la siguiente forma:
Como se puede apreciar, está únicamente configurado para escuchar peticiones desde 127.0.0.1, por lo que tendremos que realizar el correspondiente cambio para que las escuche desde 0.0.0.0 (es decir, desde todas las interfaces IPv4), quedando de la siguiente manera:
Tras ello, guardaremos los cambios, y como dice la ley del informático, cada vez que toquemos un fichero de configuración, tendremos que reiniciar el correspondiente servicio, ejecutando en este caso el comando:
Ya está todo listo para realizar la prueba de conexión desde el exterior, concretamente desde Quijote, que en un principio debería de funcionar, siempre y cuando no exista un cortafuegos bloqueando la conexión (en este caso no hay problema, pues me he asegurado previamente).
Tras ello, procederemos a instalar en Quijote el paquete necesario para llevar a cabo la conexión remota, de nombre mariadb, por lo que ejecutaremos el comando:
Una vez instalado el paquete necesario, podremos llevar a cabo la conexión remota, haciendo para ello uso de las opciones -u y -p para indicar el usuario y contraseña a utilizar, con la única diferencia que tendremos que indicar además la dirección del servidor al que nos vamos a tratar de conectar, utilizando la opción -h, en este caso, bd.alvaro.gonzalonazareno.org. La instrucción a ejecutar sería:
Al parecer, la conexión se ha realizado sin ningún problema, pues ha resuelto correctamente el nombre introducido, además de estar correctamente configurada la máquina servidora para aceptar dichas conexiones.
De nada nos serviría tener conexión si no podemos mostrar la información contenida, así que vamos a realizar una pequeña prueba listando las bases de datos existentes, utilizando para ello la instrucción:
Como se puede apreciar en la salida, se ha mostrado la única base de datos actualmente existente, por lo que podemos corroborar que la conexión remota a la base de datos está totalmente operativa y funcional.