30.12.06

Imprimir en una HP LaserJet 1018 bajo Linux

La HP1018 es de esas impresoras soportadas "a medias" en Linux, que si, que imprime perfectamente pero que hay que darle unas cuantas vueltas antes de conseguirlo.

Buscando en Google existen muchas formas de hacerlo todo automático utilizando hotplug pero nosotros vamos a hacerlo más "a mano" y más rápido:

1) Lo primero va a ser instalar la impresora utilizando gnome-cups-manager u otra aplicación similar.

2) Viendo que el driver utilizado es el de foo2zjs debemos instalar este paquete:
jose@tatooine:~$ apt-get install foo2zjs

3) La impresora necesita cargar el firmware antes de comenzar, con lo que lo descargarmos:
jose@tatooine:~$ getweb hp1018

4) Convertirmos el archivo.img descargado en un firmware válido:
jose@tatooine:~$ arm2hpdl sihp1018.img > /usr/share/foo2zjs/firmware/sihp1018.dl

5) Creamos un script (cargafirmware.sh) que cargue el firmware en la impresora:
#!/bin/bash
cat /usr/share/foo2zjs/firmware/sihp1018.dl > /dev/usb/lp0
echo "Firmware de la impresora cargado!"
sleep1

6) Ponemos el script en el arranque del sistema para no tener que ejecutarlo de cada vez:
ln -s /root/cargafirmware.sh /etc/rc2.d/S99cargafirmware

Este método debería funcionar para otros modelos de impresoras que padezcan de lo mismo.

14.12.06

Creando copias de seguridad del Master Boot Record

En ocasiones, cuando conviven diferentes sistemas operativos en la misma máquina o por haber tocado donde no se debe, perdemos el arranque de nuestro sistema. La solución habitual pasa por iniciar el sistema utilizando un CD/DVD Live u otro medio de arranque y, utilizando chroot, ejecutar los comandos pertinentes que regeneren el gestor de arranque. La siguiente propuesta se basa en realizar un backup de MBR a un fichero utilizando dd para, en caso de "desastre" poder recuperarlo de nuevo.

Instrucción para crear la copia de seguridad:

dd if=/dev/disco_duro_arranque of=fichero.bkp bs=512 count=1

Ejemplo: dd if=/dev/sda of=/media/usbdisk/copia.boot bs=512 count=1


Instrucción para recuperar el MBR:

dd if=fichero.bkp of=/dev/disco_duro_arranque bs=512 count=1

5.12.06

Deshabilitar Ctlr+Alt+Backspace en X

A la hora de configurar un kiosko u otro equipo en el que no queremos que los usuarios puedan saltar a las consolas, nos las tenemos que dar de bruces contra las combinaciones de teclas típicas:

Ctrl+Alt+Backspace que reinicia las X
Ctlr+Alt+(F1,F2,F3...) que salta a entorno texto


La solución pasa por tocar el fichero de configuración de xorg (/etc/X11/xorg.conf) y añadir la siguiente sección (si no existe):

Section "ServerFlags"
Option "DontZap" "yes"
EndSection


Otra opción sería invocar el xinit con la opción -T (xinit -T) pero se complica si queremos utilizar un gestor de inicio gráfico.

9.11.06

OSSTMM - El manual de referencia para el auditor de seguridad


A la hora de asegurar un sistema cada administrador utiliza sus aplicaciones de detección de intrusos preferida, una configuración particular, etc. En realidad no se suele seguir una metodología contrastada más que la de la propia experiencia.
La asociación ISECOM además de formar a auditores de seguridad en sus conocidas "Hackers High School", mantienen actualizado el Open Source Security Testing Methodology Manual, disponible su última versión pdf en cristiano se puede descargar aquí.

7.11.06

Sistemas multimonitor con Xorg

Instalar un sistema multimonitor con Xorg es realmente sencillo. En este ejemplo me baso en un equipo con Debian Etch instalada y una tarjeta gráfica ATI Radeon 9200 AGP.

Lo primero es instalar la extensión Xinerama, que nos permitirá expandir nuestro escritorio:

apt-get install libxinerama1

Luego debemos clonar la configuración de nuestra tarjeta(s) y la del(os) monitor(es), en la que nuestro fichero /etc/X11/xorg.conf quedaría de la siguiente forma (he obviado los parámetros no significativos):

Section "Device"
#Salida VGA que ya habia configurado Xorg durante la instalacion
Identifier "ATI Technologies Inc RV280 [Radeon 9200]"
Driver "ati"
BusID "PCI:1:0:0"
VideoRam 65536
#A continuacion le indicamos que no clone la imagen
Option "Clone" "false"
#Indicamos el orden las salidas
Option "MonitorLayout" "CRT,LFP"
#Agregamos un identificador
Screen 0
EndSection

Section "Device"
#Salida DVI que debemos crear copiando la configuracion
#de la primera salida
Identifier "ATI DVI"
Driver "ati"
BusID "PCI:1:0:0"
#Agregamos un identificador
Screen 1
EndSection

Section "Monitor"
#Configuracion realizada por Xorg
Identifier "Monitor genérico"
Option "DPMS"
HorizSync 30-70
VertRefresh 59-76
EndSection

Section "Monitor"
#Creamos un nuevo dispositivo, en mi caso un monitor CRT
Identifier "Monitor CRT"
Option "DPMS"
HorizSync 30-70
VertRefresh 59-76
EndSection

Section "Screen"
#Configuración generada por Xorg
Identifier "Default Screen"
Device "ATI Technologies Inc RV280 [Radeon 9200]"
Monitor "Monitor genérico"
DefaultDepth 24
SubSection "Display"
Depth 24
Modes "1152x864" "1024x768" "800x600" "640x480"
EndSubSection
EndSection

Section "Screen"
#Configuración creada para el monitor CRT que irá a la derecha
Identifier "RightScreen"
Device "ATI DVI"
Monitor "Monitor CRT"
DefaultDepth 24
SubSection "Display"
Depth 24
Modes "1152x864" "1024x768" "800x600" "640x480"
EndSubSection

EndSection

Section "ServerLayout"
#Sustituímos el ServerLayout por defecto por este otro que cargue
#los dos monitores.
Identifier "Dual Monitor"
Screen 0 "Default Screen" 0 0
Screen 1 "RightScreen" RightOf "Default Screen"
InputDevice "Generic Keyboard"
InputDevice "Configured Mouse"
Option "Xinerama" "true"
EndSection

Por último nos queda reiniciar el servidor Xorg y disfrutar de nuestro nuevo monitor expandido.

Python: Backup de una carpeta contra un servidor FTP remoto

Sin lugar a dudas para cosas serias se debe utilizar rsync pero cuando tienes un equipo poco accesible y necesitas mover los ficheros de un directorio a un servidor FTP, esta porción de código puede resultar útil:

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

import glob
import os
import string
from ftplib import FTP

#Path donde se encuentran los ficheros

rutaFicheiros = ?/home/jose/Documentos/*?

#Parametros de la conexion
ipServFTP = ?194.224.52.4?
ftpUser = ?jose?
ftpPasswd = ?mypasswdRocks?
ftpDir = ?/Backups/Documentos?

def atopaFicheiros(ruta):
?'?
Lista todos los ficheros de una ruta dada y devuelve
una lista con todos los paths absolutos.
?'?
listadoPaths = []
if len(ruta) > 0:
listadoPaths = glob.glob(ruta)
else:
pass
return listadoPaths

def subeFicheirosFTP(ip,usuario,passwd,directorio,ficheiros):
?'?
Sube un listado de ficheros dado a un directorio de un
servidor ftp remoto.
?'?
print ?Estableciendo conexion??
conexion = FTP(ip)
conexion.login(usuario,passwd)
conexion.cwd(directorio)
print ?Subiendo ficheiros??

for i in ficheiros:
try:
ficheiroLocal = open(i,?rb?)
nomeFicheiro = string.split(i,?/')[1:]
conexion.storbinary(?STOR ? + nomeFicheiro, ficheiroLocal, 1024)
ficheiroLocal.close()
pipe = os.popen(?rm ?? + i +???)
except:
print ?Non se puido subi-lo arquivo ? + i
conexion.close()
conexion = FTP(ip)
conexion.login(usuario,passwd)
conexion.cwd(directorio)
print ?Conexion re-establecida?

conexion.close()

if __name__ == ?__main__?:
listaXmls = atopaFicheiros(rutaFicheirosXML)
subeFicheirosFTP(ipServFTP,ftpUser,ftpPasswd,ftpDir,listaXmls)

Truco Python: romper una cadena en subcadenas de X tamaño

Con la siguiente función vamos a conseguir dividir un string en X substrings de un tamaño dado (muy útil por ejemplo para completar formularios). Es una función muy recurrida, al menos por mi:

def splitCount(s, count):

return [?".join(x) for x in zip(*[list(s[z::count]) for z in range(count)])]
Para los que empezais con Python, la forma de usarla sería:

myString = ?Esta cadena de pruebas la vamos a romper en cachitos?
LengthOfPieces = 6
a = splitCount(myString, LengthOfPieces)
print a

Grabar imágenes CD/DVD de Nero en Linux

Para los que tengais la necesidad de grabar imágenes de Nero en Linux lo único que necesitais es convertirlas a formato .iso. Para ello hay una utilidad preciosa llamada nrg2iso:

jose@tatooine:~$ apt-cache search nrg2iso
nrg2iso - Extracts ISO9660 data from Nero ?.nrg? files
jose@tatooine:~$ sudo apt-get install nrg2iso
Una vez instalado la sintaxis es realmente sencilla:

nrg2iso imagen.nrg imagen.iso

Configurar un RAID con mdadm

El funcionamiento de mdadm es similar al de otras herramientas como raidtools (kernel 2.4).
Para crear un dispositivo RAID, debemos modificar el fichero de configuración de mdadm en /etc/mdadm.conf:

DEVICE /dev/dispositivo(s)
ARRAY /dev/md(id_array) devices=/dev/disco1,/dev/disco2?.

Ejemplo de configuración para un array de dos discos /dev/sda y /dev/sdb:

DEVICE /dev/sd[ab]1
ARRAY /dev/md0 devices=/dev/sda1,/dev/sdb1

A continuación debemos crear el array utilizando la configuración que hemos guardado. En este ejemplo crearemos un array en modo mirroring:

$mdadm ?create /dev/md0 ?level=raid1 ?raid-devices=2 /dev/sda1 /dev/sdb1

Ahora solo nos queda formatearlo y comenzar a utilizarlo:

$mkfs.ext3 /dev/md0

Para establecer un punto de montaje en el inicio de sistema debemos crearle una entrada en /etc/fstab:

/dev/md0 / ext3 defaults 0 0

Soporte para RAID por software en Linux

El soporte de RAID por software es soportado por el kernel de Linux sin mayores problemas, en todos los modos de RAID que deseemos, combinaciones inclusive. También se soporta el uso de uno o más ?spare disks?, utilizados como ?discos reserva? en caso de que alguno de los discos del RAID falle. Cuando el sistema operativo detecta un fallo de discos, automáticamente comienza la réplica de datos al nuevo disco, minimizando la posibilidad de pérdida de datos y dándonos un tiempo adicional para sustituír el disco averiado.

Generalmente las distribuciones incluyen un módulo precompilado para soportar RAID por software, aunque puede estableceser de forma manual recompilando el kernel de forma que se active la opción:

Multiple devices driver support (RAID and LVM) (CONFIG_MD) [Y/n/?] y
RAID support (CONFIG_BLK_DEV_MD) [M/n/y/?] y
Linear (append) mode (CONFIG_MD_LINEAR) [M/n/y/?] y
RAID-0 (striping) mode (CONFIG_MD_RAID0) [M/n/y/?] y
RAID-1 (mirroring) mode (CONFIG_MD_RAID1) [M/n/y/?] y
RAID-4/RAID-5 mode (CONFIG_MD_RAID5) [M/n/y/?] y

Una vez compilado, para certificar que el módulo se ha cargado podemos revisar el log de arranque:

jose@pequerrecho:~$ dmesg | grep md
[17179599.548000] md: md driver 0.90.3 MAX_MD_DEVS=256, MD_SB_DISKS=27
[17179599.548000] md: bitmap version 4.39

Este mensaje nos indica que el módulo está cargado y listo para detectar dispositivos RAID. Durante el proceso de autodetección, el kernel trata de buscar particiones marcadas como 0xFD (Linux RAID autodetect). Con fdiks podemos ver y/o editar los tags de una partición:

jose@pequerrecho:~$ fdisk -l /dev/hda
Disk /dev/hda: 100.0 GB, 100030242816 bytes255 heads, 63 sectors/track, 12161 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hda1 * 1 12095 97153056 fd Linux raid autodetect
/dev/hda2 12096 12160 522112+ fd Linux raid autodetect

29.9.06

¿En qué consiste RAID?

RAID consiste en una serie de algoritmos de escritura de bloques de datos (data blocks) en múltiples discos duros. Cada modo o nivel de RAID especifica de qué forma se realizará esta escritura en los discos.
Las dos propiedades que hacen indispensable a RAID son: redundancia y velocidad. Cada nivel de RAID especifica la forma que se aprovecharán estas propiedades, velocidad de lectura/escritura, redundancia de datos o una combinación de ambas propiedades.

NIVELES DE RAID

Los niveles de RAID se nombran con un número entero, siendo los niveles más utilizados: RAID0, RAID1, RAID5 y combinaciones de los mismos (RAID0+1, RAID1+0)

RAID0 (stripping): es el nivel de RAID en que se sacrifica la redundancia en favor de la eficiencia. En este nivel se consiguen unas tasas de transferencia de lectura/escritura ideales calculables con la siguiente fórmula:

eficiencia lectura = velocidad lectura de 1 disco * número de discos
eficiencia escritura = velocidad escritura 1 disco * número de discos

Existe la creencia entre las comunidades de usuarios de en nivel 0 los bits se distribuyen de forma equitativa bit a bit entre los discos. Esto no es cierto, la repartición de datos se realiza bloque a bloque, de forma que dos bloques de datos consecutivos estarán en dos discos duros diferentes que conformen el RAID.
Al no disponer de redundancia, en nivel 0 no se dispone la posibilidad de recuperación de datos.
El mínimo número de discos necesarios para conformar un RAID0 es 2.

RAID1 (mirroring): es probablemente el nivel más utilizado en pequeños servidores. Se provee de redundancia aunque la eficiencia en escritura se ve sacrificada (debido a la redundancia). La eficiencia de este nivel puede calcularse en condiciones ideales con la siguiente fórmula:

eficiencia lectura = velocidad lectura 1 disco
eficiencia escritura = velocidad escritura 1 disco / número de discos

En este nivel cada bloque de datos es copiado en todos los discos de conforman el RAID, de forma que si un disco duro ?se cae?, los datos pueden regenerarse en un nuevo disco a partir de las copias contenidas en los restantes discos que conforman el RAID.
El número mínimo de discos necesarios para conformar un RAID1 es 2.

RAID5 (stripping with parity): es una mezcla entre RAID0 y RAID1 con la salvedad de que los bloques de datos y paridad se distribuyen entre todos los discos, en lugar de mantener imágenes de los mismos. Los cálculos de paridad se efectúan con cada proceso de escritura y son utilizados para regenerar los bloques de datos ante un fallo. Al mismo tiempo los bloques de datos consecutivos se almacenan en discos diferentes con lo que se aumenta al rendimiento tanto en lectura como en escritura. La eficiencia de un RAID5 en condiciones ideales podría calcular con la siguiente fórmula:

eficiencia lectura = velocidad 1 disco * número de discos
eficiencia escritura = velocidad 1 disco * (número de discos - 1)

RAID0+1 y RAID1+0 son modos avanzados que juntan los beneficios de RAID0 y RAID1 realizando ?grupos de RAIDs?. RAID0+1 por ejemplo, es el modo ?stripping? de un grupo de discos creando una unidad lógica mayor que los contenga en un nivel ?mirroring?. A modo de ejemplo, un RAID0+1 de 100GB estaría compuesto por 10 discos de 20GB, donde cada bloque de datos sería escrito en modo RAID0 sobre 5 discos y luego replicado en modo RAID1 sobre el otro RAID0 con los 5 discos restantes. El modo RAID1+0 es el efecto inverso.

26.9.06

Copias de seguridad por e-mail?

Hace unos días alguien me planteó la posibilidad de tener un script en el cron que enviase por correo electrónico los logs del servidor ftp. Sin lugar a dudas rsync es el rey de las copias de seguridad pero ... vamos a hacerlo con un poco de Python:

!/usr/bin/env python
# -*- coding: iso-8859-15 -*-

import zipfile
import glob, os, socket
import email
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders

rutaFicheirosLog="/var/log/vsftdp*"
logsComprimidos="/tmp/ficheiroslog.zip"
correoSuxeito="Logs vsftpd para " + socket.gethostname()
correoCorpo="Documento adxunto comprimido Zip"

def sendMail(to, subject, text, files=[], server="smtp.meuservidor.com"):
assert type(to) == list
assert type(files) == list
fro = "Administrador_Sistemas "

msg = MIMEMultipart()
msg['From'] = fro
msg['To'] = COMMASPACE.join(to)
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = subject

msg.attach( MIMEText(text) )

for file in files:
part = MIMEBase('application', "octect-stream")
part.set_payload( open(file,"rb").read() )
Encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(file))
msg.attach(part)

smtp = smtplib.SMTP(server)
smtp.sendmail(fro, to, msg.as_string())
smtp.close()


def atopaReportes(ruta):
lstReportes = []
lstReportes = glob.glob(ruta)
return lstReportes

if __name__=="__main__":

ficheiroZip = zipfile.ZipFile(logsComprimidos,"w")
listadoLogs = atopaReportes(rutaFicheirosLog)

for ficheiro in listadoLogs:
ficheiroZip.write(ficheiro, os.path.basename(ficheiro), zipfile.ZIP_DEFLATED)

ficheiroZip.close()

sendMail(["jose@meuservidor.com"], correoSuxeito, correoCorpo, ["/tmp/ficheiroslog.zip"])


Es un poco trivial, pero para echarlo a andar por casa viene siendo útil.

11.9.06

Controlando las X-Windows remotamente

Muchos usuarios de Microsoft Windows suelen echarme por cara la facilidad que les supone el controlar máquinas de forma remota utilizando productos como Symantec PC Anywhere o Radlink Remote Administrator.
Casi todo el mundo conoce VNC pero, personalmente no termina de atraerme la gran cantidad de recursos que consume. A continuación vamos a listar un par de opciones válidas para Linux:

OPCION 1: "Compartir el monitor" y lanzar aplicaciones en una máquina remota visualizándolas en el equipo local (muy útil en redes locales). Es decir, podemos tener un servidor X-Window ligero lanzado en un 486 a 66 Mhz, compartir el monitor del 486, conectarnos a una estación más potente y lanzar desde allí los procesos, por ejemplo el Firefox y, por qué no? ... el Quake. (Más de uno se quedaría de piedra viéndolo)
Los pasos para conseguirlo son los siguientes:

1.- Desde una sesión X-Window que tengamos lanzada, abrimos un terminal y "compartimos el monitor" con xhost:

jose@pequerrecho:~$ xhost +192.168.1.32
192.168.1.32 being added to access control list


En este caso permitimos que la ip 192.168.1.32 pueda utilizar nuestro servidor X. Si queremos abrir acceso para todo el mundo:

jose@pequerrecho:~$ xhost +
access control disabled, clients can connect from any host


2.- Nos conectamos a la máquina remota desde la que queremos lanzar las aplicaciones:

jose@pequerrecho:~$ ssh jose@192.168.1.32
password:
jose@maquina2:~$


3.- Indicamos a la máquina remota que queremos usar el servidor X de nuestra máquina:

jose@maquina2:~$ export DISPLAY=192.168.1.32:0.0

4.- Lanzamos la aplicación en el equipo remoto y la visionamos en nuestro pc local:

jose@maquina2:~$ firefox &


OPCION 2: Permitir login gráfico remoto con XDMCP

Esta opción nos permite acceder a nuestro "Desktop Manager" favorito de forma remota, como si estuviésemos en el equipo local. Utilizando GDM es realmente fácil:

1.- Como root lanzamos el configurador de GDM:

jose@pequerrecho:~$ gdmsetup

2.- En la pestaña "Remota", activamos la entrada remota, en principio igual que la entrada local.

3.- Reiniciamos GDM pulsando (Ctrl + Alt + BackSpace)

4.- Desde el equipo cliente iniciamos la sesión remota:

jose@equiporemoto:$ X -query ip_servidor_XDMCP

NOTA DE SEGURIDAD: Hay que tener muy en cuenta, sobre todo si las máquinas están expuestas que hay un número de puertos que debemos asegurar/denegar/filtrar para las ips interesadas. Además, estos servicios deberían correr bajo túneles ssh como medida extra de seguridad.

Spamassassin, no más correo basura en Evolution

Los spammers utilizan cada día técnicas más enrevesadas para saltarse el software anti-spam y los filtros de muchos proveedores de correo se confunden (como Dinio) y dejan pasar demasiada basura (como por ejemplo Terra).
SpamAssassin es una herramienta muy popular y hay paquetes disponibles para la gran mayoría de distribuciones, listos para instalar en un click. En nuestra distribución favorita es realmente fácil:

apt-get install spamassassin


Para los que opten por una instalación manual, SpamAssassin requiere Perl y los siguientes módulos: perl-Time-HiRes, perl-Digest-SHA1, perl-Digest-HMAC y perl-Net-DNS.

La integración de SpamAssassin con Evolution es realmente buena, simplemente debemos de tener el demonio de SpamAssassin corriendo y decirle a Evolution que lo utilice. Para ello, lo primero será configurar SpamAssasin para arranque como demonio editando el fichero de configuración /etc/default/spamassassin y cambiando el valor de ENABLED a 1, ya que por defecto es 0:

# /etc/default/spamassassin
# Duncan Findlay
# WARNING: please read README.spamd before using.
# There may be security risks.
# Change to one to enable spamd
ENABLED=1


Luego iniciamos el demonio:

/etc/init.d/spamassassin start

Por último nos queda indicarle a Evolution que debe usar SpamAssassin (en la mayoría de los casos ya está activado). Debemos de clickar en el menú Editar/Complementos y activar la casilla "Complemento de filtro de spam con SpamAssassin".
A partir de ahora el correo basura irá directamente a la carpeta "Spam" (o Junk según el idioma de instalación). Si se cuela algún correo indeseable o SpamAssassin se equivoca e impide la entrada de correos válidos, podemos entrenarlo marcando o desmarcando como spam los correos que deseemos.

5.9.06

Escritorio 3D en el portátil sin morirse en el intento

Parece ser que están de moda los escritorios 3D con XGL pero claro, no todo el mundo tiene una tarjeta gráfica nVidia o ATI. En mi caso particular la experiencia ha sido sobre un portátil con tarjeta gráfica de Intel y driver i810.
La gran premisa es conseguir un entorno bonito, lleno de efectos que ponga a trabajar a la gráfica pero que el rendimiento de la máquina no caiga. Los pasos para conseguirlo bajo Ubuntu 6.0.6 son los siguientes:

1.- Añadir los repositorios necesarios para descargarse los paquetes:

deb http://xgl.compiz.info/ dapper main aiglx
deb-src http://xgl.compiz.info/ dapper main aiglx


2.- Instalar los módulos de DRI:

sudo apt-get install linux-dri-modules-common
sudo apt-get install linux-dri-modules-`uname -r`


3.- Instalar los siguientes paquetes:

sudo apt-get install xserver-xorg-air-core, compiz, compiz-gnome, gnome-compiz-manager

4.- Enlazar los módulos del antiguo servidor X al nuevo, de lo contrar xorg-air se quejará de que no encuentra los drivers especificados en /etc/X11/xorg.con:

sudo ln -s /usr/lib/xorg/modules/drivers/ /usr/lib/xorg-air/modules/drivers
sudo ln -s /usr/lib/xorg/modules/input/ /usr/lib/xorg-air/modules/input


5.- Editar el fichero de configuración /etc/X11/xorg.conf y tocar los siguientes parámetros:

* En la sección Modules:

Load "dri"
Load "dbe"
Load "glx"
y comentar #Load "GLCore"

* En la sección Device:

Option "XAANoOffscreenPixmaps"

* En ServerLayout:

Option "AIGLX" "true"

* En DRI (probablemente ya esté así):

Section "DRI"
Mode 0666
EndSection

* Crear una sección Extensions:

Section "Extensions"
Option "Composite" "Enable"
EndSection

6.- Tocar la configuración del GDM para que cargue el nuevo servidor X en /etc/gdm/gdm.conf-custom , añadiendo las siguientes líneas al final del fichero:

[servers]
0=aiglx
[server-aiglx]
name=aiglx server
command=/usr/bin/Xorg-air :0
flexible=true


7.- Reiniciar GDM para que cargue la nueva configuración:

sudo /etc/init.d/gdm restart

8.- Tocar el script de arranque de compiz para optimizar la ejecución, en /usr/bin/compiz-start:

#Comentar esta línea: nohup compiz --strict-binding --indirect-rendering --replace dbus csm > /dev/null & exit;

Y añadir esta otra a continuación:

nohup compiz --strict-binding --indirect-rendering --replace gconf decoration wobbly fade minimize cube rotate zoom scale move resize place switcher > /dev/null & exit;

9.- Activar GLDesktop dando con el botón derecho en el icono colocado en la barra de tareas o lanzando la aplicación gnome-compiz-preferences:

jose@pequerrecho:/usr/bin$ gnome-compiz-preferences

10.- Lanzar compiz tecleando:

jose@pequerrecho:/usr/bin$ compiz-start

11.- (Opcional)Tras probar que todo está a nuestro gusto, meter compiz en el arranque de Gnome o crear un lanzador para el comando compiz-start.

24.7.06

Portátiles con Intel SpeedStep AMD Powernow

Uno de los problemas más comunes que se suele tener con Linux viene dado a la hora de configurarlo en dispositivos portátiles, especialmente en lo que a gasto de batería se refiere. Y es que muchas de nuestras distribuciones no habilitan por defecto la gestión inteligente de energía, y surge la duda de que el sistema de Microsoft sea más eficiente. Veamos en pocos pasos como habilitar la gestión inteligente de energía:

1.- Instalar el módulo correspondiente a nuestro procesador, según sea su fabricante:

Para Intel Mobile : modprobe speedstep-centrino
Para AMD Mobile: modprobe powernow-k7
Para AMD64 Mobile: modprobe powernow-k8

Una vez comprobado que el módulo funciona no queda más que añadirlo a nuestro /etc/modules para que se cargue en el arranque del sistema.

2.- Instalar los módulos de gestión de velocidad, que se encuentran en /lib/modules/version_de_kernel/kernel/drivers/cpufreq, los cuales podemos cargar de nuevo en /etc/modules:

freq_table
cpufreq_powersave
cpufreq_userspace

3.- Instalar el demonio que gestionará la velocidad. Aquí tenemos dos opciones cpudyn y powernowd y, aunque el segundo suena similar a la tecnología de AMD funciona igual de bien con Intel:

cpudyn: utiliza el módulo cpu_powersave y conmuta el micro entre la velocidad máxima y mínima, sin estados intermedios, con lo que el rendimiento de la máquina es bueno y en usos que no demanden de mucho proceso, el ahorro de energía es notable.

powernowd: utiliza el módulo cpu_userspace y conmuta los valores entre máximo y mínimo pasando por estados intermedios con lo que el ahorro de batería es superior a cpudyn pero la máquina se muestra más lenta.

Personalmente prefiero powernowd ya que lo que me interesa cuando estoy funcionando con baterías es que éstas se aprovechen al máximo alargando el tiempo de operatibilidad.

4.- Instalar un applet para nuestro entorno gráfico favorito que nos muestre en cada instante la velocidad del micro, como gnome-applets y kpowersave

23.7.06

Y quien quiere un Cisco o un Checkpoint?

Todos tenemos nuestro viejo ordenador tirado en el trastero sin hacer nada, en mi caso es un HP Intel Pentium 233MX con 32Mb de ram. Me he propuesto darle uso a base de pinguino y no hay mejor aplicación que reconvertirlo en un firewall al estilo de los Cisco Systems o Checkpoint.
Para ello simplemente debemos equipar nuestra vieja máquina con dos tarjetas de red o una tarjeta para la Lan y un módem ADSL compatible compatible con Linux (uno compatible como el de Telefónica, no como el Sagem feo que me envió a mi Wanadoo). Acto seguido podemos instalar nuestra distribución favorita y ponerle un buen script de iptables, aunque hay una forma de obtener un firewall realmente profesional y en cinco minutos.
Existen dos distribuciones ideales para este propósito como son SmoothWall e IPCop, que convierten nuestro equipo en un router potentísimo en un par de minutos. Todo con gestion gráfica remota mediante https, detección de intrusos, logs, actualizaciones remotas, VPN, etc

20.7.06

Monitorización de redes con Nagios

Cada administrador de sistemas tiene sus reglas y sus políticas, más o menos acertadas en lo que a la monitorización de sus redes se refiere y utiliza unas herramientas y otras basándose en su experiencia. Lo que me dice mi experiencia es lo siguiente:
Cierto es que existen herramientas indispensables como sniffers que nos ayudan a resolver incidencias en problemas puntuales, pero acaso tendrías un sniffer corriendo todo el día? También existen los típicos "pingeadores" como Smokeping que hacen bien lo que tienen que hacer, un ping y te avisa si la máquina no responde (acaso eso no puede hacerse con bash?).
A mi entender monitorizar una red es sinónimo de monitorizar los servicios que se ofrecen, junto con aquellos dispositivos que se consideran indispensables, como por ejemplo el router y para realizar estas tareas a mi siempre me ha funcionado Nagios. Con Nagios no sólo se puede monitorizar que una máquina esté levantada sinó que podemos ver que el servidor ftp que aloja está funcionando y que el servidor bind9 acepta escuchas. Es muy útil para mantener un historial de fallas cuando ofreces servidores de servicios como: smtp, imap, pop, ftp, www, dns, etc
Existen ejemplos de configuración muy instructivos en Bulma, Deusto y Nagios-howto.

Denegar acceso a MSN Messenger / Hotmail

Para los que tengais que administrar redes corporativas probablemente os interesará evitar que los usuarios de la red interna accedan al chat del MSN Hotmail. Basándonos en el script iptables que está posteado en este mismo blog, he aquí unas pequeñas líneas complementarias para denegar el acceso a este servicio:

iptables -A tcp_outbound -p TCP -s 0/0 --destination-port 1863 -j REJECT
iptables -t mangle -A PREROUTING -p tcp --dport 1863 -j DROP
iptables -t mangle -A PREROUTING -d 63.208.13.126 -j DROP
iptables -t mangle -A PREROUTING -d 64.4.12.200 -j DROP
iptables -t mangle -A PREROUTING -d 64.4.12.201 -j DROP
iptables -t mangle -A PREROUTING -d 65.54.131.249 -j DROP
iptables -t mangle -A PREROUTING -d 65.54.194.118 -j DROP
iptables -t mangle -A PREROUTING -d 65.54.211.61 -j DROP
iptables -t mangle -A PREROUTING -d 207.46.104.20 -j DROP
iptables -t mangle -A PREROUTING -d 207.46.110.2 -j DROP

Kioslaves, atajos útiles en KDE

Tan bien me han hablado de Kubuntu que he tenido que probarlo en el último portátil de Hewlett Packard que ha caído en mis manos (a que si Rubén!).
Había oído hablar de las "kioslaves" unos atajos que vienen con Konqueror y que facilitan ciertas tareas al usuario. Aunque hay una gran cantidad de kioslaves, los que me han parecido más útiles son los siguientes (por cierto, para utilizarlos simplemente teclearlos en la barra de direcciones de Konqueror):

smb:/, accede a recursos compartidos windows en red
fish:/, establece una conexión ssh con un equipo remoto
pop3:/, imap:/ y smtp:/, se conectan a diferentes servidores de correo
ftp:/ y sftp:/, cliente ftp y ftp seguro

Por ejemplo, si quiero conectarme con ssh a mi otra máquina de red de forma gráfica, simplemente he de teclear fish://mi_usuario@ip_de_mi_maquina (pensar que hay gente que utiliza VNC para lo mismo). Otro ejemplo útil sería el descubrir los recursos compartidos de los windozes que hay en red, con un simple smb://

Teneis un listado más completo en Linux Magazine.

17.7.06

pyHardware, un bot IRC escrito en Python

Como había comentado en post anteriores, es francamente sencillo implementar un simple bot IRC de ayuda utilizando pyIRClib. Este módulo nos da el protocolo totalmente másticado y además incluye el módulo pyIrcBot, muy útil para este caso.
Al bichejo en cuestión lo he llamado pyHardware y su finalidad es la de realizar búsquedas en google y mostrar los resultados en el canal. En principio tenía más comandos, como uno de aprendizaje mediante el cual los usuarios le iban enseñando cosas pero, me lo estaban maleducando con lo que decidí eliminarle esa función (en realidad no es más que manejar el comando !aprende e ir guardando en un fichero de texto o una pequeña base de datos).
Aquí podeis encontrar el código fuente del bot perfectamente indentado.

13.7.06

Previniendo ataques de diccionario a nuestros servicios SSH, FTP ...

Para los que vivimos aíslados del mundo, de los virus del churros (más conocido como Windows) y de los últimos ingenios antispyware, ver como al auth.log crece sin parar nos pone nerviosos. Confieso pertenecer a ese grupo de usuarios paranoicos que vuelcan el auth.log en el tty12 (para los que no lo hacen, tail -f /va/log/auth.log > /dev/tty12) y la primera vez que vi correr líneas con intentos de login fallidos casi se me escapan unas gotitas.

Una vez me expliraron que era un virus, sabiendo que mis claves parecen sumas md5 y que no tengo definidos usuarios con shell válida salvo el mío, entonces me sentí a salvo. Aún así, no me apetece que alguien, sea ente o persona, esté machacando mi conexión y haciendo crecer mi log, con lo que aupado por el calor del momento son tiempos de plantar cara y declarar la guerra al invasor.

Se me ocurren tres soluciones:

1.- La ley marcial. Denegar el acceso a los servicios desde el exterior o limitarlos a un cierto número de ips concreto. Lo cierto es que todos los servicios sensibles como SSH deberían estar limitados pero, cuando tienes ips dinámicas es un poco complicado.

2.- DenyHosts. Se trata de un script Python configurable con una serie de reglas que va leyendo el fichero /var/log/auth.log (o /var/log/secure para los del sombrero rojo) y toma decisiones cuando detecta una actividad anormal, como por ejemplo, denegar el servicio.

3.- PortKnocking. La idea es tener todos los puertos "firewalleados" y "llamando" a una secuencia de puertos concretos abrir/cerrar puertos según políticas establecidas. Por ejemplo, podemos establecer una regla para abrir el puerto 22 que sea atacara en esta secuencia a los puertos puertos 87, 54, y 344 y acto seguido el puerto 22 será accesible. El único pero, es que se necesita la aplicación de "marcado" en cada uno de los equipos clientes (siempre se puede llevar en un lápiz usb).

DenyHosts, no más flood a mi SSHd

DenyHosts es un script escrito en Python que tiene como único fin el evitar ataques de fuerza bruta, algo más que habitual cuando tenemos una máquina corriendo un servidor SSH público. Este script monitoriza el fichero /var/log/auth.log en búsqueda de un anormal crecimiento del mismo, como por ejemplo mi propio auth.log:

Jul 9 09:20:18 firewall-one sshd[687]: Failed password for root from 222.122.160.115 port 35695 ssh2
Jul 9 09:20:21 firewall-one sshd[689]: Could not reverse map address 222.122.160.115.
Jul 9 09:20:21 firewall-one PAM_unix[689]: authentication failure; (uid=0) -> root for ssh service
Jul 9 09:20:23 firewall-one sshd[689]: Failed password for root from 222.122.160.115 port 35909 ssh2
Jul 9 09:20:26 firewall-one sshd[691]: Could not reverse map address 222.122.160.115.


Para comenzar a utilizar denyhost, un simple apt-get install denyhost y, he aquí la configuración simple para impacientes:

/etc/denyhosts.conf
DENY_THRESHOLD_INVALID = 2 #Número de intentos fallidos permitos a un usuario inexistente antes de denegar acceso
DENY_THRESHOLD_VALID = 4 #Número de intentos fallidos permitidos a un usuario existente antes de denegar acceso


Documentación más ampliada en la web de DenyHosts.

PortKnocking, abriendo puertos bajo demanda

Se conoce como portknocking a la técnica de abrir puertos utilizando una combinación de llamadas a un grupo de puertos en concreto en una concreta secuencia, es decir, girando la rueda de nuestra caja fuerte (atacando puertos) en una secuencia de números secretos (grupo de puertos) para poder abrirla (abrir un puerto).

Partiendo de un firewall que lo deniega todo, un script perl vigila el log del firewall en busca de una secuencia de llamadas a puertos concreta que actúa a modo de password, desbloqueando la ejecución de una aplicación o una línea de comandos. La secuencia de llamadas se realiza utilizando el software cliente de la propia aplicación, la cual debe estar instalada en los equipos remotos desde los que queremos accecer al servicio oculto (también puede estar en un lápiz usb).

Veamos una configuración simple partiendo del paquete knockd disponible para Debian.

1.- Instalamos el paquete

pequerrecho:~# apt-get install knockd
....
Configurando knockd (0.4-1) ...
Not starting knockd. To enable it edit /etc/default/knockd

2.- Modificamos /etc/default/knockd para permitir que knockd arranque en el inicio de sistema
START_KNOCKD=1
3.- Editamos /etc/knockd.conf y configuramos nuestros servicios

[options]
logfile = /var/log/knockd.log
[abrirCerrarSSH]
sequence = 874, 29, 173
seq_timeout = 5
tcpflags = syn
start_command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
cmd_timeout = 10
stop_command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT

4.- Reiniciar el servicio
pequerrecho:~# /etc/init.d/knockd restart

A partir de este momento, nuestro sistema será invisible a los portscanners pero utilizando el cliente knock y la secuencia de puertos que hemos establecido, podemos abrir el puerto bajo demanda:

pequerrecho:~# knock 194.224.52.4 874 29 173


Existe un cliente portknocking para Windows, cuyo funcionamiento no he verificado llamado It's Me.

11.7.06

Firewalls serios con iptables

Que tiempos aquellos en que poníamos "echo 1 > /proc/sys/net/ipv4/ip_forward" para routear nuestras redes internas!
Hay muchas formas de construirse un buen firewall, una de ellas es copiando y pegando este script (la otra es leyéndose la documentación, pero seamos realistas...):

#!/bin/bash
SYSCTL="/sbin/sysctl -w"
IPT="/sbin/iptables"
INET_IFACE="eth0" #Interface conectado a Inet
INET_IP="192.168.0.2" #IP del iface conectado a Inet
LAN_IFACE="eth1" #Interface conectado a la Lan
LAN_IP="192.168.1.1" #IP del iface conectado a la Lan
LAN_NET="192.168.1.0/24"
LAN_BCAST="192.168.1.255"
LOCAL_IFACE="lo"
LOCAL_IP="127.0.0.1"

#Carga de módulos
modprobe ip_tables
modprobe ip_conntrack
modprobe ip_nat_ftp
modprobe ip_conntrack_ftp #Estos dos últimos por si tenemos un ftp no pasivo

#Parámetros del kernel
$SYSCTL net.ipv4.ip_forward="1"
$SYSCTL net.ipv4.tcp_syncookies="1"
$SYSCTL net.ipv4.conf.all.rp_filter="1"
$SYSCTL net.ipv4.icmp_echo_ignore_broadcasts="1"
$SYSCTL net.ipv4.conf.all.accept_source_route="0"
$SYSCTL net.ipv4.conf.all.secure_redirects="1"
$SYSCTL net.ipv4.conf.all.log_martians="1"

#Borrado de reglas establecidas
$IPT -P INPUT ACCEPT
$IPT -P FORWARD ACCEPT
$IPT -P OUTPUT ACCEPT
$IPT -t nat -P PREROUTING ACCEPT
$IPT -t nat -P POSTROUTING ACCEPT
$IPT -t nat -P PREROUTING ACCEPT
$IPT -t nat -P POSTROUTING ACCEPT
$IPT -t nat -P OUTPUT ACCEPT
$IPT -t mangle -P PREROUTING ACCEPT
$IPT -t mangle -P OUTPUT ACCEPT
$IPT -F
$IPT -t nat -F
$IPT -t mangle -F
$IPT -X
$IPT -t nat -X
$IPT -t mangle -X

#Política por defecto: DROP
$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP
$IPT -N bad_packets
$IPT -N bad_tcp_packets
$IPT -N icmp_packets
$IPT -N udp_inbound
$IPT -N icmp_packets
$IPT -N udp_inbound

$IPT -A bad_packets -p ALL -i $INET_IFACE -s $LAN_NET -j LOG --log-prefix "fp=bad_packets:2 a=DROP "
$IPT -A bad_packets -p ALL -i $INET_IFACE -s $LAN_NET -j DROP
$IPT -A bad_packets -p ALL -m state --state INVALID -j LOG --log-prefix "fp=bad_packets:1 a=DROP "
$IPT -A bad_packets -p ALL -m state --state INVALID -j DROP
$IPT -A bad_packets -p tcp -j bad_tcp_packets
$IPT -A bad_packets -p ALL -j RETURN
$IPT -A bad_tcp_packets -p tcp -i $LAN_IFACE -j RETURN
$IPT -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j LOG --log-prefix "fp=bad_packets:1 a=DROP "
$IPT -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j DROP
$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL NONE -j LOG --log-prefix "fp=bad_packets=2 a=DROP "
$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL NONE -j DROP
$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL ALL -j LOG --log-prefix "fp=bad_tcp_packets:3 a=DROP "
$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL ALL -j DROP
$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL FIN,URG,PSH -j LOG --log-prefix "fp=bad_tcp_packets:4 a=DROP "
$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j LOG --log-prefix "fp=bad_tcp_packets:5 a=DROP "
$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL SYN,RST,ACL,FIN,URG -j DROP
$IPT -A bad_tcp_packets -p tcp --tcp-flags SYN,RST SYN,RST -j LOG --log-prefix "fp=bad_tcp_packets:6 a=DROP "
$IPT -A bad_tcp_packets -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
$IPT -A bad_tcp_packets -p tcp --tcp-flags SYN,FIN SYN,FIN -j LOG --log-prefix "fp=bad_tcp_packets:7 a=DROP "
$IPT -A bad_tcp_packets -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
$IPT -A bad_tcp_packets -p tcp -j RETURN
$IPT -A icmp_packets --fragment -p ICMP -j LOG --log-prefix "fp=icmp_packets:1 a=DROP "
$IPT -A icmp_packets --fragment -p ICMP -j DROP
$IPT -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j DROP
$IPT -A icmp_packets -p ICMP -s 0/0 --icmp-type 11 -j ACCEPT
$IPT -A icmp_packets -p ICMP -j RETURN
#Denegar el acceso a Netbios
$IPT -A udp_inbound -p UDP -s 0/0 --destination-port 137 -j DROP
$IPT -A udp_inbound -p UDP -s 0/0 --destination-port 130 -j DROP
##
$IPT -A udp_inbound -p UDP -j RETURN
$IPT -A udp_outbound -p UDP -s 0/0 -j ACCEPT
$IPT -A tcp_inbound -p TCP -s 0/0 --destination-port 22 -j ACCEPT #Aceptamos SSH
$IPT -A tcp_inbound -p TCP -j RETURN
$IPT -A tcp_outbound -p TCP -s 0/0 -j ACCEPT
$IPT -A INPUT -p ALL -i $LOCAL_IFACE -j ACCEPT
$IPT -A INPUT -p ALL -j bad_packets
$IPT -A INPUT -p ALL -d 224.0.0.1 -j DROP
$IPT -A INPUT -p ALL -i $LAN_IFACE -s $LAN_NET -j ACCEPT
$IPT -A INPUT -p ALL -i $LAN_IFACE -d $LAN_BCAST -j ACCEPT
$IPT -A INPUT -p ALL -i $INET_IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A INPUT -p TCP -i $INET_IFACE -j tcp_inbound
$IPT -A INPUT -p UDP -i $INET_IFACE -j udp_inbound
$IPT -A INPUT -p ICMP -i $INET_IFACE -j icmp_packets
$IPT -A INPUT -m pkttype --pkt-type broadcast -j DROP
$IPT -A INPUT -j LOG --log-prefix "fp=INPUT:99 a=DROP "
$IPT -A FORWARD -p ALL -j bad_packets
$IPT -A FORWARD -p tcp -i $LAN_IFACE -j tcp_outbound
$IPT -A FORWARD -p udp -i $LAN_IFACE -j udp_outbound
$IPT -A FORWARD -p ALL -i $LAN_IFACE -j ACCEPT
$IPT -A FORWARD -i $INET_IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT

#Redireccionar un puerto
#$IPT -A FORWARD -p tcp -i $INET_IFACE --destination-port 80 # --destination 192.168.1.20 -j ACCEPT

$IPT -A FORWARD -j LOG --log-prefix "fp=FORWARD:99 a=DROP "
$IPT -A OUTPUT -m state -p icmp --state INVALID -j DROP
$IPT -A OUTPUT -p ALL -s $LOCAL_IP -j ACCEPT
$IPT -A OUTPUT -p ALL -o $LOCAL_IFACE -j ACCEPT
$IPT -A OUTPUT -p ALL -s $LAN_IP -j ACCEPT
$IPT -A OUTPUT -p ALL -o $LAN_IFACE -j ACCEPT
$IPT -A OUTPUT -p ALL -o $INET_IFACE -j ACCEPT
$IPT -A OUTPUT -j LOG --log-prefix "fp=OUTPUT:99 a=DROP "

$IPT -t nat -A POSTROUTING -o $INET_IFACE -j SNAT --to-source $INET_IP




Psyco, python a toda máquina

Si estás escribiendo un programa bastante largo y quieres agilizar la ejecución sin revisar tu código para quitar 40 "ifs" que sobran, existe un módulo llamado Psyco que lo hace por ti.

Para los impacientes que no se van a leer la documentación, he aquí la forma más rápida de acelerar tus aplicaciones:

import psyco
psyco.full()
Y para aplicaciones con ingentes cantidades de código:

import psyco
psyco.profile()

NMEA, leer datos del GPS y no morir en el intento

Esta receta es útil para quien tenga la necesidad de programar una aplicación que lea de un GPS (como es mi caso particular). La estructura de las cadenas que nos indican el posicionamiento es la siguiente:

Trama de ejemplo:
$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47

Donde:
GGA Datos GPS
123519 Hora del dato en horario UTC
4807.038,N Latitud
01131.000,E Longitud
1 Validez: 0 = invalido
1 = GPS valido
2 = DGPS valido
6 = estimatedo
8 = modo simulación
08 Número de satelites utilizados
0.9 Desviación horizontal
545.4,M Altitud en metros
46.9,M Geoid
(vacío) Tiempo desde última actualización
(vacío) ID estación DGPS
*47 checksum

Expresiones regulares en Python

He aquí un tutorial sobre expresiones regulares en Python.

Es bastante completo y en mi caso particular me ha sido de gran ayuda.

Expresiones regulares en Python - milugar.net

Usuarios virtuales vs usuarios sin shell

Pongámonos en situación:

Tenemos que dar acceso FTP e IMAP a un cierto número de usuarios, para que puedan colgar sus ficheros y tener su correo electrónico almacenado. Nuestra política de seguridad más básica a la hora de crear los usuarios será la de darles acceso a estos servicios pero denegarles las entradas a la shell (más que básico es obvio). Para realizar esta tarea, tenemos dos opciones:

a) Crear usuarios virtuales en cada uno de los servicios con sus consecuentes políticas de acceso. Esta opción es profesional, segura pero muy lenta y tediosa de administrar.

b) Añadir los usuarios que nos interese a una shell nula, con lo que nunca podrán hacer login. Es una solución sobria y rápida. Los pasos que debemos seguir son los siguientes:

1.- Añadir la shell nula a la lista de shells permitidas: echo "/bin/false" >> /etc/shells
2.- Indicar a los usuarios la shell que deben usar: useradd -g users -s /bin/false -d /home/nombre_usuario nombre_usuario

Sencillo, rápido y efectivo!

pyGoogle, búsquedas en tus programas

En ocasiones puede resultar útil el realizar búsquedas en Google desde nuestros programas escritos en Python. En mi caso, he utilizado este módulo para crear un simple bot IRC que escucha el comando !google y realiza búsquedas mostrando los dos primeros resultados en el canal.

El módulo puede obtenerse en su repositorio de SourceForge y para poder acceder al API de Google es necesario dar de alta una cuenta de desarrollador gratuíta. La forma de utilizarlo es la siguiente:

import google

parametro = "texto a buscar"
google.setLicense("mi_licencia_del_API_de_Google")
google.maxResults=2
google.language="es"
busqueda = google.doGoogleSearch(parametro)
print busqueda.results[0].URL + busqueda.results[0].title
print busqueda.results[1].URL + busqueda.results[1].title