viernes, 5 de agosto de 2011

Et Gira tutto intorno alla estanza

Perdón por el título en italiano, pero es que la mar de músicas de este año ha estado muy bien y de ahí mi pequeño homenaje.

El título viene a colación porque vamos a ver cómo evitar que los logs de nuestro sistema de alertas montado sobre zabbix nos llenen '/' y hagan que nuestro servidor deje de funcionar.

Nunca me había planteado cómo de complicado sería utilizar logrotate y resulta que era asombrosamente simple, cómo una gran cantidad de cosas que nuestro querido linux nos puede proporcionar para que nuestra vida sea más cómoda.

Básicamente debemos crearnos un directorio en el que se almacenarán los archivos de log generados por nuestros scripts. Posteriormente nos crearemos un archivo de texto en '/etc/logrotate.d/' con el nombre que elijamos y con las siguientes líneas:

# Para los archivos de debug
/[directorio]/*.log {
daily
rotate 45
compress
nocreate
missingok
}

Las opciones aquí reflejadas harán que nuestros logs conserven una cantidad razonable de datos para su posterior consulta cuando se detecte un error en el sistema. El resto de opciones pueden consultarse en la página de manual del propio logrotate.

lunes, 4 de julio de 2011

Uno rápido

Dentro de un buen sistema de backups siempre debería aparecer la opción de tener el respaldo de los datos lejos del lugar donde residen diariamente.

Una solución sería sincronizar tus datos con un sistema remoto, o como dicen ahora: 'en la nube'...cuanto daño han hecho los anuncios de Isabel Coixet.

Otra solución, más física, consistiría en tener un par de discos duros, gemelos, que tuvieran los datos semanales. Al final de la semana desenchufamos uno y colocamos el otro. Tan pronto como se realice la siguiente ventana de sincronización se actualizarían los datos de la semana anterior en el nuevo dispositivo.

Suena simple, verdad? Pues la ejecución de la tarea no va mucho más allá:

# apt-get install usbmount

Con esta orden conseguimos que los discos duros externos se monten en '/media/usb0', siempre que posean una única partición, con lo que si cambiamos nuestro target diario en las copias de seguridad por este punto de montaje, listo.

Los discos duros se montan por defecto con la opción 'sync', para que en todo momento los datos reflejen los cambios en el dispositivo físico. Esto evita pérdidas de datos cuando se extraigan semanalmente los dispositivos. Por esta razón se desaconseja el uso de esta opción con memorias flash.

martes, 19 de abril de 2011

Auto-Post

No, no es que vayamos a hablar de coches, es que desde el último post le he estado dando vueltas a la forma en la que el código, ya sea python, ya sea c++, se muestra en nuestro querido servicio blogger. Hay muchas entradas por ahí, un rápido uso de google nos dará infinidad de resultados, siento no nombrar a nadie, pero creo que cogí cosas de aquí, cosas de allí y alguna de cosecha propia ya que no encontré el proceso completo en ningún sitio.

Lo de auto es porque lo que explico en este post aparece mostrado dentro de él jeje

En fin, de momento, para mi código python utilizaré pygments, el paquete en debian se llama 'python-pygments', para ser exactos. Primero debemos crear el código css que añadiremos a nuestra plantilla de blogger. Por poner algo, vamos a utilizar la clase codehilite, para ello generamos nuestro css de la siguiente forma:

$ pygmentize -O bg=light,python=cool -S default -f html -a html -a ".codehilite" > syntax.css

Así obtenemos una lista de clases que nos coloreará, posteriormente, las palabras clave y demás cacharrería como todos vemos en las webs sobre python. Debemos añadir el contenido de este archivo en nuestra plantilla de blogger, en el apartado de 'Diseño', en 'Edición de HTML', entre las palabras clave:

b:skin [[CDATA
...
]] b:skin

Ahora sólo debemos coger nuestro código python, procesarlo mediante la siguiente orden:

$ pygmentize -O bg=light,python=cool -o prueba.html prueba.py

El código html obtenido simplemente tenemos que pegarlo a continuación cambiando la clase del div, la llamamos 'codehilite', eliminamos el tag 'pre' y ya lo tenemos.


#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys

print 'Hola Mundo'


Sólo faltaría lidiar con los tabuladores, no entiendo muy bien cómo trata blogger los espacios, debo estar equivocándome en el tipo de edición, pero he observado que lo que mejor resultado me da es añadirle la siguiente variable 'style="padding-left:20px"' al span correspondiente al comienzo de la línea a ser tabulada.

Intentaré seguir mejorando el método...

miércoles, 13 de abril de 2011

Reptiles acechantes

Una de las cosas más útiles que me he encontrado últimamente con python ha sido la posibilidad de enviar correos mediante un script. Esto nos puede valer para enriquecer nuestro sistema de backups automatizado, para enviar incidencias desde algún programa que hayamos implantado en alguna empresa y mil usos más que se nos irán ocurriendo.

Aquí dejo el código de un script muy simple para enviar un correo a cierta dirección de correo utilizando una cuenta de la empresa. Para los backups es perfecto ya que cuando detectemos algún problema en los scripts nos llegará un aviso que podremos procesar como máximo al día siguiente al revisar el correo.

Este script no lo invocamos directamente, utilizaremos un entorno virtual desde el cuál lanzarlo para mantener el código python independiente de las posibles actualizaciones del servidor. Pero como muestra creo que es bastante útil. Si observáis el código es bastante simple, añadimos un disclaimer al correo, componemos el resto del mensaje con los datos pasados en los argumentos y lo enviamos autenticándonos en el servidor de correo.


#!/usr/bin/python
# -*- coding: utf-8 -*-

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.Header import Header

# Probamos a enviar la incidencia por correo
disclaimer = u'''_________________________________________
CONFIDENCIALIDAD

[...]'''

soporte = 'soporte@nombre.es'
destino = 'destino@nombre.com'
msg = MIMEMultipart('alternative')
msg_dest = MIMEMultipart('alternative')
msg['Subject'] = Header(u'Título', 'UTF-8')
msg_dest['Subject'] = Header(u"Ticket Enviado :'", 'UTF-8')
msg['From'] = soporte
msg_dest['From'] = soporte
msg['To'] = soporte
msg_dest['To'] = destino
text = disclaimer
text_dest = u'Contenido original del mensaje:\n\n' + disclaimer
part = MIMEText(text.encode('UTF-8'), 'plain', 'UTF-8')
part_dest = MIMEText(text_dest.encode('UTF-8'), 'plain', 'UTF-8')
msg.attach(part)
msg_dest.attach(part_dest)
smtpserver = smtplib.SMTP('mail.nombre.es', 587)
try:
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.ehlo()
smtpserver.login(soporte, 'contraseña')
smtpserver.sendmail(soporte, soporte, msg.as_string())
smtpserver.sendmail(soporte, profesor, msg_prof.as_string())
smtpserver.quit()
except:
# Error en el envío
print u'Error en el envío'
else:
print u'Operación correcta'

miércoles, 6 de abril de 2011

Backups extendidos

Hace tiempo expliqué como realizar mirrors de páginas webs mediante 'wget'. Ahora vamos a utilizar estos mirrors para realizar pruebas locales y para comprobar que todo se está realizando correctamente.

Los pasos seguidos a continuación están sacado de este interesante post, antiguo pero muy útil. Algunas cosas ya las había experimentado, pero esto es como todo, siempre cogemos cosas de aquí y de allá para montar algo mejor.

Lo primero es comprobar que podemos recrear los ftps guardados en nuestro servidor en nuestra máquina de trabajo mediante un rsync:

$ rsync -avz -e ssh usuario@servidor:directorio_mirrors directorio_local

Si el comando se completa sin problema podremos pasar a la siguiente fase, establecer una sincronización periódica. Para ello necesitamos poder acceder al servidor sin necesidad de que nos pregunte la contraseña del usuario elegido. Para llevar a cabo esta operación debemos crearnos un par de claves mediante el comando:

$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:x root@cliente
The key's randomart image is:
+--[ RSA 2048]----+
...
+-----------------+

Con este comando se nos han creado dos archivos, dentro de '~/.ssh', 'id_rsa' y 'id_rsa.pub'. Ahora debemos copiar la clave pública al servidor:

$ ssh-copy-id -i ~/.ssh/id_rsa.pub root@servidor

Con esto ya podemos ejecutar comandos en el servidor.

El problema nos surge cuando queremos hacer que los mirrors en la máquina de prueba sean accesibles mediante apache para comprobar directamente la corrección de las copias. Dado que en el servidor realizamos los mirrors mediante un script en el cron, el propietario de estos archivos sería root. La solución pasará por cambiar el propietario a root antes de realizar la sincronización, para que el uso de red se minimice.

Una primera aproximación a nuestro script de backup sería esta:

# Cambiamos el propietario del directorio 'mirrors' para hacer el rsync
chown -R root.root [directorio_mirrors_local]

# Sincronizamos
# Comprobación de si es domingo para limpiar los archivos borrados
if [ `date +%w` -eq 0 ]; then
rsync -avz -e ssh --delete root@servidor:[directorio_mirrors_servidor] [directorio_mirrors_local] 2>/dev/null >/dev/null
else
rsync -avz -e ssh root@servidor:[directorio_mirrors_servidor] [directorio_mirrors_local] 2>/dev/null >/dev/null
fi

if [ $? != 0 ]
then
# Aquí invocaremos un script que nos envía un correo automáticamente si falla algo
error=1
fi

# Volvemos a dejarlo accesible para el apache
chown -R www-data.www-data /almacen/mirrors

if [ $error = 0 ]
then
# Aquí invocaremos al mismo script pero notificando el éxito
fi

exit 0

El script para notificaciones será motivo de otro artículo, así como la generación de un índice de páginas accesibles localmente para la comprobación del funcionamiento de las mismas.

Mini-tweak

Yo siempre deshabilito el acceso por ssh como root, pero buscando información para ampliar nuestro sistema de copias de seguridad de páginas web me encuentro con que no todo es blanco o negro.

Resulta que la directiva 'PermitRootLogin', aparte de 'yes' o 'no' posee una interesantísima 'without-password' para permitir el acceso como root utilizando claves generadas por ssh.

De esta forma mantenemos un grado de seguridad adecuado y una cómoda forma de realizar tareas periódicas tirando del contenido del servidor.

lunes, 4 de abril de 2011

Revelaciones

Seguro que todos los linuxeros nos preguntamos por qué razón desde una máquina windows no podemos montar dos samba shares diferentes referidos al mismo servidor...si alguien que sabe como hacerlo y no ha abierto la boca desde aquí le damos una gran colleja...

Proque resulta que sí que hay forma, es un poco bizarra pero efectiva. Resulta que si tienes uns servidor samba con un nombre, evidentemente también tiene una ip, pues la solución no puede ser más sencilla, un 'net use' lo haces apuntando a la ip y el otro, con un usuario samba diferente, al nombre de la máquina. Lo sé, parece mentira que sea así, pero es cierto!

Si necesitamos conectar más unidades samba con usuarios diferentes deberíamos crearnos un alias, en la máquina windows, para el servidor samba y apuntamos el 'net use' al alias nuevo.

domingo, 3 de abril de 2011

La lista negra

Si habéis instalado linux en varios ordenadores y durante varios años, seguro que os habrá surgido algún problema referido a la carga de algún módulo que volvía el sistema del revés. Lo más común suele ser la carga de los módulos correspondientes a la tarjeta de sonido de la placa base y alguna pci que tengáis para escuchar las cosas con cierto nivel de calidad.

El problema realmente puede partir del administrador de sonido del escritorio que por pereza, o desconocimiento, no nos preocupamos de configurar correctamente. Lo más directo siempre ha sido desactivar la tarjeta de sonido de la placa mediante la BIOS. Si no podemos realizar esta acción el problema persiste y cada reinicio se convierte en una lotería, por dónde saldrá el sonido hoy?

Bien, pues para evitar tener que elegir la tarjeta de sonido cada vez que arranquemos vamos a ver un método para borrar de la lista de módulos el que habilita la tarjeta de sonido de la placa. Si el problema se presenta con unas tarjetas de red, o con lo que sea, siempre podremos utilizar este método. Vamos allá...

Siguiendo los pasos descritos en el wiki de debian, primero debemos borrar el archivo '/etc/modules.conf', ya que es una herencia de distribuciones anteriores. Seguramente ya no aparecerá en vuestros sistemas, pero por si acaso lo revisamos.

La forma de añadir un módulo a la blacklist es crear un archivo con el nombre del módulo, dentro del directorio '/etc/modprobe.d/' con la palabra clave 'blacklist', de modo, que si queremos eliminar la carga del módulo con nombre 'prueba', la forma más rápida sería:

# echo "blacklist prueba" > /etc/modprobe.d/prueba.conf

Después de añadir los módulos que precisemos debemos reconstruir la cadena de arranque mediante las siguientes órdenes:

# depmod -ae -F[System.map_del_sistema]
# update-initramfs -u

A la opción -F del depmod, simplemente hay que añadirle la ruta hacia el system.map del kernel actual, que suele encontrarse en el directorio '/boot'.

Reiniciamos y ya no tendremos que lidiar con esa molesta segunda opción que en realidad nunca queremos utilizar.

martes, 15 de marzo de 2011

Miniaporte

Para que la gente no se queje hoy dos posts. Resulta que en las aulas linux que mantenemos cada cierto tiempo el chequeo de los sistemas de archivos da inconsistencias que requieren de la supervisión del administrador.

Esto es un engorro y realmente da igual si se pierden archivos en este tipo de sistemas ya que los datos de los alumnos están centralizados en el servidor. Por ello la reparación automática de los sistemas de archivos que componen los ordenadores de los alumnos, en principio, no es peligrosa y nos ahorraremos bastantes visitas físicas a las aulas.

Para ello, simplemente debemos activar una opción en un archivo al que hemos hecho referencia hoy en el otro post '/etc/default/rcS':

[...]
FSCKFIX=yes
[...]

Y listo.

A long time...

Sí, lo sé, todos pensaréis que el título de la entrada se refiere al tiempo que hace que no escribo, pero en realidad se refiere a algo que explicaré en el artículo. Lo primero que debo decir es que hace tanto tiempo que no escribo por aquí porque me he estado dedicando más a tareas 'administrativas' de la empresa, coordinación, protocolos y demás cosas no directamente relacionadas con mis queridos sistemas.

En fin, a lo que interesa. Nosotros, desde el principio de la empresa tenemos una compartición samba para manejar los documentos comunes. Todo iba bien hasta que los responsables de debian decidieron formalizar más la secuencia de arranque del sistema, gran acierto por otra parte.

Resulta que yo tenía un script muy simple para montar automáticamente esta compartición en la secuencia de arranque. Creo recordar que el enlace simbólico en el nivel 2 debería estar detrás del que hacía referencia a la inicializacón de la red. Pero hete aquí que cuando se introdujo la nueva secuencia de arranque este 'apaño' quedó obsoleto. Ahora tenía que ponerle una cabecera al script con los requerimientos de arranque, los niveles en los que debía iniciarse, etc. Maravilloso, con esta cabecera e invocando a 'insserv' todo sería más fáicl.

El problema es que en mi máquina utilizo el demonio 'wicd' porque de vez en cuando hago pruebas con las llaves wifi que caen en mis manos para ver si funcionan correctamente con linux. Pues bien, resulta que este demonio parece que no comunica bien su inicialización ya que poniendo en los requerimientos de arranque de mi script que se invoque cuando termine el anterior la cosa no funciona.

Me volví loco el par de veces que lo probé hace tiempo, incluso poniendo el tag genérico '$all' la cosa no iba. Hasta que ayer me decidí a solucionar el problema...no lo consideraba importante ya que mi máquina casi no se reinicia y cuando tengo que consultar algo en la compartición y no está simplemente invocaba el script y listo, pero mis socios tenían que hacerlo más frecuentemente.

Lo gracioso es que el script estaba bien, lo que no está bien es el wicd ya que el montaje siempre se intentaba sin la red preparada. Al final la solución ha pasado por volver a la configuración de la red ethernet tradicional, mediante '/etc/network/interfaces' y dejar el tag '$all' al script, aunque con el tag '$network' intuyo que también servirá. Total que el script quedaría de la siguiente forma:

#!/bin/sh

### BEGIN INIT INFO
# Provides: montarHsolucio
# Required-Start: $all
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: montar el directorio hsolucio
# Description: montar el directorio hsolucio
### END INIT INFO

mount -t smbfs -o username=...

Y simplemente lo añadiríamos a la secuencia mediante el comando:

# insserv -v -r (para borrarlo)
# insserv -v

Otro dato curioso encontrado por el camino es la paralelización del arranque, que en debian está desactivada por defecto, no he apreciado una mayor velocidad de arranque, pero por ahí se asegura que se consigue. Total, que añadiendo:

CONCURRENCY=startpar

al fichero '/etc/default/rcS' se realiza la acción.

martes, 8 de febrero de 2011

Agárrame esos fantasmas

Uno de nuestros problemas siempre ha sido tener un backup de las cosas importantes, nuestra colección de bases de datos, nuestra pequeña página web personal y muchas otras cosas.

Bien, en este minipost nos ocuparemos de salvar esa pequeña parte de nuestro mundo, nuestra página personal. Hay multitud de herramientas ante nuestros ojos, con interfaces bonitos, feos, cómodos, menos cómodos, pero en el fondo el fantasma que alimenta a todas ellas, o a una gran parte de las mismas, es esa poderosa herramienta llamada 'wget'.

Los más viejos del lugar la seguirán utilizando para descargar esos pdf's pesados o esas imágenes de cd que sabes de buena tinta que el gestor de descargas de firefox no podrá con ellas. Directamente copiamos la ruta del enlace, nos vamos a una consola y escribimos 'wget -c dirección_web', et voilá, archivo al canto.

Pues bien con una ordena tan sencilla como aquella podemos mantener un mirror de nuestra página web, a la que tenemos acceso mediante el ftp de nuestro hosting, es tan simple como esto:

wget --mirror --ftp-user=USER --ftp-password=PASSWORD -Pdirectorio_destino ftp://dirección_ftp

Con esta sencilla orden y una entrada en el cron podríamos configurar un completo sistema de backups sin necesidad de 'complicadas ventanas de configuración'.

Esto último parece una contradicción pero la belleza de la consola de texto es simplemente perfecta.