Eramos tan pobres…

En Argentina, país bananero si los hay, que nos hace bien cuesta arriba el acceso a nuevas tecnologías, cuando algo se rompe, lo atamos con alambre para seguir usándolo.

Este es uno de esos casos: Resucitar esos viejos módulos de memoria RAM rotos, que ya dabas por muertos y que de otra forma no servirían mas que para hacerse un llavero y competir contra tus amiguitos –cada cual mas nerd que el anterior– a ver quien tiene mas megas de ram desperdiciados en el bolsillo.

…Había una vez, un tal Rick Vanrein, que era mucho mas pobre que todos los Argentinos juntos y que sabía de programación. Motivado por un interés púramente económico escribió en su página web:

Summary: This page proposes an approach to support RAMs with defective addresses, This may open interesting business perspectives, where those RAMs can be sold under a white label for less money rather than discarded of without any profit.

Claro que no tuvo en cuenta que su idea de negocio iba en contra de la producción en serie y que globalización –y chinos que trabajan por el plato diario de arroz– de por medio el costo de fabricación de memoria RAM se abarataría muchísimo dando por tierra con su proyecto.

Lo importante es que lo hizo: BadRAM, un módulo para el kernel de linux que permite a este sistema operativo funcionar normalmente inclusive cuando la memoria RAM está en mal estado.

¿Y como funciona?

Facil, se basa en la salida de memtest86 para saber cuales son las direcciones de memoria defectuosas y por medio del gestor de arranque, pasárselas como parámetro al kernel para que no las use. Genial, ¿No?.

Como se usa:

Primero lo primero; Tu kernel tiene que tener soporte para BadRAM. En kernels relatívamente nuevos (desde 2.6.16 si no recuerdo mal) BadRAM viene ya pre-incluído en el kernel… A lo sumo tocará activarlo si no lo estuviera pero eso está «out of the scope of this guide» como dicen en inglés cuado quieren decir «me da flojera entrar tan en detalle».

En versiones anteriores del kernel se puede incluir soporte para badram bajando el parche en cuestión y recompilando el kernel parchado:

~ # cp BadRAM-2.6.19.1.patch /usr/src/linux

~ # cd /usr/src/linux

~ # patch -p1 < BadRAM-2.6.19.1.patch

Segundo – Memtest86:

Habiéndole dado soporte a tu kernel para BadRAM si hiciera falta, bien por medio del parche o bien habilitándolo en donde el kernel lo incluya por defecto, lo siguiente es ejecutar memtest86 para diagnosticar cuales son los rangos de direcciones de memorias que están fallando.

De nuevo, memtes86 viene de serie hoy en día incluído en el kernel por defecto y habilitado o no dependiendo de cada distribución.

Ejecutado memtest, tendrán en pantalla algo como esto:

Memtest86 enseñandole a ese módulo de memoria defectuoso quien es el jefe.

Memtest86 enseñandole a ese módulo de memoria defectuoso quien es el jefe.

Lo importante es cambiar la configuración de memtest86 para que muestre los errores de salida en formato badram. Esto se hace con la tecla «C» para entrar en la configuración, activando la opción 5 – Error Reporting Mode y por ultimo eligiendo la opción 2 – BadRam Patterns, saliendo de cada menú y submenú con la tecla «0»

Hay que dejarlo correr al menos una «pasada» completa de tests.

Arriba a la derecha el primer indicador de porcentaje indica justamente el avance de cada pasada.
Al terminar una pasada completa en pantalla quedan una serie de rangos de memoria expresados en hexadecimal que se ven mas o menos así:

badram=0xfefdffc,0x2404ea30,0xfe05fffc etc.

Tomar nota (yo lo hice en papel pero seguro hay una forma mas elegante de hacerlo) de todos estos rangos de memoria que fallan para pasarselos al kernel.

Por último, iniciar la PC en modo «lo mas seguro posible»

Iniciar la pc en modo interactivo frenandola con la tecla «4», o pasarle init=/bin/bash a la línea que menciona al kernel editando al vuelo el menú de Grub, o bien cambiando las memorias rotas por unas en buen estado.

Montar /boot/ si no lo estuviera y agregar una entrada nueva para BadRam en /boot/grub/menu.lst que en mi caso quedó así:

title  Gentoo Linux Kernel 2.6.30-r4 con memorias rotas
root (hd0,0)
kernel /boot/kernel2.6.30-r4 root=/dev/sda2 badram=0x2400ea30,0xff81fffc,0xffd07ffc,0x24016a30,0xfe01fffc

Y eso es todo! Linux se salteará limpiamente las direcciones de memoria conocidas como defectuosas con lo que no deberías volver a tener inconvenientes siempre y cuando tu memoria RAM no se siga rompiendo con el uso.

Si se dispone del tiempo necesario, es conveniente dejarle hacer como mínimo dos pasadas a memtes86 antes de fiarse de los resultados. Cuantas mas, mejor. Aveces ciertas fallas se presentan recién después de un tiempo de uso, cuando el modulo dimm toma temperatura.

Bajo la premisa: «No es que yo sea paranoico, es que me están siguiendo…» alguien ha creado un par de scripts que hacen a tu pc ridículamente segura y hasta le ha dado nombre (y apellido); Crypto Port Knocking 0 Single packet authentication. –o ambas cosas juntas, en realidad–

Sencillamente genial.

¿Creíste que tu Linux con SELinux, ACL, Port knocking, Fail2ban, Snort, OSSEC, sin puertos abiertos, con autenticación SSH basada en llaves, con el usuario root deshabilitado y todos los servicios enjaulados, los DNS y la tabla ARP estática era seguro?

No… No es seguro. Al menos no para el creador de esta obra maestra de la seguridad que ha llevado la cosa a tal extremo que raya con el absurdo.

Si te interesan estos temas, después del salto viene lo bueno. Es fundamental tener una noción básica de bash y entender un poco de inglés para echarlo a andar:  Continúa leyendo

Viene de este otro artículo anterior, a raíz de la necesidad de ejecutar aplicaciones remotas en el servidor X local usando X11-Forwarding sin que se nos pregunte una contraseña. (Ideal para el acceso directo de la dama o el alias de bash del caballero).

Normalmente, si necesitamos conectarnos a un servidor SSH habitualmente, tendríamos que especificar el nombre de usuario y una contraseña. (Se especifica el usuario únicamente si nos autenticaremos remotamente como un usuario distinto al usuario que localmente ejecutará ssh)

Al cabo de un tiempo esto termina volviéndose tedioso por lo que usar un juego de llaves (key authentication) es la mejor solución.

Por otro lado, desde el punto de vista de la seguridad, –además de correr sshd en un puerto no privilegiado (de 1024 en adelante) y el buen fail2ban controlando los logs- la autenticación por llaves es muchísimo mas confiable en la medida en que nuestra clave privada se mantenga así (privada) y no caiga en manos de nadie.

Habiendo generado nuestro par de llaves RSA para autenticación ssh, una llave privada, y una pública, basta con copiar nuestra llave pública a todo servidor o pc contra la cual nos autenticaremos para que nos deje entrar sin preguntar quien está en la otra punta ni cual es la contraseña.

Sea cual sea el motivo que te lleve a implementar autenticación por llaves, por comodidad o por seguridad, veamos como se pone en funcionamiento:

Generar el par de llaves:

El comando ssh-keygen, que viene de serie con el paquete openssh es el encargado de generar nuestro juego de llaves:

~ $ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/mn/.ssh/id_rsa):
Created directory ‘/home/mn/.ssh’.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/mn/.ssh/id_rsa.
Your public key has been saved in /home/mn/.ssh/id_rsa.pub.

Dejando la contraseña (passphrase) en blanco durante el proceso, he generado mis dos llaves, la pública: id_rsa.pub dentro del directorio /home/mn/.ssh/  y la privada: id_rsa dentro del mismo directorio.

Copiar la llave pública a la ubicación remota:

Usando secure copy movemos nuestra clave pública hasta el servidor que frecuentamos:

~ $ scp ~/.ssh/id_rsa.pub usuario@servidor:

Instalar la llave pública en la ubicación remota:

Nos logueamos en el servidor (que todavía nos preguntará la contraseña):

~ $ ssh usuario@servidor

Password: **********
Last login: Wed Jul 29 23:19:44 ART 2009 from 5.192.233.114 on ssh

Y copiamos el contenido de nuestra llave pública dentro del archivo authorized_keys en el directorio  ~/.ssh/:

~ $ cat id_rsa.pub >> ~/.ssh/authorized_keys

~ $ exit

¡Y eso es todo!

Si nuevamente intento loguearme usando SSH en este servidor, ya no pregunta mi contraseña. Mi llave privada se coteja contra la llave pública y me permite el acceso de forma cómoda e instantanea:

~ $ ssh usuario@servidor
Last login: Wed Jul 29 23:20:09 ART 2009 from 5.192.233.114 on pts/0
servidor ~ $

Es importantísimo tener en cuenta que este método planteado, si bien es mucho mas seguro que el método tradicional de autenticación –que es vulnerable a ataques de fuerza bruta– a la vez representa un gran riesgo para la seguridad si alguien se hace con nuestra llave privada.

Quien tenga acceso local a la pc que almacena la llave privada automáticamente tiene acceso remoto a las pc o servidores que conocen nuestra llave pública.

Existiendo la posibilidad de especificar un password en nuestra llave privada automáticamente el sistema se vuelve seguro ya que en el caso de que este password no esté en blanco:

  • El acceso SSH no es vulnerable a ataques de fuerza bruta.
  • Nuestra clave privada no se puede desencriptar sin conocer el password.
  • Se nos pide el password de la clave privada en lugar de el password de usuario para iniciar sesión.

En este último caso se pierde la comodidad de loguearnos sin contraseña. Se nos pregunta la contraseña pero de la llave y no del usuario en cuestión. Esto también se puede automatizar haciendo uso de ssh-agent, pero es tema para otro artículo, para no complicar demasiado las cosas.