lunes, 25 de junio de 2007

QoS con pf

Intentando establecer un límite de bajada para un servidor web he estado haciendo pruebas con mod_bandwidth (en el post anterior) pero no funciona todo lo bien que debiera.

Como alternativa he probado a hacer QoS con pf (el cortafuegos de openBSD), funciona realmente bien, se pueden establecer colas con prioridad de la siguiente forma en el archivo pf.conf:

altq on ne3 cbq bandwidth 10Mb queue {http, std}

queue http bandwidth 1Mb priority 1
queue std bandwidth 9Mb priority 4 cbq (default)

pass in quick log on ne3 proto tcp from any to any port 80 queue http

ne3 es la interfaz de red, he definido una cola para http y el resto para los demás servicios, los límites también se pueden establecer mediante porcentajes.

Para recargar las reglas en el cortafuegos simplemente pfctl -e -f /etc/pf.conf como root.

Limitar el ancho de banda de apache en openBSD

Como no solemos tener ancho de banda de subida de sobra (siempre es más caro que el de bajada), puede ser interesante limitar el ancho de banda de apache.

En openBSD solo hay que hacer lo siguiente:

pkg_add ftp://ftp.openbsd.org/pub/OpenBSD/4.1/packages/i386/mod_bandwidth-2.0.6.tgz

/usr/local/sbin/mod_bandwidth-enable

Y editar el httpd.conf y poner lo siguiente:

<Directory "/var/www/htdocs/">
BandWidth all 10240
</Directory>

Siendo /var/www/htdocs/ el directorio a limitar, y el 10240 el número de bytes/segundo máximo, en el caso de arriba estamos limitando a 10KB/s.

Para que apache lea esta configuración:

apachectl restart

Para otros sistemas que no sean openBSD lo único que variará será la forma de instalar el mod_bandwidth.

sábado, 23 de junio de 2007

Descargar la wikipedia

Siempre viene bien tener la información en soporte físico para aquellas ocasiones en las que no tenemos conexión a internet, la gente que contribuye a la wikipedia ya ha pensado en esto.

Podéis bajaros la wikipedia completa en español, en inglés o en cualquier cualquier otro idioma.

El último backup que he encontrado para descargar es a fecha de abril del 2007, aunque quizá haya por ahí versiones más actualizadas, los archivos están comprimidos con 7-zip.

El programa para descomprimir los archivos lo podéis encontrar aquí.

viernes, 15 de junio de 2007

Filtrando ataques de fuerza bruta a ssh

Todos los que hayáis instalado un servidor de ssh en alguna máquina conectada a internet os habréis dado cuenta de la cantidad de ataques de fuerza bruta que recibe.

Si algún despistado no sabe de lo que hablo solo tiene que leer el fichero /var/log/auth.log (la ruta puede variar), si se encuentra cosas como esta:


Jun 7 15:16:50 ubuntu sshd[10729]: Invalid user root from 192.168.0.20
Jun 7 15:16:50 ubuntu sshd[10729]: Failed none for invalid user root from 192.168.0.20 port 47762 ssh2
Jun 7 15:16:50 ubuntu sshd[10729]: Failed password for invalid user root from 192.168.0.20 port 47762 ssh2
Jun 7 15:16:50 ubuntu last message repeated 2 times
Jun 7 15:16:51 ubuntu sshd[10731]: Connection from 192.168.0.20 port 44584
Jun 7 15:16:52 ubuntu sshd[10731]: Invalid user root from 192.168.0.20
Jun 7 15:16:52 ubuntu sshd[10731]: Failed none for invalid user root from 192.168.0.20 port 44584 ssh2
Jun 7 15:16:52 ubuntu sshd[10731]: Failed password for invalid user root from 192.168.0.20 port 44584 ssh2
Jun 7 15:16:52 ubuntu last message repeated 2 times
Jun 7 15:16:52 ubuntu sshd[10733]: Connection from 192.168.0.20 port 35640
Jun 7 15:16:52 ubuntu sshd[10733]: Invalid user root from 192.168.0.20
Jun 7 15:16:52 ubuntu sshd[10733]: Failed none for invalid user root from 192.168.0.20 port 35640 ssh2
Jun 7 15:16:52 ubuntu sshd[10733]: Failed password for invalid user root from 192.168.0.20 port 35640 ssh2
Jun 7 15:16:52 ubuntu last message repeated 2 times
Jun 7 15:16:53 ubuntu sshd[10735]: Connection from 192.168.0.20 port 12587
Jun 7 15:16:53 ubuntu sshd[10735]: Invalid user root from 192.168.0.20
Jun 7 15:16:53 ubuntu sshd[10735]: Failed none for invalid user root from 192.168.0.20 port 12587 ssh2
Jun 7 15:16:53 ubuntu sshd[10735]: Failed password for invalid user root from 192.168.0.20 port 12587 ssh2
Jun 7 15:16:53 ubuntu last message repeated 2 times
Jun 7 15:16:53 ubuntu sshd[10737]: Connection from 192.168.0.20 port 20968
Jun 7 15:16:54 ubuntu sshd[10737]: Invalid user root from 192.168.0.20
Jun 7 15:16:54 ubuntu sshd[10737]: Failed none for invalid user root from 192.168.0.20 port 20968 ssh2
Jun 7 15:16:54 ubuntu sshd[10737]: Failed password for invalid user root from 192.168.0.20 port 20968 ssh2

etc...


Como se puede ver, hay muchos intentos de acceso fallidos desde la misma ip, y ocurren tan rápido que sabemos que al otro lado no hay nadie tecleando, seguramente será algún programa probando una lista de contraseñas por fuerza bruta para conseguir acceso a nuestra máquina.

¿Qué podemos hacer para evitarlo? podríamos poner una regla en el cortafuegos para denegar el acceso a es ip en concreto, pero eso es pan para hoy y hambre para mañana, ya que el siguiente que lo intente se va a encontrar que no tiene problemas para probar.

Para no estar poniendo y quitando reglas del firewall todo el tiempo, y aprovechando que estaba aprendiendo perl, pues me he programado el siguiente script para evitar estos ataques:

#!/usr/bin/perl
use POSIX qw(strftime);
use Time::Local;


#ssh_abf.pl
#Deniega ips en el cortafuegos (iptables)
#que esten atacando por fuerza bruta al demonio ssh.
#Probado con perl 5.8.8 y openSSH4.3


#Ruta al fichero auth.log a analizar
$entrada="/var/log/auth.log";


#Intervalo durante el que se deniegan las ips
$intervalo_denegacion=600;


#Intervalo tras el cual se analiza el fichero
$intervalo_analisis=5;


#Maximo de ips denegadas
$max_denegadas=10;


#Numero de entradas en el fichero para ser denegada la ip
$intentos=2;


#Puerto en el que escucha el demonio ssh
$puerto=22;


@meses = qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec );


while(1){
if(scalar(@IPs)<$max_denegadas){
my @IPs=();
my @momentos=();
my @veces=();


open (ENTRADA,"<$entrada")
|| die "ERROR: No puedo abrir el fichero $entrada\n";


$anio = strftime "%Y", localtime;


# Obtiene los intentos fallidos durante el ultimo
# $intervalo_denegacion.
# Las ips se guardan en @IPs y el momento en el que atacaron en
# @momentos.
# Si una ip aparece mas de una vez solo se tiene en cuenta la
# ultima ocurrencia.
while ($linea=<ENTRADA>){
if($linea=~/Failed password*/){
$linea=~/(\S+)\s+(\d+)\s+(\d+):(\d+):(\d+)/;
$i=0;
while($meses[$i] ne $1){$i++;}
$t=timelocal($5, $4, $3, $2, $i,($anio-1900));


if((time-$t)<$intervalo_denegacion){
$linea=~/(\d+\.\d+\.\d+\.\d+)/;


$esta=0;
$pos=0;
foreach $dir (@IPs){
if($dir eq $1){$esta=1;}
if($esta==0){$pos++;}
}


if($esta==0 and scalar(@IPs)<$max_denegadas){
push(@IPs, $1);
push(@momentos, (time-$t));
push(@veces,1);
}
elsif($esta==1){
$momentos[$pos]=time-$t;
$veces[$pos]++;
}
}
}
}


#Insertar reglas en el cortafuegos
$pos=0;
foreach $v (@veces){
if($v>=$intentos and $activadas{$IPs[$pos]}==0){
system("iptables -I INPUT -p tcp -s $IPs[$pos] --dport $puerto -j DROP");
$activadas{$IPs[$pos]}=1;
}
$pos++;
}


#Borra las reglas antiguas del cortafuegos
foreach $dir (keys %activadas){
$desactivar=1;
foreach $j (@IPs){
if($dir eq $j){
$desactivar=0;
}
}
if($desactivar==1){
system("iptables -D INPUT -p tcp -s $dir --dport $puerto -j DROP");
delete $activadas{$dir};
}
}
close (ENTRADA);
}
sleep($intervalo_analisis);
}



Para probarlo solo hay que guardarlo como un fichero de texto (por ejemplo ssh_abf.pl), darle permisos de ejecución chmod u+x ssh_abf.pl y ejecutarlo como root.

Es posible que tengáis/queráis cambiar alguno de los parámetros que aparecen al principio, sobre todo la ruta del fichero auth.log.

Lo que hace el script es simplemente cada cierto tiempo lee el fichero auth.log, comprueba si alguien está haciendo un ataque de fuerza bruta, si lo está haciendo crea automáticamente una regla en el cortafuegos para que se ignore lo que llega de esa ip.

Cuando termina el "intervalo de denegación", elimina esa regla (seguramente tras ese tiempo el atacante esté con otro y ya no se acuerde de nosotros), de esta forma nos aseguramos que no hay reglas innecesarias en el cortafuegos.

Agradecería que si alguien lo prueba me comente si encuentra algún error, ¡hasta otra!.

martes, 12 de junio de 2007

De estreno

¡Hola! esta es la primera entrada de mi blog, no aspiro a actualizarlo diariamente, pero de vez en cuando iré poniendo cosillas.

¿La temática? Programación, redes, sistemas operativos...esas cosillas.

Espero que conseguir muchos lectores, eso significará que a alguien le interesa lo que escribo :P, bueno, ¡hasta otra!.