Instalación y configuración del servicio NGINX y PHP-FPM en CentOS 7

Este manual nos permitira configurar un servicio HTTP usando NGINX y con soporte PHP usando PHP-FPM.

Las configuraciones presentadas funcionan bajo el esquema de seguridad SELINUX.

Instalemos el servicio NGINX desde los reposotorios EPEL.

$ sudo yum install nginx --enablerepo epel

Si no tiene el repositorio EPEL configurado hagalo desde aquí

Ahora vamos a habilitar el servicio en el inicio de sistema con el comando enable y despues iniciamos el servicio (start).

$ sudo systemctl enable nginx.service
$ sudo systemctl start nginx.service

Por defecto CentOS 7 trae el servicio firewalld como servicio de muro de fuego, firewalld maneja perfiles de servicio para habilitar puertos por lo cual vamos ha habilitar el perfil http que nos abre el puerto 80/TCP.

$ sudo firewall-cmd --zone=public --add-service=http --permanent
$ sudo firewall-cmd --reload

Podemos ver el estatus del firewall usando el comando firewall-cmd --list-all.

Configuración de NGINX

Ahora vamos a configurar el NGINX, primero creamos una carpeta llamada sites-enabled que sera el directorio donde NGINX cargará configuraciones.

$ sudo mkdir /etc/nginx/sites-enabled

El esquema como buena practica, es que nosotros crearemos los archivos desde el directorio /etc/nginx/conf.d y “activaremos” la configuracion creando un acceso directo de la configuracion apuntando a /etc/nginx/sites-enabled.

Ejemplo:

$ ln -s /etc/nginx/conf.d/misitio.conf /etc/nginx/sites-enabled/misitio.conf

De esta manera nos es mas facil desactivar sitios sin borrar sus archivos de configuracion.

Antes de iniciar la edicion del archivo principal de configuracion de NGINX respaldamos la configuracion inicial.

$ sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.old

Configuramos de la siguiente manera, siga las instruccion de los comentarios del archivo.

$ sudo vim /etc/nginx/nginx.conf
user  nginx;
worker_processes  4;                        # Ajuste de acuerdo al numero de CPUs

#error_log  /var/log/nginx/error.log;
#error_log  /var/log/nginx/error.log  notice;
#error_log  /var/log/nginx/error.log  info;
error_log  /var/log/nginx/error.log  warn;  # Logs a nivel de advertencia

pid        /run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile    on;
    tcp_nopush  on;                         # Optimiza el rendimiento de sendfile
    keepalive_timeout  65;                      # Ajuste de tiempo de espera
    gzip  on;                                   # Reduce la cantidad de datos a transferir

    include /etc/nginx/sites-enabled/*.conf;    # Directorio de configuraciones
}

Configuracion de php-fpm (Soporte FastCGI para PHP)

El servicio php-fpm nos da el sorporte para sitios web hechos en PHP. Procedamos a instalar php-fpm y los modulos PHP necesarios para su funcion.

$ sudo yum install php-fpm php-common php-cli php-pear php-pdo php-gd php-mbstring php-xml php-pecl-apc --enablerepo epel

Ahora editamos el archivo de configuracion de php-fpm. Configuraciones importantes en la variable listen donde declaramos el socket del servicio y las variables user y group.

$ vim /etc/php-fpm.d/www.conf
;listen = 127.0.0.1:9000
listen = /var/run/php5-fpm.sock

;user = apache
;group = apache
user = nginx
group = nginx

request_terminate_timeout = 65

security.limit_extensions = .php .php3 .php4 .php5

Creamos directorios indispensables para el servicio y le asignamos los permisos correspondientes.

$ mkdir -p /var/lib/php/{session,tmp}
$ chmod 750 -R /var/lib/php/
$ chown nginx:nginx -R /var/lib/php/

Ahora agregamos el siguiente archivo, este contiene configuraciones de seguridad que he recopilado y que nos permite agregarle un extra de seguridad.

$ vim /etc/php.d/security.ini
; Ocultar version de PHP
expose_php=Off
; Ocultar errores
display_errors=Off
; Bloquear subidas de archivos
;file_uploads=Off
; ó limitar los archivos a subir
file_uploads=On
upload_max_filesize=1M
; Bloquear ejecucion remota via ftp,http
allow_url_fopen=Off
allow_url_include=Off
; Desactivar (Obsoleto a partir de PHP 5.4.0)
magic_quotes_gpc=Off
; Limita los paquetes POST, (Default 8M)
post_max_size=1M
; Control de recursos
max_execution_time =  30
max_input_time = 30
memory_limit = 8M
; Desactivar funciones que podrían ser explotadas
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_multi_exec,parse_ini_file,show_source
; Directorio temporal
upload_tmp_dir = /var/lib/php/tmp/
; Limitar la ejecución a php en directorio
open_basedir = /home/www/

Para esta prueba no desabilitamos phpinfo en la variable disable_functions para poder realizar la prueba, recomiendo agregarlo una vez terminada las pruebas. Estas opciones las puede ajustar a su criterio.

Habilitamos el servicio en el inicio de sistema e iniciamos el servicio.

$ systemctl enable php-fpm.service
$ systemctl start php-fpm.service

Configuracion de un sitio de prueba

Lo primero que haremos es crear el archivo de configuracion de nuestro sitio en NGINX (recuerde que estas van en el directorio /etc/nginx/conf.d).

$ vim /etc/nginx/conf.d/test.conf
server {
    listen       80 default;
    server_name  localhost;

    ## Deshabilitamos que imprima la version de NGINX ##
    server_tokens off;

    ## Registros del virtualhost ##
    access_log  /var/log/nginx/test.access.log;
    error_log  /var/log/nginx/test.error.log;

    ## Metodos validos ##
    if ($request_method !~ ^(GET|HEAD|POST)$ ) {
         return 444;
    }

    location / {
        ## Los index validos, entre ellos el .php
        index  index.html index.htm index.php;

        ## Directorio del sitio
        root  /home/www/test/public_html;

        ## Soporte PHP ##
        location ~ \.php$ {
                root            public_html;
                fastcgi_pass    unix:/var/run/php5-fpm.sock;    #Socket de php-fpm
                fastcgi_index   index.php;
                fastcgi_param   SCRIPT_FILENAME  /home/www/test/public_html$fastcgi_script_name;
                include         /etc/nginx/fastcgi_params;
        }

        ## Denegar accesos a archivos ocultos ##
        location ~ /\. { deny  all; }

        ## Bloquear logs de archivos estaticos ###
        location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
                access_log        off;
                log_not_found     off;
                expires           360d;
        }
    }
}

Usted puede ver que estamos declarando que los archivos de nuestro sitio estaran alojados en /home/www.

Ahora lo que haremos es activar nuestra configuracion nginx de prueba, para esto creamos un enlace directo hacia /etc/nginx/sites-enabled que es donde se NGINX carga los archivos de configuracion (como lo declaramos anteriormente).

$ ln -s /etc/nginx/conf.d/test.conf /etc/nginx/sites-enabled/test.conf

Creamos el directorio donde alojaremos nuestros sitio

$ mkdir -p /home/www/test/public_html

Creamos un archivo php donde ejecutaremos la funcion phpinfo() para compobrar que este funcionando correctamente.

$ vim /home/www/test/public_html/index.php
<?php
        phpinfo();
?>

Asignamos permisos adecuados.

$ chmod 750 -R /home/www
$ chown nginx:nginx -R /home/www

Permisos necesarios para SELinux

$ semanage fcontext -a -t httpd_sys_content_t "/home/www(.*)"
$ restorecon -R -v /home/www/

No olvide asignar los permisos que se mencionan anteriormente para cada proyecto PHP que configure.

Reiniciamos el servicio para cargar todo

$ systemctl restart nginx.service