Hardening PHP
PHP es el lenguaje más popular para la creación de Webs, y por lo tanto muy conocido, y a la vez atacado.
Si bien es trabajo del programador (y el mayor responsable de) tomar los recaudos necesarios para que sus aplicaciones no sean vulnerables, un administrador de sistemas puede utilizar varias opciones para que el servidor sea lo más resistente posible. PHP ofrece varias opciones que aumentan la seguridad significativamente, si se encuentran bien configuradas.

La siguiente es una lista de directivas que se pueden configurar en el archivo de configuración de php (/etc/php.ini, o /etc/php5/apache2/php.ini, dependiendo la distribución) para mejorar la seguridad del servidor:
  • Restringir el acceso al sistema de archivos. Dado que los sites se alojarán en /var/www, salvo casos excepcionales, los scripts PHP no necesitan acceso al resto del sistema de archivos, a excepción del directorio /tmp que es donde se alojan los archivos cuando el usuario hace un upload. Por ello, es posible restringir los directorios a los que se puede acceder, mediante la opción:
    open_basedir = /var/www:/tmp
    Esta configuración se puede cambiar por site en el correspondiente Virtual Host, utilizando la directiva:
    php_admin_value open_basedir /var/www/[nombre site]/
  • Deshabilitar funciones riesgosas. Hay funciones que deben ser permitidas sólo en casos particulares, debido a que se usan raramente y representan un gran riesgo. Esta configuración se realiza con la directiva disable_functions:
    disable_functions = show_source, system, shell_exec, passthru, exec, phpinfo, popen, proc_open
  • No revelar información de PHP en los headers. Esto le permitiría a un atacante saber que el servidor posee PHP, además de la versión instalada, y así poder realizar un ataque más específico:
    expose_php = Off
  • No exponer errores de scripts al cliente. Los errores de programación no deben quedar expuestos a los clientes, sino que deben loggearse en archivos para que el programador los pueda depurar:
    display_errors = Off
    display_startup_errors = Off
  • Loggear errores permiten detectar cuál fue la falla que causó que el programa no funcione o lo haga de forma imprevisible:
    log_errors = On
  • No utilizar register_globals. Esta funcionalidad se considera extremadamente peligrosa y por default viene desactivada en toda configuración actual, pero por las dudas se debe checkear que el valor sea el siguiente:
    register_globals = 0
  • No utilizar magic_quotes. PHP provee, hasta la versión 5, de una utilidad para escapar caracteres peligrosos (', “, \, NULL), antes de ser utilizados por los scripts del servidor. Esto permite evitar algunos ataques de SQL Injection, pero tiene complicaciones con las distintas codificaciones de caracteres y además puede introducir problemas en la programación. Este tipo de controles deben estar implementados en la aplicación y no en el servidor, por lo cual a partir de PHP 5.3 se considera deprecated y en la versión 6 ya no existe.
    magic_quotes_gpc = Off
    magic_quotes_runtime = Off
    magic_quotes_sybase = Off
  • Para realizar upload de archivos desde el cliente, utilizar el directorio tmp correspondiente al site, es decir /var/www/[nombre site]/tmp. Esta configuración se realiza en el virtual host con la sentencia:
    php_admin_value upload_tmp_dir /var/www/[nombre site]/tmp
  • No tratar las URLs (como http:// o ftp://) como archivos. En caso de encontrar un error en la programación, un atacante podría realizar remote file inclusion si esto se encuentra activado.
    allow_url_fopen = Off
    allow_url_include = Off
  • Cambiar el nombre de la variable de sesión. Por defecto esta variable se llama PHPSESSID y demuestra que el servidor ejecuta PHP, y que la página actual está escrita en PHP. Si bien esto agrega poca seguridad, agrega una traba más al atacante.
    session.name = SESSION_ID
Como dije, estas opciones ayudan a la seguridad, pero no evitan, por ejemplo, que un programa vulnerable a SQLi permita a un atacante romper la base de datos.
Espero que les sean de utilidad!


Referencias

- Description of core php.ini directives
- Securing PHP: Step-by-Step
Links: ACLs en GNU/Linux
Hace años que abandoné esta sección que denominé "Links", y ahora encontré una buena razón para retomarla... mi trabajo con ACLs =)

En GNU/Linux la asignación de permisos a archivos y directorios se realizó históricamente con los permisos estándar Unix. El sistema de permisos es una de las primeras cosas que se enseñan en cualquier tutorial o manual de este sistema operativo, ya que son un concepto nuevo para casi cualquier usuario desktop Windows (donde los permisos suelen estar ocultos para el usuario...).
Los permisos Unix se administran por usuario, grupo y otros, y es posible asignar lectura, escritura y ejecución (rwx), además de algunos bits adicionales como sticky bit, set user id y set group id.
Esta forma de asociar permisos con archivos y directorios es suficiente para la gran mayoría de los casos, pero se queda corto cuando hay varios usuarios y grupos en juego, y se desea mayor granularidad.

Una forma bien conocida (al menos para cualquier estudiante de computación) de asignar permisos es utilizar listas de control de acceso (Access Control Lists - ACLs). Las ACLs permiten asignar permisos a listas de usuarios o grupos, en lugar de asignar permisos a sólo un usuario o grupo en particular, como sucede en el sistema Unix tradicional. Esta es la forma en que se asignan los permisos en la familia Windows NT.

Si bien GNU/Linux implementa POSIX ACLs desde hace años, no son tan utilizadas entre los linuxeros, y pocas veces mencionadas en los manuales introductorios. Dado que se utiliza poco, no hay muchas herramientas gráficas que lo implementen (una es eiciel), y por lo tanto la mejor manera es hacerlo por consola. Las herramientas utilizadas para setear y obtener las ACLs son setfacl y getfacl, y vienen en el paquete acl.
Para poder utilizar ACLs, el sistema de archivos debe poseer esta capacidad, y la partición debe ser montada con la opción acl. Casi todos los filesystems modernos la implementan, por lo que no deberían tener problemas con ello, sólo es cuestión de modificar el /etc/fstab para que se monte con la opción correspondiente.
Lo bueno es que si se activa el uso de POSIX ACLs, todavía es posible utilizar el sistema Unix tradicional, dado que, por compatibilidad, las mismas se crearon con esto en mente.

A continuación les dejo una interesante lista de páginas donde se explica el uso de ACLs en GNU/Linux. Anímense, que una vez que se acostumbran, son fáciles de administrar!

- POSIX Access Control Lists on Linux. Completísimo paper donde se discute el uso de ACLs en sistemas tipo Unix, describiendo el estandar POSIX ACLs, el orden en que se evalúan los permisos, ejemplos, análisis de performance, el uso en sistemas de archivos de red NFS y Samba. Es un buen punto de partida.
- Using ACLs with Fedora Core 2   (Linux Kernel 2.6.5). Muy buen artículo sobre el uso de ACLs, con varios escenarios como ejemplo para ver mejor su funcionalidad. Si bien el artículo asume el uso de Fedora, sirve para cualquier distribución.
- Linux ACL (Access Control Lists). Tutorial práctico sobre el uso de ACLs en Linux.
- Samba-3: Windows file and directory. Descripción del uso de ACLs en Samba.
- ACL(Access Control List) Configuration in Debian. Pequeño artículo sobre la configuración de ACLs en debian.

Espero que les sea de utilidad ^_^
Instalación de MIT Kerberos
En el artículo anterior aprendimos sobre qué es kerberos, y para qué sirve. Es hora de ver cómo instalar un servidor para este servicio.
Este artículo forma parte del proyecto Autenticación y administración centralizada de usuarios en GNU/Linux (Autenticación y administración centralizada de usuarios en GNU/Linux).

Si bien existen varias implementaciones del protocolo, elegí MIT kerberos por estar desarrollado por MIT, autores del protocolo original, ser muy completa, muy soportada por librerías y la más utilizada. Otras implementaciones bastante utilizadas son Heimdal y GNU Shishi.

Antes de comenzar a instalar kerberos, es muy importante que los relojes de los hosts participantes estén sincronizados. Como se explicó, kerberos es muy dependiente del tiempo, una desincronización conlleva problemas de acceso.
También es importante tener un servidor de nombres de dominio con los registros correspondientes a cada host, incluidos los registros PTR, dado que kerberos utiliza los nombres de dominio para validar el hosts desde donde se piden los tickets.

A continuación se describe la instalación de kerberos en debian y derivados, pero en otras distribuciones es muy similar. Por su parte, la configuración del sistema es igual para todas las distribuciones.
En debian y derivados, instalar el servicio kerberos (con kdc incluido) es tan simple como ejecutar:
  # apt-get install krb5-admin-server
La interfaz debconf de este paquete pregunta por parámetros básicos para el funcionamiento de kerberos:
  • configurar realm con el nombre del dominio, por ejemplo: demasiadovivo.org
  • escribir la dirección del servidor kerberos (es decir, la dirección del servidor donde estamos instalando kerberos, en este caso): kdc01.demasiadovivo.org
  • En este paso, obviamente necesitarán tener registrado el nombre kdc01 en el servidor de nombres. Lo mejor es tener un servidor de nombres propio para la red interna. Instalar y configurar bind es simple, por lo cual no debería implicar mayores problemas.
  • escribir el nombre del servidor administrativo de kerberos (cambio de contraseñas). Al igual que en el punto anterior, dado que estamos instalando el servidor kerberos, el nombre será el del mismo servidor actual: kdc01.demasiadovivo.org. El servidor administrativo es el que permite al administrador conectarse remotamente (herramienta kadmin) y trabajar sobre la base de datos de kerberos.
Al terminar la configuración inicial, tanto kadmind como kdc intentarán iniciar pero fallarán, dado que todavía no configuramos ningún realm.
Toda esta configuración inicial se puede realizar a mano, editando el archivo /etc/krb5.conf.

Para la creación de realms, poseemos la herramienta krb5_newrealm. Al ejecutar este comando, se creará la base de datos de kerberos para nuestro realm, y nos solicitará un password (master key del KDC) que se utiliza para generar la clave a almacenar en el stash (/etc/krb5kdc/stash), la cual sirve para encriptar la base de datos. Como se imaginan, este password es MUY importante y debe ser lo más fuerte posible. Aquel que posea el password, será capaz de desencriptar la base de datos y obtener todas las claves de los usuarios.

Una vez generado el realm, hace falta editar /etc/krb5.conf para agregar nuestro dominio default. Cuando abran este archivo se encontrarán que la sección [realms] cuenta con muchos realms famosos (varios del MIT, GNU.ORG, stanford.edu, etc). Si quieren tener una configuración limpia, lo mejor es eliminar todos estos realms; lo mismo para la sección [domain_realm]. Ahora, para agregar el dominio default, editen la definición del realm para que quede como lo siguiente:
[realms]
  DEMASIADOVIVO.ORG = {
    kdc = kdc01.demasiadovivo.org
    admin_server = kdc01.demasiadovivo.org
    default_domain = demasiadovivo.org
  }
y agreguen el dominio a la definición de dominios:
[domain_realm]
  .demasiadovivo.org = DEMASIADOVIVO.ORG
  demasiadovivo.org = DEMASIADOVIVO.ORG
se colocan tanto el nombre de dominio como el nombre de dominio iniciando con punto ".", para indicar que se aplica a todos los subdominios del mismo.
Por defecto, kerberos loggea en syslog, pero si quieren tener los logs separados, pueden agregar la sección [logging] con una definición como la siguiente:
[logging]
  kdc = FILE:/var/log/kerberos/kdc.log
  admin_server = FILE:/var/log/kerberos/kadmin.log
  default = FILE:/var/log/kerberos/krblib.log
Si utilizan el path propuesto anteriormente, deberán crear el correspondiente directorio en /var/log
  # mkdir /var/log/kerberos
Para que los cambios surtan efecto, reiniciar tanto kadmin como el kdc
  /etc/init.d/krb5-admin-server restart
  /etc/init.d/krb5-kdc restart
Una vez instalado y configurado el servicio, podemos testear como va todo. Para esto, usamos la herramienta kadmin.local, la cual es como kadmin, pero destinada a utilizarse localmente, y por ello el usuario debe estar logueado en el servidor con una cuenta de usuario lo suficientemente privilegiada para poder abrir la base de datos de kerberos (por ej. root). A diferencia de kadmin que requiere un usuario de kerberos válido para acceder, kadmin.local no requiere password dado que el usuario que la utiliza es un administrador del servidor.
Usemos entonces kadmin.local de la siguiente forma:
  # kadmin.local
  Authenticating as principal root/admin@DEMASIADOVIVO.ORG with password.
  kadmin.local: listprinc
  K/M@DEMASIADOVIVO.ORG
  kadmin/admin@DEMASIADOVIVO.ORG
  kadmin/changepw@DEMASIADOVIVO.ORG
  kadmin/dvpem01.demasiadovivo.org@DEMASIADOVIVO.ORG
  kadmin/history@DEMASIADOVIVO.ORG
  krbtgt/DEMASIADOVIVO.ORG@DEMASIADOVIVO.ORG
  kadmin.local: quit
Lo que hicimos es entrar al modo administración de kerberos y listar los principals existentes con listprinc.

Los permisos para administrar kerberos se configuran en /etc/krb5kdc/kadm5.acl. Como vimos, kerberos permite utilizar roles, y en este archivo podemos utilizarlos. Por defecto vemos que figura el acl "*/admin *", el cual está deshabilitado, como comentario. Este acl permite acceso de administración full a todos los usuarios cuyo principal tenga el rol admin. Si descomentamos esta línea, podemos utilizar el rol admin en los principals para indicar qué usuarios pueden administrar kerberos.
Agregando el principal root/admin, podremos acceder con el usuario root a través de kadmin:
# kadmin.local
Authenticating as principal root/admin@DEMASIADOVIVO.ORG with password.
kadmin.local: addprinc root/admin
WARNING: no policy specified for root/admin@DEMASIADOVIVO.ORG; defaulting to no policy
Enter password for principal "root/admin@DEMASIADOVIVO.ORG":
Re-enter password for principal "root/admin@DEMASIADOVIVO.ORG":
Principal "root/admin@DEMASIADOVIVO.ORG" created.
Y podemos probar utilizando el comando:
  # kadmin
  Authenticating as principal root/admin@DEMASIADOVIVO.ORG with password.
  Password for root/admin@DEMASIADOVIVO.ORG:
  kadmin:
Si vemos el prompt de kadmin, es que todo fue bien.


Referencias

- The Kerberos protocol and its implementations
- Kerberos V5 System Administrator's Guide
- Kerberos FAQ, v2.0
- MIT Kerberos installation on Debian
- Kerberos Infrastructure HOWTO
El mítico Kerberos
Uno de los servicios más utilizados actualmente para la autenticación en diferentes organizaciones es kerberos. Cualquiera que utilice o haya utilizado Active Directory seguramente conozca, aunque sea vagamente, kerberos, dado que este entorno lo utiliza como base. También se utiliza bastante en soluciones empresariales de Red Hat.
Dado que es un servicio de mucha importancia y uno de los que cualquier persona que trabaje en administración de sistemas o seguridad debe conocer, me parece bien dedicar un artículo para describir como funciona. En un próximo artículo veremos cómo instalarlo y configurarlo en GNU/Linux.
Este artículo forma parte del proyecto Autenticación y administración centralizada de usuarios en GNU/Linux.


Qué es?

Kerberos es un protocolo de autenticación desarrollado por el MIT e implementado en varios sistemas operativos. La principal función es permitir que dos nodos puedan autenticarse entre sí sobre una red insegura. Se utiliza principalmente en modelos cliente-servidor donde cliente y servidor pueden autenticarse mutuamente.
Kerberos funciona utilizando criptografía simétrica y requiere de una tercera parte confiable (siempre hay que confiar en alguien...).

Dato interesante: el nombre kerberos proviene del perro con tres cabezas y cola de serpiente, guardian de la entrada del templo de Hades en la mitología griega. El nombre era acertado porque la idea era proveer 3 mecanismos de seguridad: autenticación, contabilidad y auditoria. Desgraciadamente, sólo se implementó el componente de autenticación.

En el modelo kerberos contamos con dos servidores lógicos (que en la práctica suelen estar implementados en un sólo servidor físico denominado Key Distribution Center o KDC):
  • Authentication Server (AS): servidor encargado de autenticar al cliente y proveer un ticket para contactar al TGS. Este servidor almacena la clave de los clientes y las utiliza para autenticarlos.
  • Ticket Granting Server (TGS): servidor encargado de proveer tickets a los clientes para que puedan acceder al servicio deseado.

Qué servicios se puede acceder con un ticket de kerberos? cualquiera que implemente este tipo de autenticación. Por ejemplo, la autenticación de usuarios en un sistema operativo, acceso a servicios ldap, web, smtp, etc. Para poder utilizar un servicio kerberizado, el cliente debe primero contactar al AS y el TGS para obtener un ticket, que luego utiliza para acceder el servicio.
Los tickets tienen una validez de tiempo limitada, para lo cual se utilizan timestamps. Debido a esto, tanto clientes como servidores deben tener sus relojes sincronizados, porque sino el sistema no funciona. Normalmente esta sincronización se realiza utilizando el protocolo NTP.


Descripción del protocolo

El handshake de autorización para acceder a un servicio es la siguiente:
  • Cliente C contacta al AS requieriendo acceso a un servicio del Service Server (SS).
  • AS utiliza la clave que tiene almacenada del usuario (user master key) para encriptar la clave de sesión necesaria para encriptar los mensajes con el TGS (TGSsk). Además, AS envía al cliente otra tupla (denominada Ticket Granting Ticket - TGT) pero encriptada con la clave del TGS, la cual contiene el ID del cliente, la dirección de red del mismo, el tiempo de validez del ticket y la clave de sesión (TGSsk).
  • Cuando el cliente recibe los mensajes, desencripta el primero para obtener la clave de sesión TGSsk. Al desencriptar este mensaje, prueba quién es, dado que otro cliente no tendrá la clave necesaria para desencriptar el mensaje. El TGT no lo desencripta porque está encriptado con la clave del TGS.
  • El cliente ahora envía el TGT al TGS y un mensaje autenticador, compuesto por el ID del cliente y el timestamp, encriptado con la clave de sesión TGSsk.
  • Una vez que el TGS recibe los mensajes del cliente, desencripta el TGT para obtener la clave de sesión TGSsk, y con esta clave desencripta el otro mensaje (el autenticador) y responde al cliente enviando un nuevo ticket, muy similar al TGT, pero para ser utilizado con el Service Server, que provee el servicio deseado (por ejemplo ldap). Este mensaje contiene el ID del cliente, la dirección de red, el período de validez y una nueva clave de sesión para utilizar con el servidor (SSsk). Además, envía otro mensaje que contiene el SSsk, encriptado con la clave de sesión del TGS (TGSsk).
  • Finalmente el cliente tiene todo lo necesario para acceder el servicio que desea, por lo que contacta al SS enviando el ticket que recibió del TGS y un nuevo autenticador encriptado con la SSsk.
  • SS desencripta el ticket recibido para obtener la clave de sesión SSsk, con la cual desencripta el autenticador del cliente. SS responde con el último mensaje del handshake inicial que contiene el timestamp encontrado en el autenticador del cliente más 1, encriptado con la clave de sesión SSsk.
  • Con el último mensaje el cliente puede comprobar la autenticidad del servidor.

Resumiendo, obtenemos el siguiente flujo:
C ---- pedido de servicio -----> AS
AS ---- TGSsk encriptada con clave del cliente ----> C
AS ---- TGT ----> C
C ---- TGT ----> TGS
C ---- autenticador encriptado con TGSsk ----> TGS
TGS ---- ticket para acceder servicio ----> C
TGS ---- SSsk encriptado con clave del cliente ----> C
C ----> ticket para acceder servicio ----> SS
C ----> autenticador encriptado con SSsk ----> SS
SS ----> timestamp +1 encriptado con la clave de sesión SSsk ----> C

Sí, parece (o es) tremendo lío el sistema de autenticación, pero es efectivo y seguro, y prestando atención llega a entenderse bien (aunque con el tiempo uno se vuelve a olvidar =P).
Gracias a que la autenticación con usuario y contraseña genera el TGT, para acceder a distintos servicios sólo necesitamos este ticket, por lo cual no es necesario cargar las credenciales por cada servicio accedido. Esto permite que sistemas como el single sign-on funcionen. Además el TGT puede ser renovable dentro de un dado período de tiempo, lo que da flexibilidad a servicios que necesitan mucho tiempo para completarse.

Se desprende de la explicación anterior que el KDC contiene todas las credenciales de todos sus usuarios. Obviamente estas credenciales no se almacenan de forma plana en la base de datos. La base de datos se encripta utilizando una master key que el administrador debe elegir al momento de configurar el KDC. Pero esta master key también debe estar almacenada en algún lugar si se desea que el servicio se cargue automáticamente! En el kerberos de MIT la master key se almacena en el archivo stash. En AD existe un usuario denominado kbrtgt cuya contraseña es la utilizada como master key del KDC, este usuario no puede loguearse y está deshabilitado.


Limitaciones y desventajas

  • La obvia desventaja de un sistema de autenticación centralizado es el único punto de falla. Si se cae el AS o el TGS, nadie puede acceder a ningún servicio. Esto se soluciona utilizando más de un servidor y replicando los datos.
  • Todos los participantes deben tener coordinados sus relojes, porque sino, los tickets no funcionan.
  • Dado que todas las claves se almacenan en un servidor, si un atacante logra hackearlo, podrá acceder como cualquier usuario!
  • Otro problema es el replay attack, un ataque que no simple, pero tampoco imposible como se demuestra en el paper Replay Attack on Kerberos V and SMB.


Terminología

En el mundo kerberos existen ciertas definiciones que es necesario conocer para poder configurarlo correctamente. Veamos entonces los términos utilizados:
  • Realm (reino, interesante nombre): indica el dominio de autenticación. El realm establece los límites en los cuales un servidor de autenticación tiene autoridad para autenticar usuarios, hosts o servicios. Es posible, sin embargo, realizar autenticaciones cross-realm entre, por ejemplo, un usuario de un realm y un servicio de otro. Esto se lleva a cabo a través de una relación de confianza entre los realms que debe ser establecida previamente.
  • Básicamente un usuario/servicio pertenece a un realm sólo si comparte un secreto (password/key) con el servidor de autenticación. Es recomendable que el nombre del realm sea igual al del dominio (DNS) en el que nos encontramos, escrito con letras mayúsculas (los nombres son case-sensitive). Si nuestro dominio es demasiadovivo.org, lo aconsejable es nombrar al realm DEMASIADOVIVO.ORG.
  • Principal: es el nombre utilizado para referirse a las entradas en la base de datos del servidor de autenticación. Cada usuario/host/servicio del realm tiene asociado un principal (string) que lo identifica. Ejemplos de principals son el nombre de usuario, el nombre de un host, etc. Cada principal puede tener varios componentes, pero generalmente se usan 3:
    • primary: la primera parte del principal. En el caso de un usuario, este es su nombre de usuario. En el caso de un servicio, es el nombre del servicio.
    • instance: la segunda parte de principal. Da información que califica al primary y puede ser null. En el caso de un usuario, el instance suele usarse para describir el uso para el cual están destinadas las credenciales. En el caso de un host, el instance es el hostname.
    • realm: el nombre del realm en mayúsculas.
    Los principals se escriben con el formato "primary/instance@REALM". Por ejemplo, un principal para el servicio ldap sería ldap/lab.demasiadovivo.org@DEMASIADOVIVO.ORG
  • Ticket: en la explicación anterior se describió el concepto de tickets en kerberos. Un ticket permite demostrar la autenticidad de un cliente. Los tickets caducan luego de un cierto tiempo, y es necesario obtener uno nuevo cuando esto sucede, o bien renovarlo si esto es posible.
  • Keytab: es un archivo que contiene pares principal -> clave. Este archivo se puede utilizar para obtener tickets sin que el sistema pida password en el proceso de autenticación. El uso más común es en scripts que necesitan utilizar kerberos sin interacción humana. Los archivos keytab son muy importantes y deben mantenerse seguros.


Referencias

- Kerberos protocol wik
- The Kerberos protocol and its implementation
- Kerberos FAQ, v2.0
Sincronicemos relojes con NTP
En el artículo Configurar NTP en GNU/Linux se explicó como instalar y configurar NTP en una máquina cliente, pero faltaron detalles concernientes al protocolo y la instalación de servidores. El protocolo NTP es el más conocido y utilizado para sincronización de relojes, por lo cual es importante conocer las bases del mismo antes de instalar el servicio.

De la teoría de sistemas distribuidos sabemos que existen varios algoritmos para esta tarea. NTP emplea el algoritmo de Marzullo para la estimación, y usa un sistema jerárquico de niveles de fuentes horarias. Cada nivel se denomina stratum, y comienzan en el valor 0. Este valor se utiliza para indicar la distancia desde la fuente horaria, y no es un indicador de calidad o confiabilidad, dado que hay fuentes de stratum 3 de mejor calidad que algunos stratum 2.
Los stratum se definen de la siguiente manera:
  - stratum 0 son dispositivos como relojes atómicos (por ejemplo de cesio), GPS, u otros relojes de radio. En general, estos dispositivos no están conectados a la red, sino conectados a computadoras (por ej, por RS-232).
  - stratum 1 son computadoras conectadas a dispositivos stratum 0. Normalmente actúan de servidores NTP para servidores de stratum 2.
  - stratum 2 son computadoras que envían solicitudes a servidores stratum 1. Estas computadoras suelen utilizar varias fuentes stratum 1 y utilizan el algoritmo NTP para obtener la mejor muestra. Las computadoras de este stratum se comunican entre sí en modalidad peer-to-peer para proveer tiempos más estables y robustos.
  - stratum 3 son computadoras que emplean las mismas funciones que las de stratum 2, y pueden actuar de servidores de capas inferiores. NTP soporta hasta el stratum 256.
De esta organización jerárquica, tenemos que un cliente NTP puede operar en modelo cliente-servidor (donde el stratum del cliente es 1 más que el del servidor), o peer-to-peer (clientes con el mismo stratum). Además de estas dos, un servidor NTP puede funcionar enviando la hora en forma broadcast o multicast, y los clientes se configuran para sincronizarse con estas señales.

El proceso comienza cuendo un cliente NTP envía un paquete conteniendo su timestamp a un servidor. Cuando el servidor recibe el paquete, este almacena su propio timestamp y un timestamp de transmisión en el paquete, y lo envía de regreso al cliente. Una vez que el cliente recibe la respuesta, logguea la hora a la que lo recibió para estimar el tiempo de transmisión del paquete.
Teniendo varias fuentes horarias, el algoritmo de Marzullo selecciona las fuentes que se consideren confiables (en base a ciertos parámetros) para encontrar la hora precisa. De los intervalos retornados por las fuentes, se calcula el menor intervalo que sea consistente con el mayor número de fuentes (intersección). Si por ejemplo, los intervalos son [8,12], [11,13] y [10,12], la intersección de todos da [11,12]. Si en cambio, los intervalos son [8,12], [11,13] y [14,15], no existe un intervalo consistente con todos los valores, pero [11,12] es consistente con el mayor número de fuentes.
En el algoritmo original de Marzullo, el mejor valor se toma como el centro del intervalo. Un acercamiento más sofisticado (y utilizado en NTP) es reconocer que esto puede desperdiciar información valiosa de los intervalos confiables, y por ello es mejor utilizar un modelo probabilístico, que puede retornar un valor distinto al centro.

En GNU/Linux se instala un demonio que puede actuar como servidor y cliente, permitiendo sincronizar relojes con servidores de stratums superiores o entre pares del mismo nivel. La diferencia entre un servidor y un cliente está dada por los comandos de control de acceso.

En una configuración estándar, un host que trabaje de servidor puede configurarse teniendo en cuenta lo siguiente:
  - debe contener al menos una fuente horaria superior (por ejemplo relojes stratum 2 o 1), o bien deben existir otros servidores del mismo nivel (peers) para calcular la hora, o ambos.
  - debe utilizar una fuente horaria local, para el caso en que no se pueda conectar con otros servidores.
  - debe permitir que hosts de la red consulten la hora, pero que no participen en el cálculo de la hora, o modifiquen la configuración.
Por su parte, un host cliente debera configurarse teniendo en cuenta que:
  - debe sincronizar su hora con uno o más servidores NTP superiores
  - no debe permitir que otros hosts consulten su hora, ni alteren la configuración.

Como se vió en el artículo anterior, la instalación del demonio NTP es tan simple como:
  # apt-get install ntpd

Los comandos más utilizados dentro de la configuración (/etc/ntp.conf) son:
  * server define servidor superior con el cual conectarse para obtener información horaria
    + iburst envía una ráfaga de ocho paquetes en lugar de uno en caso que el servidor esté inalcanzable
  * peer define un servidor NTP que se encuentra al mismo nivel
  * fudge permite establecer el stratum de un servidor
  * restrict establece el control de acceso para una dada red o host:
    + kod envía un paquete "kiss of death" si el flag limited está presente y un paquete viola el límite de rate establecido
    + notrap niega el uso del servicio trap
    + nomodify niega consultas que intenten modificar el estado del servidor
    + nopeer evita que el host sea utilizado como servidor de hora
    + noquery previene consultas por el estado del ntpd
 
Teniendo en cuenta lo descripto líneas atrás, la configuración (/etc/ntp.conf) debe contener lo siguiente:
  - En servidores NTP:
    # servidores default debian, cambiar por los deseados
    server 0.debian.pool.ntp.org iburst
    server 1.debian.pool.ntp.org iburst
    server 2.debian.pool.ntp.org iburst
    server 3.debian.pool.ntp.org iburst

    # configurar un servidor del mismo nivel (opcional)
    # peer 192.168.1.10
 
    # reloj local como fuente en caso que la conexión a internet se corte (esto lo asegura el stratum 10)
    server 127.127.1.0
    fudge  127.127.1.0 stratum 10
 
    # acceso completo para localhost
    restrict 127.0.0.1
 
    # permitir a los hosts de la red 192.168.1.0/24 realizar consultas, pero no modificar nada
    restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap
 
    # restringir el acceso a todo el resto
    restrict default kod notrap nomodify nopeer noquery

  - Los hosts clientes, por su parte, deberán contar con las líneas:
    # direccion del servidor configurado anteriormente (ej 192.168.1.56)
    server 192.168.1.56
 
    # restringir consultas para que otros hosts no lo utilicen como servidor
    restrict default kod notrap nomodify nopeer noquery

Una vez terminada la configuración, reiniciar el demonio en clientes y servidores:
  # /etc/init.d/ntp restart

Para testear la configuración, se puede ejecutar:
  # ntpq -p
  # ntpdc -p


Referencias

- Network Time Protocol wiki
- Marzullo's algorithm wiki
- Introduction to NTP
- Network Time Protocol daemon
- Access Control Commands and Options
- 6.5. ntpd access restrictions
Autenticación y administración centralizada de usuarios en GNU/Linux
Desde que estoy en mi actual trabajo, me vi forzado a utilizar Active Directory (AD), a aprender de qué trata, cómo funciona, y cómo administrarlo.
Realmente este servicio me parece una buena idea por parte de MS, y a nivel empresa es muy útil. La experiencia en el trabajo me enseñó que cuando la cantidad de usuarios supera un cierto número, administrarlos por workstation y/o por servicio es muy complejo, inaceptable. Además, la facilidad de independizar al usuario de la workstation en la que se encuentra, es muy importante para muchas empresas.
El problema, claro está, es que AD es de MS, con todo lo que ello representa:
- código cerrado
- licencias caras y limitantes
- poco flexible
- software malo (si, la idea de AD es buena, pero el soft de MS es malo)
- hay que utilizar Windows
- fuerza a utilizar más software MS, gracias a su política "incompatible con el mundo no MS"
- no se puede aprender de él
- mientras todo anda, es fácil, pero cuando algo falla, arreglarlo es extremadamente difícil
- etc, etc
No es ningún secreto que MS no me cae bien, y creo que las razones anteriores son suficientes para ello.
Por eso me di a la tarea de buscar una alternativa libre que brinde capacidades similares. El objetivo es tener un sistema centralizado de usuarios, donde los usuarios tienen una identidad única para utilizar el sistema operativo (y las aplicaciones que utilicen autenticación integrada) desde cualquier máquina.

MS no inventó nada nuevo con Active Directory, sino que supo combinar protocolos que ya se utilizaban desde hace años y que mayoritariamente nacieron como protocolos libres, por lo cual existen alternativas para cada componente. El problema es unir estos componentes para que trabajen en conjunto.
Los componentes básicos para lograr la funcionalidad deseada son:
- Autenticación con Kerberos.
- NTP para mantener sincronizados los relojes (requerimiento importante para kerberos).
- Servicio de directorio LDAP para almacenar datos de usuarios, grupos, hosts, etc.
- DNS para asignar nombres de dominio.
- DHCP para distribuir direcciones IPs (opcional pero muy útil).
- Replicación de los datos entre múltiples servidores (multi-master replication).
- Administración de seguridad a través de políticas de grupo (GPOs).
Es claro que AD no se queda ahí y gracias al la integración con el resto del soft MS, es posible tener integrado servicio de email (Exchange), y servicio de archivos (SMB), entre otros.

Sacando las GPOs, todo el resto se puede lograr utilizando software libre, por ejemplo:
- MIT Kerberos
- NTP
- OpenLDAP
- Bind (DNS)
- Samba
- Postfix
La tarea entonces es configurar los servicios para que trabajen en conjunto.
Existe mucha información en internet sobre cómo lograr que las herramientas interactúen, pero poco sobre proyectos que integren todo.
El más notable al respecto es la distribución Calculate Linux. Si bien todavía no probé esta distribución, la descripción de la misma es muy alentadora, ya que hasta permite integrar hosts Windows para que interactúen con los servidores Linux.

En base a lo expuesto, desde hace un par de meses estoy trabajando en armar una infraestructura como la de Active Directory, pero utilizando software libre y documentando todo al respecto, desde la definición de kerberos y LDAP, hasta la instalación y configuración de los diferentes servicios en servidores y clientes para lograr la funcionalidad deseada.
Como la información es mucha, decidí repartirla en varios artículos que iré publicando a lo largo del próximo mes (o tal vez dos meses). Uno de estos artículos ya lo publiqué hace un par de semanas, y trata sobre PAM.
La lista de artículos es la siguiente:
- Un servicio básico, el DNS: breve descripción y cómo utilizar bind
A medida que los vaya publicando, volveré a este artículo para actualizar los links y tener así todo integrado.
De los citados, sólo me falta escribir el de DNS, y puede que alguno lo termine partiendo en 2 por ser muy largos, pero básicamente no cambiará mucho a lo planteado.
También espero tener tiempo de armar un sistema de archivos y montar un servidor de mail con postfix, pero como viene la mano en el trabajo, puede que eso quede para más adelante.

Mi recomendación es que si les interesa la idea, vayan armando sus propios proyectos y compartan dudas, mejoras o lo que se les ocurra. Pueden utilizar comentarios en el blog o en la página de IT Freek Zone en facebook.
Les recomiendo utilizar máquinas virtuales para poder probar servidores y clientes con una sola máquina de forma rápida. Además clonando discos virtuales es fácil deshacer y volver a empezar.
Autenticación en GNU/Linux con PAM
Antiguamente, la autenticación en sistemas UNIX estaba ligada al que hoy conocemos como "sistema tradicional UNIX", el cual verifica usuario y contraseña contra los valores almacenados en el archivo /etc/passwd (en versiones modernas el password se movió al archivo /etc/shadow por cuestiones de seguridad).
Dado que con los años se fueron desarrollando distintos métodos de autenticación más seguros, seguir clavados utilizando el método tradicional era poco flexible y sin sentido.
A partir de la necesidad de poder cambiar fácilmente entre métodos de autenticación y utilizar distintos métodos, Sun diseñó PAM (Pluggable Authentication Modules). PAM es un conjunto de librerías que permiten una gran variedad de mecanismos de autenticación, entre los cuales contamos con Kerberos, LDAP, y RADIUS (además del tradicional /etc/passwd). Gracias a esto, actualmente es posible autenticar usuarios GNU/Linux contra bases centralizadas de usuarios como el citado kerberos.
PAM no sólo permite utilizar distintos métodos de autenticación, sino que permite utilizar varios al mismo tiempo. Además agrega la posibilidad de utilizar otros medios de autenticación (más allá del clásico usuario/password), como ser smartcards, tockens, etc.

En este artículo les explicaré cómo se configura la autenticación utiliando PAM, y sobre el final podremos entender la configuración de un debian default.


Configuración

PAM divide la tarea de autenticación en cuatro grupos de administración separados:
- account provee verificación de tipos de servicio para la cuenta: el password expiro? tiene permitido acceder el servicio requerido? root puede loguearse por consola?
- authentication autentica el usuario, y luego otorga los privilegios correspondientes (como membresía de grupo). Este módulo permite setear distintos requerimientos para autenticar al usuario, como passwords, smartcards, tockens, etc.
- password es responsable de actualizar los mecanismos de autenticación. Estos servicios están fuertemente acoplados con los del grupo authentication.
- session cubre las acciones que se deben hacer antes de que se otorgue un servicio y luego de que el servicio haya sido retirado. En el caso de login, las acciones pueden ser logging y montado de directorios.
La configuración de PAM se realiza a través de reglas y el archivo principal es /etc/pam.conf, aunque en general se prefiere dividir las reglas en diferentes archivos del directorio /etc/pam.d/.
Cada regla tiene cinco campos, separados por espacios:
servicio tipo control path-modulo argumentos-modulo
donde:
- servicio es el nombre familiar que corresponde a la aplicación (ej: login, su, sshd). Este campo no se incluye en los archivos de /etc/pam.d, dado que el servicio está indicado por el nombre del archivo en minúscula. El servicio correspondiente a login utiliza a los archivos common-account, common-auth, common-password y common-session para configurar cada uno de los grupos.

- tipo: es el grupo de administración al que se aplica la regla (account, auth, password o session).

- control indica el comportamiento que PAM debe seguir en caso de que el módulo asociado tenga éxito o falle. Este campo permite dos notaciones. En la notación simple, se utiliza una palabra clave, y en la compleja se encierran pares valor=acción entre corchetes [valor1=acción1, valor2=acción2, ....]
Una característica importante de PAM es que las reglas se pueden "apilar" para combinar los servicios de varios PAMs para una dada autenticación. Los valores de retorno de cada módulo se guardan en una pila. Gracias a esto, es posible, por ejemplo, intentar autenticar primero con kerberos, y si esto falla, intentar autenticar localmente con autenticación unix.

Las palabras claves más comúnmente utilizadas en la notación simple, son:
- required: indica que la ejecución del módulo debe ser exitosa para que la operación sea exitosa. Sin embargo, si el módulo falla, la operación fallará recién luego de que se invoque al resto de los módulos que vienen después.
- requisite: igual que required, pero si el módulo falla, se retorna el control directamente a la aplicación. Es decir, no se continua invocando módulos como sucede con required.
- sufficient: el éxito del módulo es requerimiento suficiente para la operación, esto es, no se continúa procesando los siguientes módulos. Si falla, el proceso continúa en la siguiente regla.
- optional: el resultado de este módulo es importante sólo si es el único en el stack.
En la notación compleja, los valores son códigos de retorno. Los más vistos comúnmente son:
- success: la función retornó ok
- ignore: ignorar el módulo en cuestión, sin importar si el flag de control es required, optional o sufficient.
- new_authtok_reqd: se requiere un nuevo token de autenticación. Utilizado generalmente cuando el password debe ser cambiado.
- default: implica todos los valores que no se mencionan explícitamente.
Las posibles acciones en esta notación pueden ser un entero n sin signo, que indica la cantidad de módulos a saltar en el stack, o tomar alguna de las siguientes formas:
- ignore: el estado de retorno del módulo no influenciará el resultado final, a menos que no haya otro módulo en el stack.
- bad: el estado de retorno debe indicar el fallo del módulo. Si esta es la primer falla, este estatus se usará para todo el stack.
- die: idem a bad, excepto que el stack termina y se retorna el control a la aplicación inmediatamente.
- ok: el código de retorno sobreescribirá un valor previo de éxito, pero no un estado previo de falla.
- done: idem a ok, excepto que el stack termina y el control se retorna inmediatamente a la aplicación.
- reset: se limpia el stack y se comienza de nuevo con el próximo modulo.
Como se puede observar, en la notación compleja se permite mucha más granularidad que utilizando palabras claves. Por ello, es posible representar los mismos valores que las palabras claves con notación compleja:
required = [success=ok new_authtok_reqd=ok ignore=ignore default=bad]
requisite = [success=ok new_authtok_reqd=ok ignore=ignore default=die]
sufficient = [success=done new_authtok_reqd=done default=ignore]
optional = [success=ok new_authtok_reqd=ok default=ignore]
- path-modulo es el path al módulo, o la dirección relativa al directorio donde se ubican los módulos por default, el cual es /lib/security en debian.

- argumentos-modulo son los argumentos, separados por espacios, que se envían al módulo.

Ejemplo práctico

Para entender mejor cómo funciona PAM, veamos el contenido de los archivos en la configuración de un sistema debian default.
/etc/pam.d/common-account (verificación de tipos de servicio)
account [success=1 new_authtok_reqd=done default=ignore] pam_unix.so
account requisite pam_deny.so
account required pam_permit.so
De la explicación anterior, podemos entender que el sistema utilizará el módulo pam_unix. Si esta autenticación tiene éxito (success=1), se saltea la siguiente regla y se ejecuta el módulo pam_permit, permitiendo el acceso.
En caso de fallar, se ejecuta el módulo pam_deny, el cual siempre retorna un valor de fallo; y como el parámetro de control es "requisite", la operación termina inmediatamente.

/etc/pam.d/common-auth (autenticación de usuario y seteo de credenciales)
auth [success=1 default=ignore] pam_unix.so nullok_secure
auth requisite pam_deny.so
auth required pam_permit.so
Este caso es casi igual al anterior, sólo que se utiliza el parámetro nullok_secure al llamar al módulo. En la acción default del módulo no se permite el acceso a un servicio si su password oficial es nulo. Lo que hace este parámetro es sobreescribir este comportamiento y permitir usuarios con password en blanco.

/etc/pam.d/common-password (actualización de passwords)
password [success=1 default=ignore] pam_unix.so obscure sha512
password requisite pam_deny.so
password required pam_permit.so
password optional pam_gnome_keyring.so
En este archivo el cambio es que se agregan los parámetros obscure y sha512 al módulo pam_unix. obscure fuerza el checkeo de la fortaleza del password y sha512 hace que los passwords se almacenen hasheados con sha512.
El módulo pam_gnome_keyring permite el desbloqueo del archivo donde Gnome almacena credenciales del usuario (viene con Gnome). Como ven, el resultado de la ejecución de este módulo no afecta el resultado final de la operación.

/etc/pam.d/common-session (acciones a realizar antes de login y luego de logout)
session [default=1] pam_permit.so
session requisite pam_deny.so
session required pam_permit.so
session required pam_unix.so
En este último archivo no encontramos nada especial, sólo que se ejecuta el módulo pam_unix. El formato de este archivo no tiene mucho sentido, porque dado que pam_permit siempre termina bien, lo siguiente a ejecutar es nuevamente pam_permit, con lo cual se continúa hasta la ejecución de pam_unix. La razón de que esto esté así es por compatibilidad con los archivos anteriores, ya que si observan bien, la estructura es similar.


Referencias

- PAM configuration guide for Debian
- The Linux-PAM System Administrators' Guide - 4. The Linux-PAM configuration file
- Understanding PAM
Metiendo mano en el hardware

En este artículo voy a relatar una de las experiencias más satisfactorias que he tenido lidiando con hardware.

Este viernes encendí mi computadora de escritorio y al poco tiempo mi monitor lamentablemente se "murió". Era Es un monitor Samsung modelo SyncMaster740N LCD de 17" 4:3. Se trata de un modelo bastante común, ya que es usado generalmente en cibercafés, oficinas, etc.

Al poco tiempo de encender la computadora, la pantalla se volvió negra, como cuando se activa el ahorro de energía, pero la luz de power permaneció encendida (cuando está en ahorro de energía se mantiene parpadeando). Primero pensé en un problema de video por lo que reinicié la computadora sin éxito. Luego apagué y encendí el monitor repetidas veces y tampoco tuve éxito.

En ese momento me sentí frustrado al pensar en tener que afrontar un gasto de aproximadamente U$S 250, sobretodo teniendo en cuenta que el monitor tiene sólo 5 años de vida. Pero pensé que tal vez podría tener arreglo y, tocando botones de configuración y mirando detenidamente la pantalla, me dí cuenta que se veía una ventana muy pero muy tenuemente (con buena luz ambiente y prestando mucha atención). Parecía como si el monitor funcionara correctamente, aunque sin brillo o iluminación (la pantalla se veía opaca como la de una calculadora de bolsillo, aunque mucho más tenue).

Inmediatamente me puse a investigar en Internet y descubrí que a alguien ya le había sucedido exactamente lo mismo (http://www.fixya.com/support/t4636238-samsung_740n_blank_screen). Desde hace un tiempo el monitor emitía un zumbido extraño pero funcionaba correctamente, hasta que un día la pantalla se puso negra. Aparentemente los zumbidos se deben a capacitores en mal estado.

En otro sitio descubrí que cuando la pantalla se vuelve oscura pero se pueden ver las ventanas, significa que el problema son las backlights. Las backlights son una especie de pequeños tubos fluorescentes que se ubican detrás (o al costado) del panel LCD para darle iluminación y brillo a la pantalla y así producir una imagen visible. Esto se debe porque, a diferencia de las pantallas CRT, los paneles LCD no producen luz por sí mismos (http://en.wikipedia.org/wiki/Backlight). Entonces el problema podía estar en las backlights mismas o en el circuito que las alimenta. Aunque el zumbido que emitía el monitor hasta el momento de apagarse indicaba que el problema era algún capacitor en mal estado.

En un foro que me resultó extremadamente útil (http://www.yoreparo.com/foros/plasma_lcd/falla-lcd-samsung-740n-t259814.html) encontré la respuesta a mi problema:
Atención reparadores de monitores SAMSUNG 740 N, 17 pulgadas. Al cabo de tres años de funcionamiento, estos monitores fallan debido a la temperatura que alcanza la fuente de alimentación, por cierto muy mal ventilada.

Deja de funcionar la fuente de la lámpara del panel, sin embargo, el monitor sigue trabajando normalmente (se comprueba al abrir el menu de ajustes, porque se puede ver muy tenuemente)

Los primeros en fallar son tres capacitores de 820 uF/25v que filtran la etapa previa a los exitadores de la fuente de 650 v, 17 mA
(c112, c111, c301) extrañamente de un color distinto a los demas (marrones), se ve que son de inferior calidad. Con la temperatura se inchan y se desvalorizan. Tambien salta un pico fusible de 3A (ubicado entre medio de una pegamento blanco entre el disipador de D105 y los capacitores nombrados. Reemplazando estos se soluciona. [sic]

A eso se resume básicamente mi experiencia, podría cerrar el artículo en este punto pero voy a continuar explicando los detalles.

Esperanzado me puse a desensamblar el monitor y en un principio me resultó imposible ya que no tiene tornillos. Me puse a buscar en Google y encontré un manual (http://www.eserviceinfo.com/downloadsm/28685/Samsung_740N.html) del fabricante donde explica paso a paso como desarmar y armar el monitor con fotos (muy bueno, asombrosa la calidad de los manuales de Samsung). De forma increíble todo el monitor es sostenido por la carcasa de plástico, la cual se mantiene unida con unas pequeñas trabitas de plástico (afortunadamente no se rompió ninguna al desarmarlo, como me ha sucedido otras veces al tratar de desarmar otros dispositivos como radios, controles remotos, etc.).


En la foto se observa el monitor completamente destripado. Al examinar los componentes de la plaqueta rápidamente me dí cuenta que los tres capacitores indicados en el post del foro yoreparo.com estaban "inflados", incluso uno tenía un sedimento en la parte superior. Esto es algo que aprendí cuando cursaba taller de electrónica en la secundaria: si un capacitor está inflado significa que está roto. Por eso es uno de los componentes más fáciles de detectar.


En la foto se ve claramente la parte superior inflada (notar la diferencia con los otros capacitores).

El siguiente paso fue retirar del circuito los capacitores dañados. Esto se debe realizar cuidadosamente para no dañar el resto de los componentes. Con un soldador de estaño (si se dispone uno de baja potencia, por ejemplo 15W, mejor) se calientan las patas y se va tirando del capacitor suavemente y alternando entre patas hasta removerlo completamente.

Con uno de los capacitores me dirigí a la casa de electrónica más cercana (ninguna realmente cercana así que tuve que patear bastante) para buscar los recambios. Estos capacitores son de 820uF y son difíciles de conseguir, entonces tuve que comprar de 1000uF. Además no conseguí de 105º, los que compré son de 85º (espero que aguanten la temperatura elevada hasta que pueda conseguir de 105º).

Procedí entonces a instalar los nuevos capacitores. Primero se debe eliminar el estaño de la pista (sería ideal disponer de un removedor de soldadura) y luego colocar la pieza. Se debe prestar extrema atención al colocar los capacitores electrolíticos, ya que estos poseen polaridad. Si se conectan de forma inversa van a, literalmente, explotar (lo cual por cierto es muy divertido http://www.youtube.com/watch?v=ipiyP6Cph9M). En la plaqueta y en el capacitor se indica claramente el polo negativo. De todas formas hay que revisar la polaridad antes de soldar y antes de conectar.

La forma adecuada de soldar es calentar con la punta del soldador la pista y la pata al mismo tiempo y luego aplicar la cantidad suficiente de estaño. Si la pista o la pieza están frías la soldadura será defectuosa y seguramente no hará contacto, por lo que hay que tener cuidado al realizar la unión. Luego se corta el excedente de pata y se revisa cuidadosamente la pista para que no queden puentes de estaño entre pistas contiguas.


Bien, lo que quedaba era ensamblar precariamente el monitor para poder comprobar el correcto funcionamiento. En la primera prueba que hice el monitor no encendió, por ello tuve que volver al post encontrado en yoreparo.com para darme cuenta que también el picofusible podía estar quemado. De hecho lo estaba, para darme cuenta simplemente hice un puente en el fusible y el monitor encendió, para mi alegría.


Dado que no conseguí hasta el momento un picofusible de repuesto, lo reemplacé con un fusible común de 3A y probé continuidad con el tester para comprobar que estuviera todo OK.
Luego de terminada la reparación, ensamblé el monitor y lo probé con la notebook.


Perfetto!


El costo total de la reparación fue de aproximadamente U$S 2.

Conclusión: vale la pena intentar reparar las cosas :)

Espero que les haya gustado.
Administrar proyectos libres con Launchpad y Bazaar
En los últimos días estuve ocupado creando una herramienta que me permitiera realizar consultas sobre un servicio LDAP para obtener información de los usuarios de un dominio. La herramienta en cuestión la realicé en Python y me pareció que era lo suficientemente interesante como para compartirla con la comunidad libre para que cualquiera pueda utilizarla y/o modificarla.
Esto me llevó a la búsqueda de un servicio de versionado y hosting libre donde subir el proyecto. Algunos años atrás hubiera utilizado SourceForge sin pensarlo, pero gracias a su cambio de política hacia una censurista y asquerosamente repudiable (que raro que provenga de una ley yankee "defensores de la libertad"...) que deja afuera a los países Iran, Corea del Norte, Cuba, Siria, Libia y Sudan, decidí buscar una alternativa que sea realmente libre. La idea es compartir código entre comunidades sin importar estatus social, país de orígen, color de piel, etc, etc, y SourceForge no cumple con este importantísimo requisito. Lo mismo sucede con Google Code, lo cual elimina al segundo gran proveedor de software open source.
Por ello, utilizando la muy completa entrada de wikipedia Comparison of open source software hosting facilities, revisé cuál de los servicios se adaptaba mejor a lo que quería. Por orden de popularidad tenemos SourceForge (descartado), Launchpad, Google Code (descartado), GitHub y Assembla. De entre estos elegí Launchpad porque los términos de servicio de GitHub y Assembla no me terminaban de agradar. Increíblemente GitHub impone copyright sobre el código html/javascript/css de SU propia página... un site que promulga el hosting de aplicaciones open source y no es libre, no me agrada. Además, los mencionados servicios están hosteados en USA y aplican sus leyes, con lo cual corremos el riesgo que suceda lo mismo que con SourceForge.
Launchpad es de Canonical Ltd. (la gente detrás de Ubuntu) y esto también me genera dudas, dado que desconfío de las intenciones de dicha compañía... pero no encontré nada malo en sus términos de servicio (es más, no encontré términos de servicio para hosting de proyectos...), es una comunidad muy grande con proyectos importantes (MySQL, Ubuntu, Enlightenment, Bazaar, entre otros), no está hosteado en USA (por lo que vi, los servidores son de Gran Bretaña) y el administrador de proyectos me parece bueno.

A continuación describiré los pasos necesarios desde la creación hasta la publicación de una versión descargable de nuestro proyecto, utilizando Launchpad y Bazaar.


Creación del proyecto en Launchpad

Para crear un proyecto en Launchpad, primero debemos registrar una cuenta, si es que no poseemos una. La registración es simple y no requiere muchos datos.
Una vez que estamos registrados y logueados, nos dirigimos a https://launchpad.net/projects/+new para registrar nuestro proyecto.
Para tener una idea sobre cómo se administran los proyectos en Launchpad, les recomiendo leer la ayuda oficial.


Creación del proyecto en Bazaar

Launchpad utiliza Bazaar para el versionado de proyectos, por lo que necesitaremos conocer una lista de comandos básicos de este sistema. Es posible importar branchs de otros manejadores de versionado como Git, Mercurial, Subversion y CVS, pero si recién están comenzando, o si nunca utilizaron un manejador de versiones, por qué no probar con Bazaar?

Instalar Bazaar en debian y derivados es tan simple como ejecutar:
# apt-get install bzr
Una vez instalado, configuramos nuestro nombre de usuario:
$ bzr whoami "demasiadovivo <demasiadovivo@spameame.com>"
y verificamos que el nombre se registró correctamente:
$ bzr whoami
demasiadovivo <demasiadovivo@spameame.com>
Luego del simple setup inicial, nos metemos con la creación y administración de proyectos utilizando este sistema de versionado.
El primer paso es inicializar el proyecto:
- dirigirse al directorio donde se encuentra el código del proyecto:
$ cd /path/mi-proyecto
- inicializar:
$ bzr init
Al hacer esto, Bazaar crea el primer branch y almacena los datos en un directorio denominado ".bzr". Un branch es un registro de todos los commits que se han hecho. Pueden existir varios branches en paralelo, los cuales luego se pueden combinar (merge).
Para agregar los archivos que deseamos seguir, se utiliza el comando bzr add . Para agregar todos los archivos del directorio del proyecto, podemos simplemente ejecutar:
$ bzr add
adding README.txt
adding useraudit.cfg
adding useraudit.py
adding useraudit_cli.py
Ahora, cuando tenemos código sobre el cual deseamos crear un snapshot, realizamos un commit. En el commit es posible agregar un comentario, indicando la razón del mismo:
$ bzr commit -m "Primer commit"
Committing to: /ruta/mi-proyecto/
added README.txt
added useraudit.cfg
added useraudit.py
added useraudit_cli.py
Committed revision 1.
Podemos ver el historial de commits con:
$ bzr log
------------------------------------------------------------
revno: 1
committer: demasiadovivo

branch nick: mi-proyecto
timestamp: Sun 2011-06-05 16:20:03 -0300
message:
Primer commit

Subir el código a Launchpad

Para poder subir código a Launchpad, primero deberán generar un par de claves SSH, para lo cual pueden seguir el artículo Automatización de transferencias por SFTP, y a continuación publicar la clave pública en https://launchpad.net/~<usuario>/+editsshkeys
Recuerden que la clave pública se encuentra en /home/<usuario>/.ssh/id_rsa.pub, si es que no eligieron otro path al generar el par de claves.
Con esta clave podremos autenticarnos ante Launchpad y así subir código.

Una vez que registramos nuestra clave SSH, podemos subir el commit a Launchpad ejecutando:
$ bzr push sftp://<usuario>@bazaar.launchpad.net/~<usuario>/<mi-proyecto>/<branch>
donde:
bazaar.launchpad.net es la dirección de Bazaar en Launchpad
<usuario> es nuestro usuario en Launchpad
<mi-proyecto> es el proyecto que registramos en Launchpad
<branch> es el branch que deseamos crear
Si queremos hacer un commit a un branch que ya existe, deberemos ejecutar el mismo comando pero con un parámetro adicional:
$ bzr push --use-existing sftp://@bazaar.launchpad.net/~<usuario>/<mi-proyecto>/<branch>
Luego de crear el branch, es posible (al menos a mi me sucedió), que Launchpad nos diga que el proyecto todavía no tiene un branch. Esto es que Launchpad no sabe cuál es el branch principal, por lo cual nos dirigimos a https://launchpad.net//trunk/+setbranch y elegimos la opción "Link to a Bazaar branch already on Launchpad", y en el textbox donde indicamos el branch ponemos la dirección del branch recién creado:
~<usuario>/<mi-proyecto>/<branch>

Generar un release

Una vez que estamos lo suficientemente conformes con nuestro código y queremos que usuarios finales descarguen el programa, debemos generar un release y para generar un release, necesitamos un milestone.

Los milestones son puntos específicos en la vida de una serie (series en inglés), y una "serie" representa la serie de lanzamientos de una versión mayor. Los puntos representados por un milestone pueden ser beta tests, release candidates, o puntos menor y mayor de lanzamiento. Pueden leer más sobre series, milestones y releases en Projects/SeriesMilestonesReleases.
En fin, para crear un milestone, nos dirigimos a la sección "Milestones and releases" de la página principal del proyecto y le damos al link "Create milestone" (https://launchpad.net//trunk/+addrelease).
Entre la información que debemos proveer, el único campo obligatorio es el nombre, el cual se toma como la versión.

Una vez que tenemos el milestone creado, podemos proceder a realizar el release. Hacerlo es tan simple como darle al link "Create release" que se encuentra en el milestone bajo el título "Expected" y setear una fecha.

Cuando terminamos de crear el release, el site nos regresa al milestone, donde podemos ver que la fecha del release se actualizó. Ahora sí podemos agregar un archivo tarball descargable que contenga el programa completo.
Pueden generar el tarball de diferentes formas, pero si lo van a hacer desde la consola, deberán dirigirse al directorio padre del proyecto y ejecutar lo siguiente:
$ tar -czvf mi-proyecto_v0.1.tar.gz --exclude-vcs mi-proyecto/
donde la opción --exclude-vcs evita que tar incluya el directorio que utiliza Bazaar para sus datos (es decir, el ".bzr").
Ya tenemos todo lo necesario para subir el tarball con el programa completo y que se pueda descargar. Para ello, en el milestone seleccionamos "Add download file". En la interfaz de upload debemos proveer tanto el archivo como una descripción de lo que contiene el mismo (por ejemplo "mi-proyecto 0.1 tarball"). También es posible proveer una firma GPG, lo cual brinda mayor seguridad al cliente que descarga, ya que puede confiar que el archivo ha sido creado por nosotros. Para poder firmar el archivo debemos poseer una un par de claves GPG (o PGP), y la clave pública debe estar publicada en algún lugar de confianza.
El mismo site da la ayuda de cómo crear la firma digital del archivo:
gpg --armor --sign --detach-sig
lo cual crea el archivo filename.asc que después debemos subir utilizando el campo "GPG signature".


Trabajo Terminado

Si quieren ver el resultado final, pueden ingresar al site de mi proyecto. También están invitados a descargar, testear, recomendar, compartir, etc, etc, el programa. Ya escribiré algún post sobre la herramienta =)


Referencias

- Launchpad Projects
- Bazaar in five minutes
- Hosting your code on launchpad and bazaar
Estadísticas sobre uso de recursos en GNU/Linux
Si son sysadmins, necesitarán alguna forma de ver cómo se utilizan los recursos de nuestros sistemas, sobre todo cuando las cosas andan mal. Ver estadísticas sobre el uso de recursos permite tomar varias decisiones, como comprar hardware, separar servicios, virtualizar, o para solucionar errores en caso de procesos glotones, entre otras cosas.
Si bien en GNU/Linux todas las estadísticas se almacenan en el /proc, es necesario contar con alguna herramienta que las interprete y las haga más amigables. Para ello, contamos con sysstat, un paquete que provee varias herramientas para monitorear la performance del sistema y el uso de recursos.
Los componentes más interesantes de sysstat son:
- sar: reúne, reporta y almacena información de actividad del sistema (CPU, memoria, discos, interrupciones, interfaces de red, TTY, tablas del kernel, etc). Esta herramienta provee muchas opciones para filtrar los datos que deseamos obtener, y permite almacenar los resultados en archivos binarios que luego se pueden visualizar con el mismo sar. Es posible indicar la cantidad de muestras a tomar y el intervalo de tiempo entre muestras.

- sadc (system activity data collector): se encarga de recoger información del sistema una dada cantidad de veces, a intervalos específicos de tiempo, y se utiliza como backend de sar. Escribe en formato binario en un dado archivo o en la standar output. Si no se especifica la cantidad de muestras a tomar, éste escribe infinitamente.

- sa1: un shell script que utiliza sadc para generar el archivo binario /var/log/sa/sadd o /var/log/sysstat/sadd (donde dd es el día del mes, por ejemplo sa16 indica el día 16). Este script está designado para utilizarse con cron (ver /etc/cron.d/sysstat).

- sa2: otro shell script que utiliza sadc para generar reportes diarios en el archivo binario /var/log/sa/sardd o /var/log/sysstat/sardd (donde dd es el día del mes). Este script también está designado para utilizarse con cron (ver /etc/cron.daily/sysstat).

- sadf: permite mostrar el contenido de archivos binarios sar en diferentes formatos (CSV, XML, etc). El formato de salida default es uno fácilmente parseable por diferentes herramientas shell como grep, awk, sed, etc.

- pidstat: reporta estadísticas de procesos como uso de CPU, memoria, I/O, etc. Como en sar, es posible indicar la cantidad de muestras y el intervalo de tiempo entre muestras.
Si deseamos medir la utilización de recursos en el server, lo mejor es dejar que sa1 y sa2 generen los correspondientes logs durante un día, una semana, un mes o el tiempo que quieran, y luego visualizarlos con sar. Por defecto las muestras se toman cada 10 minutos, lo cual provee un buena visión sobre como se utilizan los recursos.
Otra posibilidad es ejecutar sar con el parámetro "-o archivo" para almacenar los datos en un archivo binario, e indicarle el intervalo de segundos entre muestras y la cantidad de muestras a tomar. Por ejemplo, el siguiente comando almacena todos los datos de utilización de recursos en el archivo "revision" cada 5 minutos:
sar -A -o revision 300
Para poder parsear el archivo recién generado con sar, es necesario utilizar el parámetro -f, por ejemplo:
sar -A -f revision
En la mayoría de los casos lo que necesitamos visualizar es uso de memoria, CPU, disco, swap y red. Todo esto se puede hacer con el siguiente comando:
sar -rudpW -n DEV,SOCK
donde:
-r muestra uso de memoria
-u muestra uso de CPU
-d muestra uso de disco
-p imprime el nombre de los dispositivos de forma agradable (usado con -d)
-W muestra estadísticas de swap
-n DEV,SOCK muestra estadísticas de las interfaces de red y cantidad de sockets utilizados.

Si no se utiliza el parámetro -f, sar toma los datos de los logs generados por sa1 y sa2. En caso de utilizar un archivo binario generado con sar (por ejemplo revision), pueden usar el siguiente comando:
sar -rudpW -n DEV,SOCK -f revision
Como podrán observar, la salida de sar no es muy amigable para ser filtrada y/o graficada y/o almacenada en una base de datos, así que lo mejor es utilizar sadf. sadf provee un set de opciones propias y permite utilizar las opciones de sar luego de dos giones (--). Entre las opciones propias de sadf, son interesantes:
-d imprime la salida con los campos separados con punto y coma (;)
-D igual a -d pero utiliza timestamp en lugar de fechas human friendly
-h para imprimir los resultados en una sola línea
-p salida default, amigable para los parsers
-x imprime la salida en formato XML
El comando del ejemplo anterior, utilizando sadf para ser parseado fácilmente, quedaría:
sadf -- -rudpW -n DEV,SOCK
o con -h para separar fácilmente los campos en una planilla (Calc, Excel, etc)
sadf -h -- -rudpW -n DEV,SOCK
Además de las estadísticas anteriores, para hilar más fino a la hora de ver quién gasta los recursos, es necesario tener estadísticas de los procesos que se están ejecutando. Para ello contamos con pidstat, cuyos datos arrojados son similares a los de sar, pero por proceso. pidstat acepta varios argumentos para mostrar distintas estadísticas, pero para una vista básica, me alcanza la siguiente configuración:
pidstat -ru -h 300 | sed '1,2d'
donde:
-r muestra uso de memoria
-u muestra uso de CPU
-h muestra las estadísticas horizontalmente (todo en una sola tabla).
300 es el intervalo de tiempo (en segundos) para tomar muestras
sed '1,2d' elimina las primeras dos líneas de la salida (son un comentario y una línea en blanco)
pidstat no ofrece la opción de crear un archivo binario para almacenar los datos, por lo cual debemos redirigir la salida a un archivo para poder filtrarla luego.


Si lo que quieren son gráficos de utilización (siempre algo visual ayuda a captar mejor los datos), podemos utilizar la salida de sadf y graficar con Calc (o Excel), con gnuplot, o con la interesante Sysstat Graph. No tuve la oportunidad de probar esta última, pero aparenta ser muy útil. Está escrita en PHP, por lo cual es fácil de instalar.


Referencias

- Sysstat man
- How do I Find Out Linux CPU Utilization?