Información blog

Linux, tutoriales, noticias, sistemas, redes y seguridad informática, entre otras cosas.

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

martes, 29 de octubre de 2019

Cómo realizar pruebas de carga en nuestro servidor Web

Una de las labores más importantes a la hora de montar un servidor web, es la dimensionarlo correctamente para poder realizar sus labores de forma efectiva. Generalmente a la hora de realizar el dimensionamiento se suele tender a optimizar el servidor lo máximo posible, con los recursos disponibles, para poder soportar el máximo de conexiones posibles, pero aun así, siempre es importante intentar forzar dicho servidor por encima de su capacidad máxima con el fin de ver cómo reacciona... Esto puede ser una labor sencilla si el servidor soporta muy pocas conexiones, pero y si soportase 1000 conexiones simultáneas o más? Afortunadamente existen herramientas especializadas de Linux que nos pueden ayudar a realizar testear nuestro servidor web... Entre ellas hay dos especialmente conocidas: Apache Benchmark  y JMeter.

portada_pruebas_carga

Apache Benchmark

Si bien esta utilidad se puede considerar bastante inferior a JMeter, se trata de una utilidad que tiene la ventaja de que te permite realizar pruebas rápidas desde la consola sin tener la necesidad de tener una interfaz gráfica, cosa que evita el obligarnos a depender de un entorno de escritorio para poder utilizarla. La herramienta en sí es muy fácil de instalar, ya que es parte del conjunto de utilidades estándares de Apache2, llamada apache2-utils, con lo que lo podemos instalar de los repositorios tal que así:

apt-get install apache2-utils

Con esto instalado, podemos hacer pruebas de carga de forma muy rápida mediante el comando ab; donde la sintaxis sería:

ab -c concurrencias -n numero_de_peticiones -r URL

El parámetro -r sería importante, ya que evitaría que el comando se interrumpiese aún cuando hubiese algún error... Además es importante resaltar que la URL tiene que apuntar siempre a un fichero web... Por ejemplo si tenemos un servidor web con IP 127.0.0.1, no valdría con poner dicha IP como URL sino que habría que poner http://127.0.0.1/index.html pues en caso contrario Apache Benchmark pensaría que la URL es errónea.

En caso de querer hacer 1000 peticiones con 20 concurrencias a la URL atrás mencionada, haríamos:

ab -c 20 -n 1000 -r http://127.0.0.1/index.html

Esto nos daría como resultado una serie de líneas, entre las cuales se resaltarían las últimas donde se muestran el porcentaje de paquetes que ha tardado X milisegundos en tener respuesta:

prueba_carga_ab
Resultado prueba carga Apache Benchmark

Lo malo que tiene esta herramienta, es que carece de opciones de personalización a la hora de realizar las pruebas de carga; es decir, no puedes decir si las peticiones se van a hacer de forma controlada, o como un ataque DOS... Simplemente las realiza lo más rápido que puede y listo... Lo cual viene por un lado bien para saber cómo se comporta bajo cierta presión, pero que no emula entornos realistas. Es por eso que esta herramienta tienes sus pros y sus contras y es ahí donde JMeter marca la diferencia, ya que dicha herramienta sí que tiene un mayor abanico de opciones.

Apache JMeter

En este caso para poder siquiera instalar la aplicación es 100% necesario tener instalado un entorno de escritorio, pues instalar elementos gráficos. El entorno de escritorio en sí es indiferente, puede ser XFCE, KDE, Gnome... Al gusto de cada uno... Cumpliendo dicho requisito habría que escribir en la consola:

apt-get install jmeter

Esto preparará todo lo necesario para que Jmeter sea utilizable, si bien Jmeter tiene una peculiaridad. La configuración de los diferentes parámetros y planes de pruebas se realizan desde de la GUI, pero la ejecución del plan de pruebas es extremadamente recomendable hacerlo desde la consola; recomendación que es dada por los propios desarrolladores de la utilidad.

Con lo que teniendo esto claro, primero abriríamos la aplicación desde la GUI, aplicación que, desgraciadamente, al ser tan completa, puede ser algo intimidante inicialmente.

El primer paso que habría que ejecutar sería la creación de un Grupo de Hilos; dicho paso es vital pues marca el número de peticiones simultáneas que se harían, el intervalo entre éstos y el número de veces que se lanzarían peticiones (pudiendo ser infinito); las capturas de a continuación serían realizadas desde un Ubuntu 18.04, capturas en las que, en este caso mostraríamos 100 peticiones simultáneas realizadas cada segundo continuamente :

nuevo_grupo_hilos
Nuevo grupo hilos

configuracion_grupo_hilos
Configuración grupo hilos

Con esto tendríamos las peticiones preparadas; lo que habría que especificar sería qué peticiones se desean realizar... Aquí tenemos diferentes opciones, pero la más común y usada sería una petición HTTP; petición en la que únicamente sería necesario especificar que sería del tipo GET y la IP y puerto de destino de dichas peticiones; habría una serie de parámetros adicionales, pero todos ellos serían completamente optativos:

nueva_peticion_http
Petición HTTP


opciones_peticion_http
Opciones petición HTTP

Por último pero no por ello menos importante, tendríamos que crear un reporte de resumen, el cual nos servirá para conocer los resultados de nuestras pruebas. El cual se encontraría dentro de: Añadir --> Receptor --> Reporte Resumen.  El resumen se puede ver en texto plano desde la propia consola, pero desde la herramienta tendríamos el resultado mostrado de forma sintetizada, lo cual nos es ventajoso.

Ahora que tenemos todo preparado, guardaríamos el proyecto, el cual siempre es guardado en formato .jmx, por ejemplo plan_de_pruebas.jmx. Solamente sería necesario ejecutar dicho plan, ejecución que aunque se puede hacer desde la GUI, tal y como he comentado antes es recomendable hacerlo desde la consola. El comando para ejecutarlo sería:

jmeter -n -t plan_de_pruebas.jmx -l Resumen.jtl

El parámetro -l seguido del fichero jtl sería importante, pues estaríamos especificando donde guardar los resultados de las pruebas realizadas; pruebas que siempre se guardan en ficheros en formato .jtl, si bien se puede leer de forma "normal" haciendo un simple cat sobre dicho fichero.

Gracias a dicho comando estaríamos ejecutando el plan de pruebas, que se estaría ejecutando de forma continua a menos que se pulsase la combinación de teclas CTRL + C, debido a que se trata de una prueba infinita. Esto estaría haciendo una prueba de carga "infinita" sobre el servidor de destino, prueba sobre la que tendríamos más control que mediante Apache Benchmark.

El informe de salida lo podríamos leer dirigiéndonos al `Reporte resumen` antes creado y clickando en navegar para seleccionar el informe generado por nuestras pruebas; en nuestro caso Resumen.jtl... A continuación una pequeña muestra de dicho informe:

reporte_resumen
Informe Jmeter


Como se puede observar, la aplicación JMeter ofrece una amplia gama de posibilidades; estas son solo algunas de ellas, pero las mostradas serían las más "comunes" y usadas. Eso no implica que Apache Benchmark no sea útil; cada una ofrece una serie de características, la cuestión está en saber qué aplicación se adapta mejora nuestras necesidades, al igual que también no siempre se puede contar con una interfaz gráfica, y ahí es donde JMeter flaquea, pues dicho entorno es un requisito para la propia instalación.

Espero que os haya resultado útil.

Saludos.

lunes, 21 de octubre de 2019

Cómo solucionar el error too many open files en Linux

En un servidor en producción de Linux con bastante carga pueden ocurrir errores tipo "Too many open files" o que los servicios no puedan abrir más sockets (ficheros) de conexión. Esto se debe a que en Linux se pueden establecer limites de ficheros abiertos simultáneamente y ésta limitación es por usuario.  Puede parecer un error raro, pero en caso de tener un servidor SQL y/o web, no es un error tan extraño, dependiendo del volumen de información tratado.

toomanyopenfiles

Para solucionarlo hay que cambiar la configuración en varios sitios, pero primero hay que comprobar la configuración actual:

ulimit -n

Esto nos indicará la cantidad máxima por usuario y sesión. El valor por defecto es 1024, lo que aunque en un principio, pueden parecer muchos, no siempre dan basto, especialmente cuando se trabaja con un sistema que tiene un servidor web/SQL instalado, ya que éstos trabajan con muchos ficheros temporales y los necesita mantener abiertos por cuestiones de rendimiento. Para cambiar este valor:

ulimit -n 75000

Este comando aplicará el cambio en términos de la sesión actual. Para hacerlo persistente tenemos que editar los límites a nivel de configuración del sistema, lo cual se realizaría en /etc/security/limits.conf

root soft core unlimited
root hard core unlimited
root soft memlock 131072
root hard memlock 131072
root soft nofile 999999
root hard nofile 999999

Luego, aparte de limites por usuario y sesión, existen limites a nivel del propio sistema operativo. Para ajustarlos habría que editar el fichero /etc/sysctl.conf, el cual realiza cambios a nivel de kernel,  y añadir esta línea al final:

fs.file-max = 999999

Con esto ya tendríamos el cambio aplicado, para que haga efecto podemos o bien recurrir al clásico reinicio o bien ejecutar el comando:

sysctl -p

Con esto ya tendríamos los nuevos límites establecidos en el sistema, evadiendo así los errores del tipo too many open files.

Espero que os haya resultado útil.

Saludos.

martes, 17 de abril de 2018

Hotlinking; qué es y como evitarlo en Apache 2

Todos aquellos que tienen un servidor web expuesto al público, saben que al hacerlo dejan dicho servidor expuesto al mundo, y aún con un firewall bien configurado para evitar, en su medida, ciertos ataques, saben que siempre se corre riesgo de que por un motivo u otro, la web deje de estar disponible, su tiempo de respuesta sea lento o que ésta sea vulnerada. Teniendo en cuenta que el objetivo de una web es que "todos" la vean, es harto difícil lograr combinar una seguridad "infranqueable" y disponibilidad, y lo peor de todo es que a veces, acciones insignificantes que no son malintencionadas, pueden afectar al rendimiento de nuestra web... Hoy quiero hablaros de dicho último en especial; concretamente de una acción llamada hotlinking.

hotlink_portada

El hotlinking es una acción que si bien en sí no es maligna, puede perjudicar a otros en determinados aspectos, pues se trata de el uso de imágenes de otros servidores en vez de imágenes propias para enriquecer el contenido de una web. A modo de ejemplo, supongamos que queremos añadir una imagen a nuestra web; tenemos dos opciones, o subirla a nuestro servidor, o hacer referencia a la URL de una imagen ya hospedada en otro servidor; la segunda opción se trataría de un hotlink. Esto en sí no es un problema cuando se tratan de pocas imágenes y pocos links... Pero sí que puede ser problemático cuando el número de hotlinks es muy alto; especialmente si las páginas desde las que se reciben los hotlinks son muy visitadas, pues cada vez que dicha imagen es cargada en la otra página, estaría consumiendo ancho de banda de nuestro servidor, ya que la imagen que estarían solicitando estaría alojada en nuestro servidor, con lo que en verdad nos estarían haciendo una solicitud de imagen a nosotros y no a ellos.

Con el fin de que el ancho de banda de nuestra web no sea consumido involuntariamente, lo ideal es protegernos del hotlinking; lo cual afortunadamente es sencillo de implementar en Apache 2. Para ello hay dos tipos de prevención de hotlinking; aquel que directamente te pone muestra una imagen nula o aquel que te muestra una imagen concreta (y diferente) con el fin de dar a entender que están realizando una práctica no deseada contra nuestras imágenes.

Para poder aplicar dicha medida de protección en nuestro servidor, lo primero que necesitamos hacer es tener el módulo mod_rewrite activado en nuestro servidor web Apache2. Dicho módulo es instalado por defecto con Apache2, pero al mismo tiempo se encuentra desactivado por defecto, con lo que primero activaríamos dicho módulo, lo cual es tan sencillo como escribir el comando de a continuación como root:
a2enmod rewrite 
Veremos que nos solicita reiniciar Apache2 con el fin de hacer efectivo el cambio, pero todavía no lo haremos debido a que necesitaremos hacer un pequeño cambio en la configuración de este servicio para que pueda trabajar con el módulo rewrite... Esto es debido a que Apache2 por defecto está diseñado para no trabajar con dicho módulo y para no permitir que se "sobrescriban" las políticas del servidor web. En este caso, al querer modificar el comportamiento del servidor para prevenir el hotlinking, editaremos el fichero /etc/apache2/apache2.conf; teniendo en cuenta que lo más común es que la página web esté alojada en /var/www/ (o en uno de sus subdirectorios), cambiaremos lo siguiente:

Antes:
<Directory /var/www/>
        Options Indexes FollowSymLinks
        AllowOverride none
        Require all granted
</Directory>

Despues:
<Directory /var/www/>
        Options Indexes FollowSymLinks
        AllowOverride all
        Require all granted
</Directory>

Con dicho cambio realizado, ahora sí que procederíamos a reiniciar Apache2 mediante el comando:
service apache2 restart
Una vez tengamos los preparativo realizados, pasaremos a implantar nuestra protección contra hotlinks, lo cual lograremos gracias a la intervención de un fichero que crearemos llamado .htaccess, cuya función es rescribir la configuración usada para el servicio web dentro del directorio en el que se aloja ésta y, también, dentro de los subdirectorios de la susodicha. En mi caso en concreto la web se encontraría alojada en /var/www/html, web en la cual estaría hospedada la siguiente imagen:

no_hotlink_prevent

Dicha imagen se encontraría desnuda en estos momentos, es decir que podría ser accedida desde cualquier otra web, con lo que dentro del directorio /var/www/html crearíamos el fichero .htaccess con el siguiente contenido:

RewriteEngine on
RewriteOptions InheritDown
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)://(www\.)?192.168.1.8/.*$ [NC]
RewriteRule \.(jpg|jpeg|png|gif)$ - [NC]

Desgranemos cada línea con el fin de entender el contenido del fichero y no hacer un simple copia-pega.

La primera línea, RewriteEngine on; habilita la posibilidad de realizar las opciones "rewrite" que se ejecutan a continuación, acciones realizadas gracias al módulo rewrite de Apache2; en caso de carecer de dicha línea o tener dicho valor establecido a off.

La segunda línea, RewriteOptions InheritDown, la cual es opcional, sirve para que los subdirectorios hereden la configuración aplicada en dicho .htaccess.

La tercera y cuarta línea, son las condiciones bajo las cuales se ejecutaría el rewrite. En ambas se tiene en cuenta qué IP o dominio va a hacer referencia a la web debido a que en la condición, RewriteCond, se revisa dicho valor gracias a %{HTTP_REFERER}, después del cual se dice desde donde se realiza una petición HTTP al servidor. Dicha petición se realizaría desde dos orígenes, desde el propio servidor (a nivel interno) para lo cual pondríamos el parámetro en cuestión vacío, lo cual se representa como: !^$. En cambio, para especificar nuestro host, tendríamos que escribir el nombre (o la IP) de éste teniendo en cuenta que se puede hacer referencia al host como http, https (si lo tenemos habilitado), con www o sin este. En mi caso el servidor Apache2 sería la IP 192.168.1.8. Además, veremos que al lado hay un parámetro llamado [NC]; dicho parámetro se encargaría de no hacer distinción entre mayúsculas y minúsculas.

Por último se pondría la re-escritura de "reglas" mediante el RewriteRule, el cual en este caso haría que todas las peticiones que HTTP que se hagan a las imágenes jpg,jpeg,png y gif, sean bloqueadas. Por ejemplo, si hacemos una petición a dicha imagen desde otro servidor web, veremos una imagen en blanco:


hotlink_block
Esto nos serviría para bloquear el hotlinking desde otros sitios; si deseásemos que se mostrase una imagen concreta que fuese indicativa de que tenemos la protección contra hotlinks activada, podríamos editar el contenido anterior para que en la línea RewriteRule nos redirija a una imagen local previamente preparada. La re-dirección la haríamos especificando la ruta local de dicha imagen.

RewriteEngine on
RewriteOptions InheritDown
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?192.168.1.8/.*$ [NC]
RewriteRule \.(jpg|png)$ /var/www/html/imagenes/candado.png [NC]

Ahora en caso de intentar acceder a la imagen desde un origen no grato, veríamos la imagen de un candado tal y como podemos ver en la siguiente captura:

hotlink_redirect

Esta medida puede ser incluso más efectiva que la del bloqueo, ya que sería claramente disuasoria de que las personas intenten hacer hotlinks a dichas imágenes propias y que en caso de desear mostrarlas, tengan la necesidad de descargárselas y subírselas a sus propios servidores.

Como podéis ver la técnica de prevención de hotlinks es fácil y sencilla de aplicar, medida que si bien puede uno pensar que no necesita, puede prevenirle a uno del consumo indeseado de ancho de banda; prevención que se puede aplicar de una forma muy rápida como se ha podido ver aquí.

Espero que os haya resultado útil.

Saludos.

lunes, 22 de mayo de 2017

DNSspoof; qué es y cómo reconocerlo

Existen hoy en día miles de forma de que la seguridad de uno se pueda ver afectada. Desde el reciente escándalo de WannaCry a ataques simples, pero efectivos que si bien son populares y conocidos, siguen siendo efectivos. Existen muchos, pero hoy me centraré en uno de ellos bastante interesante, tanto por su sutileza como por las formas en las que uno puede reconocerlo: El DNS Spoofing.

DNS_spoofing

Lo primero de todo que uno se puede preguntar es: ¿Qué es dicho concepto? ¿En qué consiste? Primero de todo hay que tener claro que la función del DNS (Domain Name Service) es la conversión de un nombre de dominio (el nombre de una web, por ejemplo) a una dirección de IP; por defecto toda comunicación entre equipos se realiza vía IP, pero debido a que recordar éstas es muy difícil para un humano, los DNSs hacen que solamente tengamos que recordar nombres; encargándose éste de la traducción. Es decir que lo que haríamos sería preguntar al DNS qué IP tiene el nombre de dominio al que queremos acceder, ya sea Facebook, Google, este blog o cualquier página a la que queramos acceder. Para tener más claro este concepto he aquí el siguiente esquema, que resume el funcionamiento de forma muy simplificada:

Diagrama_DNS
Diagrama DNS

La cuestión está que estas peticiones pueden ser interceptadas y ser redirigidas a otro lugar con el fin de engañar al usuario... Es decir que el DNS puede ser suplantado o spoofeado para que a la hora de decirle al equipo la IP del nombre de dominio, en vez de darle la IP correspondiente le de una falsa para que el equipo acceda a ésta. El pequeño esquema simplificado de a continuación puede ayudar a aclarar este punto:

diagrama_dns_spoof
Diagrama DNS spoofing

Esta suplantación puede parecer complicada, pero desgraciadamente no lo es tanto; solamente requiere de las herramientas adecuadas... La prueba de concepto de a continuación se ha realizado con un equipo Debian como atacante/suplantador, pero puede hacerse con cualquier otra distribución de Linux. Imaginemos que tenemos un equipo de sobremesa normal y corriente (no importa el S.O que esté usando) y otro equipo con Debian instalado... ¿Cómo puedo hacer con Debian para que el otro equipo acceda a una IP bajo mi control cuando quiera acceder a una página web conocida (Facebook, Twitter, Google...)?  Las IPs que usaré a modo de prueba serán la 192.168.1.1 (router), 192.168.1.2 (equipo que queremos que se dirija a otro DNS) y la 192.168.1.3 (equipo atacante).

Lo primero que hay que tener instalado en Debian sería el paquete dsniff, que incluye un conjunto de herramientas que incluye una serie de utilidades de pentesting, entre otras, estarían utilidades para ataques de Man in the middle y DNS spoofing. Esto es tan sencillo como hacer:

apt-get install dsniff

Con las herramientas en nuestro poder, el primer paso para suplantar el DNS sería el realizar un ataque de man in the middle entre el equipo victima (192.168.1.2) y el router (192.168.1.1) para así manipular más adelante el tráfico entre ambos. Hay varios tipos de ataques (para más detalles podéis acceder al link anterior) pero el que usaremos en esta ocasión será el arp spoffing, el cual consiste de únicamente 3 comandos:

El primer comando para realizar el ataque con éxito, sería la activación de reenvío de paquetes en la máquina atacante para que así al lograr realizar el ataque con éxito, no se corte la comunicación:

echo 1 > /proc/sys/net/ipv4/ip_forward

Ahora pasaríamos a realizar un envenenamiento de la tabla ARP tanto del router como del equipo, lo cual obedece a la sintaxis:

arpspoff -i interfaz_red -t equipo1 equipo2
arpspoff -i interfaz_red -t equipo2 equipo1

Lo que si lo aplicamos a este caso en concreto sería:

  1. arpspoff -i eth0 -t 192.168.1.2 192.168.1.1
  2. arpspoff -i eth0 -t 192.168.1.1 192.168.1.2

Con el ataque de man in the middle realizado, ahora tocaría tener claro qué nombre de dominio queremos suplantar y a qué IP lo queremos dirigir... Por ejemplo podemos decirle a la victima que cuando pida la IP del nombre de dominio facebook, la IP no sea la de facebook sino la del equipo atacante... Para ello, antes de nada vamos a crear un fichero llamado, por ejemplo, dominio_falso.txt con el siguiente contenido:

192.168.1.3  facebook.es

Este txt estaría diciendo que la IP de facebook.es sería la 192.168.1.3, es decir la IP del equipo atacante; ahora obviamente habría que hacerle creer a la victima que en efecto el nombre de dominio hace referencia a dicha IP.

dnsspoof -i eth0 -f dominio_falso.txt

Esto haría que toda petición realizada al nombre de dominio facebook.es, será redirigida a la IP falsa, IP que sería en este caso la del atacante. Este atacante tendría que tener un servidor web levantado con una apariencia similar al nombre de dominio original, cosa que se podría conseguir con herramientas especializadas tales como SET (Social Engineering toolkit), pero el objetivo de este post no es enseñar cómo hacer que la apariencia del sitio web falseado sea lo más "realista" posible, sino demostrar la relativa facilidad con la que se ha podido interceptar la petición DNS, con lo que no ahondaremos en dicho tema...

Obviamente lo suyo sería que el ataque hubiese sido bloqueado por herramientas de análisis de red o por diferentes políticas de seguridad pero... ¿Cómo podemos saber que el sitio web al que hemos accedido es el autentico? Hay diferentes cosas que se pueden tener en cuenta:

  • Ping: Al hacer ping al sitio web, veríamos que la IP no corresponde a una de las IPs pertenecientes a la web; es más para este ataque estaríamos viendo que al hacer ping a facebook estaríamos viendo que se está haciendo ping a una IP de clase C, usada para redes locales, cosa que no tiene sentido en una web pública.
  • Certificado: Los portales de login del 99% de los sitios web usan certificados SSL para securizar la conexión; si vemos una pantalla de login sin certificado alguno (es decir, si vemos que la web es HTTP y no HTTPS), habría que salir de allí de inmediato. Algunos ataques de DNSspoof usan certificados SSL hechos por ellos mismos, pero son certificados no validados por entidades certificadoras con lo que el navegador diría que la web estaría usando un certificado cuya veracidad no esté asegurada.
  • Analizador de red: Si usamos un analizador de red, podemos ver que habrá una brutal cantidad de paquetes arp fluyendo en nuestra interfaz de red, pues los ARP spoofing son muy agresivos y veremos, que no solo hay muchas ARP requests y replies ¡Si no que veremos que la MAC del atacante está duplicada y que pertenecerá a su propio equipo y al router!
  • ARP: Si consultamos nuestra tabla ARP con arp -n (Linux) o arp -a (Windows) veremos que habrá una MAC que pertenecerá a dos IPs distintas, lo cual será indicativo de haber sufrido un Man In The Middle.
  • DNSSEC: En caso de tener un DNS propio que esté protegido por DNSSEC, podemos verificar que nuestro DNS es efectivamente el que tiene que ser mediante el comando: dig DNSKEY nombre_dominio +multiline

Como veis existen diferentes recursos para comprobar la veracidad del sitio al que queremos acceder; desafortunadamente la mayoría de ellos requieren ser algo paranoico y que se realicen varias comprobaciones antes de entrar a un sitio, si bien eso no significa que dichas comprobaciones no sean recomendables, ya sea para este tipo de ataques u otros.

Espero que os haya resultado útil.

Saludos.

viernes, 20 de enero de 2017

Ataque de transferencia de zona DNS en Linux

En anteriores ocasiones ya he hablado sobre la importancia del DNS (Domain Name Service), y su configuración, pues se tratan de un servicio de una enorme relevancia que hace que Internet sea lo que hoy en día todos conocemos; basta con escribir un nombre de dominio para poder acceder a una web; evitándonos tener que memorizar las IPs de los sitios. Hoy quiero hablaros de una configuración especifica que tienen estos servidores; una configuración que puede convertirse en un arma de doble filo si no tenemos cuidado: Se trata de la transferencia de zona.

DNS_Portada

Lo más común en los entornos empresariales y/o pensados para dar servicio a un gran número de personas, es que los servidores DNS estén compuestos por varios equipos físicos: Un maestro y varios esclavos que estarían para ayudar a distribuir el tráfico y para que en caso de que el maestro se cayese, no nos quedásemos tirados. Para que no haya problemas con la información, cuando un DNS secundario es arrancado para convertirse en el DNS principal se realiza una transferencia de zona; transferencia que replicaría la "base de datos" del DNS y que, para bien o para mal, está activada por defecto. Veamos un sencillo ejemplo basado en el archivo de configuración named.conf.local de bind9.

  1. zone "pruebaivan2.net" {
  2.         type master;
  3.           file "/etc/bind/db.pruebaivan2";
  4. };
  5. zone "1.168.192.in-addr.arpa" {
  6.         type master;
  7.         file "/etc/bind/db.192";
  8. };

Esta configuración es una muy típica en los servidores DNS, con la diferencia de que obviamente las IPs serán distintas; pero lo importante no son los datos sino el concepto en sí. Si os fijáis bien, no hay ningún parámetro que haga referencia a la transferencia de zona; dicho concepto ya está por defecto activado. Esto está pensado para que así no haya restricción alguna para realizar la transferencia y que no haya ningún impedimento a la hora de pasar la información desde el servidor primario a algún secundario. El problema está en que dicha transferencia es abierta; es decir que se puede realizar la transferencia a cualquier destino; y he ahí el problema.

Todo sistema informático, tan pronto como está expuesto al público, es susceptible de ser hackeado; y el DNS, obviamente, no es una excepción; más aún cuando éste servicio es de vital importancia para evitar tener que memorizar direcciones IP.

Para hacer la prueba usaremos un comando muy conocido pero que cuyo uso no es tan extendido como otros comandos de red, tales como traceroute o nmap. Sería el comando dig, cuyo proposito es recavar información sobre un host en concreto o, en este caso, recabar y transferir dicha información. Hay que recalcar que dig en sí no es una herramienta con fines malignos; la cuestión está que toda herramienta puede tener diferentes usos dependiendo de quien la use.

Para realizar una transferencia de zona usaríamos la siguiente estructura del comando dig:

dig @host_origen axfr host_destino

El comando en sí haría lo siguiente: Mediante el @host_origen, haríamos referencia al DNS al que queremos realizar la transferencia de zona; el parámetro axfr especifica que la acción que se quiere realizar es la transferencia de zona; mientras que el host_destino sería el DNS al que queremos realizar la transferencia. Por ejemplo:

dig @pruebaivan2.net axfr pruebaivan2.net

Lo más impactante es que ni siquiera es necesario tener otro host propio; el propio host suyo puede darnos la información al realizar la transferencia de zona, ya que lo que estamos haciendo al realizar dicha transferencia sería actualizar y sincronizar los datos DNS existentes. Mirad este pequeño ejemplo:

lista_dns

Como podéis ver estaríamos viendo el contenido de la base de datos, cosa muy peligrosa ya que vemos qué información maneja, y la información es poder...

Afortunadamente tenemos una solución a dicho problema; una solución muy simple que no conlleva apenas esfuerzo por nuestra parte. Limitar la transferencia de zona para que haga las transferencias a unas IPs en concreto; IPs que nosotros conozcamos y que sepamos que son de "confianza". Para aquello editaremos el fichero named.conf.local y usaremos el parámetro allow-transfer. Dicho parámetro especificará qué IPs en concreto queremos que puedan realizar la acción de transferencia; cualquiera que lance la petición de transferencia que no tenga una de las IPs mostradas en dicho parámetro, simplemente no tendrá éxito.

  1. zone "pruebaivan2.net" {
  2.         type master;
  3.           file "/etc/bind/db.pruebaivan2";
  4.           allow-transfer {192.168.1.7; localhost; };
  5. };
  6. zone "1.168.192.in-addr.arpa" {
  7.         type master;
  8.         file "/etc/bind/db.192";
  9.         allow-transfer {192.168.1.7; localhost; };
  10. };

Obviamente, para aplicar los cambios habría que reiniciar el servidor DNS; es decir:

/etc/init.d/bind9 restart

Por último, para comprobar si en efecto la transferencia de zona está "capada"; tendríamos que, por un lado, ejecutar el comando dig a nivel local para ver que efectivamente todavía funciona la transferencia; y por otro lado ejecutar edig desde una IP no autorizada. En caso de realizar la petición de transferencia desde una IP inadecuada obtendríamos un mensaje de respuesta tal como el siguiente:

dnstransfer_fail

Como veis, una configuración descuida del servidor DNS puede resultar fatal, ya que podríamos estar dejando "abiertos" varios parámetros que por defecto están pensados para darnos flexibilidad, pero que pueden ser aprovechados por personas malintencionadas para obtener información de nuestros servicios.

Espero que os haya resultado útil.

Saludos.

sábado, 7 de enero de 2017

Cookies: Qué son y qué podemos hacer con ellas

Hoy quiero hablar sobre uno de los conceptos más famosos de todo Internet; concepto qué en algunos casos nos es mostrado hasta la saciedad: Las cookies. Sí, ese famoso concepto que generalmente vemos al visitar cualquier página web medianamente conocida y/o moderna. ¿Quien no ha visto mensajes parecidos a: "Al entrar a este sitio web, aceptas nuestra política de cookies?" Así es; es raro que no hayamos visto estos mensajes en la actualidad, pero más de uno nunca se ha parado a pensar en lo que ese texto conlleva o, mejor dicho, lo que dichas cookies, o galletitas, suponen.

cookies_portada

Las cookies son una serie de datos, almacenados en formato texto, que contienen datos de la sesión de navegación y los parámetros de configuración de la web, entre otros... Esos datos son creados por los servidores web y luego serían descargados y almacenados por el navegador web y pueden ser usados para hacer un seguimiento de nuestra navegación web. Además, es importante saber que hay más de un tipo de cookie; en concreto habría cinco tipos de cookies:

  • Cookies de sesión: Son aquellas que se eliminan automáticamente al terminar la navegación. 
  • Cookies persistentes: Estas cookies no importa que cerremos la sesión de navegación que seguirán guardadas en nuestro equipo para ofrecernos una experiencia más ágil la próxima vez que se viste la página, ya que guardan los datos de las sesiones, tales como los datos de login o las preferencias de idioma. Este tipo cookies tienen una fecha de caducidad tras la cual se eliminarían automáticamente; la cuestión está en que está que generalmente dicha fecha de caducidad puede ser a muy largo plazo; desde uno o dos años hasta 10,20 años o más... Con lo que hay que tener cuidado, ya que si no limpiamos nuestras cookies a menudo podríamos tener cookies de una enorme antigüedad guardadas en nuestro equipo; cookies que podrían contener información sensible. 
  • Super cookies: No, no son cookies con más información, sino cookies más peligrosas que el resto. Una cookie normal está siempre asociada a un nombre de dominio; ya sea bytelearning o el que sea, pero una super cookie está asociada a extensiones de dominio (.com, .es, .net...). Esto no puede parecer relevante, pero sí que lo es, ya que dichas cookies pueden seguir el "rastro" de una persona independientemente del dominio que visite. Afortunadamente la mayoría de los navegadores más modernos ya bloquean dicho tipo de cookie automáticamente, pero si se estuviese usando una versión antigua de Chrome o Firefox podríamos sin querer "comernos una galleta equivocada".
  • Cookies zombies: Cookies que aún cuando son borradas, son generadas de nuevo debido JavaScript o HTML5.
  • Cookies Flash: Esta "cookie" es un archivo especial usado por las páginas web que implementan Flash. Para bien o para mal, estas cookies cada vez son menos frecuentes, pues hay navegadores que directamente bloquean Flash por defecto; tales como Chrome y Firefox.

Ahora bien; estas cookies que son almacenadas por el navegador, tienen que estar almacenadas en algún lado... ¿Pero donde? La ubicación de éstas dependería de dos factores: El navegador y el sistema operativo. En mi caso me centraré en el sistemas operativos basados en GNU/Linux y los navegadores más populares; Chrome y Firefox.

En chrome:

La ubicación de las cookies, en caso de estar usando este navegador sería:

~/.config/google-chrome/Default/cookies

En Firefox:

En caso de usar este navegador o Iceweasel (que para el caso son prácticamente iguales).

~/.mozilla/firefox/serie_de_numeros_y_letras.default


Ambos tipos cookies pueden ser leídas tanto mediante la consola con sqlite (cosa no demasiado recomendable, debido a que lo mostrado no queda demasiado ordenado) o con sqlitebrowser, que se trata de una aplicación gráfica que muestra dicha información de forma más intuitiva y amigable. Esta última aplicación no estaría por defecto instalada pero su instalación sería algo tan sencillo como:

apt-get install sqlitebrowser

Esta aplicación es muy amigable pero tiene como pega el hecho de que requiere introducir la ruta completa donde se encuentra alojada la cookie; ruta que por defecto está oculta (todo aquello que empieza por . significa que el fichero o directorio está oculto) y que es algo engorrosa de introducir a la hora de querer abrir la base de datos que almacena dichas  cookies. Con lo que si bien este método "global" es muy potente y versátil, lo más cómodo para un usuario final sería revisar las cookies de su navegador especifico con una herramienta más "directa".

Las opciones más amigables serían el uso de extensiones especificas para cada navegador; aquí, como siempre para gustos están los colores, pero la extensión con la que me he sentido más cómodo con cada navegador sería:

  • Firefox: Cookies Manager. Es un gestor de cookies bastante sencillo a nivel visual, pero que cumple con su objetivo; que es el poder visualizar, editar o eliminar nuestras cookies.
  • Chrome: Edit this Cookie. Tiene las mismas funciones que la mencionada antes para Firefox, si bien ésta es algo más atractiva a nivel visual.

cookies_manager
Cookies Manager Iceweasel

Gracias a estas herramientas podemos controlar con gran libertad nuestras cookies, logrando tener cierta noción de las cookies que están siendo descargagadas a nuestro equipo.

Como veis, las cookies es un asunto bastante amplio y completo; aunque afortunadamente hoy en día contamos con gran número de recursos para tenerlas bajo control y saber qué se está descargando nuestro equipo. Además gracias a recursos tales como la navegación privada y/o el no recordatorio del historial, nos pueden ayudar a no almacenar esas cookies persistentes que pueden llegar a ser contraproducentes almacenar dependiendo de nuestras necesidades.

Saludos.

miércoles, 2 de noviembre de 2016

Cómo concatenar varios proxys con proxychains

La privacidad y seguridad de nuestras conexiones es un asunto cada vez más demandado en la actualidad y uno de los aspectos más atractivos es el ocultamiento de nuestra dirección IP pública real... Muchas veces querremos que al conectarnos a un sitio, cuando éste revise sus logs vea una dirección ip que no sea la nuestra, para lo cual hoy en día se usan generalmente dos métodos: Uno de ellos es el famoso y polémico TOR, y otro sería el uso de uno o varios proxys. Puede que nos puedan parecer iguales, debido a que el objetivo final es ocultar nuestra IP, pero mientras que TOR usa el "encaminamiento cebolla" en sus conexiones, y usa la topología punto a punto, aquí usamos una red entre iguales pero haciendo que varios equipos enmascaren nuestra dirección IP pública.

mapa_mundo

Para entender mejor este concepto podemos plasmarlo con un par de imagenes que nos pueden resultar muy esclarecedoras. A modo muy, muy resumido podríamos decir que cuando nos conectamos a un servidor, lo que hacemos es conectarnos desde una IP pública (que sería la de nuestro router) a otra IP que pertenecería al servidor de destino. Es decir que haríamos algo parecido a esto:

Esquema_simple

Repito que esto está muy simplificado y que hay muchos más elementos de por medio: Routers, ISPs, DNSs... Pero a nivel teórico este esquema nos es suficiente para entender el concepto. La cuestión está en que al conectarnos al servidor directamente, los logs del servidor mostrarán que la conexión se ha realizado desde nuestra IP pública, cosa que dependiendo para qué prueba o acción, no nos interesa que sea así, más aún cuando nuestra IP muestra información tan valiosa cómo la geolocalización o incluso el navegador usado. Para evitar proporcionar esta información usaremos varios proxys para realizar varios enmascaramientos de IPs, lo que se traduciría en el siguiente esquema:


Diagrama_red_proxy

Este esquema vendría a significar lo siguiente:

  1. Desde la IP 10.1.185.10 nos dirigimos al proxy con IP 200.60.250.10.
  2. Desde el proxy con IP 200.60.250.10 nos conectaremos al proxy con IP 200.60.250.11; este nuevo proxy verá que la IP de origen de la conexión será 200.60.250.10.
  3. Una vez más desde el proxy con IP 200.60.250.11 nos conectaremos al proxy con IP 200.60.250.12; aquí la IP que verá el proxy será la 200.60.250.11.
  4. Por último nos conectamos a la IP 216.58.210.195, solo que éste verá que se han conectado desde la IP 200.60.250.12.

Gracias a esto tendremos varias "capas" de protección que dificultarán que sepan la IP real de origen, lo cual hace que el servidor final no tenga nuestra información real y evitando que pueda "jugar" con nuestra IP para cualquier "experimento". 

A sabiendas de las ventajas que nos ofrece el uso de varios proxys, usaremos una herramienta que nos facilitará el uso concatenado de éstos; esta herramienta se llama proxychains y si bien no está instalada por defecto en ningún equipo, instalarla es tan sencillo como escribir en la consola:

apt-get install proxychains

Con esto instalaríamos el paquete en cuestión, aunque obviamente no tendría configuración alguna... Dicha configuración se realizaría dentro del fichero /etc/proxychains.conf. Este fichero tiene dos conceptos muy importantes: El cómo tratar el listado de proxys, y la lista de proxys. Al hacer referencia al tratamiento del listado estaríamos hablando de cómo hacer la conexión a través de la lista de proxys. Hay tres tipos de tratamiento, y siempre tiene que haber solamente uno de ellos activo:


  • dynamic_chain: Se conecta al listado de proxys por orden, pero en caso de que uno de éstos estuviese offline, pasaría al siguiente. Por defecto está opción está comentada; es decir que comienza por el carácter #.
  • strict_chain: Funciona igual que dynamic_chain, con la diferencia de que aquí es necesario que todos los proxies estén online para que la conexión funcione. Es la opción habilitada por defecto si bien lo recomendable suele ser optar por usar dynamic_chain.
  • random_chain: En este caso el orden de conexión no importa pues selecciona el orden de conexión aleatoriamente.

Al querer nosotros tener la opción dynamic_chain habilitada y strict_chain deshabilitada, tendríamos que quitar el caracter # de la línea dynamic_chain y agregar dicho carácter al comienzo de la línea strict_chain, tal y como muestra la captura de a continuación:


dynamic_chain

Obviamente faltaría la parte más importante, que sería el listado de proxys; una sección que comienza con la nomenclatura: [ProxyList]. Cada línea del listado tendría esta estructura:

Tipo IP puerto [usuario contraseña]

El motivo por el cual los últimos dos campos están puestos entre [ ] es debido a que son opcionales... Algunos proxys requieren contraseña, si bien lo normal es que no; es por eso que estos dos campos no son obligatorios. Para conocer todos estos datos podemos consultar por Internet los proxys disponibles hoy en día; por ejemplo hay una página muy completa en Español que te da toda la información de éstos, incluyendo el tipo de conexión; esta página se llama: https://incloak.es/proxy-list/. Obviamente esto es una referencia y hay muchísimas páginas de las que obtener listados de proxys.

Aquí simplemente tendremos que seleccionar los proxys que queremos añadir y los pondremos dentro de nuestra sección ProxyList. Por ejemplo nosotros añadiremos 2:

  1. [ProxyList]
  2. http    134.213.148.8   3124
  3. http    88.208.238.110  3128

Ahora únicamente habría que ejecutar el comando que queramos precedido por el comando proxychains; gracias al cual haríamos que la interacción de red realizada por dicho comando se realice mediante los proxys puestos en la lista. Varios de estos comandos que pueden seguir al comando proxychains serían: firefox, curl o wget. En caso de tener problemas con los proxys que hemos añadido, simplemente habría que buscar otros hasta encontrar los que mejor se adapten a nuestras circunstancias y/o geolocalización.

Con esto tendríamos una conexión mucho más segura que nos ocultaría nuestra dirección de origen al usuario final. Tened en cuenta que esta técnica está diseñada para fines benignos y que la mayoría de los proxys recogen y analizan las conexiones, con lo que pensad en esto como una técnica de protección y nada más.

Por último, simplemente recomendaros que escojáis con prudencia los proxys que queráis utilizar y que tratéis de buscarlos en páginas de confianza, pues en caso contrario, quien sabe a quien le podríais estar dando la información de vuestras conexiones.

Espero que os haya resultado útil.

Saludos cordiales.

viernes, 16 de septiembre de 2016

Cómo filtrar accesos no deseados en Linux por países

El tener un equipo expuesto en la red se ha convertido en una práctica cada vez más extendida, y obviamente ello a hecho que también se convierta en una práctica cada vez más peligrosa. Los cybercriminales no cesan de intentar vulnerar diferentes servicios expuestos en la red: HTTP, SSH, Asterisk, telnet, FTP... Generalmente uno piensa ¿Quien va a querer hackearme a mí? Pero hemos de tener en cuenta que hay una gran cantidad de ataques que son efectuados por herramientas automáticas que simplemente buscan IPs en la red e intentan acceder a ciertos servicios de éstas, indistintamente de si se es un particular o una empresa. Las técnicas de ataque van evolucionando con el tiempo, siendo cada vez más sutiles y efectivas, con lo cual las defensas tienen que ser equiparables para poder salvaguardar los servicios expuestos en Internet.  Una buena medida es bloquear el acceso dependiendo del país de origen de la conexión.

firewall_country

Generalmente deseamos que todo el mundo pueda acceder a nuestro contenido desde cualquier origen, especialmente si hablamos de una web, pero hay ciertos países que tienen fama por realizar cyber-intrusiones en sistemas ajenos y que dependiendo del contenido o idioma de nuestra web, no tiene sentido que accedan; me explico: Este blog está escrito en castellano al 100% y si bien es uno de los idiomas más hablados del mundo, hay países que por un lado tienen fama por vulnerar sistemas informáticos, y que por otro lado poseen una tasa muy baja de hispanohablantes, por no decir que casi nula. Dos de esos países que tienen un gran fama por cumplir ambas condiciones serían Rusia y China, con lo que ver conexiones con dichos países de origen sería bastante inusual... Es más, hay varios sitios que, estén el idioma en el que estén, suelen bloquear esos países debido a su alta tasa de ataques cybernéticos, cosa que es más sencilla de lo que parece gracias a una combinación de iptables y xtables_addons.

Xtables_addons son una serie de complementos que se aplican sobre el kernel y que hacen que iptables tenga un mayor número de funcionalidades de las que ya de por sí traen (que no son pocas). Estos complementos se pueden instalar directamente gracias a los repositorios oficiales del sistema escribiendo lo siguiente:

apt-get install libtext-csv-xs-perl xtables-addons-common xtables-addons-dkms

Esto hará que instalemos todas las dependencias necesarias para poder usar los addons, en concreto uno de ellos que nos interesa especialmente llamado GeoIP y que asocia unos rangos de IPs con sus respectivos países. Aún así, si bien la funcionalidad está preparada, no contiene dato alguno con el que poder reconocer qué ip está asociada a qué país; es por eso que lo primero que tendremos que hacer será descargarnos la base de datos que contiene dicha información; base de datos que no tendremos que descargarnos desde ninguna web, sino que podemos descargarnos desde un script:

  1. cd /usr/lib/xtables-addons/
  2. ./xt_geoip_dl

Este proceso nos descargará un fichero en formato .csv llamado GeoIPCountryWhois.csv que contendrá toda la información; el problema radica en qué dicha información no es reconocible por iptables ni por xtables_addons, y es por ello es necesario hacerla "legible" para ambas herramientas. Para ello primero hay que crear un directorio llamado LE dentro del directorio /usr/share/xt_geoip para después ejecutar el comando que hará el csv legible y que hará que la información correspondiente se guarde dentro del directorio que hemos creado:

  1. mkdir /usr/share/xt_geoip/LE
  2. /usr/lib/xtables-addons/xt_geoip_build -D /usr/share/xt_geoip/ GeoIPCountryWhois.csv

Este proceso mostrará una salida en la que se verán los países junto con el número de IPs asociados a éstas, IPs que pueden ser tanto IPv4 como IPv6... El listado mostrado es enorme, pero he aquí un pequeño extracto para que os hagáis una idea de la salida del último comando:

BD_GeoIP

Ahora tanto iptables como xtables son perfectamente capaces de asociar las IPs a sus respectivos países, con lo que llegaría el turno de añadir nuevos filtros que nos proporcionen cierta seguridad. En este caso nos encargaremos de filtrar tanto los proxies anónimos como los países Rusia y China. Para ello combinaremos las reglas habituales de iptables junto con las características especiales ofrecidas por los addons instalados. Toda regla que incluya la característica GeoIP, tendrá las siguiente estructura básica:

iptables -A INPUT -m geoip --src-cc $SIGLAS_ORIGEN -j $ACCION

Al hacer referencia a las siglas del origen, estaríamos haciendo referencia al origen de la conexión. Por ejemplo los proxies anónimos tendrían las siglas "A1", mientras que china tendría las siglas "CN". La acción a tomar quedaría a nuestra elección, pero generalmente sería o ACCEPT (para aceptar la conexión de dicho origen) y DROP (denegar dicho acceso). Partiendo de la base de que vamos a aceptar las conexiones de todos lados a excepción de unos lugares concretos usaremos la acción DROP para el ejemplo de a continuación.

  1. iptables -A INPUT -p tcp --dport 21:23 -m geoip --src-cc A1 -j DROP
  2. iptables -A INPUT -m geoip --src-cc CN-j DROP
  3. iptables -A INPUT -p udp --dport 5060 -m geoip --src-cc RU -j DROP

En este pequeño ejemplo estaríamos haciendo que no se pudiese acceder a los puertos 21,22 y 23 (protocolo TCP) desde proxies anónimos, que ninguna conexión procedente de China fuese posible y que todo intento de conexión hacia el puerto 5060 (protocolo UDP) procedente desde Rusia fuese posible. Obviamente estas son meras reglas de ejemplo y cada uno podría elegir el país que desee y las reglas de filtrado que más se adapten a sus necesidades.

Como podéis observar el filtrar conexiones por países no es complicado; si bien la primera instalación es algo incomoda, la gestión de las reglas del cortafuegos tras dicha instalación es una tarea muy cómoda que cualquier que tenga ciertas nociones de iptables puede realizar sin problema alguno.

Espero que os haya sido útil.

Saludos.