viernes, 8 de febrero de 2013

Ejecutar consulta SQL guardada en un archivo

Esta semana se presentó en mi trabajo la necesidad de hacer dos consultas a una base de datos Oracle (Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - Production) para crear un reporte de producción que permitiera visualizar ciertos campos no disponibles mediante el menú estándar en el sistema.
Estas son las dos consultas y los comentarios sobre lo que aprendí al escribirlas. Para ejecutar el contenido del archivo, se escribe @nombredearchivo.sql desde el prompt del frontend del RDBMS (Relational Database Management System).
Para bases MySQL (no hace mucho adquirida por Oracle), la sintaxis es parecida, aunque reemplazando "@" por la palabra clave "source": source nombredearchivo.sql.

PRIMER CONSULTA: Uso de la función TO_DATE() para comparar fechas y SPOOL/SPOOL OFF para guardar los resultados en un archivo de texto.


SEGUNDA CONSULTA: Uso de la función TRUNC(sysdate) para obtener los registros pertenecientes a un intervalo de tiempo fijo (pero configurable).


El sitio donde aprendí lo necesario para hacer estas consultas es Burleson Consulting. Se trata de una consultora que brinda soporte y aplicaciones de Oracle (aunque indican que no están afiliados con ellos).

lunes, 28 de enero de 2013

Montando un RAID1 (mirror) en Debian

RAID (Redundant Array of Inexpensive Disks) es una tecnología de almacenamiento que combina varios unidades de disco en una misma unidad lógica. Los datos se distribuyen en los discos en una de varias formas denominadas "Niveles RAID", dependiendo en los requisitos de redundancia y de rendimiento que se necesiten.

Los diferentes esquemas (o niveles) se nombran utilizando la palabra RAID seguida de un número (por ejemplo, RAID0, RAID1, etc); cada uno de ellos provee un balance diferente entre los objetivos principales: confiabilidad, disponibilidad, rendimiento, y capacidad. Los niveles RAID mayores que RAID0 proveen protección contra errores irrecuperables, tanto en sectores aislados como en todo el disco.

En RAID1 (espejo sin paridad), los datos se escriben idénticamente en dos unidades (generalmente, aunque se pueden utilizar más unidades), produciendo de esa manera un "conjunto espejo". Cuando se hace una petición de lectura, la información es devuelta por cualquiera de las dos unidades independientes que la contienen. De manera similar, cuando se escribe en el conjunto, se actualiza el estado de ambos discos. El RAID1 continúa operando mientras al menos una unidad que lo compone se mantiene en funcionamiento.
  • El RAID1 crea una copia exacta (o espejo) de un conjunto de datos en dos o más discos.
  • Puede ser tan grande como el más pequeño de sus discos.
  • El rendimiento de lectura se incrementa aproximadamente como múltiplo lineal del número de unidades (puede estar leyendo de manera simultánea dos datos diferentes en dos discos separados)
  • En algunos entornos 24x7, es posible "dividir" el espejo: marcar un disco como inactivo, hacer una copia de seguridad de dicho disco, y luego "reconstruir" el espejo. 
La herramienta que se utiliza para administrar los RAIDs en Linux es mdadm, y está disponible desde los repositorios de Debian:


Voy a utilizar las unidades sdc y sdd que se muestran en el siguiente listado:


PRIMER PASO: Creo las particiones en las unidades (se muestra solamente para /dev/sdd):


SEGUNDO PASO: Creo el array:


(el progreso de creación del raid1 puede verse leyendo el archivo /proc/mdstat). En el caso de que este archivo indique resync=PENDING, se puede forzar el build del RAID1 con el comando: mdadm --readwrite /dev/md0.


Y cuando ya está listo:


TERCER PASO: Formateo el RAID:


CUARTO PASO: Montar el RAID y verificaciones:

  1. Línea 1: Tiro un listado detallado del contenido de mi home. Se puede ver en la línea 12 que hay un directorio llamado raid1 que será donde montaré el dispositivo /dev/md0 recién formateado y que utilizaré como RAID1.
  2. Línea 20: Monto el RAID1. No es necesario especificar el tipo de sistema de archivos ya que lo formateé como ext3 en el TERCER PASO.
  3. Línea 21: Muestro los sistemas de archivos montados actualmente. Veo que /dev/md0 está montado en /home/gacanepa/raid1 (línea 33).
  4. Línea 34: Intento copiar el archivo cliente.tar dentro de raid1, pero recibo el mensaje de "Permiso denegado" (línea 35) debido a que el usuario root se convirtió en dueño de ese directorio al montar el dispositivo /dev/md0 en él. Cambio el usuario dueño y el grupo del directorio (línea 36) e intento realizar la operación nuevamente (37), sin problemas esta vez.
  5. Línea 39: Veo el contenido del directorio en cuestión y se puede ver que el archivo fue copiado al mismo.
  6. Línea 41: Salgo del directorio para desmontar el filesystem (42). Luego de hacerlo, vuelvo al mismo (43) y veo su contenido (44), el cual no muestra nada ya que el dispositivo fue desmontado, y es en el mismo donde reside el archivo que había copiado anteriormente.
  7. Línea 46: Vuelvo a montar el RAID y veo su contenido (48).
  8. Línea 51: Marco como fallado uno de los dispositivos que componen el RAID para simular una falla de hardware, y veo en /proc/mdstat (53) el estado actual del RAID ([_U] indica que la primera unidad del RAID está fallada).
  9. Línea 59: Quito ("remuevo físicamente") "en caliente" la unidad que presenta problemas. Aun así, el contenido del RAID no se modifica (68-69) y puede accederse a su contenido.
  10. Línea 70: Muestro el espacio ocupado y disponible en cada filesystem activo del equipo. En (78) puedo ver el detalle del RAID.
  11. Línea 79: Reemplazo la unidad que presentaba fallos con una de similares características y la vuelvo a agregar al conjunto, luego de lo cual comienza a resincronizarse nuevamente (85). Mientras tanto, el contenido del RAID continúa siendo accesible (89).


¿Qué puede salir mal?

1) Al intentar crear el RAID, uno de los dispositivos puede estar ocupado (siendo utilizado por un proceso). En este caso, se puede identificar dicho proceso mediante lsof | grep nombreDeDispositivo, y luego matarlo utilizando su PID con el comando kill PID (o kill -9 PID, si con el anterior se resiste ;).

2) Para que el RAID esté disponible al reiniciar el equipo (persistencia), se debe configurarlo mediante la siguiente línea del archivo /etc/default/mdadm:


Si además de tener disponible el arreglo, se desea montarlo cuando arranca el sistema, se le debe asignar un punto de montaje y sus correspondientes opciones en el archivo /etc/fstab.

Si a alguien se le ocurre (o se encuentre con) otro problema que pueda surgir, deje un comentario y lo vemos :).

jueves, 24 de enero de 2013

Instalación de GNU/Linux Mint 14 "Nadia"

Hasta el momento, tenemos la PC familiar en casa con dual boot: GNU/Linux Debian Squeeze y Windows 7. A este último sistema operativo lo uso muy de vez en cuando para programar en Visual C# y usar el SQL Management Studio por cuestiones de trabajo.

Hace un par de días me dio ganas de probar personalmente GNU/Linux Mint 14 "Nadia", que es la última versión de Mint, y el escritorio Cinnamon. Personalmente me considero más fanático de la consola, pero para el resto de la familia quise instalar una "linda" distro con una interfaz gráfica más "llamativa" o "user-friendly" que la que provee Debian.

PRIMER PASO: Documentación de aplicaciones agregadas luego de la instalación original y determinación de la necesidad de las mismas actualmente.
  • Teamviewer (asistencia remota) - Descarga (archivo .deb, v.7.0.9377) disponible desde aquí. Versión actual:
  • Google Chrome (navegador de Internet) - Descarga (archivo .deb) disponible desde aquí. Versión actual:
  • FileZilla (cliente ftp) - Disponible desde los repositorios
  • Sane (API para uso de escáneres) - Disponible desde los repositorios
  • Terminator (múltiples terminales en una misma ventana) - Disponible desde los repositorios
  • Aptitude (gestor de paquetes) - Disponible desde los repositorios
  • CUPS (Sistema Común de ImPresión de Unix) - Disponible desde los repositorios
  • Smb-cliente (cliente Samba) - Disponible desde los repositorios
  • Jedit (editor de archivos de texto) - Disponible desde los repositorios
 Como ejemplo, al buscar los paquetes que contienen la palabra "samba", obtuve lo siguiente:


(Una descripción de la información anterior puede encontrarse en man aptitude, y en este link)

SEGUNDO PASO: Backup de directorios seleccionados dentro de /home, y de los favoritos de Google Chrome (en formato html).



CONTINUARÁ...

viernes, 7 de diciembre de 2012

enscript - Convertir archivos de texto a formato PostScript, HTML, RTF, y ANSI

Acabo de encontrar esta joyita en Linux: el paquete enscript. Como el título de este post lo dice, permite convertir archivos de texto plano a varios formatos, incluso proveyendo resaltado de sintaxis en el resultado para un montón de lenguajes de programación.
En los siguientes dos ejemplos voy a exportar 1) un script del Bash, y 2) un programa sencillo del tipo "Hola mundo!" escrito en Java, a correspondientes archivos bash.html y java.html.

holamundo.java:


Ahora ejecuto el siguiente comando desde la terminal:
Y muestro el resultado en el navegador:


servicios.sh:

Ahora ejecuto el siguiente comando desde la terminal:
Quedando:


Primeros pasos - VBA en Excel 2007 (Primera parte)

Mi jefe ayer me encargó atender un requerimiento proveniente de una planta ubicada en el Reino Unido. Se trata de una plantilla de Excel 2007 que incluye macros escritas en VBA y a la que se le debe incorporar un form que permita manipular datos de manera intuitiva y automática.

En realidad, sé algo de Visual Basic, pero nunca incorporé VBA a mis planillas de cálculo, más allá de un par de macros para facilitar ediciones de formato u otras cosas simples. También he hecho algo de scripting con VBScript, así que... ¿qué tan difícil puede ser? No tanto. Esto es lo que me di maña en un rato:

Un botoncito (un control ActiveX) que inicia el form principal:


Luego de hacer clic en "OK", se abre el menú:


Donde en el primer textbox ingreso un texto cualquiera, en el segundo la celda donde deseo escribirlo, y finalmente la hoja en la que voy a guardarlo:


Resultado:


Otro ejemplo:


Ahora, el código y los comentarios:

En primer lugar, el código del control ActiveX (el botón se llama "Saludo") que inicializa el form principal:

El resto del código:

miércoles, 5 de diciembre de 2012

Firmas y certificados digitales

Una firma digital es un esquema matemático que se utiliza para demostrar la autenticidad de un mensaje o documento digital. Una firma digital válida le da al receptor la garantía que el mensaje ha sido creado por un emisor conocido, y que no ha sido alterado en el camino. Las firmas digitales se emplean por lo general en la distribución de software, en transacciones financieras, y en otros casos en los que sea importante detectar falsificaciones o manipulación indebida. (Resumen traducido de Digital Signature, Wikipedia).

Un certificado digital (también conocido como certificado de identidad) es un documento electrónico que utiliza una firma digital para vincular una clave pública con una identidad determinada - tal como el nombre de una persona o de una organización, sus direcciones, etc. Este certificado también puede usarse para verificar que una clave pública le pertenece a un individuo específico. (Resumen traducido de Public key certificate, Wikipedia)

Generando una firma digital mediante DSA (Digital Signature Algorithm):

Primera fase: Elección de los parámetros del algoritmo, los cuales pueden ser compartidos por varios usuarios del sistema.
(Nota: /dev/random es un archivo especial que se encuentra presente en sistemas operativos basados en Unix y se emplea como un generador de números aleatorios mediante el acceso a "ruido ambiental" recogido de drivers de dispositivos y otras fuentes).


Segunda fase: Cálculo de clave pública y privada para un usuario determinado.


Creo el archivo "archivo.sha1" con el hash sha1 de "archivo" (por eso filtro con awk la primer columna a fin de utilizar el hash propiamente dicho, ver las diferencias en las imágenes siguientes. Con print $0 muestro todo el contenido del archivo sin filtrar, pero a mí me interesa únicamente el hash, por ese motivo empleo print $1). Para esto se puede utilizar tanto el comando sha1sum como openssl dgst -sha -sha1.



Creo la firma digital del hash (archivo.sha1) correspondiente al archivo "archivo", con mi clave privada. Luego verifico con mi clave pública que la firma "firma" es la que corresponde al hash que contiene archivo.sha1:


De esta manera, si se pudo verificar la firma con la clave pública del emisor, significa que éste último es el único que puede haberla creado a partir de su clave pública.

Por último, en este link hay un excelente recurso para comprender los conceptos de clave pública y privada, y firmas / certificados digitales.

lunes, 3 de diciembre de 2012

Funciones hash

Una función hash genera una cadena de caracteres a partir de un mensaje o de un archivo para determinar si el mismo ha sido modificado en la cadena de transmisión (de ser así, el resultado de la función cambia) y de esa manera asegurar su integridad y autenticidad.

Para evitar la posibilidad de que tanto el mensaje (archivo) como su hash correspondiente sean modificados en el camino, el emisor puede utilizar un cifrador asimétrico para encriptar el hash con una clave pública. El problema con esto es que cualquiera que tenga la clave pública puede interceptar el mensaje con su hash, modificarlos, y enviarlos nuevamente.

La manera de evitar este último incoveniente es combinar un algoritmo simétrico con uno asimétrico, generando un secreto compartido (clave simétrica) entre emisor y receptor, el cual si bien no va a ser usado para encriptar, el emisor va a concatenar esta clave al contenido del mensaje original, y a eso le va a calcular el hash, para luego encriptar este último con la clave pública. Sin embargo, lo que se envía es el mensaje original sin la clave concatenada, y el hash encriptado. Cuando se recibe, se descifra el hash enviado, se concatena el mensaje con el secreto compartido, se le calcula el hash en destino y se calcula con el que se recibió - la igualdad de ambos asegura la autenticidad y la integridad de la transmisión.

En resumen:
  1. Se genera un secreto compartido entre emisor y receptor.
  2. El emisor concatena el mensaje original junto con el secreto compartido, y calcula el hash del resultado.
  3. Se envía el mensaje original y el hash obtenido en el punto 2 de forma separada.
  4. En el destino, se concatena el mensaje recibido y el secreto compartido.
  5. Se calcula el hash del resultado obtenido en el punto 4.
  6. Se compara el hash del punto 2 con el del punto 5.
MD5 utiliza hashes de 128 bits. Se considera que, dadas las capacidades de cálculo actuales, puede llegar a ser vulnerable o que existan dos archivos cuyos hashes sean idénticos.
SHA-1 emplea hashes de 160 bits, y el SHA-512 de 512 bits.

Ejemplos:
  • Creo el archivo llamado "archivo" y le agrego la cadena "Yo uso CentOS :)".
  • Calculo el hash MD5 de archivo.
  • Le agrego un espacio (" ") a "archivo".
  • Vuelvo a calcular el hash MD5 y comparo los hashes obtenidos.
  • Creo el archivo "archivo" con el texto original ("Yo uso CentOS :)") y calculo los hashes SHA-1 (160 bits) y SHA-2 512 de 512 bits.