Instalación
En Debian es recomendable usar los repositorios dotdeb ya que contiene las versiones pre compiladas actualizadas del Nginx.Para hacer esto coloca en /etc/apt/sources.list el repositorio: packages.dotdeb.org, bajar su llave pública de la dirección: http://www.dotdeb.org/dotdeb.gpg y agregarla al llavero de Debian.
echo "deb http://packages.dotdeb.org squeeze all" >> /etc/apt/sources.list"
wget http://www.dotdeb.org/dotdeb.gpg
apt-key add dotdeb.gpg
apt-get update
Luego se descarga el Nginx de manera normal con apt-get:apt-get install nginx
En FreeBSD basta con usar pkg_add -vvv nginx (en FreeBSD 10 en adelante se usa pkg install nginx). También puede instalarlo con make install clean desde /usr/ports/www/nginx (siempre y cuando tenga bien configurado el árbol de puertos). Nginx viene instalado por defecto en OpenBSD a partir de la versión 5.2.
Configuración
Una vez instalado Nginx encontraremos los archivos de configuración en el directorio /etc/nginx.
Para los que vienen de apache notaran que en Debian se mantiene el uso de la carpeta sites-available y sites-enabled (localizadas en /etc/nginx/). Los que no han trabajado con esta modalidad en la primera carpeta se encuentran los archivos de configuración de los sitios web “disponibles” y en la segunda un enlace simbólico a los sitios que están en sites-available que el administrador (osea ustedes) desea que sean servidos por Nginx.
A continuación coloco el /etc/nginx/nginx.conf editado por mí con sus respectivas explicaciones:
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
events {
worker_connections 768;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
types_hash_max_size 2048;
server_tokens off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_types text/plain text/css application/x-javascript application/xml
application/json image/png image/gif image/jpeg image/jpg;
gzip_comp_level 6;
gzip_buffers 16 8k;
client_body_in_single_buffer on;
client_body_buffer_size 1K;
client_header_buffer_size 1k;
client_max_body_size 1k;
large_client_header_buffers 2 1k;
client_body_timeout 10;
client_header_timeout 10;
keepalive_timeout 30;
send_timeout 10;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
En el archivo por defecto se notan varias cosas interesantes, como por ejemplo, los bloques events y http, delimitados por llaves ({}). El bloque events contiene las directivas que afectan el procesamiento de conexiones.
El bloque http comprende las opciones de servidor http. Los parámetros colocados fuera de cualquiera de los bloques anteriormente mencionados se dicen que se encuentran en el bloque principal (main).
En el bloque main tenemos en orden: utilizar el usuario www-data para ejecutar Nginx, usar 4 procesos simultáneos para atender peticiones (se recomienda tener un proceso por cada núcleo de procesador), almacenar el identificador de proceso(pid) en un archivo llamado nginx.pid y colocarlo en el directorio /var/run/.
En el bloque events esta worker_connections 768, esto le indica a Nginx que cada proceso atenderá un máximo de 768 conexiones, esto implica, que en este caso limitamos a Nginx a atender un máximo de 4*768=3072 conexiones (max_clients=worker_processes* worker_connections) al mismo tiempo.
Nginx es capaz de manejar mas de 10000 conexiones de manera simultánea pero esto dependerá directamente de los recursos de hardware (procesador, ram, velocidad de disco, ancho de banda) disponibles.
Nota: la formula usada para calcular el número máximo de conexiones cambia si se esta usando Nginx como proxy reverso ya que por defecto el navegador abre dos conexiones por defecto al servidor y hay que considerar las conexiones usadas para la comunicación con los servidores finales (backends), por lo tanto la formula queda max_clients= (worker_processes * worker_connections)/4.
Ahora describiremos brevemente las opciones encontradas en el bloque http:
sendfile (on|off): le dice a Nginx que use el método sendfile() para escribir/leer archivos, sendfile es una función del kernel de linux/unix que mantiene abiertos un descriptor de archivos para lectura y otro para escritura, optimizando de manera significativa estas operaciones.
tcp_nopush (on|off): con esta opción activa Nginx tratará de enviar el encabezado http de respuesta en un solo paquete.
tcp_nodelay (on|off): cuando esta encendida no coloca en un buffer el envío de datos del servidor al cliente.
types_hash_max_size n: Nginx almacena la información estática como nombre de servidor, valores de directivas de mapeado, MIMEs, nombres de encabezados de peticiones, entre otros en tablas de hashes. El tamaño por defecto de estas tablas es de 2048 y según el manual de Nginx solo se cambia en caso de que salga un mensaje pidiendo que se aumente.
server_tokens (on|off): aquí se coloca si se desea que Nginx muestre su número de versión o no (en este caso se puso en off por razones de seguridad).
include /etc/nginx/mime.types: indica la ubicación del archivo con las extensiones multipropósito de correo de Internet (MIME) (http://es.wikipedia.org/wiki/Multipurpose_Internet_Mail_Extensions).
default_type application/octet-stream: esta opción le indica a Nginx que si el cliente solicita un archivo existente en el servidor con una extensión desconocida permitirle descargar el archivo en vez de tratar de ejecutarlo en el servidor.
access_log /var/log/nginx/access.log y error_log /var/log/nginx/error.log: Estas dos indican en que directorio y con que nombre se deben almacenar los registros (logs) de acceso (los cuales indican los datos de los clientes: sistema operativo, navegador, dirección ip, entre otros) y los registros de errores (los cuales muestran los errores ocurridos al servir una página, encontrar un archivo o con el servidor en general).
gzip (on|off): permite activar o desactivar la compresión de los archivos antes de enviarlos al cliente, esta opción es importante debido a que permite ahorrar ancho de banda y contribuye con el aumento de la velocidad de la carga de la página (siempre y cuando se elija un nivel de compresión adecuado).
gzip_disable "msie6": se utiliza para deshabilitar la compresión si el navegador del cliente es internet explorer en su versión 6 y es necesario debido a que éste presenta problemas con los datos comprimidos.
gzip_vary (on|off): los encabezados vary (variables) son utilizados para indicarle a los caches del mundo que información deben almacenar y cual no. Se recomienda que esta opción se mantenga encendida cuando se use compresión.
gzip_types text/plain text/css application/x-javascript application/xml application/json image/png image/gif image/jpeg image/jpg: indica cuales extensiones de archivo deben ser comprimidas.
gzip_comp_level (0 – 9): aquí se define el nivel de compresión que se debe utilizar, es importante destacar que si utiliza un valor muy alto (9) los nodos clientes tardaran mas descomprimiendo el archivo que descargando el original a pesar de su tamaño, si escoge un valor muy bajo (1) el archivo casi no se comprimirá y no obtendrá un beneficio significativo de ahorro de ancho de banda y rapidez en la carga de la página.
gzip_buffers 16 8k: sirve para indicar cuantos buffers se van a crear para almacenar los archivos comprimidos antes de enviarlos y de que tamaño deben ser.
client_body_in_single_buffer (on|off): permite almacenar en un buffer todo el cuerpo de la solicitud del cliente.
client_body_buffer_size nK: especifica el tamaño en kilobytes del buffer que almacena la solicitud del cliente.
client_header_buffer_size nK: indica el tamaño del buffer que almacena el encabezado de la solicitud del cliente.
client_max_body_size nK: sirve para decirle al Nginx que no permita que el cuerpo de la solicitud del cliente exceda los 1024 bytes.
large_client_header_buffers n nK: limita la cantidad de buffers para almacenar encabezados y fija el tamaño maximo de los buffers. En caso de que la petición de un cliente sea mas grande que el tamaño de un buffer Nginx envia un error 414 (URI muy grande) . Si el encabezado de la petición es mas grande que el indicado en esta opción Nginx enviará un error 400 (petición erronea).
client_body_timeout n: especifica el tiempo a esperar para que el cliente envíe el cuerpo de la petición. Se recomienda que no sea demasiado corto porque se los clientes van a obtener muchos timeouts y les costará ver la página. Si se pone muy alto uno o varios clientes le pueden hacer a los servidores una denegación de servicio (quizás usando slowlorris) aparte de que bajo altos niveles de tráfico sera muy lenta la visualización de la página y se consumirán muchos recursos de manera innecesaria.
client_header_timeout n: especifica el tiempo a esperar para que el cliente envíe el encabezado de la petición. Se recomienda que no sea demasiado corto porque se los clientes van a obtener muchos timeouts y les costará ver la página. Si se pone muy alto uno o varios clientes le pueden hacer a los servidores una denegación de servicio (quizás usando slowlorris) aparte de que bajo altos niveles de tráfico sera muy lenta la visualización de la página y se consumirán muchos recursos de manera innecesaria.
keepalive_timeout n: representa el tiempo en segundos que se debe esperar antes de matar una conexión que se encuentra "ociosa" (iddle). En este caso igual que los anteriores un valor muy pequeño enviará demasiados timeouts y dejarlo muy grande consumirá muchos recursos y expondrá al servidor Nginx a una denegación de servicio.
Nota: el hecho de que una conexión este ociosa no significa que sea dañina, puede estar esperando a ser atendidas por un worker de Nginx durante un periodo de mucho tráfico.
send_timeout n: indica cuanto tiempo esperar para que el cliente lea la data que le fue enviada. No aplica para toda la transferencia.
include /etc/nginx/conf.d/*.conf y include /etc/nginx/sites-enabled/*: estas dos opciones le indican al Nginx que el resto de los archivos de configuración se encuentran en las ubicaciones /etc/nginx/conf.d/ y /etc/nginx/sites-enabled/. Permite tener archivos de configuración para cada sitio que se tenga en el servidor (estilo apache).
Los archivos de configuración de los sitios se debe realizar en /etc/nginx/sites-available/ y para activarlos se debe usar ngxensite nombre_de_archivo_de_conf.
A continuación se presentará un archivo de configuración para un sitio llamado foo.bar.com de contenido estático cuyos archivos se encuentran en la carpeta /var/www/foo y se describirán las opciones colocadas:
server {
listen XX.XX.XX.XX:80 default_server;
listen [XXXX:XXXX:XXXX:XXX::XX]:80 default_server;
access_log /var/log/nginx/foo.bar_access.log;
error_log /var/log/nginx/foo.bar_error.log;
server_name foo.bar.com;
root /var/www/foo;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location ~* \.(ico|pdf|flv)$ {
expires 1y;
}
location ~* \.(js|css|png|jpg|jpeg|gif|swf|xml|txt)$ {
expires 14d;
}
location ~ /\.ht {
deny all;
}
}
listen 80 default_server: esta opción es usada para especificar en que dirección IP y puerto debe escuchar Nginx. Si no se especifica la dirección ella escuchará en todas las redes Ipv4 disponibles en el servidor. default_server indica que en caso de que un cliente envie una solicitud al servidor solicitando un sitio desconocido sea redireccionado a este sitio web.Nota: solo puede haber un default_server en ipv4 y uno en ipv6 en Nginx crear mas de uno producirá un error.
listen [::]:80 default_server: esta opción es usada para especificar en que dirección IPv6 y puerto debe escuchar nginx. La dirección [::] significa escuchar en todas las redes Ipv6 disponibles en el servidor.
access_log /var/log/nginx/foo.bar_access.log y error_log /var/log/nginx/foo.bar_error.log: indica donde almacenar los registros del sitio foo.bar.com únicamente.
server_name foo.bar.com: aquí se indica el FQDM (nombre completamente calificado de dominio). Es importante indicar esto sobre todo si se van a colocar multiples servidores web en un mismo Nginx.
root /var/www/foo: en esta opción se coloca en donde esta el directorio raiz del sitio a servir.
index index.html index.htm: se especifica que el archivo a enviar al cliente cuando no este no lo coloque explicitamente es index.html o index.htm.
location /: indica al Nginx que hacer cuando se realiza una petición por parte del usuario del archivo raiz (/).
try_files $uri $uri/ =404: try_files es una función que prueba si un archivo existe, $uri es una variable que almacena la solicitud realizada por el cliente (sin incluir nombre del servidor ni del dominio, ejm: foo.bar.com/teatro/index.html, en este caso $uri tendrá almacenado teatro/index.html), en este caso toda la linea significa prueba si existe el archivo especificado por el cliente, si no existe prueba usando ese nombre como directorio, en caso de no existir ninguno de los dos envia un error 404 (no encontrado) al cliente.
location = /favicon.ico: esto signfica que si en una petición se pide exactamente el archivo favicon.ico ejecutar las instrucciones especificadas en el bloque delimitado entre llaves ({}).
log_not_found off: desactivar en los registros la alerta de que no se encuentra el archivo.
access_log off: no colocar en los registros ningún aviso con respecto a este archivo.
Nota: es recomendable colocar el bloque mostrado anteriormente debido a que si no existe el favicon.ico no ocurrirá nada grave pero los registros se llenaran de alertas de manera innecesaria.
location ~* \.(ico|pdf|flv)$: este bloque es interesante porque aquí se ve de manera explicita el uso de expresiones regulares (http://es.wikipedia.org/wiki/Expresi%C3%B3n_regular). Cuando se coloca el simbolo ~ le estará indicando al Nginx que lo que sigue será una expresión regular, * indica que un carácter que puede aparecer 0, 1 o más veces, \. significa tomar el simbolo "." como literal y (ico|pdf|flv)$ significa que puede terminar en ($) ico, pdf o flv. Ejm: se solicita pelicula.flv, Nginx pasa la solicitud por la expresión regular location ~* \.(ico|pdf|flv)$, los carácteres que encuentra son p,e,l,i,c,u,l,a seguido de un "." luego revisa el final del nombre (flv) por lo tanto ese nombre de archivo va a ejecutar las instrucciones dentro del bloque.
expires 1 y: esta instrucción le indica a los caches del mundo que pueden almacenar los archivos de los tipos especificados por la expresión regular por un lapso máximo de un año.
Similar a la expresión anterior todos los nombre de los archivos que terminen en .js, .css, .png, .jpg, .jpeg, .gif, .swf, .xml o .txt pueden ser almacenados en los caches del mundo por un máximo de 14 dias.
location ~ /\.ht: Esta expresión regular busca todo lo que comience con / seguido de .ht (como por ejemplo el archivo de contraseñas .htpasswd) y la instrucción de adentro deniega el acceso desde cualquier sitio.
Nginx y PHP
Para usar php con Nginx hay que instalar php-fpm (php fastcgi proccess manager) y configurarlo para que todo lo que termine en .php sea enviado a ese programa.
Si colocó los repositorios dotdeb como se recomendo al principio basta con colocar apt-get install php5-fpm para instalarlo.
Despues debe cambiar algunos parámetros dentro de sus archivos de configuración para optimizar su funcionamiento y aumentar su seguridad.
Comenzaremos con el archivo /etc/php5/fpm/php.ini. Aquí cambié las variables por lo siguiente:
date.timezone = America/Caracas
cgi.fix_pathinfo=0
Donde la primera opción evita un error recurrente debido a que se debe especificar la zona horaria en la que se encuentra el servidor (America/Caracas es mi caso ustedes coloquen la zona horaria en la que se encuentre su servidor) y la ultima evita que en sitios donde se permite subir imagenes u otros archivos un kiddie suba un archivo con doble extensión y codigo php malicioso dentro de el y lo pueda ejecutar.Luego vamos a /etc/php5/fpm/php5-fpm.conf y descomentamos y cambiamos lo siguiente:
emergency_restart_threshold 10
emergency_restart_interval 1m
process_control_timeout 10s
Donde emergency_restart_threshold 10 y emergency_restart_interval 1m le indica a php5-fpm que si 10 procesos hijos no responden en un intervalo de tiempo de un minuto debe reiniciar el proceso.
process_control_timeout 10s: tiempo máximo que deben esperar los procesos hijos por una respuesta de su proceso padre.
Ahora solo falta cambiar la configuración de la piscina de procesos de php-fpm para optimizar y evitar que consuma demasiada memoria la aplicación. Ir a /etc/php5/fpm/pool.d/www.conf y cambiar lo siguiente:
listen = /var/run/php5-fpm.sock
pm.max_children = 9
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 400
La primera opción viene por defecto como listen = 127.0.0.19000, esto no es óptimo debido a que usa sockets TCP los cuales son recursos relativamente escasos en entornos virtualizados y posiblemente tarde unas milesimas de segundos mas creando el socket tcp enviando el código php a la red interna para luego recibir la petición y procesar el código php que enviandolo a un socket unix que recibe el código y lo procesa.pm.max_children se utiliza para especificar cuanto es el número máximo de hijos que tendrá un proceso php-fpm en un determinado momento, pm.start_servers dice cuantos procesos hijos se deben tener en standby al arrancar el demonio, pm.min_spare_servers sirve para indicar la cantidad máxima de procesos que deben estar ociosos antes de crear nuevos procesos, pm.max_spare_servers es la cantidad máxima de procesos que deben estar ociosos antes de empezar a matar los procesos y pm.max_requests es la cantidad máxima de peticiones que procesará cada proceso hijo de php-fpm. Cabe destacar que si se clocan valores muy altos aquí se consumirá bastante memoria ram y tiempo de procesador, debido a esto se eligieron estos mínimos que pueden contestar bastantes peticiones sin usar muchos recursos.
Fuente: http://www.if-not-true-then-false.com/2011/nginx-and-php-fpm-configuration-and-optimizing-tips-and-tricks/
Ahora se reinicia php-fpm usando /etc/init.d/php5-fpm restart.
Luego colocamos en los sitios que usen php el siguiente bloque después del location /:
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
fastcgi_split_path_info ^(.+\.php)(/.+)$: esta función se encarga de dividir el URI en dos variables $ fastcgi_script_name y $fastcgi_path_info. La expresión regular que se usa a continuación separa en dos grupos la URI, el primero ^(.+\.php) dice: el primer grupo (^()) debe tener uno o mas caracteres (excluyendo el salto de linea) (.+) seguidos de .php (\.php). El ultimo grupo (()$) empieza con un slah (/) y puede terner uno o mas caracteres excluyendo el salto de linea (.+). Como pueden ver el primer grupo será el nombre del script php y la función lo almacenará en la variable $fastcgi_script_name y el último grupo es el nombre del directorio (/nombre) y se alamacenará en la variable $fastcgi_path_info.fastcgi_pass unix:/var/run/php5-fpm.sock: aquí pasamos el script php al socket unix en donde escucha el php5-fpm.
fastcgi_index index.php: especifica que el archivo que se mostrará cuando no se encuentre el script php especificado por el URI será el index.php.
include fastcgi_params: le dice a Nginx que el resto de los parámetros de configuración se encuentran en el archivo fastcgi_params.
Nginx y Mysql
Para usar mysql se debe instalar el servidor mysql, el cliente mysql y las librerias de manejo de mysql php5-mysql. Esto se hace mediante apt-get install mysql-client mysql-server php5-mysql.
Despues de instalado y para ver si todo salio bien se debe crear un archivo .php que contenga el siguiente codigo:
<? php
phpinfo();
?>
Luego navegamos hacia donde se encuentre el archivo y nos mostrará todas las librerias instaladas en el servidor, allí deberia verse una sección llamada mysql mostrando sus opciones.Joomla
Para servir paginas con joomla hay que asegurarse de que se protejan los directorios images, cache, media, logs y tmp para que ningún usuario malicioso ejecute scripts, esto se logra con la siguiente expresión regular con su bloque de instrucciones despues del location \.php:
location ~* /(images|cache|media|logs|tmp)/.*\.(php|pl|py|jsp|asp|sh|cgi)$
{
return 403;
error_page 403 /403_error.html;
}
location~*/(images|cache|media|logs|tmp)/.*\.(php|pl|py|jsp|asp|sh|cgi)$: significa * cualquier carácter que se repita una o varias veces, seguido de slash (/) que se llame images, cache, media, logs o tmp (images|cache|media|logs|tmp) y le siga otro slash (/) seguido de cualquier carácter que se repita una o varias veces (.*) seguido de un punto (\.) y php, pl, py, jsp, asp, sh o cgi (php|pl|py|jsp|asp|sh|cgi) en su parte final ($) debe ejecutar el bloque de instrucciones return 403 (retornar 403 codigo que indica operación prohibida) y mostrar la pagina 403_error.html.Si es de las personas que le gusta subir los archivos al servidor por medio de Joomla hay altas probabilidades de que el sistema le arroje un error 413 (entidad muy grande). Mi consejo es que suba los archivos por medio de scp o si usa windows como S.O. cliente Winscp. Si su única opción es usar Joomla para subir archivos debe cambiar el valor de client_max_body_size en /etc/nginx/nginx.conf a un valor adecuado para los archivos que normalmente sube. Posiblemente tenga que cambiar el client_body_timeout también.
La mayoría de las descripciones de las opciones fueron tomadas de la pagina http://wiki.nginx.org, la cual es el wiki oficial de Nginx.
EOF

No hay comentarios.:
Publicar un comentario