Archive for the ‘Apache’ Category

Rotar log en Apache

Friday, January 11th, 2008

Hay varias maneras de rotar logs, pero voy explicar como hacerlo con una utilidad llamada rotatelogs. El post se basa en una distribución Debian y Apache 2. Esta utilidad la podemos encontrar en el paquete apache2-utils, lo instalaremos


$ aptitude install apache2-utils

Una vez instalado tenemos que verificar la ruta en donde se instaló, utilizaremos el siguiente comando


# whereis rotatelogs
rotatelogs: /usr/sbin/rotatelogs /usr/share/man/man8/rotatelogs.8.gz

La salida del comando nos indica que el binario esta en la carpeta /usr/bin, la otra ruta es la entrada en el man lo cual no nos sirve.

whereis es un comando que sirve para localizar archivos binarios, fuentes o páginas de manual.

Luego nos vamos a los archivos de configuración de nuestro servidor en /etc/apache2/sites-enabled/ (ver comentario de este post) y en mi caso edito el archivo de configuración default agregando la siguiente linea


<VirtualHost *>
...
TransferLog "|usr/sbin/rotatelogs /var/log/apache2/error.log 100M"
...
</VirtualHost>

Nota: también se podría haber editado el archivo apache2.conf que se encuentra /etc/apache2, debido al contexto de la directiva.

Expliquemos un poco lo que hemos hecho, la directiva TransferLog le dice a Apache que “entube” la información del log a un programa externo (por eso el signo | al comienzo), el programa lo indicamos entre comillas que en este caso es rotatelogs y luego indicamos los parametros propios de rotatelogs, la ruta del log que rotaremos (/var/log/apache2/error.log) y el tamaño que tendrá el archivo para ser rotado(100M), 100 MegaBytes.

En vez de especificar un tamaño para el rotado, se puede también indicar un tiempo, por ejemplo cada 1 semana


TransferLog "|usr/sbin/rotatelogs /var/log/apache2/access.log 604800"

Nota: el tiempo de rotado se especifica en segundos, en el ejemplo tenemos 7 * 24 * 60 * 60

Y para terminar, al rotar los log podríamos agregarle la fecha en que se roto, para tener más control


 TransferLog "|usr/sbin/rotatelogs /var/log/apache2/%y%m%d_error.log 5M"

Al rotar nos quedaría un archivo como 080101_error.log, %y indica el año en dos dígitos, %m indica el mes con dos dígitos y %d indica el día con dos dígitos.

¿Cómo saber que versión de Apache tenemos instalada?

Friday, January 11th, 2008

Hay varios métodos para determinarlo, veamos algunas formas:

SI tenemos instalado Apache 2, contamos con una excelente herramienta, apache2ctl (ubicada en /usr/sbin). Es un front end (interface) para el servidor Apache, esta diseñada para ayudar al administrador controlar las funcionalidades de el demonio httpd Apache. Apache2ctl, tiene dos modos de operar, acá usaremos uno de ellos, porque el otro tiene que ver con el script de inicio. La salida de apache2ctl esta en función de los parámetros pasados, con uno de éstos (v) podemos obtener la versión de Apache 2 que tenemos instalada.


$ apache2ctl -v
Server version: Apache/2.2.3
Server built:   Nov 01 2006 10:14:00

Si utilizamos la opción V (mayúscula) además de la versión nos da información de las opciones establecidas en la compilación.


$ apache2ctl -V
Server version: Apache/2.2.3
Server built:   Nov 01 2006 10:14:00
Server’s Module Magic Number: 21053335:3
Server loaded:  APR 1.2.7, APR-Util 1.2.7
Compiled using: APR 1.2.7, APR-Util 1.2.7
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
 -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
 -D APR_USE_SYSVSEM_SERIALIZE
 -D APR_USE_PTHREAD_SERIALIZE
 -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
 -D APR_HAS_OTHER_CHILD
 -D AP_HAVE_RELIABLE_PIPED_LOGS
 -D DYNAMIC_MODULE_LIMIT=128
 -D HTTPD_ROOT=”"
 -D SUEXEC_BIN=”/usr/lib/apache2/suexec”
 -D DEFAULT_PIDLOG=”/var/run/apache2.pid”
 -D DEFAULT_SCOREBOARD=”logs/apache_runtime_status”
 -D DEFAULT_LOCKFILE=”/var/run/apache2/accept.lock”
 -D DEFAULT_ERRORLOG=”logs/error_log”
 -D AP_TYPES_CONFIG_FILE=”/etc/apache2/mime.types”
 -D SERVER_CONFIG_FILE=”/etc/apache2/apache2.conf”

Para mayor información sobre está herramienta se puede consultar la página del proyecto Apache o apache2ctl -h.

Está forma depende de la versión 2 de Apache, podríamos utilizar algo más genérico. Una herramienta fantástica para determinar las versiones de los servicios que corren en una máquina es nmap. En casi todas las distribuciones de GNU/Linux viene instalada, sino lo instalamos (el programa sólo ocupa 434K), si estamos en Debian (o algún fork) aptitude install nmap. Para ver la versión del servidor utilizaremos la opción detección de versiones(sV) de nmap.


$ nmap -sV localhost
Interesting ports on beirut.dattaweb.com (127.0.0.1):
Not shown: 1689 filtered ports
PORT    STATE  SERVICE  VERSION
20/tcp  closed ftp-data
21/tcp  open   ftp      ProFTPD 1.3.0a
25/tcp  open   smtp     Exim smtpd 4.63
53/tcp  closed domain
80/tcp  open   http     Apache httpd 1.3.37
110/tcp open   pop3     Courier pop3d
143/tcp open   imap     Courier Imapd (released 2004)
443/tcp open   http     Apache httpd 1.3.37
Service Info: OS: Unix

En éste caso tengo un Apache versión 1.3.37 escuchando en el 80.

Nota:Este método puede fallar, si tenemos deshabilitada la firma del servidor http. Cómo determinarlo.

Ocultando PHP

Friday, January 4th, 2008

En un anterior post expliqué cómo ocultar los detalles de versión que suministraba Apache en las cabeceras de solicitud HTTP. Ahora si tenemos PHP instalado, hay información de éste dentro de la cabecera, que puede resultar de ayuda a un cracker.

Una cabecera sin la firma del servidor web pero con información de PHP luce así


HTTP/1.0 200 OK
Date: Fri, 04 Jan 2008 14:25:36 GMT
Server: Apache
X-Powered-By: PHP/5.2.1
X-Pingback: http://localhost
Connection: close
Content-Type: text/html; charset=UTF-8

Para deshabilitar esa información hay que ir a /etc/php5/apache2 y editamos el archivo php.ini


#nano php.ini

Ahora debemos cambiar el valor de la opción expose_php de On a Off


; Misc
;
; Decides whether PHP may expose the fact that it is installed on the server
; (e.g. by adding its signature to the Web server header).  It is no security
; threat in any way, but it makes it possible to determine whether you use PHP
; on your server or not.
expose_php = Off

Guardamos la nueva configuración y reiniciamos el servidor


#etc/init.d/apache2 restart

Y listo, ahora podríamos hacer una prueba para ver si no es suministrada la información de PHP.


#telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
HTTP/1.0 200 OK
Date: Fri, 04 Jan 2008 14:29:24 GMT
Server: Apache
X-Pingback: http://localhost
Connection: close
Content-Type: text/html; charset=UTF-8

A desaparecido el campo X-Powered-By, el cuál informaba sobre PHP.

Ajustar concurrencia en Apache

Friday, December 28th, 2007

Leyendo descubrí esta fantástica herramienta llamada ApacheBench que viene junto a Apache. Con ella podemos determinar la performance de nuestro servidor. Como dice el man de apachebench: “Especialmente te muestra como muchas solicitudes por segundo es capaz de servir tu instalación de Apache”. Mediante la salida de está herramienta podremos saber cómo configurar correctamente el módulo MPM que tengamos compilado. El modulo MPM que tengamos compilado por default depende del sistema operativo

Modulos MPM según la plataforma
SO MPM
BeOS beos
Netware mpm_netware
OS/2 mpmt_os2
Unix prefork worker
Windows mpm_winnt

Para saber que MPM tiene nuestro servidor, ejecute

 #apache2ctl -l
...
mod_logio.c
prefork.c
http_core.c
…

A ver veamos un poco de teoría para saber como funcionan MPM. Un servidor web pre-forking, no maneja hilos para atender a las solicitudes. En cambio las solicitudes son tratas de una manera similar a como lo hacía Apache 1.3, creando un nuevo proceso hijo por cada una. La ventajas de esto es que si surge un problema con una solicitud, esta no afecta al resto, ya que cada proceso hijo es independiente del resto y maneja una única solicitud, por lo tanto ganamos en estabilidad. Una desventaja es que perdemos escalabilidad. La creación de procesos es muy lenta, comparada con la de hilos, por lo tanto para tratar varias solicitudes simultaneas este modelo no es muy adecuado. También es importante notar que todos los hilos de un mismo hilo comparten sus recursos, logrando que los hilos sean más “livianos” que los procesos. Por ejemplo un servidor web threaded, maneja varias solicitudes en un solo proceso hijo, por cada solicitud el proceso hijo le asigna un hilo, de esta manera dentro de un hijo hay varios hilos, si uno tiene un problema afecta al al hijo y a todos sus hilos.

En el archivo de configuracion de apache (/etc/apache2/apache2.conf) tenemos la siguiente configuración de MPM


    StartServers          5
    MinSpareServers       5
    MaxSpareServers      10
    MaxClients          150
    MaxRequestsPerChild   0

Ahora haremos una prueba con apachebench, haremos 100 solicitudes concurrentes y en total 200 solicitudes y veremos como responde el servidor

ab -n 200 -c 100 http://localhost

la salida es


Completed 100 requests
Finished 200 requests

Server Software:        Apache/2.2.4
Server Hostname:        localhost
Server Port:            80

Document Path:          /
Document Length:        153 bytes

Concurrency Level:      100
Time taken for tests:   0.117805 seconds
Complete requests:      200
Failed requests:        0
Write errors:           0
Total transferred:      82205 bytes
HTML transferred:       31365 bytes
Requests per second:    1697.72 [#/sec] (mean)
Time per request:       58.902 [ms] (mean)
Time per request:       0.589 [ms] (mean, across all concurrent requests)
Transfer rate:          679.09 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    9   8.2      6      18
Processing:     6   37  18.5     41      61
Waiting:        3   35  18.1     39      59
Total:         22   47  11.8     53      70

Percentage of the requests served within a certain time (ms)
  50%     53
  66%     54
  75%     55
  80%     57
  90%     60
  95%     61
  98%     61
  99%     62
 100%     70 (longest request)

Un parámetro a tener en cuenta es Request per second, que en este caso dio 1697.72. Variando los valores de las directivas MPM, por ejemplo MaxClients, y ejecutando nuevamente apachebench, el valor de Request per second crecerá o bajará en función del cambio.

Aumentar la seguridad de nuestro sitio

Wednesday, December 26th, 2007

Una persona mal intencionada que quiera tirar abajo nuestro sitio web, debe contar con información, esta puede ser obtenida de varias formas, pero mientras mayor sea el esfuerzo que deba realizar en conseguirla menor será su ganas de atacar.

Algunas versiones de Apache 2 por defecto trae activada una directiva que informan sobre el servidor. Por ejemplo, al contar con información del número de versión de Apache, tiene a su disposición todas las vulnerabilidades reportadas. En base a esto y ganas de hacer daño es cuestión de tiempo para bajar el sitio. Por lo cual no se recomienda que esté activada está directiva, sólo en el caso de que Apache se utilice como un servidor proxy y de esta manera poder determinar qué proxy causa un error.

Pie de imagen con información del servidor

Vamos a ver como desactivar esta información que suministra Apache. La explicación se basa en Debian y Apache 2. La directiva ServerSignature, agrega un pie en las páginas generadas detallando número de versión, nombre y puerto por el que escucha el servidor. Es importante notar que los detalles del número de versión mostrado en éste pie es controlado a través de la directiva ServerTokens, a partir de la versión 2.0.44 de Apache.

ServerSignature puede tomar los siguientes valores: On, Off, EMail. EMail, además de mostrar información detallada por ServerTokens, muestra el valor de la directiva ServerAdmin.

ServerTokens puede tomar los siguientes valores

Valor Muestra
Prod[uctOnly] Apache
Major Apache/2
Minor Apache/2.0
Min[imal] Apache/2.0.41
OS Apache/2.0.41 (Unix)
Full Apache/2.0.41 (Unix) PHP/4.2.2 MyMod/1.2

Nos vamos a


#cd /etc/apache2
#vi apache2.conf

Nota:Puede ser que la gestión de la configuración del servidor se encuentre en varios archivos y no sólo en apache2.conf. La ruta en dónde pueden encontrarse estos archivos se obtiene a través de las directivas Include dentro de apache2.conf. Por defecto podemos encontrar el resto de los archivos en /etc/apache2/sites-available. En éstos archivos también tenemos que modificar los valores de ServerSignature.

Buscamos la directiva ServerSignature y la establecemos en Off.


# 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

Reiniciamos Apache para que tome la nueva configuración


#/etc/init.d/apache2 force-reload

Con esto desaparecerá el pie de página

Pie de imagen sin información del servidor

Podemos comprobar que información está suministrando el servidor, a través del encabezado devuelto en las solicitudes HTTP[1]


# telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET / HTTP/1.1
HTTP/1.1 200 OK
Date: Wed, 26 Dec 2007 21:57:51 GMT
Server: Apache/1.3 (Debian) PHP/5.2.1
Last-Modified: Tue, 27 Nov 2007 02:16:58 GMT
ETag: “1390096-7b7-ace83a80″
Accept-Ranges: bytes
Content-Length: 1975
Connection: close
Content-Type: text/html; charset=UTF-8
…

Dentro del encabezado HTTP, se esta mostrando información detallada, tenemos que minimizarla, esto lo hacemos modificando el valor de la directiva ServerTokens


# ServerTokens
# This directive configures what you return as the Server HTTP response
# Header. The default is 'Full' which sends information about the OS-Type
# and compiled in modules.
# Set to one of:  Full | OS | Minor | Minimal | Major | Prod
# where Full conveys the most information, and Prod the least.
#
ServerTokens Prod

Ahora si hacemos un telnet aparecera[1]


# telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET / HTTP/1.1
HTTP/1.1 200 OK
Date: Wed, 26 Dec 2007 21:57:51 GMT
Server: Apache
Last-Modified: Tue, 27 Nov 2007 02:16:58 GMT
ETag: “1390096-7b7-ace83a80″
Accept-Ranges: bytes
Content-Length: 1975
Connection: close
Content-Type: text/html; charset=UTF-8
…


[1] También podríamos utilizar NetCat, para obtener sólo el encabezado de la solicitud HTTP. Donde a NetCat le pasamos la dirección IP del servidor (localhost) y el puerto por el que está escuchando (80). Después de presionar enter utilizamos el método de solicitud HEAD.


# nc localhost 80
HEAD / HTTP:1.0

HTTP/1.1 200 OK
Date: Thu, 17 Jan 2008 21:00:51 GMT
Server: Apache
Last-Modified: Tue, 27 Nov 2007 02:16:58 GMT
ETag: "1390096-7b7-ace83a80"
Accept-Ranges: bytes
Content-Length: 1975
Connection: close
Content-Type: text/html; charset=UTF-8

bibliografía

Limitar ancho de banda en Apache2

Wednesday, December 19th, 2007

La siguiente explicación tiene en cuenta cualquier distribución basada en Debian y apache 2.

Apache 2 a diferencia de Apache 1, no trae un modulo propio para limitar el ancho de banda. Este es un modulo con dicha funcionalidad que probe.

Notar que este paquete hace conflicto con apache 1.3…Una vez bajado el modulo del sitio lo descomprimimos


tar xzvf mod_bw-0.8.tgz

Luego dentro del directorio del modulo descomprimido, ejecutamos apxs. Apxs es una herramienta para compilar dinámicamente, instala modulos a partir del código fuente creando un DSO y cargandolo dinámicamente en nuestro servidor. Para instalarlo debemos ejecutar

apt-get install apache2-prefork-dev

Hay que notar que existen varias versiones de apxs2, la versión correspondiente para nuestro servidor es según con que módulo de MPM fue compilado, suena complicado pero no alarmase. Para saber con que MPM está compilado su servidor ejecute el siguiente comando


apache2ctl -l

La salida de dicho comando mostrará los modulos que tiene compilado. Mi servidor tiene compilado prefork.


...
mod_logio.c
prefork.c
http_core.c
…

Dentro del directorio descomprimido mod_bw esta el archivo fuente del modulo (*.c), entonces para compilarlo hacemos:


apxs2 -i -a -c mod_bw.c

La opción -i instalar el módulo, -c compilarlo y -a activarlo. Dentro de la salida de dicho mensaje podemos encontrar el siguiente mensaje. Hasta ahora vamos bien


Libraries have been installed in:/usr/lib/apache2/modules

Vamos y verificamos en /usr/lib/apache2/modules si se compilo, debería aparecer como mod_bw.so.

Luego vamos a /etc/apache2/httpd.conf, y ordenamos a Apache que cargue el modulo, utilizamos la directiva LoadModule


LoadModule bw_module /usr/lib/apache2/modules/mod_bw.so

Nota: LoadModule relaciona el nombre de un módulo con una librería que tengamos instalada. En el comando anterior relacionamos el nombre bw_module con la librería mod_bw.so, la cual se encuentra en /usr/lib/apache2/modules.

luego reiniciamos apache para que tome la configuración

/etc/init.d/apache2 force-reload

vamos a /etc/apache2/sites-available

y editamos default o el archivo que tengan sobre su sitio habilitado

Activamos el modulo y forzamos que las solicitudes sean procesadas por él.


BandWidthModule On
ForceBandWidthModule On

Después agregamos las directivas para limitar el ancho de banda, un ejemplo sería:


<Directory "/uploads">
BandWidth all 8096
MaxConnection all 7
</Directory>

Expliquemos un poco cada directiva

BandWidth toma dos parámetros. El primero es de dónde se origina la conexión, la dirección ip, por ejemplo:

192.153.2.0/24
192.153.2.0/255.255.255.0
all

El segundo parámetro indica la velocidad disponible para el origen. Si el parámetro toma el valor 0, el origen no tiene limite de velocidad. La velocidad está expresada en bytes/s.

8 bits = 1 Byte
1024 Bytes = 1 KB
1024 KB = 1 MB

El modulo permite varios tipos de directivas interesantes para restringir en función de diferentes parámetros, ahora voy a describir las más interesantes. Todas están directivas, junto con su explicación y ejemplos se pueden obtener del archivo txt que está con el modulo.

Algo que han agregado en la versión 0.8, es la capacidad de limitar de acuerdo al agente del origen de la conexión, un ejemplo sería:


BandWidth "u:^Opera/9(.*)" 10240
BandWidth "u:^Lynx/2.8(.*)" 10240

Toma dos parámetros, el primero hace referencia al agente, y el segundo limita

Algo interesante que tiene este modulo es la capacidad de limitar en función de la extensión del archivo, por ejemplo:


LargeFileLimit .avi 500 10240

El primer parámetro hace referencia a la extensión afectada, también es posible poner .*, afectando a todos. El segundo parámetro es el tamaño mínimo de (los) archivo(s) para que limite. Y el último hace referencia a la velocidad permitida. Estos dos últimos valores se expresan en bytes/s.

Se puede limitar el número de conexiones simultaneas, aquí va un ejemplo de la directiva:

MaxConnection all 30

Toma dos parámetros, el origen de la conexión que puede tomas los mismos valores que en el parámetro de la directiva BandWidth. Y el segundo define el máximo número de conexiones de ese origen. Algo que han agregado en la versión 0.8, que se pude limitar el número de conexiones limitadas según el agente, por ejemplo:

MaxConnection "u:wget" 5

Por último, algo que encontré muy interesante es la capacidad de limitar ciertos directorios, aquí les pongo un ejemplo


<VirtualHost *>BandWidthModule On
BandWidth all 16384
LargeFileLimit .png 5 4096
<Directory “/download”>
LargeFileLimit .png 5 1024
</Directory>

Creería que eso es todo. Como dije al principio del artículo, todas las explicaciones y ejemplos se encuentran en la documentación del modulo