Nginx vs Apache con PHP

A pesar de lo pretensioso que se lee nginx vs apache he estado haciendo pruebas a estos 2 servidores WEB y el resultado podría no ser tan favorable para Nginx

Mi opinión con NginX es como la de Qmail, fue una moda creada debido a que muchos les gusta adoptar soluciones que no son propias para el proyecto. por ejemplo muchos Sendmail fueron sustituidos por Qmail hace unos 15 años ¿por que? ¿por que Sendmail no hacia bien su trabajo? no. El asunto era por que hotmail usaba en sus servidores de correo Qmail.

Asi paso con GNU/Linux, muchos Linux fueron sustituidos por FreeBSD solo por que yahoo y otros portales de la época usaban FreeBSD como OS y asi hay varios ejemplos.

Como modas que son terminaron pasando y las aguas volvieron a su cauce y todo de nuevo normal.

Actualmente veo que existe mucho movimiento con el NginX , incluso he visto comparaciones tramposas donde un Apache cargado con N cantidad de módulos es puesto a competir contra un Nginx que solo sirve paginas HTML, no PHP, no ASPX, no perls, no cgis, NADA!!! es una comparación un poco injusta ya que si liberamos a apache de la carga modular sin duda podría comportarse como un Nginx o incluso mejor. pero mejor un poco de detalle

NginX

Es un ligero servidor WEB con pocas funcionalidades y las que tiene son delegadas como la ejecución de PHP, una delegación que tiene problemas de seguridad

Delegación de PHP

No tiene un modulo de PHP que trabaje directamente la interpretación del PHP se tiene que delegar a un proceso externo del PHP con el método de
FPM (FastCGI Process Manager)

es un FastCGI pero orientado a sesión de red, como las X de X-Windows, donde un programa no accede directamente a la tarjeta de video sino entrega sus datos por red en localhost, así mismo hace FPM.

Esto tiene ciertas ventajas, por ejemplo es posible crear servidores y clusterizarlos para altar cargas de trabajo ya que podría tener cientos de servidores WEB dedicados a ejecutar PHP como único propósito dejando la parte de entrega de información solo al servidor WEB.

Este método tiene un alto costo de seguridad y de rendimiento cuando todo se ejecuta en una misma máquina, no tiene sentido usar FPM si tanto el servidor WEB y el php se ejecutan en la maquina y se usan de forma local por que el acceso al FPM es atreves de conexión de red dando por lo tanto una latencia y causando los problemas que el X le causa al entorno grafico pero en este caso en el despacho de páginas WEB.

Que nos da a cambio, el proceso es independiente y el que un proceso PHP se bloquee no afecta de ninguna forma al servidor WEB aunque esto no es del todo una ventaja y pronto cuando le toque a Apache comparare estos párrafos, a lo mucho su ventaja se limita a protección de memoria, es decir. Tener un usuario para el servidor WEB y un usuario para el PHP de forma que si un Script en PHP es vulnerable no pueda afectar de ninguna forma a otros sitios archivos alojados en el servidor. Por lo que si incrementa la seguridad cuando de PHP se trata sin embargo deja una vulnerabilidad en el servidor WEB

Volviendo a NginX al delegar la parte PHP lo hace más liviano rápido en si mismo pero lento en el cuello de botella al mandar por red los datos php y esperar la respuesta y su propia seguridad se entrega como pago Nginx y PHP en la misma maquina no tiene sentido y el costo de seguridad es alto y la supuesta velocidad ganada se pierde en el cuello de botella de la sesión de red

NginX no cuenta prácticamente con ningún modulo, solo tiene funciones básicas de rewrite y ssl por lo que toda la configuración incluso la de las maquinas virtuales se puede hacer en poquito más de 50 líneas

     
      1 user  web;
      2 worker_processes  1;
      3
      4 events {
      5    
worker_connections  1024;
      6 }
      7
      8
      9 http {
     10    
include       mime.types;
     11     default_type 
application/octet-stream;
     12
     13    
sendfile        on;
     14
     15    
keepalive_timeout  65;
     16
     17     server {
    
18        
listen       80;
    
19         server_name 
localhost;
     20
    
21         location / {
    
22            
root   /usr/ngix1.2.0/exechtml;
    
23            
index  index.html index.htm;
    
24         }
     25
    
26        
error_page   500 502 503 504  /50x.html;
    
27         location = /50x.html
{
    
28            
root   html;
    
29         }
     30
     31     }
     32
     33
     34     server {
    
35        
listen       80;
    
36         server_name 
lastdragon.net  alias  www.lastdragon.net;
     37
    
38         location / {
    
39            
root   /paginas/lastdragon/html;
    
40            
index  index.html index.php;
    
41         }
     42
    
43          location ~
\.php$ {
    
44            
fastcgi_pass   127.0.0.1:9000;
    
45            
fastcgi_index  index.php;
    
46            
fastcgi_param  SCRIPT_FILENAME 
/paginas/lastdragon/html/$fastcgi_script_name;
    
47            
include        fastcgi_params;
    
48         }
     49
    
50         location 
/wp-admin  {
    
51        
auth_basic           
.Restricted.;
    
52        
auth_basic_user_file  /.htaccess;
     53
    
54         }

Apache Web Server

Apache es un servidor WEB maduro y poderoso tal poder requiere de modularizar funciones, sin embargo esta característica modular le permitiría quitarse todos los módulos que le dan poder y ser robusto y quedar tan liviano o mas que el NginX un Apache compilado sin prácticamente nada da el mismo resultado que NginX en rendimiento pero realmente nadie quiere quitarle esas funcionalidades al Apache, seria absurdo, la seguridad del sitio está en esos módulos que de hecho no lo hacen tan lento como para justificar una migración a NginX o a otro servidor WEB

Apache WEB Server con PHP

Apache de la serie 1.3.X podía compilarse con el PHP incrustado, era parte del código de PHP esto lo hacía verdaderamente rápido ya que incluso la parte PHP estaba en RAM junto con la parte del servidor WEB, es posible que nunca haya sido mas rápido el PHP y Apache como en esa serie. Sin embargo en la serie 2.X.X se reescribió Apache y el PHP tuvo que funcionar únicamente como un modulo, sin embargo el modulo aun siendo código externo al cargarse queda en RAM y todos sabemos que dentro de la PC la RAM y el CPU son uña y mugre por lo tanto, unos cuantos punteros y se mueve información tan rápido como no se puede hacer por ningún otro medio, al estar cargado PHP en RAM el apache solo tiene que enviar por RAM y los datos del Script PHP y esperar por RAM la respuesta del PHP algo realmente rápido ya que no existe la latencia de bajar estos movimientos a la capa de Red del sistema operativo como todos sabemos más capaz en el proceso significan mayor latencia al tener que atravesar capa por capa.

Cuando de PHP se habla la carga de los módulos adicionales de PHP se ve amortiguada en cuanto a la rapidez y flujo de ejecución de PHP , lo inverso en NginX su velocidad adicional se ve mermada al pasar por las capas de Red y ni siquiera hablamos de que termina los datos en UDP, no señor. TCP con todo y el ritual de sesión que eso involucra porque TCP se requiere por seguridad

Aunque de forma simple el PHP configurado en Apache usa la misma memoria que Apache, esto nos deja un poco vulnerables con un Script PHP mal hecho, sin embargo se pueden aplicar otros medios de seguridad e incluso asignarle por código un usuario diferente al ejecutar el PHP aunque prácticamente ningún programador hace eso y deja la seguridad del lado del administrador del servidor.

Un servidor WEB Apache con algunos módulos básicos son por mucho mas de 100 líneas, son tantas que incluso la configuración debe ser modular con un archivo para los Vhost , otro para SSL, otro para el manejo de sesiones TCP tanto al menos unas 150 líneas de configuración repartidas en varios archivos, esta complejidad que de hecho no lo es tanto nos da como recompensa un sitio mas seguro

El siguiente httpd.conf no incluye los módulos .conf de vhost pero ni ssl pero sera suficiente para probar el punto.

     1 ServerRoot “/usr/apache2.4.2”
      2
      3 Listen 80
      4
      5 LoadModule authn_file_module
modules/mod_authn_file.so
      6 LoadModule authn_core_module
modules/mod_authn_core.so
      7 LoadModule authz_host_module
modules/mod_authz_host.so
      8 LoadModule authz_groupfile_module
modules/mod_authz_groupfile.so
      9 LoadModule authz_user_module
modules/mod_authz_user.so
     10 LoadModule authz_core_module
modules/mod_authz_core.so
     11 LoadModule access_compat_module
modules/mod_access_compat.so
     12 LoadModule auth_basic_module
modules/mod_auth_basic.so
     13 LoadModule socache_shmcb_module
modules/mod_socache_shmcb.so
     14 LoadModule socache_dbm_module
modules/mod_socache_dbm.so
     15 LoadModule reqtimeout_module
modules/mod_reqtimeout.so
     16 LoadModule filter_module
modules/mod_filter.so
     17 LoadModule mime_module modules/mod_mime.so
     18 LoadModule log_config_module
modules/mod_log_config.so
     19 LoadModule env_module modules/mod_env.so
     20 LoadModule headers_module
modules/mod_headers.so
     21 LoadModule setenvif_module
modules/mod_setenvif.so
     22 LoadModule version_module
modules/mod_version.so
     23 LoadModule ssl_module modules/mod_ssl.so
     24 LoadModule unixd_module modules/mod_unixd.so
     25 LoadModule status_module
modules/mod_status.so
     26 LoadModule autoindex_module
modules/mod_autoindex.so
     27 LoadModule dir_module modules/mod_dir.so
     28 LoadModule alias_module modules/mod_alias.so
     29 LoadModule
php5_module        modules/libphp5.so
     30
     31 <IfModule unixd_module>
     32 User web
     33 Group web
     34
     35 </IfModule>
     36
     37 ServerAdmin you@example.com
     38
     39 <Directory />
     40     AllowOverride none
     41     Require all denied
     42 </Directory>
     43
     44 DocumentRoot “/usr/apache2.4.2/htdocs”
     45 <Directory “/usr/apache2.4.2/htdocs”>
     46     Options Indexes
FollowSymLinks
     47     AllowOverride None
     48     Require all granted
     49 </Directory>
     50
     51 <IfModule dir_module>
     52     DirectoryIndex
index.html index.php
     53 </IfModule>
     54
     55 <Files “.ht*”>
     56     Require all denied
     57 </Files>
     58
     59 ErrorLog “logs/error_log”
     60
     61 LogLevel warn
     62
     63 <IfModule log_config_module>
     64     LogFormat “%h %l %u
%t \”%r\” %>s %b \”%{Referer}i\” \”%{User-Agent}i\”” combined
     65     LogFormat “%h %l %u
%t \”%r\” %>s %b” common
     66
     67     <IfModule
logio_module>
     68      
LogFormat “%h %l %u %t \”%r\” %>s %b \”%{Referer}i\”
\”%{User-Agent}i\” %I %O” combinedio
     69     </IfModule>
     70
     71     CustomLog
“logs/access_log” common
     72
     73 </IfModule>
     74
     75 <IfModule alias_module>
     76     ScriptAlias
/cgi-bin/ “/usr/apache2.4.2/cgi-bin/”
     77
     78 </IfModule>
     79
     80 <IfModule cgid_module>
     81 </IfModule>
     82
     83 <Directory “/usr/apache2.4.2/cgi-bin”>
     84     AllowOverride None
     85     Options None
     86     Require all granted
     87 </Directory>
     88
     89 <IfModule mime_module>
     90     TypesConfig
conf/mime.types
     91     AddType
application/x-compress .Z
     92     AddType
application/x-gzip .gz .tgz
     93     AddType
application/x-httpd-php .php
     94
     95 </IfModule>
     96
     97 # Virtual hosts
     98 Include conf/extra/httpd-vhosts.conf

El siguiente video muestra como esas 2 configuraciones pueden ser un detrimento de seguridad en el caso de NginX

¿Por que NginX falla en algo tan simple?

El problema está en la delegación de responsabilidad en la zona de configuración

 43          location
~ \.php$ {
    
44            
fastcgi_pass   127.0.0.1:9000;
    
45            
fastcgi_index  index.php;
    
46            
fastcgi_param  SCRIPT_FILENAME 
/paginas/lastdragon/html/$fastcgi_script_name;
    
47            
include        fastcgi_params;
    
48         }

Esta linea rompe con la seguridad, debido a que se le dice protege esta carpeta..

 50         location 
/wp-admin  {
    
51        
auth_basic           
.Restricted.;
    
52        
auth_basic_user_file  /.htaccess;
     53
    
54         }

y al PHP se le dice ejecuta despues de esta carpeta y wp-admin esta despues de esa carpeta

fastcgi_param SCRIPT_FILENAME /paginas/lastdragon/html/fastcgi_script_name

En la parte de PHP le dice ejecuta todo después de este punto, al no estar coordinados el NginX protege su carpeta pero el PHP no sabe que NginX no quiere que se ejecute nada después de esa carpeta si no se da primero las credenciales correctas esto es porque el PHP no es parte del NginX es un proceso delegado, en apache no ocurre por que tanto el Apache como el PHP son el mismo proceso y por lo tanto PHP sabe que Apache no desea que ningún dato se lea de la carpeta

Todas las delegaciones como la de PHP tendrán como resultado hoyos en la seguridad

Y sin embargo a mí se me hace un error fatal que NginX permita la ejecución incluso como un delegado porque finalmente la solicitud de ejecución viene del navegador y la recibe el NginX, esto me dice que el NginX tiene poco código pero que esta programado por con las patas. Tan simple que sería no entregarle la ejecución al PHP-FPM

Como esta hoy el mundo de los servidores WEB

Apache nunca ha dejado de ser el rey indiscutido, esto es debido a que los administradores saben que es una gran pieza a la hora de despachar paginas WEB incluso si por seguridad debe cargar con módulos, en el 2007 Internet Information Server estuvo muy cerca de Apache como nunca antes un servidor WEB lo estuvo, sin embargo después del 2008 la gente perdió el interés y regreso a Apache.

Esto nos da muchos diagnósticos, aunque apache puede ejecutar .NET y ASPX con Mono, la realidad es que muy pocos sitios usan .NET porque su plataforma nativa es Windows con IIS y es obvio que si el total de IIS es mínima entonces los sitios con ASPX también son mínimos.

Por lo que en PHP vs (.NET C# ASPX)

PHP le pone una brutal paliza a .NET en el área de páginas WEB

Esta es la grafica de cómo se veía la guerra de servidores web en hace unos años


Ver mas grande

Y así se ve hoy en el 2012-05-14


Ver mas grande

10 Comments

Add a Comment

Comment spam protected by SpamBam