Autor: Joel Barrios Dueñas
Correo electrónico: darkshram en gmail punto com
Sitio de Red: https://www.alcancelibre.org/
Licencia de este documento: Creative Commons Reconocimiento-NoComercial-CompartirIgual 2.1
© 1999-2022 Joel Barrios Dueñas. Usted es libre de copiar, distribuir y comunicar públicamente la obra y hacer obras derivadas bajo las condiciones siguientes: a) Debe reconocer y citar al autor original. b) No puede utilizar esta obra para fines comerciales (incluyendo su publicación, a través de cualquier medio, por entidades con fines de lucro). c) Si altera o transforma esta obra o genera una obra derivada, sólo puede distribuir la obra generada bajo una licencia idéntica a ésta. Al reutilizar o distribuir la obra, tiene que dejar bien claro los términos de la licencia de esta obra. Alguna de estas condiciones puede no aplicarse si se obtiene el permiso del titular de los derechos de autor. Los derechos derivados de usos legítimos u otras limitaciones no se ven afectados por lo anterior. Licencia completa en castellano. La información contenida en este documento y los derivados de éste se proporcionan tal cual son y los autores no asumirán responsabilidad alguna si el usuario o lector hace mal uso de éstos.
Nginx es un servidor Web y Proxy muy ligero, rápido y versátil enfocado en el alto rendimiento que permite servir miles e incluso millones de peticiones a través de los protocolos HTTP y HTTPS. Fue creado por Igor Sysoev en el año 2009, originalmente para resolver la necesidad de millones de peticiones solicitadas en el motor de búsqueda Ruso conocido como Rambler, mismas que eran un problema utilizando Apache. En el año 2021 Nginx se convirtió en el servidor Web más popular del mundo, acabando con los 25 años de reinado de Apache. Sin realizar ajustes a la configuración predeterminada, Nginx es capaz de soportar hasta 10 mil conexiones simultáneas.
Acceda al sistema como root.
Habilite el almacén PowerTools ejecutando lo siguiente:
dnf -y install dnf-plugins-core && dnf config-manager --set-enabled powertools
Instale y habilite el muro cortafuegos:
dnf -y install firewalld && systemctl enable --now firewalld
Encontrará conveniente esté instalado bash-completion
a fin de facilitar el uso de la consola y lynx
como navegador Web para la consola a fin de poder realizar pruebas y diagnósticos.
dnf -y install bash-completion lynx
SElinux estará activo en modo forzado. Ejecute lo siguiente para habilitar la políticas necesarias para realizar los procedimientos descritos en este documento:
setsebool -P httpd_unified=1 httpd_can_network_connect=1 httpd_enable_homedirs=1 nis_enabled=1
Actualice el sistema y reinicie. Es importante trabajar con los parches correctivos y de seguridad.
dnf -y update && reboot
Nginx viene incluido en los almacenes de software de AlmaLinux 8, CentOS 8 y Red Hat Enterprise Linux 8. Sólo es necesario instalar del siguiente modo:
dnf -y install nginx
Ejecute lo siguiente para iniciar el servicio nginx
:
systemctl enable --now nginx
Ejecute lo siguiente para abrir los puertos 80 y 443 en el muro cortafuegos:
firewall-cmd --add-service=http --permanent
firewall-cmd --add-service=https --permanent
firewall-cmd --reload
Acceda con cualquier navegador hacia http://direccion.ip.servidor/
o bien desde la consola hacia http://localhost/
para validar que Nginx está arriba y funcionando.
Acceda con lynx
hacia http://localhost/
:
lynx http://localhost/
Deberá poder ver la página predeterminada de Nginx.
De modo predeterminado los sistemas operativos mencionados arriba sólo incluyen PHP 7.2. Dicha versión es obsoleta para la mayoría de las aplicaciones Web modernas. Es por este motivo que será importante habilitar el almacén de EPEL e instalar el almacén de Remi a fin de poder utilizar versiones de PHP más recientes.
Instale EPEL, yum-utils, vim-enhanced, nano y lynx ejecutando lo siguiente:
dnf -y install epel-release yum-utils vim-enhanced nano httpd-tools
Instale Remi ejecutando lo siguiente:
dnf -y install https://rpms.remirepo.net/enterprise/remi-release-8.rpm
Una vez instalado Remi, puede utilizar PHP en las siguientes opciones:
Algunas aplicaciones podrían presentar problemas con PHP 8.x, como ocurre con Wordpress (todas las versiones hasta el momento de redactar este documento en mayo de 2022). La recomendación es utilizar PHP 7.4. Ejecute lo siguiente para configurar que el sistema utiliza PHP 7.4:
dnf -y module reset php
dnf -y module install php:remi-7.4
dnf -y update
Ejecute lo siguiente para instalar los componentes principales de PHP:
dnf -y install php-bcmath php-cli php-dba php-enchant php-fpm php-gd php-gmp php-imap php-intl php-json php-ldap php-litespeed php-mbstring php-mysqlnd php-opcache php-pdo php-pdo-dblib php-process php-pspell php-snmp php-soap php-sodium php-tidy php-xml php-xmlrpc
A diferencia de Apache, Nginx requiere utilizar el servicio php-fpm para permitir a las aplicaciones utilizar PHP. Ejecute lo siguiente para activar el servicio:
systemctl enable --now php-fpm
La estructura de configuraciones para AlmaLinux, CentOS y Red Hat Enterprise Linux es muy distinta a la de Debian y Ubuntu. El directorio para los archivos de configuración de Nginx está en /etc/nginx
y éste además incluye dos directorios relevantes:
/etc/nginx/nginx.conf
: archivo principal de configuración.
Evite modificarlo para permitir actualizaciones transparentes de Nginx./etc/nginx/default.d
: archivos que se incluyen automáticamente a la configuración del anfitrión virtual predeterminado. Aquí es donde añadirá todas la configuraciones para realizar pruebas./etc/nginx/conf.d
: archivos que se incluyen a la configuración principal de Nginx.El archivo /etc/nginx/nginx.conf
tiene la siguiente estructura:
...
# Configuración princpal de Nginx como usuario, módulos, zócalo;
# archivo PID y otras opciones usadas por el daemon;
# Todas terminan en punto y coma;
...
http {
...
# Configuración general de Nginx;
# Todas terminan en punto y coma;
...
include /etc/nginx/conf.d/*.conf;
server {
...
# Configuración del anfitrión virtual predeterminado;
# Todas terminan en punto y coma;
...
include /etc/nginx/default.d/*.conf
}
}
Es decir, si se requiere añadir alguna opción que aplique a la configuración general o crear un nuevo anfitrión virtual, sólo es necesario crear un archivo con extensión *.conf
dentro de /etc/nginx/conf.d
.
Para añadir configuraciones para el anfitrión virtual predeterminado, sólo es necesario crear un archivo con extensión *.conf
dentro de /etc/nginx/default.d
.
Nginx viene configurado de modo predeterminado con opciones básicas que cumplen con lo necesario para uso general. En la actualidad hay muchas amenazas en Internet que se ejecutan principalmente en los navegadores y que pueden ser mitigadas fácilmente desde el servidor Web.
Para añadir un encabezado sólo es necesario utilizar la opción add_header
con los valores deseados y el parámetro always
para asegurar que los encabezados sean establecidos en todas las respuestas.
Una de las amenazas más comunes es el abuso de los marcos internos (etiquetas HTML <frame>
e <iframe>
), debido a que éstos permiten mostrar en cualquier servidor ilegítimo el contenido de otro sitio Web legítimo. Utilizando X-Frame-Options
con el valor SAMEORIGIN
se puede impedir que otro sitio Web use el contenido de un sitio legítimo en otro servidor.
Utilizando X-XSS-Protection
con los valores 1; mode=block
se puede forzar a que los navegadores activen la protección contra a ejecución cruzada de programas (Cross Site Scripting o XSS).
Puede complementar la opción anterior con Content-Security-Policy
para generar una lista blanca de contenidos remotos a ser utilizados en un sitio web. Si añade la opción Content-Security-Policy
con el valor default-src 'self'
, sólo se permitirá cargar contenidos del mismo sitio y bloquea la carga de contenidos remotos. Si necesita cargar contenidos remotos, puede añadir los URL de origen de los contenidos remotos utilizados, como por ejemplo https://code.jquery.com
o https://cdnjs.cloudflare.com
o https://analytics.google.com
o fonts.gstatic.com
. Debe poner entre comillas desde default-src
hasta casi el final de la línea, antes del punto y coma. Considere que si la plantilla o el sitio Web incluye componentes remotos que sean omitidos de la lista, Content-Security-Policy
impedirá acceder al sitio.
Utilizando X-Content-Type-Options
con el valor nosniff
se puede impedir que el servidor Web permita examinar las vulnerabilidades de contenidos mime.
El encabezado Strict-Transport-Security
se utiliza para definir que sitio Web se debe acceder a través del protocolo HTTPS
en lugar de HTTP
. Este encabezado sólo se debe utilizar en sitios que ya han sido configurados para funcionar por HTTPS.
Ejecute lo siguiente para generar el siguiente archivo /etc/nginx/default.d/headers.conf
:
vim /etc/nginx/default.d/headers.conf
Añada el siguiente contenido:
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Content-Security-Policy: "default-src 'self' https://code.jquery.com https://cdnjs.cloudflare.com https://analytics.google.com https://fonts.gstatic.com";
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
Guarde los cambios y reinicie Nginx ejecutando lo siguiente:
systemctl restart nginx
Errores más comunes por los que puede fallarlo anterior y los siguientes procedimientos:
a. Omitió poner un punto y coma al final de una línea. b. Escribió incorrectamente alguna opción, valor o parámetro. c. Omitió una línea.
Es común que los registros de cualquier servidor Web crezcan considerablemente y se dificulte el diagnóstico de problemas. Puede crear un archivo para ser incluido automáticamente en el anfitrión virtual que establezca algunas acciones con algunos tipos de contenidos.
Ejecute lo siguiente para crear el archivo /etc/nginx/default.d/common-configs.conf
:
vim /etc/nginx/default.d/common-configs.conf
Añada el siguiente contenido:
# Denegar el acceso a cualquier archivo .ht* o .git*, aunque no los use
# Nginx.
location ~/\.(ht|git) {
deny all;
}
# Establecer el tipo mime predeterminado para el directorio /.well-known
location '/.well-known' {
default_type "text/plain";
}
# Indicar a los servidores cache que este tipo de contenidos expiran a los 14 días
location ~* \.(js|css|png|jpg|jpeg|gif|swf|xml|txt)$ {
expires 14d;
}
# Si olvidamos poner un archivo favicon.ico, indicar a Nginx que omita registrar
# la actividad relacionada con este archivo y además indicar a los servidores
# cache que este archivo expira al año.
location = /favicon.ico {
log_not_found off;
access_log off;
expires 1y;
}
# Si olvidamos poner un archivo robots.txt, indicar a Nginx que omita registrar
# la actividad relacionada con este archivo.
location = /robots.txt {
log_not_found off;
access_log off;
}
Guarde los cambios y reinicie Nginx ejecutando lo siguiente:
systemctl restart nginx
Todo lo anterior aplicará exclusivamente para el anfitrión virtual predeterminado. Si se quiere re-utilizar esta misma configuración en otros anfitriones virtuales, es posible hacerlo a través de una inclusión de este archivo en la configuración correspondiente.
Habilitar la compresión gzip contribuye a optimizar el uso del ancho banda disponible a realizar una compresión al vuelo de ciertos contenidos.
Genere el archivo /etc/nginx/default.d/gzip.conf
:
vim /etc/nginx/default.d/gzip.conf
Añada el siguiente contenido:
# Activar el soporte de compresión gzip
gzip on;
# Activar para archivos que tengan o no compresión gzip
gzip_vary on;
# Comprimir sólo archivos de al menos 1024 bytes. Con archivos
# menores hay pocos pocos beneficios y elevaría innecesariamente
# el uso del CPU y memoria.
gzip_min_length 1024;
# Activar compresión para conexiones a través de proxy
gzip_proxied expired no-cache no-store private auth;
# Tipos específicos de archivos a comprimir
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml;
# Desactivar para MS Internet Explorer
gzip_disable "MSIE [1-6]\.";
Al igual que las configuraciones adicionales recomendadas, todo lo anterior aplicará exclusivamente para el anfitrión virtual predeterminado. Si se quiere re-utilizar esta misma configuración en otros anfitriones virtuales, es posible hacerlo a través de una inclusión de este archivo en la configuración correspondiente.
Sí se tiene una carpeta hipotética en la ruta /var/www/aplicaciones/prueba
, ésta se puede compartir de dos maneras:
location = /prueba {
# Ruta absoluta de la carpeta en el sistema de archivos:
alias /var/www/aplicaciones/prueba;
}
location /prueba {
# /prueba es relativo a esta carpeta en sistema de archivos:
root /var/www/aplicaciones;
}
La configuración de directorios virtuales tiene la siguiente estructura:
location = /directorio {
alias /var/www/carpeta;
}
O bien:
location /directorio {
# Se asume existe /var/www/directorio
root /var/www;
}
El parámetro location requiere como argumento el nombre del URI a mostrar desde el navegador y opcionalmente permite utilizar los siguientes prefijos:
=
: El nombre del URI es exactamente como se define. Utilizar este prefijo acelera el procesos de solicitud.~
: El nombre del URI utilizará expresiones regulares sensibles a mayúsculas y minúsculas.~*
: El nombre del URI utilizará expresiones regulares indiferentes a mayúsculas y minúsculas.^~
: Se omite la verificación de expresiones regulares.El parámetro alias se utiliza para definir una carpeta cuyo nombre es diferente al directorio definido en location
. Ejemplo:
location /images {
alias /var/www/estaticos/imagenes;
}
El parámetro root
debe corresponder a la carpeta inmediata superior a la carpeta a utilizar. Se prefiere sobre alias
cuando el nombre del directorio del URI coincide con el nombre de la carpeta en sistema de archivos. Ejemplo:
location /datos {
root /var/www/estaticos;
}
Se recomienda utilizar root
cuando el nombre de la carpeta definida en location
coincide con la carpeta en el sistema de archivos.
Ejecute lo siguiente para generar una carpeta en el sistema de archivos denominada /var/www/estaticos/datos
:
mkdir -p /var/www/estaticos/datos
Ejecute lo siguiente para crear el archivo /etc/nginx/default.d/estaticos.conf
:
vim /etc/nginx/default.d/estaticos.conf
Añada el siguiente contenido:
location /datos {
root /var/www/estaticos;
}
Guarde los cambios, salga del editor de texto y ejecute lo siguiente para aplicar los cambios en Nginx:
systemctl reload nginx
Acceda con lynx
hacia http://localhost/datos/
:
lynx http://localhost/datos/
El servidor le indicará que la carpeta existe, pero que está prohibido el acceso.
Para mostrar el contenido de un carpeta, es necesario definir el archivo índice y colocar un archivo index.html o bien configurar la carpeta para mostrar contenido.
Ejecute lo siguiente para volver a editar el archivo /etc/nginx/default.d/estaticos.conf
:
vim /etc/nginx/default.d/estaticos.conf
Modifique el contenido del siguiente modo:
location /datos {
root /var/www/estaticos;
autoindex on;
}
Guarde los cambios, salga del editor de texto y ejecute lo siguiente para aplicar los cambios en Nginx:
systemctl reload nginx
Acceda nuevamente con lynx
hacia http://localhost/datos/
:
lynx http://localhost/datos/
El servidor deberá permitir ver el contenido de la carpeta.
Ejecute lo siguiente para crear el archivo /var/www/estaticos/datos/index.html
:
vim /var/www/estaticos/datos/index.html
Añada el siguiente contenido:
<!DOCTYPE html>
<html>
<head>
<title>Hola mundo.</title>
</head>
<body>
<h1>Hola mundo</h1>
<p>Hola mundo</p>
</body>
</html>
Ejecute lo siguiente para volver a editar el archivo /etc/nginx/default.d/estaticos.conf
:
vim /etc/nginx/default.d/estaticos.conf
Quite autoindex on;
y añada index index.html index.htm;
en su lugar:
location /datos {
root /var/www/estaticos;
index index.html index.htm;
}
Guarde los cambios, salga del editor de texto y ejecute lo siguiente para aplicar los cambios en Nginx:
systemctl reload nginx
Acceda nuevamente con lynx
hacia http://localhost/datos/
:
lynx http://localhost/datos/
El servidor deberá mostrar el documento HTML que se configuró como índice del directorio.
Ejecute lo siguiente para crear una carpeta denominada /var/www/estaticos/privado
:
mkdir -p /var/www/estaticos/privado
Ejecute lo siguiente para crear un archivo de contraseñas con el usuario tudominio:
htpasswd -c /var/www/estaticos/.htpasswd tudominio
Ejecute lo siguiente para hacer propiedad de Nginx el archivo de contraseñas:
chown nginx:nginx /var/www/estaticos/.htpasswd
Ejecute lo siguiente para hacer que sólo Nginx pueda acceder al archivo de contraseñas:
chmod 640 /var/www/estaticos/.htpasswd
Edite nuevamente el archivo /etc/nginx/default.d/estaticos.conf
:
vim /etc/nginx/default.d/estaticos.conf
Añada el siguiente contenido:
location /privado {
root /var/www/estaticos;
auth_basic "Acceso restringido";
auth_basic_user_file /var/www/estaticos/.htpasswd;
autoindex on;
}
Guarde los cambios, salga del editor de texto y ejecute lo siguiente para aplicar los cambios en Nginx:
systemctl reload nginx
Acceda con lynx
hacia http://localhost/privado/
:
lynx http://localhost/privado/
Navegador deberá solicitar un usuario (tudominio
) y contraseña para acceder al directorio.
Nginx requiere utilizar php-fpm
para permitir la ejecución de programas escritor en PHP. De modo predeterminado php-fpm
crea un zócalo como /run/php-fpm/www.sock
con permisos de acceso exclusivamente a Apache y Nginx.
Ejecute lo siguiente para crear una estructura de carpetas para una aplicación PHP hipotética:
mkdir -p /var/www/aplicaciones/aplicacion1/{cache,config,tmp}
Los contenidos de la carpeta donde se instale la aplicación PHP que requieran acceso de escritura o estén restringidos deben pertenecer al usuario y grupo apache
. Ejecute lo siguiente para establecer los directorios que deben pertenecer al usuario y grupo apache
:
chown apache:apache /var/www/aplicaciones/aplicacion1/{cache,config,tmp}
Ejecute lo siguiente para crear el archivo /var/www/aplicaciones/aplicacion1/index.php
:
vim /var/www/aplicaciones/aplicacion1/index.php
Añada el siguiente contenido:
<!DOCTYPE html>
<html>
<head>
<title>Aplicación 1</title>
</head>
<body>
<h1>
<?php
echo 'Aplicación 1';
?>
</h1>
<p>
<?php
echo 'Esta es la aplicación 1';
?>
</p>
<hr>
<?php
phpinfo(INFO_GENERAL);
?>
</body>
</html>
Ejecute lo siguiente para crear el archivo /etc/nginx/default.d/aplicaciones.conf
:
vim /etc/nginx/default.d/aplicaciones.conf
Añada el siguiente contenido para la primera aplicación, donde client_max_body_size
deberá tener el mismo valor de post_max_size
y upload_max_filesize
(128M
) a fin de permitir gestionar archivos de hasta 128 MiB:
location /aplicacion1 {
root /var/www/aplicaciones;
index index.html index.htm index.php;
client_max_body_size 128M;
# Si requiere reescribir el URI para activar el soporte de
# 'URLs bonitos' en aplicaciones como Wordpress, descomente
# la siguiente línea.
# try_files $uri $uri/ /aplicacion1/index.php?$query_string;
location ~ \.php$ {
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PHP_VALUE "upload_max_filesize=128M \n post_max_size=128M \n date.timezone=America/Mexico_City";
fastcgi_pass unix:/run/php-fpm/www.sock;
}
}
Nginx carece de soporte para archivos .htaccess. Si requiere añadir variables de PHP, puede hacerlo del mismo modo que se muestra en el ejemplo anterior en una lista separada por espacios y nuevas líneas en secuencia de escape.
Guarde los cambios, salga del editor de texto y ejecute lo siguiente para aplicar los cambios en Nginx:
systemctl reload nginx
Acceda con lynx
hacia http://localhost/aplicacion1/
:
lynx http://localhost/aplicacion1/
Deberá mostrarse el contenido generado con PHP y validar al mismo tiempo la versión y variables de PHP. Posteriormente considere eliminar la función phpinfo()
del código a fin de evitar incidentes de seguridad. Esta información jamás debe estar a la vista del público en general.
Ejecute lo siguiente para instalar PHP 5.6 en paralelo con PHP 7.4.
dnf -y install php56-php-fpm php56-php-bcmath php56-php-cli php56-php-dba php56-php-mbstring php56-php-xml php56-php-cli php56-php-mysqlnd
Puede instalar otros paquete de PHP 5.6 si así lo requiere. Éstos tendrán el mismo patrón de nombres que los paquetes de PHP 7.4, pero con el prefijo "php56-
" como se muestra arriba.
De modo predeterminado el archivo de la instancia predeterminada de php-fpm para PHP 5.6 sólo permite a Apache utilizar dicha instancia.
Edite el archivo /etc/opt/remi/php56/php-fpm.d/www.conf
:
vim /etc/opt/remi/php56/php-fpm.d/www.conf
Localice la línea correspondiente a listen.acl_users = apache
y añada a nginx a la lista:
listen.acl_users = apache,nginx
Ejecute lo siguiente para iniciar el servicio php56-php-fpm:
systemctl enable --now php56-php-fpm
De modo predeterminado php56-php-fpm
crea un zócalo como /var/opt/remi/php56/run/php-fpm/www.sock
con permisos de acceso exclusivamente a Apache y Nginx.
Ejecute lo siguiente para crear una estructura carpetas para una segunda aplicación PHP hipotética:
mkdir -p /var/www/aplicaciones/aplicacion2/{config,cache,tmp}
Igualmente, los contenidos de la carpeta donde se instale la aplicación PHP que requieran acceso de escritura o estén restringidos deben pertenecer al usuario y grupo apache
. Ejecute lo siguiente para establecer los directorios que deben pertenecer al usuario y grupo apache
:
chown apache:apache /var/www/aplicaciones/aplicacion2/{config,cache,tmp}
Ejecute lo siguiente para crear el archivo /var/www/aplicaciones/aplicacion2/index.php
:
vim /var/www/aplicaciones/aplicacion2/index.php
Añada el siguiente contenido:
<!DOCTYPE html>
<html>
<head>
<title>Aplicación 2</title>
</head>
<body>
<h1>
<?php
echo 'Aplicación 2';
?>
</h1>
<p>
<?php
echo 'Esta es la aplicación 2';
?>
</p>
<hr>
<?php
phpinfo(INFO_GENERAL);
?>
</body>
</html>
Ejecute lo siguiente para editar de nuevo el archivo /etc/nginx/default.d/aplicaciones.conf
:
vim /etc/nginx/default.d/aplicaciones.conf
Añada el siguiente contenido para la primera aplicación, donde client_max_body_size
deberá tener el mismo valor de las variables de PHP post_max_size
y upload_max_filesize
(64M
) a fin de permitir gestionar archivos de hasta 64 MiB:
location /aplicacion2 {
root /var/www/aplicaciones;
index index.html index.htm index.php;
client_max_body_size 64m;
# Si requiere reescribir el URI para activar el soporte de
# 'URLs bonitos' en aplicaciones como Wordpress, descomente
# la siguiente línea.
# try_files $uri $uri/ /aplicacion2/index.php?$query_string;
location ~ \.php$ {
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PHP_VALUE "upload_max_filesize=64M \n post_max_size=64M \n date.timezone=America/Mexico_City";
fastcgi_pass unix:/var/opt/remi/php56/run/php-fpm/www.sock;
}
}
Guarde los cambios, salga del editor de texto y ejecute lo siguiente para aplicar los cambios en Nginx:
systemctl reload nginx
Acceda con lynx
hacia http://localhost/aplicacion2/
:
lynx http://localhost/aplicacion2/
Deberá mostrarse el contenido generado con PHP y validar al mismo tiempo la versión y variables de PHP. Igualmente que con el ejemplo anterior, posteriormente considere eliminar la función phpinfo()
del código a fin de evitar incidentes de seguridad.
Nginx permite gestionar múltiples anfitriones virtuales de manera similar a cómo lo hace Apache. Si los anfitriones virtuales serán administrado exclusivamente por root, la configuración de PHP será igual a la que se ha mostrado hasta ahora. Si se requiere que los anfitriones virtuales sean administrados por usuarios regulares, se requiere configurar una instancia de php-fpm
ejecutada por el usuario correspondiente. Se requerirá lo siguiente para realizar el procedimiento de anfitriones virtuales:
/etc/hosts
del sistema donde se va a configurar.Defina el nombre de anfitrión. Éste deberá estar asociado a la dirección IP del servidor que hospeda Nginx.
Edite el archivo /etc/hosts
:
vim /etc/hosts
Encontrará el siguiente contenido:
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
Añada debajo de lo anterior la dirección IP del servidor, seguido de la lista separada por tabuladores con los nombres que en adelante estarán asociados a la dirección IP:
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.2 www.tudominio.net tudominio.net
Guarde los cambios y salga del editor de texto.
Valide que lo anterior funciona ejecutando lo siguiente:
ping -c3 www.tudominio.net
Lo anterior deberá devolver una salida similar a la siguiente:
PING www.tudominio.net (192.168.1.2) 56(84) bytes of data.
64 bytes from www.tudominio.net (192.168.1.2): icmp_seq=1 ttl=64 time=0.042 ms
64 bytes from www.tudominio.net (192.168.1.2): icmp_seq=2 ttl=64 time=0.060 ms
64 bytes from www.tudominio.net (192.168.1.2): icmp_seq=3 ttl=64 time=0.061 ms
--- mirror0.alcancelibre.org ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 57ms
rtt min/avg/max/mdev = 0.042/0.054/0.061/0.010 ms
NOTA: Si es posible, solicite además resolver el nombre de anfitrión en un servidor DNS. Si lo anterior es imposible por limitaciones de infraestructura y quiere poder visualizar los ejemplos descritos en este documento desde su sistema, edite en Windows el archivo
C:\Windows\System32\drivers\etc\hosts
y añada un registros igual al que añadió en el servidor.
Ejecute lo siguiente para crear un usuario regular que será designado como administrador de un anfitrión virtual:
useradd -c "Administrador de Fulano" tudominio
Ejecute lo siguiente para asignar contraseña al nuevo usuario:
passwd tudominio
Ejecute lo siguiente para cambiar el permiso de acceso de la carpeta de inicio del usuario a fin de permitir que Nginx pueda acceder a ésta:
chmod 755 /home/tudominio
Se requerirá que este usuario tenga la siguiente estructura de carpetas:
/home/tudominio
public_html
logs
tmp
Ejecute lo siguiente para generar esta estructura de carpetas:
mkdir -p /home/tudominio/{public_html,logs,tmp}
Ejecute lo siguiente para cambiar los atributos de pertenencia de estas nuevas carpetas para correspondan a los del usuario:
chown tudominio:tudominio /home/tudominio/{public_html,logs,tmp}
Ejecute lo siguiente para cambiar los contextos de SElinux a los que corresponden:
restorecon -Rv /home/tudominio
Ejecute lo siguiente para crear el archivo /home/tudominio/public_html/index.php
:
vim /home/tudominio/public_html/index.php
Añada el siguiente contenido:
<!DOCTYPE html>
<html>
<head>
<title>Sitio Web de Fulano</title>
</head>
<body>
<h1>
<?php
echo 'Fulano';
?>
</h1>
<p>
<?php
echo 'Esta es el sitio Web de Fulano';
?>
</p>
</body>
</html>
Ejecute lo siguiente para ver la configuración limpia predeterminada de php-fpm:
cat /etc/php-fpm.d/www.conf |grep -v ^$ |grep -v ^\;
Lo anterior mostrará un contenido similar al siguiente:
[www]
user = apache
group = apache
listen = /run/php-fpm/www.sock
listen.acl_users = apache,nginx
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
slowlog = /var/log/php-fpm/www-slow.log
php_admin_value[error_log] = /var/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
php_value[session.save_handler] = files
php_value[session.save_path] = /var/lib/php/session
php_value[soap.wsdl_cache_dir] = /var/lib/php/wsdlcache
Algunos de los valores mostrados arriba sólo pueden ser utilizados si php-fpm es ejecutado con el usuario y grupo apache
. Si copia esta configuración, el usuario regular no dispondrá de los privilegios necesarios para utilizar el zócalo de php-fpm y registros. Los usuarios regulares sólo pueden acceder a las instancias de php-fpm utilizando un puerto en el anfitrión local.
Ejecute lo siguiente para generar una configuración de php-fpm que se ejecutará en paralelo con la predeterminada:
vim /etc/php-fpm.d/tudominio.conf
Añada el siguiente contenido simplificado que será el más adecuado para permitir sea ejecutado por el usuario regular:
[tudominio]
user = tudominio
group = tudominio
listen = 127.0.0.1:8001
pm = dynamic
pm.max_children = 9999
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 5
php_admin_value[upload_tmp_dir] = /home/tudominio/tmp
php_admin_value[session.save_path] = /home/tudominio/tmp
php_value[date.timezone] = America/Mexico_City
La configuración establece al usuario y grupo tudominios como los utilizados para ejecutar esta instancia en particular de php-fpm utilizando el puerto 8001 en el anfitrión local. Define además una carpeta donde el usuario tiene privilegios para ser utilizado como carpeta temporal para subir archivos y para almacenar datos temporales de la sesión.
Como puede observar, también puede añadir aquí mismo variables de PHP con los valores que necesite. Es mucho mas eficiente hacerlo aquí que en la configuración de Nginx. Sin embargo, puede configurar indistintamente las variables de PHP en uno u otro servicio.
De modo predeterminado SELinux sólo permite trabajar al servicio php-fpm en el puerto 9000. Ejecute lo siguiente para autorizar en SELinux que php-fpm pueda utilizar el puerto 8001:
semanage port -a -t http_port_t -p tcp 8001
Ejecute lo siguiente para reiniciar el servicio php-fpm
:
systemctl restart php-fpm
En adelante podrá utilizar esta nueva instancia del servicio php-fpm en 127.0.0.1:8001
en cualquier configuración donde se requieran privilegios para el usuario específico en la misma configuración.
Ejecute lo siguiente para crear el archivo donde se configurarán los nuevos anfitriones virtuales del servidor:
vim /etc/nginx/conf.d/virtualhosts.conf
Añada el siguiente contenido:
server {
listen 192.168.1.2;
server_name www.tudominio.net tudominio.net;
access_log /var/log/nginx/tudominio-access_log main;
error_log /var/log/nginx/tudominio-error_log notice;
root /home/tudominio/public_html;
client_max_body_size 64M;
# Puede reutilizar los archivos dentro de /etc/nginx/default.d
# para ahorrar trabajo.
include /etc/nginx/default.d/headers.conf;
include /etc/nginx/default.d/common-configs.conf;
include /etc/nginx/default.d/gzip.conf;
location / {
index index.html index.htm index.php;
# Si requiere reescribir el URI para activar el soporte de
# 'URLs bonitos' en aplicaciones como Wordpress, descomente
# la siguiente línea.
# try_files $uri $uri/ /index.php?$query_string;
location ~ \.php$ {
try_files $uri =404;
fastcgi_intercept_errors on;
include fastcgi_params;
fastcgi_param SERVER_NAME $host;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:8001;
fastcgi_param PHP_VALUE "upload_max_filesize=64M \n post_max_size=64M";
fastcgi_index index.php;
}
}
}
Igualmente que con ejemplos anteriores, el valor de client_max_body_size
debe ser el mismo de las variables de PHP memory_limit
y upload_max_filesize
(64M
) a fin de permitir gestionar archivos de hasta 64 MiB.
Guarde los cambios, salga del editor de texto y ejecute lo siguiente para aplicar los cambios en Nginx:
systemctl reload nginx
Desde el mismo servidor acceda con lynx
hacia http://www.tudominio.net/
:
lynx http://www.tudominio.net/
Deberá mostrarse el nuevo anfitrión virtual y contenido generado con PHP. Si desea visualizar este anfitrión virtual desde otro sistema, es necesario exista un registro en la zona de DNS correspondiente resolviendo el nombre del anfitrión virtual apuntando a la dirección IP del servidor.
Puede generar cuanto sitios virtuales como considere necesarios. Cada uno se sugiere esté asignado a un usuario en particular y utilizando su propia instancia de php-fpm.
Ejecute lo siguiente para genera un certificado auto-firmado provisional con firma de 4096 bits:
openssl req -newkey rsa:4096 -x509 -sha256 -days 365 -nodes -out /etc/pki/tls/certs/servidor.crt -keyout /etc/pki/tls/private/servidor.key
Lo anterior le solicitará ingresar los datos estándar de un certificado, como son el código del país, estado, ciudad, empresa, unidad o departamento, nombre de anfitrión para el certificado (www.tudominio.net
si sigue el ejemplo de este documento) y una cuenta de correo electrónico.
Ejecute lo siguiente para crear el archivo donde se configurarán los nuevos anfitriones virtuales del servidor:
vim /etc/nginx/conf.d/virtualhosts.conf
En la configuración del anfitrión virtual debe añadir el siguiente esquema:
server {
listen 443 http2 ssl;
ssl_certificate /ruta/del/archivo/del/certificado.crt;
ssl_certificate_key /ruta/del/archivo/de/firma.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
...
}
Siendo así, la configuración sería similar a la siguiente:
# Redireccionar todo tráfico de puerto 80 para este anfitrión virtual
# hacia https.
server {
if ($host = www.tudominio.net) {
return 301 https://$host$request_uri;
}
if ($host = tudominio.net) {
return 301 https://$host$request_uri;
}
listen 80;
server_name www.tudominio.net tudominio.net;
return 404;
}
# Se convierte a https el antiguo sitio en http.
server {
listen 443 http2 ssl;
ssl_certificate /etc/pki/tls/certs/servidor.crt;
ssl_certificate_key /etc/pki/tls/private/servidor.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
server_name www.tudominio.net tudominio.net;
access_log /var/log/nginx/tudominio-access_log main;
error_log /var/log/nginx/tudominio-error_log notice;
root /home/tudominio/public_html;
client_max_body_size 64M;
# Puede reutilizar los archivos dentro de /etc/nginx/default.d
# para ahorrar trabajo.
include /etc/nginx/default.d/headers.conf;
include /etc/nginx/default.d/common-configs.conf;
include /etc/nginx/default.d/gzip.conf;
location / {
index index.html index.html index.php;
# Si requiere reescribir el URI para activar el soporte de
# 'URLs bonitos' en aplicaciones como Wordpress, descomente
# la siguiente línea.
# try_files $uri $uri/ /index.php?$query_string;
location ~ \.php$ {
try_files $uri =404;
fastcgi_intercept_errors on;
include fastcgi_params;
fastcgi_param SERVER_NAME $host;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:8001;
fastcgi_param PHP_VALUE "upload_max_filesize=64M \n post_max_size=64M";
fastcgi_index index.php;
}
}
}
Guarde los cambios, salga del editor de texto y ejecute lo siguiente para aplicar los cambios en Nginx:
systemctl reload nginx
Desde el mismo servidor acceda con lynx
hacia https://www.tudominio.net/
:
lynx https://www.tudominio.net/
Deberá mostrarse el anfitrión virtual a través de HTTPS mostrando una advertencia de certificado auto-firmado.
Instale certbot y su complemento para Nginx:
dnf -y install certbot python3-certbot-nginx
Si dispone de una dirección IP pública fija y un registro de DNS para el dominio a utilizar, puede ejecutar lo siguiente para generar un certificado válido de Let's Encrypt:
certbot --nginx --agree-tos -d www.tudominio.net -d tudominio.net
Lo anterior le solicitará proporcionar una cuenta de correo electrónico válida y realizará automáticamente todos los cambios pertinentes requeridos en la configuración del anfitrión virtual en el archivo donde esté configurado (/etc/nginx/conf.d/virtualhosts.conf
). Es requisito que los dominios a registrar estén resueltos en un DNS y que estén definidos como valor de server_name
en el anfitrión virtual.
Asumiendo que lo anterior tuvo éxito, ejecute lo siguiente para habilitar el servicio que se encargará de renovar automáticamente el certificado cuando sea necesario:
systemctl enable --now certbot-renew.timer