jueves, 4 de septiembre de 2014

Apache, el amigo de los niños, pero ...cuando te haces mayor?

Apache, una nueva herramienta... que os voy a decir de Apache? Todos sabemos instalarlo, todos sabemos administrar nuestros vhosts y habilitar nuestros módulos, pero... y cuando el webserver es pieza clave para la organización, y procesa cientos, miles de conexiones por hora? Estamos sacando el máximo provecho de nuestros recursos hardware?.

Quiero aclarar que no soy un experto en Apache, es más, ni me gusta !!! Prefiero de calle las nuevas versiones de IIS 8 o Nginx como webserver, pero por casualidades de la vida me ha tocado ir un poco mas allá del apt-get apache.

************************************************************
Microsoft, el malo de la película. Las pantallas azules. Los problemas de seguridad. La falta de consola de scripting...Si, en el 2000, en 2005, en 2010, pero vivimos en 2014, las cosas evolucionan y Microsoft por mucho que no le guste a muchas gente, es referente o por qué no decirlo líder en casi todo lo que hace. En 5 años se ha puesto a la par en virtualización frente a Vmware, y en unos años sobrepasará a los "esx" como solución completa de virtualización de escritorio, servidores y cloud.


Para terminar esta reflexión, cual es el servidor web más instalado ahora mismo?

http://news.netcraft.com/archives/2014/07/31/july-2014-web-server-survey.html
**************************************************************************

Un clásico en la monitorización de Apache es Mod Status. Sencillo de configurar nos presenta una web con información importante en tiempo real de los procesos e hilos abiertos por Apache.



Si, el google dorks es este xD: google: inurl:"server-status" site:.es

Con este otro comando lanzamos un número de conexiones contra un objetivo, indicándole el número máximo de concurrentes.

-n requests     Number of requests to perform
    -c concurrency  Number of multiple requests to make
    -t timelimit    Seconds to max. wait for responses
    -b windowsize   Size of TCP send/receive buffer, in bytes
    -p postfile     File containing data to POST. Remember also to set -T
    -u putfile      File containing data to PUT. Remember also to set -T
    -T content-type Content-type header for POSTing, eg.
                    'application/x-www-form-urlencoded'
                    Default is 'text/plain'
    -v verbosity    How much troubleshooting info to print
    -w              Print out results in HTML tables
    -i              Use HEAD instead of GET
    -x attributes   String to insert as table attributes
    -y attributes   String to insert as tr attributes
    -z attributes   String to insert as td or th attributes
    -C attribute    Add cookie, eg. 'Apache=1234. (repeatable)
    -H attribute    Add Arbitrary header line, eg. 'Accept-Encoding: gzip'
                    Inserted after all normal header lines. (repeatable)
    -A attribute    Add Basic WWW Authentication, the attributes
                    are a colon separated username and password.
    -P attribute    Add Basic Proxy Authentication, the attributes
                    are a colon separated username and password.
    -X proxy:port   Proxyserver and port number to use
    -V              Print version number and exit
    -k              Use HTTP KeepAlive feature
    -d              Do not show percentiles served table.
    -S              Do not show confidence estimators and warnings.
    -g filename     Output collected data to gnuplot format file.
    -e filename     Output CSV file with percentages served
    -r              Don't exit on socket receive errors.
    -h              Display usage information (this message)
    -Z ciphersuite  Specify SSL/TLS cipher suite (See openssl ciphers)
    -f protocol     Specify SSL/TLS protocol (SSL2, SSL3, TLS1, or ALL)


ab -n 500 -c 200 http://url:80/index.html

De esta manera podemos monitorizar un poco el comportamiento de nuestro webserver ante la carga esperada. Esta prueba no es real del todo ya que un webserver expuesto a Internet, con cientos/miles de conexiones de distintas ubicaciones se comporta de distinta manera. Este simple comando nos puede servir para realizar un DOS sobre un web server mal configurado xD.

La salida del comando podría ser esta:


Server Software:        ***********
Server Hostname:        **********
Server Port:            80

Document Path:          /index.php
Document Length:        54819 bytes

Concurrency Level:      100
Time taken for tests:   6.333 seconds
Complete requests:      500
Failed requests:        0
Write errors:           0
Non-2xx responses:      502
Total transferred:      27618082 bytes
HTML transferred:       27436860 bytes
Requests per second:    78.95 [#/sec] (mean)
Time per request:       1266.636 [ms] (mean)
Time per request:       12.666 [ms] (mean, across all concurrent requests)
Transfer rate:          4258.65 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       38   42   3.1     41      55
Processing:   342  680 589.7    519    4826
Waiting:      171  500 587.6    339    4660
Total:        382  722 589.7    559    4867

Percentage of the requests served within a certain time (ms)
  50%    559
  66%    657
  75%    740
  80%    767
  90%    909
  95%   1867
  98%   3534
  99%   4111
 100%   4867 (longest request)

Aunque los datos son reveladores, podemos leer los detalles de la salida aquí mismo.
Por curiosidad prueba a deshabilitar el EngineMode en Mod security, si lo usas, y haz el mismo test. Podrás ver al impacto sobre el servidor, alrededor del 1%.

Para realizar esta aproximación debemos hacerla en varios momentos del día, para intentar medir las respuestas del server en distintos "workload".

Podría ser interesante lanzar el test después de usar el siguiente comando, para tener una base de referencia de la actividad "real" del servidor, no podemos esperar resultados homogéneos si lanzamos el test en máxima carga de producción, o en horas que apenas hay actividad.

netstat -plan|grep :80|awk {'print $5'}|cut -d: -f 1|sort|uniq -c|sort -nk 1

Vemos el número de procesos por cada ip conectada al puerto 80.

Otro comando MUY útil para calcular la carga media de procesos de Apache. No es lo mismo una petición de contenido estático tipo imágen, o un script que realizar operaciones criptográficas.

ps -ylC httpd | awk '{x += $8;y += 1} END {print "Apache Memory Usage (MB): "x/1024; print "Average Proccess Size (MB): "x/((y-1)*1024)}'

Con este comando vamos a establecer una base para acercarnos a la configuración óptima de nuestro webserver. Nos indica la suma de todos los procesos httpd y la media de cada uno. Válido para todos los procesos, interesante comando.

La optimización de Apache es algo complejo que se me escapa de las manos, pero puedes leer recomendaciones de los experos sobre el uso del módulo prefork y la configuración óptima.
Para no reinventar la rueda os recomiendo este artículo.

Como os decía, el propósito de este post no es dar una Master Class de Apache Tunning, porque como en todo, hay que ser un poco experto en el tema, pero espero que os sirva para daros una aproximación sobre como medir el rendimiento y qué cosas mirar.

Gracias por leerme !!!