Implantación de Aplicaciones Web
José Juan Sánchez Hernández
Curso 2023/2024
php-fpm
y php-mysql
php-fpm
a través de un socket UNIXphp-fpm
a través de un socket TCP/IP
cgi.fix_pathinfo
para mejorar la seguridadEn esta práctica vamos a instalar la pila LEMP que es una variación de la pila LAMP. La única diferencia es que usa el servidor Nginx en lugar de Apache.
Nginx está considerado como un servidor web ligero de alto rendimiento que además suele ser utilizado como proxy inverso y balanceador de carga.
php-fpm
y php-mysql
php-fpm
El paquete php-fpm
(PHP FastCGI Process
Manager) es una implementación alternativa al PHP FastCGI
con algunas características adicionales útiles para sitios web
com mucho tráfico.
El uso de PHP-FPM (PHP FastCGI Process Manager) con Nginx es ideal porque permite mejorar el consumo de memoria del servidor, haciendo que el servidor tenga un bajo consumo de recursos, mejorando de esta manera su rendimiento y escalabilidad. PHP-FPM se ejecutará como un servicio independiente de Nginx que se va a encargar de interpretar las peticiones que incluyen código PHP que reciba el servidor Nginx. Cuando el servidor Nginx reciba una petición HTTP donde haya que procesar código PHP, el servidor Nginx se comunicará con PHP-FPM a través de un socket UNIX o un socket TCP/IP para recibir la respuesta del código PHP interpretado y servirla al cliente que realizó la petición.
php-mysql
El paquete php-mysql
permite a PHP interaccionar con el
sistema gestor de bases de datos MySQL.
php-fpm
a través de un socket UNIXLos sockets UNIX nos permiten realizar comunicación entre procesos, también conocida como IPC (Inter-Process Communication)), que es una función básica de los sistemas operativos que permite el intercambio de datos entre procesos de una forma eficiente. Sin embargo, los sockets TCP/IP nos permiten comunicar procesos a través de una red.
Un sockets UNIX es un tipo de archivo especial, donde los procesos pueden escribir y leer datos para comunicarse.
Los sockets UNIX tienen la ventaja que permiten realizar comunicaciones más rápidas entre los procesos, pero tienen el inconveniente de que son menos escalables que los sockets TCP/IP porque sólo permiten comunicar procesos que se están ejecutando en el mismo sistema operativo de la misma máquina.
En esta sección vamos a explicar cómo podemos configurar Nginx para
que pueda comunicarse con el proceso php-fpm
a través de un
socket UNIX.
Editamos el archivo de configuración
/etc/nginx/sites-available/default
:
Realizamos los siguientes cambios:
index
añadimos el valor
index.php
en primer lugar para que darle prioridad respecto
a los archivos index.html
.location ~ \.php$
indicando dónde se
encuentra el archivo de configuración fastcgi-php.conf
y el
archivo php8.1-fpm.sock
.location ~ /\.ht
para no permitir que un usuario pueda descargar los archivos
.htaccess
. Estos archivos no son procesados por Nginx, son específicos de Apache.Un posible archivo de configuración para el servidor podría ser el siguiente:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.php index.html index.htm index.nginx-debian.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
# pass PHP scripts to FastCGI server
#
location ~ \.php$ {
include snippets/fastcgi-php.conf;
# With php-fpm (or other unix sockets):
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
location ~ /\.ht {
deny all;
}
}
Nota: En el momento de redactar esta guía la versión de PHP es la 8.1. Tenga en cuenta que esta versión puede cambiar en un futuro.
Podemos comprobar que la sintaxis del archivo de configuración es correcta con el comando:
Una vez realizados los cambios reiniciamos el servicio
nginx
:
Crea un archivo llamado info.php
en el directorio
/var/www/html
.
sudo nano /var/www/html/info.php
Añade el siguiente contenido:
<?php
phpinfo();
?>
Ahora accede desde un navegador a la URL: http://IP/info.php, donde IP será la dirección IP de su máquina virtual. Por ejemplo, si la dirección IP de su máquina virtual es 192.168.22.200, la URL será: http://192.168.22.200/info.php
php-fpm
a través de un socket TCP/IPLos sockets TCP/IP nos permiten comunicar procesos que se pueden estar ejecutando en la misma máquina o en máquinas diferentes, a través de una red.
php-fpm
se ejecutan en la misma máquinaphp-fmp
En primer lugar hay que modificar la directiva listen
del archivo /etc/php/8.1/fpm/pool.d/www.conf
.
sudo nano /etc/php/8.1/fpm/pool.d/www.conf
Si buscamos la directiva listen
en el archivo de
configuración nos encontramos que en la configuración por defecto está
escuchando en el socket UNIX /run/php/php8.1-fpm.sock
. A
continuación se muestra un fragmento del archivo de configuración por
defecto que hace referencia a la directiva listen
.
; The address on which to accept FastCGI requests.
; Valid syntaxes are:
; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on
; a specific port;
; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
; a specific port;
; 'port' - to listen on a TCP socket to all addresses
; (IPv6 and IPv4-mapped) on a specific port;
; '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = /run/php/php8.1-fpm.sock
Habrá que modificar la directiva listen
por la dirección
de localhost (127.0.0.1
) y un puerto. En este ejemplo
utilizaremos el puerto 9000
. La directiva
listen
quedaría así:
listen = 127.0.0.1:9000
Una vez que hemos realizado las modificaciones en la configuración
reiniciamos el servicio de php-fpm
para que se apliquen los
cambios:
En este caso hay que configurar en el archivo
/etc/nginx/sites-available/default
que los scripts PHP se
van a enviar al servidor FastCGI a través de un socket TCP/IP.
Habrá que modificar la directiva de configuración
fastcgi_pass
para indicar la dirección y el puerto donde se
encuentra el servidor FastCGI. Por ejemplo, si el servidor FastCGI se
está ejecutando en la misma máquina (127.0.0.1
), en el
puerto 9000
habrá que asignarle el siguiente valor:
fastcgi_pass 127.0.0.1:9000;
Un posible archivo de configuración para el servidor podría ser el siguiente:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.php index.html index.htm index.nginx-debian.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
# pass PHP scripts to FastCGI server
#
location ~ \.php$ {
include snippets/fastcgi-php.conf;
# With php-cgi (or other tcp sockets):
fastcgi_pass 127.0.0.1:9000;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
location ~ /\.ht {
deny all;
}
}
Podemos comprobar que la sintaxis del archivo de configuración es correcta con el comando:
Una vez realizados los cambios reiniciamos el servicio
nginx
:
php-fpm
se ejecutan diferentes máquinasAl utilizar diferentes máquinas para el servidor web Nginx y
php-fpm
, debemos buscar una solución para compartir los
archivos de contenido estático y el código fuente de la aplicación web,
entre las dos máquinas.
Algunas de las soluciones que podemos utilizar para compartir el contenido entre los dos servidores son las siguientes:
rsync
+ cron
cgi.fix_pathinfo
para mejorar la seguridadEs recomendable realizar un cambio en la directiva de configuración
cgi.fix_pathinfo
por cuestiones de
seguridad. Editamos el siguiente archivo de configuración:
Nota: En el momento de redactar esta guía la versión de PHP es la 8.1. Tenga en cuenta que esta versión puede cambiar en un futuro.
Buscamos la directiva de configuración cgi.fix_pathinfo
que por defecto aparece comentada con un punto y coma y con un valor
igual a 1.
;cgi.fix_pathinfo=1
Eliminamos el punto y coma y la configuramos con un valor igual a 0.
cgi.fix_pathinfo=0
Una vez modificado el archivo de configuración y guardados los
cambios reiniciamos el servicio php8.1-fpm
.
Referencias sobre los problemas de seguridad relacionados con
la directiva cgi.fix_pathinfo
:
Esta
página forma parte del curso
Implantación de Aplicaciones
Web de José Juan Sánchez
Hernández y su contenido se distribuye bajo una
licencia
Creative Commons Reconocimiento-NoComercial-CompartirIgual 4.0
Internacional.