Archivo de la categoría: Servidor Web

FreeBSD: PHP-FPM y NGINX Página en Blanco | White Page

PHP-FPM Página en Blanco | White Page

He estado montado unos servidores con FreeBSD con NGINX y PHP-FPM y me he encontrado que no funcionaba el PHP con la configuración habitual, tampoco salia nada en los logs, el único síntoma era una página en blanco al acceder a cualquier archivo PHP.

La solución al problema, añadir el PATH_TRASLATED que no esta definido a la configuración de fcgi:

fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;

Esto se tiene que añadir o bien al vhost de la web o directamente en fastcgi_params para que tome efecto en todas las páginas, luego reiniciamos nginx y listo ( no hace falta reiniciar php-fpm)

Configurar ServerLimit en WHM/cPanel Usando MPM_Event [Error]

Bueno hace poco habla de configurar mpm_event y las directivas ServerLimit cosa que pueden ver en este enlace: MPM_Event – MPM_Prefork – Configuración de ServerLimit y MaxClients

Resulta que en cPanel da errores al definir un valor en ServerLimit menor que MaxClients, he reportado el problema en cpanel, que parece que ya han tenido ese problema y lo están investigando, según la respuesta del soporte:

WHM/cPanel MPM_Event Configuración

We are currently tracking the issues with the apache configuration in WHM where certain directives and combinations of values are not possible due to the interface being designed with prefork in mind. For your reference, the case number is 52321. Our developers are already pursuing a resolution. While there is no set timeline for when this issue will be fixed, please note that new patches are advertised in our changelog as soon as they are implemented.

El error es que no se le puede asignar a ServerLimit un valor menor que MaxClients o MaxRequestWorkers ( apache 2.4 ) ya que el sistema esta diseñado para trabajar con Prefork, al intentar cambiarlo nos devuelve el siguiente error:

The following settings are invalid and were rejected:

maxclients: 100

Bien la solución temporal a sido definir el ServerLimit editando el fichero /var/cpanel/conf/apache/local

nano /var/cpanel/conf/apache/local

Definiendo ahí la directiva ServerLimit:

  "serverlimit":
    "item":
      "serverlimit": 40

También podemos editar la directiva MaxClients, luego solo tenemos que actualizarlo:

Con:

/scripts/rebuildhttpdconf

El resultado de que todo a ido bien:

Built /usr/local/apache/conf/httpd.conf OK

Listo ya no nos dará error en WHM al cambiar esa directiva si usamos MPM_Event.

Edito: para configurar otras directivas podemos editar este otro archivo:

/usr/local/apache/conf/includes/pre_main_global.conf

Eso para las directivas que no se pueden editar desde whm.

MPM_Event – MPM_Prefork – Configuración de ServerLimit y MaxClients

Este es solo un pequeño resumen de las directivas de apache, ya que he visto que muchos no saben la diferencia que hay en la configuración del ServerLimit, según el MPM que usamos, ya sea Event o Prefork, así que lo daré con algunos ejemplos:
En Prefork

ServerLimit         256
    MaxClients          150

En event

ServerLimit 40
MaxRequestWorkers 400

Ahí tienen las dos configuraciones normalmente por defecto siempre viene prefork como mpm, por ejemplo en cpanel, la config por defecto es algo así:

 ServerLimit 256
 MaxClients 150

Ahora bien, el punto es que en prefork si subimos el maxclients por encima del ServerLimit no nos dejará iniciar con ese valor y lo dejará igual que ServerLimit.

Esto por que Prefork abre una procesos por conexión.

En Event es diferente, el ServerLimit es la cantidad de servidores que tendremos, puede ser por ejemplo 40 y el MaxRequestWorkers es el número de peticiones que se le podrán hacer a cada uno de esos servidores.

Bien, el problema es cuando en servidores como cpanel cambiamos el mpm_prefork por mpm_worker y dejamos la configuración tal cual estaba, o sea el serverlimit tan alto, por ejemplo que lo tuviéramos en 500, en ese caso apache podrá abrir 500 procesos, esto no es nada bueno, es un consumo de RAM innecesario y si nos hacen muchas peticiones el servidor puede colapsar ya que abrirá muchos procesos en este caso hasta 500 y cada uno podrá aceptar el número de conexiones definido en MaxRequestWorkers.

Bajo ataque o en un pico alto de tráfico será un caos, ya que abrirá todos los procesos que le dejemos.

Event viene siendo como una copia de nginx para que se entienda mejor, en nginx tenemos estas dos directivas que funcionan exactamente igual:

worker_processes 1;
worker_connections 600;

( bueno igual no, por que si lo pones en apache 1 -> 600 no va a funcionar pero en apache ajustas otros valores para compensar, es solo que funciona muy similar )

En ese caso es igual que en event, nginx abrirá un proceso solo y simultáneamente aceptará hasta 600 conexiones ese proceso, si subimos el worker_processes a 2 y dejamos las conexiones a 600 cada procesos aceptara 600 conexiones simultaneas, lo cual nos dará como resultado que en total podremos recibir hasta 1200 peticiones a la vez, de manera similar funciona mpm_event en apache 2.4 ( en los anteriores también pero en esta versión se lanzo event estable )

Aunque en nginx es mucho más sencillo, tiene menos parámetros que definir a diferencia de apache que todo interviene, pero la idea de este tema era explicar esto, ya que es importante explicar lo del cambio a event y las consecuencias que se pueden tener si se dejan los valores iguales a prefork. Pero también cabe mencionar que los demás valores también son importantes y hay que tener cuidado con ellos.

En lo personal me gusta mucho más NGINX para configurar bajo mucho tráfico, hablamos de 5 mil a más peticiones, es mucho más fácil de controlar, con apache hay que trabajar más rato para lograr que este igual de estable que nginx, como dije antes más valores que ajustar en apache.

Por lo demás si buscan una configuración para event usen la default y ajustenla sus necesidades, no copien la primera que vean en internet.

Nginx config para xenforo y phpbb

Nginx vhost para xenforo

server {
    listen   [::]:80;
    server_name  example.com www.example.com;
    root   /var/www/example.com;
    index  index.html index.htm index.php;
    access_log  /var/www/logs/example.com.access.log;  

    location / {
        try_files $uri $uri/ /index.php?$uri&$args;
    }

    location ~ /(internal_data|library) {
         internal;
    }

    location ~ \.php$ {
        fastcgi_pass   unix:/tmp/php.socket;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include fastcgi_params;
    }   
}

Nginx vhots para phpbb

server {
    listen   [::]:80;
    server_name  www.domain.com parkeddomain.com *.parkeddomain.com;
    rewrite ^    http://domain.com$request_uri? permanent;
}

server {
    listen   [::]:80;
    server_name  domain.com;
    root   /var/www/domain.com;
    index  index.php index.html index.htm;
    access_log  /var/logs/domain.com.access.log;

    location ~ /(config\.php|common\.php|cache|files|images/avatars/upload|includes|store) {
        deny all;
        return 403;
    }

    location ~* \.(gif|jpe?g|png|css)$ {
        expires   30d;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass   unix:/tmp/php.socket;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

Los vhost gracias a nginxlibrary.com

Aunque no es muy distinto de los demás, es más que todos los vhost son similares lo que cambia es que nginx no tiene htaccess y se tienen que integrar la reescritura de urls en el vhost directamente, aparte de las rutas de algunos directorios a los que tal vez queremos denegar el acceso, redirigir, pero el principio es el mismo 🙂

Instalar Varnish en Centos 6 con YUM – Repos

Centos siempre pone las cosas complicadas con los repos, no por que sea complicado si no por que nunca tienen nada y cuando no hay tiempo para compilar los repos es la mejor opción.

En este caso los repos de varnish.

Actualmente podemos instalar los repos con este comando:

rpm --nosignature -i http://repo.varnish-cache.org/redhat/varnish-3.0/el6/noarch/varnish-release/varnish-release-3.0-1.el6.noarch.rpm

Mañana puede que ya no, así que si no funciona por que no esta el archivo podemos revisar este otro enlace para ver si a cambiado, ya sea la reversión o lo que sea: Repos varnish

También podemos descargarnos la fuente o bien los RPM desde este otro enlace: RPM de varnish o source code es el mismo enlace de antes solo que un par de niveles más arriba 🙂

Evitar el cacheo en el navegador con htaccess.

Hace tiempo hablamos de como cachear en el navegador o forzar el cacheo del contenido estático por medio de htaccess, podemos verlo aquí: Forzar cacheo de imágenes en el navegador

Si queremos hacer lo contrario podemos usar este otro código:

<FilesMatch "\.(html|htm|js|css)$">
FileETag None
<ifModule mod_headers.c>
Header unset ETag
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 1 han 2000 05:00:00 GMT"
</ifModule>
</FilesMatch>

Con eso evitamos que se cachee el contenido, aunque en el ejemplo solo se previene el cacheo del css, js y los html, esto por ser los archivos más propensos a cambiar y a la vez los que menos ancho de banda gastan, aunque el primer motivo es mas influyente para evitar que se cacheen estos archivos.

Cargar un subdirectorio en el index / con htaccess

Instalar web en subdirectorio pero cargarla en el index

Aveces por ciertas razones necesitamos tener nuestra página web en un subdirectorio y no en el public_html, pero necesitamos que el contenido se vea en el index, ejemplo:

/home/skamasle/public_html -> este es el index skamasle.com

Pero por algún motivo queremos que nuestra web este en:

/home/skamasle/public_html/blog , pero que al entrar a skamasle.com se cargue el contenido de blog sin que aparezca la url skamasle.com/blog.

Pues bien, podemos hacerlo con htaccess de esta manera:

RewriteCond %{HTTP_HOST} ^skamasle.com$ [NC,OR]
RewriteCond %{HTTP_HOST} ^www.pruebas.skamasle.com$
RewriteCond %{REQUEST_URI} !blog/
RewriteRule (.*) /blog/$1 [L]

Otras soluciones

Por la web encontramos otras soluciones como esta:

RewriteEngine On

# Map http://www.example.com to /site.
RewriteRule ^$ /site/ [L]

# Map http://www.example.com/x to /site/x unless there is a x in the web root.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/site/
RewriteRule ^(.*)$ /site/$1

# Add trailing slash to directories within /site
# This does not expose the internal URL.
RewriteCond %{SCRIPT_FILENAME} -d
RewriteRule ^site/(.*[^/])$ http://www.example.com/$1/ [R=301] 

Y una larga discusión sobre el tema en este enlace: http://www.webmasterworld.com/apache/4095623.htm

Otra variante en que encontramos en serverfault:

RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www.)?site.com$
RewriteCond %{REQUEST_URI} !^/subdir/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /subdir/$1
RewriteCond %{HTTP_HOST} ^(www.)?site.com$
RewriteRule ^(/)?$ subdir/index.php [L]

En este enlace: http://stackoverflow.com/questions/990392/htaccess-rewrite-to-redirect-root-url-to-subdirectory

También en el foro de drupal se habla del asunto:

Drupal instalado en subdirectorio pero cargando en el index

https://drupal.org/node/144643
Options -Indexes
RewriteEngine on
Options +FollowSymLinks
RewriteCond %{HTTP_HOST} !^www\.mysite\.com$ [NC]
RewriteRule .* http://www.mysite.com/	[L,R=301]
RewriteRule ^$ drupal/index.php [L]
RewriteCond %{DOCUMENT_ROOT}/drupal%{REQUEST_URI} -f
RewriteRule .* drupal/$0 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* drupal/index.php?q=$0 [QSA]

Forzar las WWW con NGINX

Para forzar que nuestro dominio cargue directamente con las www y evitar algunos errores de «este dominio no esta redirigiendo correctamente» en el caso de wordpress y otros cms en los que en la configuración ponemos que cargue con www pero que aún así a veces deja acceder sin las www, en nginx basta con una redirección:

Con este código lo solucionamos:

Redirigir a WWW con NGINX

server {
    listen       80;
    server_name  skamasle.com;
    return       301 http://www.skamasle.com$request_uri;
}

Pero es importante tener dos directivas server, un ejemplo, una directiva normal puede ser:

server {
        listen *:80;
        server_name skamasle.com www.skamasle.com;
        root   /var/www/web;
        index index.html index.htm....................... etc
}

O sea en server_name definidos los dos dominios, así que tenemos que separar a una directiva aparte, skamasle.com en una sección server para hacer la redirección y www.skamasle.com en la directiva server principal si no, no funciona.

NOTA para versiones viejas de nginx se usaba rewrite:

server {
    server_name  skamasle.com;
    rewrite ^(.*) http://www.skamasle.com$1 permanent;
}

Usar rewrite es menos eficiente, aunque ya nadie usa versiones viejas de nginx y con el return no tendremos problemas en ninguna versión.

Quitar las WWW con nginx

server {
    server_name www.skamasle.com;
    return 301 $scheme://skamasle.com$request_uri;
}

Htaccess – Redirección y Hotlink

Un post rápido..

Prevenir hotlink y enviar una imagen cualquier en vez de la original:

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?dominio\.com/.*$ [NC]
RewriteRule .*\.(gif|jpe?g|png)$ http://www.EnlaceANuevaImagenParaQueAparezcaEnvezDeLaQueEnlazan/no.jpg [R,NC,L]

Redirrección 301 de dominio (cambio de dominio)

RewriteEngine on
RewriteRule (.*) http://www.dominio.com/$1 [R=301,L] 

Solución a: Leverage browser caching – Cachear las imágenes en el navegador

Si usan el gmetrix o usan el page speed de google, puede que se tomen con un error como este

Leverage browser caching

Esto lo que nos dice es que nuestra web no le dice al navegador que guarde el contenido estático, o sea cada vez que una visita vuelve a entrar a nuestra web carga las imágenes, al menos que le navegador tenga la opción de cachear activada por defecto.

Si tenemos mod_expires activado en nuestro servidor podemos usar este código:

<IfModule mod_expires.c>
  ExpiresActive on

# Your document html
  ExpiresByType text/html "access plus 0 seconds"

# Media: images, video, audio
  ExpiresByType audio/ogg "access plus 1 month"
  ExpiresByType image/gif "access plus 1 month"
  ExpiresByType image/jpeg "access plus 1 month"
  ExpiresByType image/png "access plus 1 month"
  ExpiresByType video/mp4 "access plus 1 month"
  ExpiresByType video/ogg "access plus 1 month"
  ExpiresByType video/webm "access plus 1 month"

# CSS and JavaScript
  ExpiresByType application/javascript "access plus 1 year"
  ExpiresByType text/css "access plus 3 month"
</IfModule>

Con esto forzamos al navegador a cachear nuestro contenido estático y dejarlo guardado por un mes, así que si una visita entra seguido a nuestra web no tendrá que descargar todo el contenido cada vez que entra y así navegará más rápido.