1.- Instalación de Apache (1.3.34-4.1)+PHP4
Debixer:/# apt-get update  Antes que todo, actualizar nuestros repositorios
Descargados 58,2kB en 15s (3867B/s)
Leyendo lista de paquetes... Hecho
Debixer:/#
Debixer:/# apt-get dist-upgrade  Vemos si necesitamos alguna actualización
 Con esto actualizamos el sistema completo
Debixer:/# apt-get install f  Ver si tenemos algún problema de dependencias Leyendo lista de paquetes... Hecho
Creando árbol de dependencias... Hecho
0 actualizados, 0 se instalarán, 0 para eliminar y 0 no actualizados.
Debixer:/#
 Instalación de Apache+PHP5+mod_ssl
apt-get install apache apache-doc php4 libapache-mod-php4 libapache-mod-ssl
Luego de unos momentos, tendremos listo la instalación de Apache 1.3.34+PHP5 funcionando en nuestro Debian etch, ahora es el momento de configurar y securizar nuestro servidor Web
 La seguridad no es una panacea día a día se ven más y más servidores crackeados, desfaceados, por distintos motivos, ya sea falta de actualización, mala configuración, programas inseguros, faltas de políticas de seguridad, etc, no nos sirve de nada tener un servidor bien configurado, tuneado, etc, si nuestras políticas de seguridad ( ya sea firewall, información a mostrar, etc) son deficientes
2.- Configuración:
A continuación trataremos de configurar nuestro Apache, para que éste muestre la menor cantidad de información referente al mismo.
Ejemplo:
El siguiente ejemplo lo teste en mi maquina corriendo Debian etch con Apache 1.3.34-4.1+PHP5+mod_ssl, luego de una instalación por defecto
Debixer:/# a2enmod php5
This module is already enabled!
Debixer:/# a2enmod ssl
This module is already enabled!
Debixer:/# echo -e "HEAD / HTTP/1.0\n" | nc localhost 80
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET / HEAD/1.0
HTTP/1.1 400 Bad Request
Date: Fri, 09 Feb 2007 12:18:06 GMT
Server: Apache/1.3.34 (Debian) PHP/5.2.0-8+etch4 mod_ssl/2.8.25 OpenSSL/0.9.8c
Connection: close
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>400 Bad Request</TITLE>
</HEAD><BODY>
<H1>Bad Request</H1>
Your browser sent a request that this server could not understand.<P>
The request line contained invalid characters following the protocol string.<P>
<P>
<HR>
<ADDRESS>Apache/1.3.34 Server at localhost Port 80</ADDRESS>
</BODY></HTML>
Connection closed by foreign host.
Debixer:/#
 Server: Apache/1.3.34 (Debian) PHP/5.2.0-8+etch4 mod_ssl/2.8.25 OpenSSL/0.9.8c
 Demasiada información a mostrar, demasiada!
 Configurando httpd.conf para mostrar la menor información posible
Ejemplo:
Debixer:/# apachectl start
/usr/sbin/apachectl start: httpd started
Debixer:/#
En un navegador escribimos nuestra dirección IP:
En mí caso Firefox:
http://192.168.0.08/asd
Not Found
The requested URL /asd was not found on this server.
________________________________________
Apache/1.3.34 Server at 192.168.0.08 Port 80
 Apache/1.3.34 Server at 192.168.0.08 Port 80
La verdad es bastante común ver este tipo de información
Debixer:/# nano /etc/apache/httpd.conf
##
## httpd.conf -- Apache HTTP server configuration file
##
 Buscamos estás líneas:
ServerSignature On
ServerTokens Full
Y las dejamos así
ServerSignature Off
ServerTokens Prod
Explicación:
ServerTokens Prod[uctOnly]
El servidor envía (por ejemplo): Server: Apache
ServerTokens Major
El servidor envía (por ejemplo): Server: Apache/2
ServerTokens Minor
El servidor envía (por ejemplo): Server: Apache/2.0
ServerTokens Min[imal]
El servidor envía (por ejemplo): Server: Apache/2.0.41
ServerTokens OS
El servidor envía (por ejemplo): Server: Apache/2.0.41 (Unix)
ServerTokens Full (or not specified)
El servidor envía (por ejemplo): Server: Apache/2.0.41 (Unix) PHP/4.2.2 MyMod/1.2
Probamos:
Guardamos los cambios y
Debixer:/# /etc/init.d/apache force-reload
Reloading apache 1.3 configuration....
Debixer:/#
Abrimos de nuevo el navegador y testeamos:
http://192.168.0.08/fds
Not Found
The requested URL /fds was not found on this server.
 Algunas opciones a tomar en cuenta:
MaxRequestsPerChild 100 Cantidad de procesos hijos que se crearán,
para prevenir DDoS
MaxClients 300  Cantidad máxima de clientes soportados, aplicar un número alto para que no se bloqueen las pagínas.
Timeout 50  Para que las conexiones Reading sean matadas
que llegue al límite MaxClients
Algunas opciones:
Muchas veces cuando accedemos a un directorio de nuestro Apache nos sale algo parecido a esto:
http://192.168.0.08/prueba/
Index of /prueba
Name Last modified Size Description
________________________________________
Parent Directory 09-Feb-2007 16:03 -
prueba1 09-Feb-2007 10:57 0k
prueba2 09-Feb-2007 10:57 0k
prueba3 09-Feb-2007 10:57 0k
pruebaetc 09-Feb-2007 10:57 0k
Por lo menos para mí es bastante molesto así que lo vamos a desactivar
Debixer:/# nano /etc/apache/httpd.conf
#<Directory />
# Options SymLinksIfOwnerMatch
# AllowOverride None
#</Directory>
Dejarlo en:
<Directory />
Options -Indexes -Includes -ExecCGI -FollowSymLinks
AllowOverride None
</Directory>
Explicación:
Options Indexes  Desactiva la exploración de Directorios
Options Includes  Desactiva los Includes del Servidor
Options ExecCGI  Desactiva la ejecución de CGI
Options FollowSymLink  Desactiva el seguimiento de enlaces simbólicos
Para el ejemplo anterior:
<Directory /var/www/>
Options -Indexes -Includes FollowSymLinks -ExecCGI MultiViews
AllowOverride None
Order allow,deny
Allow from all
</Directory>
1.
http://192.168.0.08/prueba/
Forbidden
You don't have permission to access /prueba/ on this server.
DirectoryIndex :
<IfModule mod_dir.c>
DirectoryIndex index.html index.htm index.shtml index.cgi index.php
php_value magic_quotes_gpc 0
</IfModule>
 php_value magic_quotes_gpc 0 : Hace que los caracteres ', , \ y NULL sean transformados a una barra invertida automáticamente, para prevenir ataques simples de SQL Inyection
 Denegar la descarga de todos los archivos que comiencen con .ht*
AccessFileName .httpdoverride
<Files ~ "^\.ht">
Order allow,deny
Deny from all
Satisfy All
</Files>
2.1.- Módulos:
 Monitorización mediante mod_status:
Este módulo nos muestra información referente a nuestro servidor, en el momento en que tienes muchos dominios virtuales, se hace demasiado difícil manejar información de uno por uno, sobre todo al ver la cantidad generada de logs, con mod_status, nos ahorramos esas trabas , y obtenemos información en tiempo real
Entre las características que podemos encontrar son:
 Número de procesos
 Cantidad de CPU
 Procesos idle
 Status de los procesos
 Cantidad de bytes servidos por los procesos
 Status del tiempo del Servidor Up, etc
 etc
Activación del módulo:
Debixer:/# a2enmod status
This module is already enabled!
Debixer:/#
Debixer:/# nano /etc/apache/httpd.conf
Y descomentamos estás líneas:
#<Location /server-status>
# SetHandler server-status
# Order deny,allow
# Deny from all
# Allow from X
#</Location>
Dejándola así:
<Location /server-status>
SetHandler server-status
Order deny,allow
Deny from all
Allow from 192.168.0.190  La cambian por su IP o dominio etc...
</Location>
Debixer:/# /etc/init.d/apache force-reload
Reloading apache 1.3 configuration....
Debixer:/# lynx localhost/server-status
Apache Server Status for 192.168.0.08
Server Version: Apache
Server Built: Mar 4 2007 01:34:14
________________________________________
Current Time: Friday, 09-Feb-2007 16:25:40 CLST
Restart Time: Friday, 09-Feb-2007 16:25:35 CLST
Parent Server Generation: 0
Server uptime: 5 seconds
Total accesses: 1 - Total Traffic: 0 kB
CPU Usage: u0 s0 cu0 cs0
.2 requests/sec - 0 B/second - 0 B/request
1 requests currently being processed, 5 idle servers
_W____..........................................................
................................................................
................................................................
................................................................
Scoreboard Key:
"_" Waiting for Connection, "S" Starting up, "R" Reading Request,
"W" Sending Reply, "K" Keepalive (read), "D" DNS Lookup,
"L" Logging, "G" Gracefully finishing, "." Open slot with no current process
Srv PID Acc M CPU SS Req Conn Child Slot Client VHost Request
0-0 11047 0/1/1 _ 0.00 3 1 0.0 0.000 0.000 127.0.0.1 localhost GET /server-status HTTP/1.0
1-0 11048 0/0/0 W 0.00 5 1476931258 0.0 0.00 0.00 192.168.0.190 localhost GET /server-status HTTP/1.1
________________________________________
Srv Child Server number - generation
PID OS process ID
Acc Number of accesses this connection / this child / this slot
M Mode of operation
CPU CPU usage, number of seconds
SS Seconds since beginning of most recent request
Req Milliseconds required to process most recent request
Conn Kilobytes transferred this connection
Child Megabytes transferred this child
Slot Total megabytes transferred this slot
Securizando nuestro servidor Web mediante mod_evasive
mod_evasive es un módulo de seguridad para Apache, versiones 1 y 2, que trata de detener ataques de tipo DoS, DDoS, brute force, baneando las IPs que han alcanzado un límite de conexiones que ya han sido configuradas.
Instalación:
Debixer:/# apt-get install libapache-mod-dosevasive
Verificamos que este el módulo:
Debixer:/# less /etc/apache/modules.conf | grep evasive
LoadModule dosevasive_module /usr/lib/apache/1.3/mod_dosevasive.so
Debixer:/#
Añadimos las siguientes líneas a nuestro httpd.conf:
Debixer:/# nano etc/apache/httpd.conf
#mod_evasive
<IfModule mod_evasive.c>
DOSHashTableSize 3097
DOSPageCount 5
DOSSiteCount 100
DOSPageInterval 2
DOSSiteInterval 2
DOSBlockingPeriod 600
DOSSystemCommand /sbin/iptables I INPUT p tcp dport 80 s %s j DROP
DOSEmailNotify root
DOSLogDir /var/log/evasive
</IfModule>
Explicación:
DOSHashTableSize: Tamaño de la tabla hash
DOSPageCount: Número de páginas solicitadas a partir de las cuales si se cumplen el resto de condiciones, el módulo se activa.
DOSSiteCount: Número de solicitudes máximas a partir del cual el filtro se activa.
DOSPageInterval: Segundos entre las peticiones a las páginas
DOSSiteInterval: Segunods de tiempo entre las peticiones
DOSBlockingPeriod: Tiempo que se bloqueará la web a esa IP
DOSEmailNotify root A quien notificar o dirección de correo
DOSSystemCommand Comando a ejecutar cuando una IP sea bloqueada
DOSLogDir Dirección del archivo a loguear
DOSWhitelist <IP> Dirección que quedara fuera de las reglas:
DOSWhitelist 192.168.0.02
DOSWhitelist 192.168.0.153
Probando nuestro módulo:
mod_evasive o libapache-mod-dosevasive, viene con un script en perl para probar la configuración del mismo:
Debixer:/# perl /usr/share/doc/libapache-mod-dosevasive/examples/test.pl
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 200 OK
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
Bien..., para más información: cd /usr/share/doc/libapache-mod-dosevasive/examples/
mod_security
mod_security, es módulo de seguridad para Apache el cual nos proporciona un mecanismo de prevención, detección. Es bastante similar a un IDS, solo que trabaja sobre http, entre sus características podemos encontrar:
 Es Open Source
 Creación de reglas específicas
 Alo porcentaje de ataques evitados
 Comprensión del protocólo http
 Logueado
 HTTPS Filtering
 Y una cantidad más
Instalación:
Por ahora mod_security, no se encuentroa en los repositorios de Debian ETCH, pero sí en testing y sid bajo el nombre de; libapache-mod-security, por lo que tenemos tres opciones para obtenerlo:
1.- Obtención del Código Fuente
2.- BackPort
3.- Mezclar packages en Debian (mala idea)
He elegido la primera, pero la segunda no hay ningún problema, no quiero hacer comentarios de la tercera:
Obtención del Código Fuente:
Debixer:/# cd /tmp/
Debixer:/tmp# wget wget http://www.modsecurity.org/download/modsecurity-apache_1.9.4.tar.gz
Descargados: 496,805 bytes en 1 ficheros
Debixer:/tmp# tar vxzf modsecurity-apache_1.9.4.tar.gz
Debixer:/tmp# cd modsecurity-apache_1.9.4/apache1/
Debixer:/tmp/modsecurity-apache_1.9.4/apache1# apxs -cia mod_security.c
gcc -DLINUX=22 -DEAPI -DTARGET="apache" -DHAVE_SET_DUMPABLE -DDB_DBM_HSEARCH=1 -DDEV_RANDOM=/dev/random -DUSE_HSREGEX -O1 -g -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -fPIC -DSHARED_MODULE -I/usr/include/apache-1.3 -c mod_security.c
mod_security.c: In function âperform_actionâ:
mod_security.c:1424: warning: value computed is not used
mod_security.c: In function âmultipart_process_chunkâ:
mod_security.c:7422: warning: âlocalreserve[0]â may be used uninitialized in this function
mod_security.c:7422: warning: âlocalreserve[1]â may be used uninitialized in this function
gcc -shared -o mod_security.so mod_security.o
[activating module `security' in /etc/apache/httpd.conf]
cp mod_security.so /usr/lib/apache/1.3/mod_security.so
chmod 755 /usr/lib/apache/1.3/mod_security.so
cp /etc/apache/httpd.conf /etc/apache/httpd.conf.bak
cp /etc/apache/httpd.conf.new /etc/apache/httpd.conf
rm /etc/apache/httpd.conf.new
Debixer:/tmp/modsecurity-apache_1.9.4/apache1#
Tenemos listo nuestro mod_security:
Bajamos reglas para aplicar:
Debixer:/tmp# wget
http://www.gotroot.com/downloads/ftp/mod_security/apache1/apache1-gotrootrules-latest.tar.gz
23:46:20 (54.70 KB/s) - `apache1-gotrootrules-latest.tar.gz' saved [176245/176245]
Desempaquetamos y vemos que tenemos:
Debixer:/tmp# ls apache1/
badips.conf blacklist.conf jitp.conf recons.conf rules.conf
blacklist2.conf exclude.conf proxy.conf rootkits.conf useragents.conf
Debixer:/tmp# mv mod_security/ /etc/apache/
Debixer:/tmp#
Cada nombre lo dice
Configuramos mod_security:.., analizamos los archivos y luego creamos uno final dentro de httpd.conf:
Debixer:/tmp# nano /etc/apache/httpd.conf
Debixer:/# echo >> LoadModule security_module /usr/lib/apache/1.3/mod_security.so /etc/apache/modules.conf
Debixer:/# nano etc/apache/httpd.conf
Comentamos estas líneas:
LoadModule security_module /usr/lib/apache/1.3/mod_security.so
AddModule mod_security.c
Ya que agregamos el módulo a modules.conf
Y agregamos:
#mod_security
<IfModule mod_security.c>
SecFilterEngine On
SecAuditLog /var/log/apache/audit.log
SecFilterDefaultAction deny,log,status:500.
SecFilterScanPOST On
SecFilterCheckURLEncoding On
SecFilterCheckCookieFormat On
SecFilterCheckUnicodeEncoding Off
SecFilterNormalizeCookies On
SecFilterCookieFormat 1
SecServerResponseToken Off
SecFilterForceByteRange 1 255
SecServerSignature "Server secured with Linuxers"
SecUploadDir /tmp
SecUploadKeepFiles Off
SecAuditEngine RelevantOnly
SecFilterDebugLevel 0
Include /etc/apache/mod_security/exclude.conf
Include /etc/apache/mod_security/rules.conf
Include /etc/apache/mod_security/rootkits.conf
Include /etc/apache/mod_security/useragents.conf
Include /etc/apache/mod_security/proxy.conf
Include /etc/apache/mod_security/blacklist.conf
Include /etc/apache/mod_security/blacklist2.conf
Include /etc/apache/mod_security/recons.conf
Include /etc/apache/mod_security/badips.conf
Include /etc/apache/mod_security/jitp.conf
</IfModule>
Probamos la sintaxis:
Debixer:/# apachectl stop
/usr/sbin/apachectl stop: httpd (no pid file) not running
Debixer:/# apachectl configtest
Syntax OK
Debixer:/# apachectl start
/usr/sbin/apachectl start: httpd started
Debixer:/#
Probando el mod_security
Debixer:/# nano /var/www/prueba_mod.php
<? include( $file ); ?>
Guardamos y probamos:
Debixer:/# tail -f /var/log/apache/audit.log n8
Abrimos nuestro navegador Web y ponemos:
http://192.168.0.08/prueba_mod.php?file=/etc/passwd
Your have loggin connection"
Y miramos la terminal y tenemos algo similar a esto:
==17510b4a==============================
Request: 192.168.0.08 192.168.0.190 - - [10/Feb/2007:01:15:45 -0300] "GET /prueba_mod.php?file=/etc/passwd HTTP/1.1" 500 40 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; es-AR; rv:1.8.1.4) Gecko/20070515 Firefox/2.0.0.4" - "-"
----------------------------------------
GET /prueba_mod.php?file=/etc/passwd HTTP/1.1
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Encoding: gzip,deflate
Accept-Language: es-ar,es;q=0.8,en-us;q=0.5,en;q=0.3
Connection: keep-alive
Host: 192.168.0.08
Keep-Alive: 300
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; es-AR; rv:1.8.1.4) Gecko/20070515 Firefox/2.0.0.4
mod_security-action: 500
mod_security-message: Access denied with code 500. Pattern match "/etc/passwd" at REQUEST_URI [severity "EMERGENCY"]
HTTP/1.1 500 Internal Server Error
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=iso-8859-1
--17510b4a
 El aviso que nos muestra el Navegador es manejado por la directiva
ErrorDocument 500 "Your have loggin connection" del httpd.conf, podemos hacer otras cosas como redireccionar a una página creada por nosotros etc
mod_rewrite
Enter sus características podemos encontrar:
 Prevensión de SPAM
 Páginas más limpias (permite convertir URLs dinámicas en estáticas)
 Se ejecuta después de hacer un REQUEST al servidor y antes de ejecutar cualquier script.
 La conversión se hace por detrás por lo que el usuario no ve nada
mod_rewrite es una extensión de apache que nos permite tener páginas más limpias
Activamos el módulo:
Debixer:/# a2enmod rewrite
This module is already enabled!
Debixer:/#
Configuración de httpd.conf para agregar algunas reglas:
 Prevención de SPAM
#mod_rewrite
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_REFERER} poker [NC,OR]
RewriteCond %{HTTP_REFERER} holdem [NC,OR]
RewriteCond %{HTTP_REFERER} casino [NC,OR]
RewriteCond %{HTTP_REFERER} (sex) [NC,OR]
RewriteCond %{HTTP_REFERER} (drugs) [NC,OR]
RewriteCond %{HTTP_REFERER} (rock\&roll) [NC]
RewriteRule . http://www.microsoft.com [L]
#Denegar el upload de imagenes
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://tudominio.cl/.*$ [NC]
RewriteRule .*.(gif|GIF|jpg|JPG)$ - [F]
#Limpiar URLs "diciles" a "simples"
RewriteRule ^/users/([A-Za-z0-9]+)$ /?user=$1 [PT]
RewriteRule ^/search/(.*)$ /?search=$1 [PT]
</IfModule>
Ejemplo:
 /?user=CdK1 - becomes /users/CdK1
Debixer:/# apachectl stop
/usr/sbin/apachectl stop: httpd stopped
Debixer:/# apachectl configtest
Syntax OK
Debixer:/# apachectl start
/usr/sbin/apachectl start: httpd started
Debixer:/#
mod_ssl
NC indica que no es sensible a mayúsculas
Para más información: http://httpd.apache.org/docs/trunk/misc/rewriteguide.html