Hostear varios VHosts con usuarios diferentes en Nginx

Lo más normal del mundo cuando se tiene un servidor, es pensar en seguridad y más seguridad, nunca se puede ser suficientemente paranoico 😉

Una práctica algo común y NADA recomendable, es usar el mismo usuario para todas las bases de datos, peor si se usa root, que por increíble que parezca, hay quienes (por vagancia o desconocimiento) hacen esto, ya hablé sobre el por qué NO se debe actuar así en otro post, ahora toca explicar cómo y por qué es mejor separar el procesamiento del servidor web en diferentes usuarios, en esta ocasión será usando Nginx.

DedicatedServer_SubImage

¿Qué es eso de usuarios y servidor web?

Para explicarlo de forma breve y simple, el servidor web (apache, nginx, el que sea) necesita abrir procesos en el sistema, procesos que serán quienes tomen los archivos del HDD (imágenes, etc) y los ponga disponibles para el navegador del cliente. El servidor web no puede simplemente tomar los archivos y manipularlos siendo nadie, o sea, necesita un usuario que será quien al final hará todo esto, y ese usuario es del que les hablo, ¿se entiende?

¿Qué es eso de separar en varios usuarios?

Supongamos que en nuestro servidor tenemos 2 sitios webs, el nuestro que es un proyecto personal, y otro más (imaginemos que es el de nuestra novia o hermano). Aún cuando usemos bases de datos separadas y usuarios diferentes para acceder a las mismas, al final los archivos de ambos sitios webs son manipulados por el mismo usuario, el procesamiento PHP es gestionado por el mismo usuario para todos los sitios (generalmente es www-data). Esto es una práctica no recomendable, es mejor tenerlo todo bien separado, como dice un viejo refrán, es mejor precaver que lamentar.

Ok entiendo, cómo lo hago con Nginx

2000px-Nginx_logo.svg

Lo primero es tener cuenta que Nginx no cuenta con un módulo propio que se encargue del procesamiento PHP como sí lo hace Apache, para Nginx necesitamos usar PHP-CGI o PHP-FPM, que funciona igual de bien (o mejor) que Apache. Por lo que, para separar el procesamiento PHP en diferentes usuarios, necesitaremos cambiar líneas en archivos de configuración de PHP (CGI o FPM), no de Nginx propiamente.

Supongamos que usas PHP-FPM, crearemos un archivo de configuración de pool para un sitio específico, o sea, un pool es la forma de separar el procesamiento PHP de PHP-FPM, pero vamos por partes.

1. Primero debemos saber qué usuario del sistema usaremos, asumiré que aún no tenemos ninguno creado y pues bueno, vamos a crearlo:

Todos los comandos siguientes TIENEN que ser ejecutados con privilegios de administración, bien con root directo o usando sudo

adduser blog

Nos comenzará el proceso normal de creación de un usuario, pongan el password, etc.

Le pongo blog al usuario solo por seguir el ejemplo, de que el primer sitio que hostearemos será un blog, pues eso… para saber cada usuario con qué sitio guarda relación

1. Primero entremos a /etc/php5/fpm/pool.d/ :

cd /etc/php5/fpm/pool.d/

2. Ahora, crearemos un archivo llamado blog.conf :

touch blog.conf

3. Ahora pondremos la configuración del pool que usaremos para el VHost blog:

Editen el archivo blog.conf con nano … por ejemplo: sudo nano blog.conf
[blog]
user = blog
group = blog
listen = /var/run/php5-fpm-blog.sock
listen.owner = blog
listen.group = blog
pm = ondemand
pm.max_children = 96
chdir = /

Nota: Lo que les marco en rojo es lo que deben modificar en dependencia del usuario que anteriormente crearon. Por ejemplo, si crean otro VHost con otro usuario (foro, por ejemplo) entonces ponen en vez de blog simplemente foro en cada una de las líneas, ¿se entiende no?

4. Una vez puesto ya la configuración del nuevo pool (el archivo blog.conf que recién creamos y editamos), toca el turno de indicarle al VHost de Nginx que use para ese VHost, para es sitio, un sock diferente. El sock que usará seremos el que previamente declaramos (/var/run/php5-fpm-blog.sock). Editemos el VHost de Nginx y en la parte del procesamiento PHP, indicamos que use ese socks. Por ejemplo:

location ~ \.php$ {
if (!-f $request_filename) { return 404; }
fastcgi_pass unix:/var/run/php5-fpm-blog.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME   $document_root$fastcgi_script_name;
fastcgi_read_timeout 300;
}

Como ven, le indico que el procesamiento PHP de ese VHost (esas líneas están por ejemplo dentro de /etc/nginx/sites-enabled/vhost-blog) lo haga con el socks que se encuentra en /var/run/php5-fpm-blog.sock … que es el que creamos previamente al editar /etc/php5/fpm/pool.d/blog.conf … ¿se entiende no?

5. Una vez hecho esto, reiniciamos ambos servicios (php5-fpm y nginx) y listo, veremos que el procesamiento de ese sitio (vhost) ya NO lo hace www-data ni root ni nadie similar, sino que lo hace el usuario que previamente definimos.

Aquí les muestro el output de un ps aux | grep fpm en uno de los servidores de mi nodo:

ps aux | grep fpm
ebook      586  0.0  0.0 349360  1204 ?      S    Mar30   0:00 php-fpm: pool ebook
ebook      589  0.0  0.0 349360  1204 ?      S    Mar30   0:00 php-fpm: pool ebook
www        608  0.0  0.2 350084  5008 ?      S    Mar30   0:00 php-fpm: pool www
www        609  0.0  0.2 350600  5048 ?      S    Mar30   0:00 php-fpm: pool www
tv3        611  0.0  0.0 349360  1204 ?      S    Mar30   0:00 php-fpm: pool tv3
tv3        615  0.0  0.0 349360  1204 ?      S    Mar30   0:00 php-fpm: pool tv3
revista   1818  1.7  1.7 437576 36396 ?      S    09:55   0:46 php-fpm: pool revista
revista   2264  1.9  1.7 437332 35884 ?      S    10:15   0:26 php-fpm: pool revista
pupila    2338  4.3  1.0 428992 22196 ?      S    10:18   0:53 php-fpm: pool pupila
revista   2413  1.8  1.7 437764 36152 ?      S    10:22   0:18 php-fpm: pool revista
gutl      2754  3.5  1.3 356724 27164 ?      S    10:38   0:00 php-fpm: pool gutl
cgr       5624  0.0  1.0 365168 22696 ?      S    Apr28   0:16 php-fpm: pool cgr
pupila    7900  0.3  2.5 457052 52444 ?      S    Apr25  20:23 php-fpm: pool pupila
pupila   11021  0.4  2.5 458316 52864 ?      S    Apr28   5:57 php-fpm: pool pupila
cgr      11254  0.0  1.0 363152 21708 ?      S    Apr28   0:12 php-fpm: pool cgr
cgr      13184  0.0  1.0 362872 21360 ?      S    Apr28   0:08 php-fpm: pool cgr

Como ven… separar el procesamiento PHP por usuarios usando Nginx + PHP-FPM es realmente fácil, ahí ven que son varios pools, pues son varios usuarios.

Conclusiones

Cuando se trata de servidores, nunca se es suficientemente paranoico … la seguridad no es algo para jugar, mientras más intentemos siempre mejorar la seguridad de nuestros servidores y sus servicios, menos probabilidades habrá de que pasemos un susto por intento (satisfactorio) de hack o cualquier cosa similar 😉


9 comentarios, deja el tuyo

Deja tu comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*

*

  1. Responsable de los datos: Miguel Ángel Gatón
  2. Finalidad de los datos: Controlar el SPAM, gestión de comentarios.
  3. Legitimación: Tu consentimiento
  4. Comunicación de los datos: No se comunicarán los datos a terceros salvo por obligación legal.
  5. Almacenamiento de los datos: Base de datos alojada en Occentus Networks (UE)
  6. Derechos: En cualquier momento puedes limitar, recuperar y borrar tu información.

  1.   dhunter dijo

    Gaara, en tiempos actuales estas cosas se deberían automatizar todo lo posible, te recomiendo pruebes Ansible. Sin agente, solo necesita python en el host remoto, muy simple de configurar, ficheros yaml, templates Jinja.

    https://github.com/ansible/ansible-examples/tree/master/wordpress-nginx

    1.    KZKG^Gaara dijo

      A ver, eso no siempre es solo para sitios con WordPress, y … jaja a lo mejor Ansible pincha volao, pero prefiero saber exactamente cómo funciona todo en el server, aún cuando tenga que dedicarle 1 minuto a crear yo mismo un nuevo socks y un nuevo VHost 😀

      1.    dhunter dijo

        Con Ansible automatizas de todo, haces prácticamente lo que quieras, la ventaja de este método es que encapsulas la práctica y luego ejecutas a voluntad, imagina que tienes un sitio muy cargado y quieres hacer balanceo de carga entre servidores de aplicación, estos tienen que estar configurados exactamente igual no puedes saltarte un paso o hacer nada diferente en uno de ellos, te imaginas hacer el procedimiento paso a paso 4 veces? Con Ansible es tan simple como agregar el nombre del host al fichero inventario y Voilá!!

        http://www.ansible.com/how-ansible-works

      2.    dhunter dijo

        Perdón el culto a Ansible pero es que es una de estas tecnologías que descubres y quieres que todos la usen ya porque es tan genial y práctica, es como cuando descubres NGINX y quieres que todos tus amigos dejen Apache inmediatamente.

        https://speakerdeck.com/slok/ansible-all-the-things

  2.   Mstaaravin dijo
  3.   Rots87 dijo

    Yo soy (o estudio para serlo) desarrollador y con NGIX tuve muchos problemas a la hora de configurar nginx+php-fpm. Se que la distro de archlinux no es la mejor para hacerla de servidor, pero cada vez que actualizaba una version de ngix o de php siempre se me crasheaba todo asi que abandone el intento jejeje… Por hoy me quede con el clasico Apache+PHP pero vere si me doy una vuelta por NGIX otra vez… tal vez en una maquina virtual

    1.    dhunter dijo

      La mentalidad cambia un poco, nginx sirve el contenido estático y sirve de proxy inverso para el php-fpm que es quien corre el PHP de verdad, tienes que empezar por partes e ir logrando el deploy paso por paso, busca una guía para desplegar el framework con el que trabajas, cada cual tiene su detalle por los nombres de la carpeta public, static, resources, etc…

  4.   Anónimo dijo

    Háganle a la comunidad el grandísimo favor de abandonar el palabro «hostear», que no existe. Por Dios, ¿tan difícil es decir «alojar»?

  5.   Wil dijo

    Saludos, siguiendo tu ejemplo quisiera saber si se podría hacer un pool solo para el backen de wordpress, es decir para el wp-admin haciendo un nuevo socket sol para las conexiones entrantes al backend

    location /wp-admin {
    root /var/www/tusitio.com/wp-admin;
    index index.php index.html index.htm;
    location ~ ^/wp-admin/(.+.php)$ {
    try_files $uri =404;
    root /var/www/tusitio.com/wp-admin;
    include /etc/nginx/fastcgi_params;

    fastcgi_pass server unix:/run/php5-fpm2.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_buffer_size 128k;
    fastcgi_buffers 256 4k;
    fastcgi_busy_buffers_size 256k;
    fastcgi_temp_file_write_size 256k;
    fastcgi_read_timeout 1240;
    }
    location ~* ^/wp-admin/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
    root /var/www/tusitio.com/wp-admin/;
    }
    }