viernes, 23 de mayo de 2014

introduccion a SQLAlchemy python ORM

Dejo aquí mi paso por pybcn.org, SQLAlchemy es mucho más, pero solo eran 20 minutos de presentación.




El código utilizado en la presentación está aquí

viernes, 9 de mayo de 2014

Degradación de performance de LVM, XFS, ZFS

Esto es solo una nota personal para tenerla a mano.

Aclarado lo anterior en mi computador personal con un disco duro Seagate Barracuda 1TB 7200RPM 64MB Cache y el resto

themanda@weichafe ~ # cat /proc/cpuinfo |grep "model name" |sed -e "s/model\sname\s:\s//g" |uniq
Intel(R) Core(TM) i7-3930K CPU @ 3.20GHz

root@weichafe ~ # free -g
             total       used       free     shared    buffers     cached
Mem:            47         22         24          0          0         20
-/+ buffers/cache:          1         45
Swap:           63          0         63

themanda@weichafe ~ % hwinfo --disk
77: IDE 00.0: 10600 Disk
  [Created at block.245]
  Unique ID: 3OOL.D2T1TfDreW5
  Parent ID: w7Y8.59UHdy+hk47
  SysFS ID: /class/block/sda
  SysFS BusID: 0:0:0:0
  SysFS Device Link: /devices/pci0000:00/0000:00:1f.2/ata1/host0/target0:0:0/0:0:0:0
  Hardware Class: disk
  Model: "ST1000DM003-1CH1"
  Device: "ST1000DM003-1CH1"
  Revision: "CC49"
  Driver: "ahci", "sd"
  Driver Modules: "ahci"
  Device File: /dev/sda
  Device Files: /dev/sda, /dev/disk/by-id/ata-ST1000DM003-1CH162_S1DHEX7W, /dev/disk/by-id/wwn-0x5000c5006d8e35fe
  Device Number: block 8:0-8:15
  BIOS id: 0x80
  Drive status: no medium
  Config Status: cfg=new, avail=yes, need=no, active=unknown
  Attached to: #23 (SATA controller)


Lo relevante es que le he hecho una pequeña prueba para ver la degradación de xfs sobre LVM

themanda@weichafe ~ % cat /etc/fstab
#
# /etc/fstab: static file system information
#
# file system  dir>   type  options       dump  pass
# UUID=9625d321-4c2a-4a3b-aac3-3da3136cfbf4
/dev/sda3               /               xfs             rw,relatime,attr2,inode64,noquota       0 1

# UUID=1559a839-bbea-4420-9b23-093e6c648d18
/dev/mapper/themanda-data       /home           xfs             rw,relatime,attr2,inode64,noquota       0 2

Como se ve en el bloque anterior hare las pruebas sobre 2 particiones con XFS una hecha directamente sobre disco(/dev/sd3) y la otra sobre LVM (/dev/mapper/themanda-data)

Test sobre partición xfs (/dev/sd3)

themanda@weichafe ~ % time sudo dd if=/dev/zero of=/test.img bs=1024M count=10 
10+0 records in
10+0 records out
10737418240 bytes (11 GB) copied, 16.2224 s, 662 MB/s
0.01s user 7.23s system 43% cpu 16.716 total

Test sobre partición con LVM (/dev/mapper/themanda-data)

themanda@weichafe ~ % time sudo dd if=/dev/zero of=/home/test.img bs=1024M count=10
10+0 records in
10+0 records out
10737418240 bytes (11 GB) copied, 64.5999 s, 166 MB/s
0.01s user 11.87s system 18% cpu 1:05.09 total

Bueno los resultados hablan por si solos, el rendimiento con LVM es cinco veces menor que con XFS directo al disco.

Pero tiempo despues he instalado FreeBSD 10 sobre ZFS y noto una degradación bastante menor que con LVM. Es del orden de 2 veces más lento que un partición directa sobre el disco y 3 veces más rapido que LVM.

ZFS resultados sobre FreeBSD sin tuning
[themanda@weichafe] ~% df -h
Filesystem                   Size    Used   Avail Capacity  Mounted on
zroot/ROOT/default           863G     19G    844G     2%    /
devfs                        1.0K    1.0K      0B   100%    /dev
procfs                       4.0K    4.0K      0B   100%    /proc
linprocfs                    4.0K    4.0K      0B   100%    /compat/linux/proc
zroot/tmp                    844G    3.1M    844G     0%    /tmp
zroot/usr/home               844G    152K    844G     0%    /usr/home
zroot/usr/jails              844G    144K    844G     0%    /usr/jails
zroot/usr/obj                844G    144K    844G     0%    /usr/obj
zroot/usr/pbi                847G    3.0G    844G     0%    /usr/pbi
zroot/usr/ports              844G    152K    844G     0%    /usr/ports
zroot/usr/ports/distfiles    844G    144K    844G     0%    /usr/ports/distfiles
zroot/usr/src                844G    144K    844G     0%    /usr/src
zroot/var/audit              844G    160K    844G     0%    /var/audit
zroot/var/log                844G    276K    844G     0%    /var/log
zroot/var/tmp                844G    3.7M    844G     0%    /var/tmp
zroot/usr/home/themanda      844G     34M    844G     0%    /usr/home/themanda

[themanda@weichafe] ~% ~# sudo time dd if=/dev/zero of=/test.img bs=1024M count=10 
10+0 records in
10+0 records out
10737418240 bytes transferred in 24.417965 secs (419 MB/s)
0.000u 3.300s 0:24.44 13.5%     25+172k 0+1io 0pf+0w

viernes, 2 de mayo de 2014

Varnish install vmod trick

Ok, here is the thing.
Me encuentro en el siguiente dilema, en producción tengo instalados diez varnish, en modo cache y pretendemos reemplazar nuestro CDN en akami.
Entre las cosas que necesito migrar de akamai, está el soporte para QueryString. Por lo tanto necesito implementar vmod-libquerystring.

Como los varnish ya estás instalados de rpm y no quiero desinstalar y volver a instalar desde las fuentes, ¿que hago en este caso? me saco un truco de la manga y descargando los fuentes de la misma versión, desde el repo, junto con le vmod que quiero compilar. Claro ya que estoy por la labor también me bajo otros vmod y dejo soporte, para lo que necesite o crea que pueda necesitar, mi vida sea más fácil en el futuro.

Dicho lo anterior lo explico step by step lo que hice empíricamente a continuación:
Estas pruebas las he efectuado sobre CentOS 6.5.
Para poder compilar varnish he requerido un montón de bibliotecas como:


yum install -y automake autoconf libtool ncurses-devel libxslt groff pcre-devel pkgconfig libedit libedit-devel readline-devel python-docutils git

Para replicar lo que tenia agrego el repositorio de varnish e instalo con yum:

rpm --nosignature -i http://repo.varnish-cache.org/redhat/varnish-3.0/el6/noarch/varnish-release/varnish-release-3.0-1.el6.noarch.rpm
yum install -y varnish

Con el varnish instalado desde el rpm tengo toda la estructura en su sitio y funcionando, bajas las fuentes de varnish y las dejas en un sitio seguro.

wget http://repo.varnish-cache.org/source/varnish-3.0.7.tar.gz
tar xzf varnish-3.0.7.tar.gz
git clone https://github.com/Dridi/libvmod-querystring.git
sudo mv libvmod-querystring varnish-3.0.7 /usr/src/

Con privilegios de root a compilar. (ojo: sin make install)

sudo -i
cd /usr/src/varnish-3.0.7
./autogen.sh
./configure PKG_CONFIG_PATH=/usr/lib/pkgconfig
make

Hora que ya están las fuentes compilados  y generados los objetos test, el vmod compilara y generara las biblotecas en donde se indique, para lo cual un paso previo es buscar el directorio varnish/vmods

find /usr -name vmods |grep lib |grep varnish
/usr/lib64/varnish/vmods

Ya lo tienes a compilar e instalar el modulo:

cd /usr/src/libvmod-querystring
./autogen.sh
./configure VARNISHSRC=/usr/src/varnish-3.0.7 VMODDIR=/usr/lib64/varnish/vmods
make && make install && make check

Plaf se instala correctamente en /etc/varnish/default.vcl importar el modulo y a utilizar sus características.

import querystring;

Nota: otros módulos puede tener otras dependencias. Recomiendo vmod-boltsort para complementar querystring y mejorar el hit ratio.

martes, 22 de abril de 2014

tmux

tmux es una herramienta que  me he visto "cordialmente invitado" a usar por la benevolente dicatadura del nuevo equipo de trabajo, pero se ha transformado en algo muy practico para mi díario vivir, cuando leí sobre esta y hace unos años, me pareció que con screen ya tenia suficiente, pero ahora que tuve que aprender a usarla, porque en el equipo compartimos las terminales desatachadas, en un terminal de salto, con lo cual quiero mencionar una pequeña reseña y los shortcuts más relevantes para poder sobrevivir.

tmux, por defecto es un terminal desatachado como screen (no muere si se corta la conexion o se cierra la consola), pero permite multiplexar las ttys, dividiendo una ventana en paneles, todos los que queramos, vale decir que puedo devidir una tty en muchas ttys más pequeñas, (las que quepan en mi patalla o emulador de terminal). 

Ventanas/Windows

Crear una nueva Ventana:
tmux new -s nombre
Nota: con el comando tmux a secas, se crea una ventana con un identificador numerico.

Atacharse a una ventana existente:
tmux a -t [nombre|Nº]

Listar las Ventanas existentes:
tmux ls

Paneles/Panels
Para manipular los paneles debemos Combinar Ctrl+b para activar el comando y luego al liberar precionar la tecla que ejecuta la acción
Dividir los paneles /Splits:
dividir panel Horizontal -> Ctrl b %
dividir panel Vertical   -> Ctrl b "

Cerrar un panel:
Ctrl b x

Moverse entre paneles:
Ctrl b arrow_key

Redimencionar los paneles:
Ctrl B arrow_key (manteniendo el Ctrl+b presionado)

Screenshot

jueves, 20 de febrero de 2014

Cifrado de claves

El cifrado de claves debe ser algo fundamental en el desarrollo de cualquier aplicación, debido a que es un aspecto básico de seguridad, que siempre debe ser considerado. Digamos que nos asignan en un nuevo proyecto y este incluye tener acceso a la información de una o más bases de datos, al hacer una consulta a la tabla usuario vemos que campo password no tiene cifrado y las claves de los usuarios se ven en texto plano. Mi opinión seria que un entorno productivo no puede trabajar de esa forma, menos si esta de cara a Internet, porque lo que esto indica, es que puede ser muy probable la existencia otras vulnerabilidades de seguridad, como por ejemplo inyección SQL o LDAP. Por supuesto permitiría a un atacante sacar todas esas claves planas. En resumen quien trabajó en el proyecto y cometió tal descuido deja mucho que desear, por decir algo suave. Lo que nos lleva a vivir en el problema del que estuvo antes que yo no sabia lo que hacia... Y cosas por el estilo. Pero como lo importante es todo lo contrario, debemos dignificar la profesión.
Muy bien las dos consideraciones básicas son:
  1. Si se requiere de autenticación de usuarios para el propio sistema, lo más recomendado es usar un algoritmo hash como MD5 o SHA, de una sola vía. ¿Que quiere decir que es de una sola vía? Que solo puede ser cifrado u no existe algoritmo de descifrado. Lo cual permite solo la comparación de hash para saber si la clave coincide, su utilización es común en la autenticación de usuarios en sistemas como Unix o Linux o en sistemas web tipo CMS, CRM, ERP, u otras aplicaciones que manejan sus propios usuarios, obviamente también en ldap y otros sistemas SSO.
  2. Si es un sistema que debe utilizar esa password para enviar mensajes a otros sistemas, lo cual requiere utilización de clave plana. También debe ser cifrada pero esta vez se utiliza un algoritmo de cifrado de dos vías. ¿Que quiere decir que es de dos vías? Que debe permitir el cifrado y el descifrado de la información. Esto es posible con algoritmos como 3DES (lento) y AES entre otros más elaborados y seguros como PKI.
Un ejemplo practico para el primer caso seria algo como:
from django.http import HttpResponse
from django.template import RequestContext, loader
from django.db.models import User
from hashlib import md5

class Login(TemplateView):

    def dispatch(self, request):
        template = loader.get_template('login.html')
        user = User.objects.get(user_name=request.POST['user'])
        if md5(request.POST['password']).hexdigest() == user.user_password:
            data = {"status": "logueado con exito"}
        else:
            data = {"status": "password fail"}
        context = RequestContext(request, data)
        return HttpResponse(template.render(context))

En el segundo caso practico podría implementarse por ejemplo en AES de una forma como:
from Crypto.Cipher import AES
from Crypto import Random
import base64

class AESCipher:

    def __init__(self, key):
        self.bs = 32
        self.key = hashlib.sha256(key.encode()).digest()

    def encrypt(self, raw):
        raw = self._pad(raw)
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return base64.b64encode(iv + cipher.encrypt(raw))

    def decrypt(self, enc):
        enc = base64.b64decode(enc)
        iv = enc[:AES.block_size]
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return self._unpad(cipher.decrypt(enc[AES.block_size:])).decode('utf-8')

    def _pad(self, s):
        return s + (self.bs - len(s) % self.bs) * chr(self.bs - len(s) % self.bs)

    @staticmethod
    def _unpad(s):
        return s[:-ord(s[len(s)-1:])]


UnitTest para quien lo quiera integrar con TDD
import unittest
import AESCipher

class TestCore(unittest.TestCase):

    def test_aescipher(self):
        aes_key = 'basura'
        cipher = AESCipher(aes_key)
        mesg = "passphrase"
        secret = cipher.encrypt(mesg)
        self.assertNotEqual(mesg, secret, "must be different but are equals")
        self.assertEqual(cipher.decrypt(secret), mesg, "must be equal but are different")
De esta forma solo el sistema conoce explicitamente como cifrar y descifrar las claves, obviamente esto está implementado en growpy.
Bien ahora una vista a la base de datos y se vera algo como:
sqlite> .schema node
CREATE TABLE node (
        node_id INTEGER NOT NULL,
        node_name VARCHAR NOT NULL,
        node_os_name VARCHAR NOT NULL,
        node_login VARCHAR NOT NULL,
        node_password VARCHAR NOT NULL,
        PRIMARY KEY (node_id),
        unique(node_name)
);

sqlite> SELECT node_password FROM node LIMIT 1;
sqlite> 4wGtGj7/KY2yW26ciBrhQEpUFu9rakjdbc7R/qckgFtuEXXx9WMAPAY2qTWy+ae0
Espero que esto sirva para no encontrarme ni dejar sistemas cuyas bases de datos tienen campos para claves en texto plano.

martes, 21 de enero de 2014

FreeBSD 10.0 RELEASE

Ya contamos con nueva versión de FreeBSD y tiene Grandes cambios significativos no a nivel arquitectónico sino más bien en las aplicaciones que por años nos acompañaron como es el caso de GCC, BIND y pkg_add, ya que estas han sido removidas cuyos reemplazos comento ahora:
  • GCC ya no viene por defecto, en su lugar trae clang como compilador por defecto
  • BIND ha sido removido del sistema base y reemplazado por unbound
  • pkg_add/pkg_delete removidos y reemplasado por pkg(7) nueva generacion.
  • CVS es removido del sistema base en favor de SVN
Para mi estos cambios serán los más notorios a nivel de usuario, pero es muy bueno y modernizan o igualan bastante a FreeBSD frente a otros sistemas operativos.
Cabe destacar que también se puede instalar ZFS como zroot por defecto desde el instalador, evitando lo complejo que es hacerlo como en el articulo anterior FreeBSD 9.2 sobre ZFS 

viernes, 17 de enero de 2014

FreeBSD systat

Como verificar el rendimiento del sistema

Normalmente hay que buscar cuellos de botella cuando algo va mal, para lo cual un simple top no ayuda mucho.
systat te da toda la información en FreeBSD

systat -vmstat 1  # estadísticas del sistema (a intervalos de 1 segundo)
systat -tcp 1     # conexiones tcp (también probar con -ip)
systat -netstat 1 # conexiones activas
systat -ifstat 1  # trafico en la NIC activa
systat -iostat 1  # rendimiento CPU y disco

jueves, 16 de enero de 2014

Como instalar FreeBSD 9.2 con ZFS

Introducción

Debido a que es un poco complicado o engorroso de instalar FreeBSD con la raiz sobre ZFS y mediante varios artículos, no oficiales y el wiki oficial, me costo llegar a una configuración optima y básicamente, porque habían cabos sueltos que pienso atar en este articulo.

Para comenzar usaremos el nuevo bsdinstaller GPT, no MBR y seguiremos estas instrucciones paso a paso, para que saque máximo provecho a ZFS. Esta instalación no requiere tener EFI activado es en modo BIOS.
Nota 2014-01-27: Por estos días ha salido FreeBSD 10 y trae soporte desde el instalador, creando la misma configuración automáticamente. Y este documento solo podría ser usable si se desea usar ZFS como LVM para lo cual se debería aplicar la la opcion -V <size> en cada volumen. Lo que da un tamaño fijo a cada volumen, partición o punto de montaje.

Primera parte

Se debe efectuar una instalación normal y como de costumbre. Una vez arranca el disco o flash image de instalacion de freebsd selecionar el install.
Configurar el teclado:
Configurar el hostname en este caso freebsd porque será un template:
Configurar los paquetes ports y src pueden ser optativos, games fuera, la documentacion es altamente recomendable sobre todo para tener referencias a man-o:

Segunda parte

En la segunda parte se efectúan instrucciones en modo shell fuera del nuevo bsdinstaller y es aquí donde cambia el rumbo hacia el root sobre zfs, seleccionar shell y nos vamos al prompt.


Limpiamos el disco en este caso ada0 porque es sobre VBox VM.
gpart destroy -F ada0
Iniciar el disco GPT
gpart create -s gpt ada0
Crear el sector de arranque del disco GPT con un alineamiento especial para no usar zroot legacy.
gpart add -b 34 -s 94 -t freebsd-boot ada0
Crear el slice con el resto del disco sin crear freebsd-swap en vez de esto, ira sobre ZFS más adelante.
gpart add -t freebsd-zfs -l disk0 ada0
Marcar el disco como disco de arranque.
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada0
Configurar la flag de debug a 16 para ver por mensajes en caso de error
sysctl kern.geom.debugflags=0x10
Crear un gnop para linear los sectores a 4K esto mejora el rendimiento es una buena practica, indicando el altroot y finalmente montar.
gnop create -S 4096 /dev/gpt/disk0
zpool create -o altroot=/mnt -o cachefile=/var/tmp/zfs/zpool.cache zroot /dev/gpt/disk0.nop
zpool export zroot
gnop destroy /dev/gpt/disk0.nop
zfs mount zroot
Y esta el pool montado y se debe proceder a crear los volumes o particiones para optimizar mejor los recursos primero se configura el checksumer=fletcher4 que es lo más optimo para mantener la consistencia de los datos.
zfs set checksum=fletcher4 zroot
Para sacar provecho a zfs con la instalación se aplican opciones a cada volume, para así mejorar rendimiento, espacio y seguridad.
Nota 20/01/2014: El /var/crash no sirve de nada crearlo, ya que no se puede activar el dumpdev con ZFS por el momento, probé con un zvol pero es un dispositvo no valido, debido a que si el kernel cae antes de tener el modulo zfs.ko cargado no podría volcar core al zvol.
zfs create zroot/var
zfs create zroot/usr
zfs create zroot/usr/home
zfs create -o compression=on -o exec=on -o setuid=off zroot/tmp
zfs create -o exec=off -o setuid=off zroot/var/empty
zfs create -o exec=off -o setuid=off zroot/var/run
zfs create -o exec=off -o setuid=off zroot/var/db
zfs create -o compression=lzjb -o exec=on  -o setuid=off zroot/var/db/pkg
zfs create -o compression=lzjb -o exec=on  -o setuid=off zroot/var/tmp
#zfs create -o compression=lzjb -o exec=off -o setuid=off zroot/var/crash
zfs create -o compression=lzjb -o exec=off -o setuid=off zroot/var/log
zfs create -o compression=gzip -o exec=off -o setuid=off zroot/var/mail
zfs create -o compression=lzjb -o exec=off -o setuid=off zroot/usr/src
Crear la swap.
zfs create -V 2G zroot/swap -o org.freebsd:swap=on zroot/swap -o checksum=off zroot/swap
Esto se puede dejar para la post instalación si no se ha seleccionado el paquete de ports en el bsdinstaller.
zfs create -o compression=lzjb -o setuid=off zroot/usr/ports
zfs create -o compression=off -o exec=off -o setuid=off zroot/usr/ports/distfiles
zfs create -o compression=off -o exec=off -o setuid=off zroot/usr/ports/packages
Crear un link del home y agregar permisos a los tmp.
cd /mnt ; ln -s usr/home home
chmod 1777 /mnt/tmp
chmod 1777 /mnt/var/tmp
Y ahora exit para volver a la instalación.
exit

Tercera parte
Retomamos el nuevo bsdinstaller para continuar con una instalación y post configuración normal, esto tarda algunos minutos y requiere un poco de interacción para configurar las cosas tipicas passwor, zona horaria, usuarios, etc.
Ingresar la password de root.
En las siguientes imágenes se puede ver como configurar la NIC con la red en la que esta la maquina IPv4 en este caso y sin IPv6, y el respectivo Gateway y DNS.






Configurar la zona horaria, en este caso se selecciona una zona de Europa, pero bien puede ser America/Santiago u otra.




Configurar OpenSSH para que levante al arranque, recordar ir al directorio /etc/ssh y activar el PermitRootLogin yes, debido a que FreeBSD no lo permite por defecto. Por otro lado, para respetar esta politica lo mejor es crear un usuario en el grupo wheel dos paso más adelante o después que la instalación finaliza.

Crear usuarios es opcional.
Exit, para salir del bsdinstaller.

Cuarta parte y final

Ya finalizada la post configuración (yes) para volver a la shell, en el cual se terminara de configurar lo necesario para arrancar con zfs.


Una vez completada la instalación hacer los siguientes paso:

Copiar el zpool.cache
cp /var/tmp/zpool.cache /mnt/boot/zfs

Configurar zfs para arranque automatico de sus modulos.
echo 'zfs_load="YES"' >> /mnt/boot/loader.conf
echo 'vfs.root.mountfrom="zfs:zroot"' >> /mnt/boot/loader.conf
echo 'zfs_enable="YES"' >> /mnt/etc/rc.conf

Desactivar el almacenamiento de coredump's.
echo "kern.coredump=0" >> /etc/sysctl.conf

viernes, 10 de enero de 2014

Computer Science

En Chile y me da la sensación de que en la mayoría de los países de habla hispana, no suele ser común la carrera de ciencias de la computación, salvo honrosas excepciones (USACH.) 
Esta profesión es más bien impartida como "ingeniería en computación e informática". Pero algo que nos debe quedar claro tanto a estudiantes como profesionales del área, son las ramas de esta ciencia. Y por esto el siguiente gráfico:


La zona verde muestra la base que a mi criterio debería tener todo profesional en las ciencias de la computación. Con ese conocimiento podemos abordar el resto. Me explico la zona azul o aplicación es el desarrollo y la implantación de sistemas, la zona roja o técnica es la aplicación y manutención de las tecnologías existentes (SysAdmins, DBAs, técnicos de networking e infraestructura, etc.) Y la zona ámbar (naranja) o la teoría es el desarrollo y la búsqueda de nuevos teoremas para solucionar los problemas existentes y desarrollar nuevos paradigmas. Concluyentemente digo que la base es de color verde y por ende la mas importante.

También quiero ahondar en el estado del arte mediante un gráfico de artefactos que permiten seguir avanzando en investigación y desarrollo:


He creado esta imagen de como veo las capas de software sobre el hardware, no olvidar que básicamente este ultimo es el que más avanza, me quedaría pendiente desglosar las capas del sistema operativo, pero es tema para otro post.