Algo de Linux: mayo 2013

viernes, 31 de mayo de 2013

Revisar la cuenta de un usuario registrado en ldap

En ocasiones, algún usuario nos pide que revisemos su cuenta porque tiene algún problema en el entorno gráfico. Como no conocemos su contraseña, y ésta se encuentra encriptada en el servidor ldap, no vamos a poder revisarla a menos que nos diga cuál es o él mismo inicie sesión y nos la deje abierta para que investiguemos.

Una solución es acceder a nuestra base de datos de ldap con phpLDAPadmin, desplazarnos al campo "Contraseña" de su usuario y "añadir" otro valor para la contraseña. Resalto lo de añadir, porque no se trata de cambiar la contraseña, sino de añadir un valor nuevo. 

Con ésto, él podrá seguir usando su password sin tener que decírnosla, y nosotros podremos entrar en su cuenta. Una vez resuelto su problema, borramos el valor que añadimos anteriormente, y listo.

Limitar el número de informes guardados por sarg

Añado esta entrada a petición de algún compañero que me ha dicho que usa mi blog como referencia.

El otro día hablábamos en la lista de administradores que a muchos compañeros se les estaba llenando el directorio /var por la cantidad de archivos que Haarpcache estaba almacenando y se dieron soluciones para limpiar un poco la caché.

Al hilo del tema, comenté que los informes de sarg también estaban comenzando a ocupanr mucho espacio porque en el archivo de configuración /etc/sarg/sarg.conf, viene  definido, por defecto, que guarde informes de forma ilimitada mediante el parámetro:

lastlog 0

Si queremos limitar el número de informes guardados por sarg, no tenemos más que indicarle el número máximo que deseamos almacenar. Por ejemplo:

Si en /etc/sarg/sarg.conf defino:

lastlog 90

Le estoy indicando a sarg que no quiero mantener más de 90 informes en el directorio de reportes. De este modo, sarg mantendrá almacenados sólo los últimos 90 informes, eliminando cada vez el más antiguo.

lunes, 27 de mayo de 2013

Transferir archivos entre los equipos de una red local mediante UDPcast

Como ya comenté en un artículo anterior, UDPcast es una herramienta de transferencia de archivos que permite enviar datos desde un equipo a varios destinatarios a la vez en una red local de una forma bastante rápida, sobre todo si la transferencia la realizamos en modo multicast (opción por defecto).

Y, como ya dije también, podemos usar UDPcast para:
  • Transferir archivos o directorios.
  • Clonar particiones directamente.
En este artículo voy a contar cómo enviar y recibir archivos y carpetas, pero, en otro momento veremos cómo clonar directamente, usando el UDPcast que montamos en el disco duro.

Para poder transferir archivos mediante UDPcast entre mis máquinas, lo primero que tenemos que hacer es instalar el paquete udpcast. Yo lo he instalado mediante puppet en todos los clientes, pero si tuviérais que instalarlo a mano, no hay ningún problema, porque se encuentra en los repositorios:

# apt-get install udpcast

Una vez instalado, ya podemos enviar y recibir. Así que abrimos una consola en el equipo que va a realizar el envío y otra en cada uno de los equipos que lo van a recibir.

Enviar y recibir archivos
UDPcast está pensado para enviar archivos de forma individual. Así que, si comprimimos el archivo antes de enviarlo, la transferencia se realizará en menos tiempo.

En el equipo servidor ejecutaremos:

# udp-sender --file archivo

Y en los equipos receptores:

# udp-receiver --file archivo

En el servidor nos mostrará un mensaje que dice que pulsemos una tecla para comenzar a enviar datos:

"Ready. Press any key to start sending data."

En los clientes nos mostrará un mensaje que dice que pulsemos una tecla para comenzar a recibir datos:

"Press any key to start receiving data!"

Pulsamos una tecla en el servidor o los clientes y comenzará a realizarse la transferencia.

Enviar y recibir directorios
 Si queremos enviar y recibir directorios, mediante un pipe podemos hacer uso de un empaquetador como tar o gzip:

En el equipo servidor ejecutaremos:

# tar cf - directorio | udp-sender

Y en los equipos receptores:

# udp-receiver | tar xf -

Al igual que en el caso anterior, en el servidor nos mostrará un mensaje que dice que pulsemos una tecla para comenzar a enviar datos:

"Ready. Press any key to start sending data."

Y en los clientes nos mostrará un mensaje que dice que pulsemos una tecla para comenzar a recibir datos:

"Press any key to start receiving data!"

Pulsamos una tecla en el servidor o los clientes y comenzará a realizarse la transferencia.

Enviar y recibir particiones
Como las particiones se tratan como archivos, si queremos clonar una partición, tan sólo tenemos que especificar el nombre de esa partición. Por ejemplo, si queremos clonar directamente la partición sda1 de una máquina en un conjunto de máquinas remotas:

En el equipo servidor ejecutaremos:

# udp-sender --file /dev/sda1

Y en los equipos receptores:

# udp-receiver --file /dev/sda1

En el servidor nos mostrará un mensaje que dice que pulsemos una tecla para comenzar a enviar datos:

"Ready. Press any key to start sending data."

En los clientes nos mostrará un mensaje que dice que pulsemos una tecla para comenzar a recibir datos:

"Press any key to start receiving data!"

Pulsamos una tecla en el servidor o los clientes y comenzará a realizarse la transferencia.

 Algunas opciones útiles
UDPcast tiene muchas opciones. Algunas de las que me parecen más interesantes son las siguientes:
  • --interface ethX: Útil, si el equipo tiene varias interfaces de red para que escuche en una determinada.
  • --nokbd: Sirve para que el comando no espere a que el usuario pulse una tecla.
  • --min-receivers n: Sirve para indicar el número mínimo de receptores.
  • --min-receivers n: Sirve para indicar el número máximo de receptores.
  • --min-wait t: Mínimo tiempo (en segundos) a esperar antes de comenzar la transferencia.
  • --max-wait t: Máximo tiempo (en segundos) a esperar antes de comenzar la transferencia.

Insertar una cadena al final justo antes de la última línea de un archivo mediante sed

En muchas ocasiones tenemos que insertar, mediante bash, una cadena de texto al final de un archivo, justo antes de la última línea, como por ejemplo, en el archivo /etc/rc.local o /etc/gdm3/PostSession/Default, donde hay que insertar los comandos antes de la línea que dice: "exit 0".

En linux tenemos muchas formas de hacerlo, pero para mí la más sencilla es ésta:

# sed -i '$ i\cadena' archivo

Vamos a verlo con un ejemplo:

Si quiero lanzar ocsinventory-agent en el inicio de una máquina, tengo que hacer una llamada a ocsinventory-agent en el archivo /etc/rc.local.

El archivo /etc/rc.local tiene por defecto el siguiente contenido:

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

exit 0

Como lo que necesito es insertar la cadena "ocsinventory-agent" justo antes de la línea que dice "exit 0", lo que tengo que hacer es ejecutar el siguiente comando:

# sed -i '$ i\ocsinventory-agent\n' /etc/rc.local

Como se puede ver, inserto in-line ( parámetro -i) la cadena ocsinventory-agent y un salto de línea en el archivo /etc/rc.local.

Después de ejecutar el comando, el archivo quedaría así:

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

ocsinventory-agent 

exit 0

Un detalle importante: Debemos tener cuidado si ejecutamos el comando más de una vez porque estaremos insertando varias veces la misma cadena. Si queremos ejecutar el comando dentro de un script, de tal manera que la cadena se inserte tan sólo una vez, deberíamos controlarlo de algún modo. Por ejemplo, así:

# grep -q ocsinventory-agent /etc/rc.local 2> /dev/null || sed -i '$ i\ocsinventory-agent\n' /etc/rc.local

De este modo, la inserción sólo se realizará cuando la cadena no estuviera ya insertada en el archivo.

Instalar UDPCast en una partición

En el siguiente artículo, mostré cómo podíamos añadir dos entradas de grub a nuestros portátiles: una para permitir autorestaurar el portátil y la otra para lanzar clonezilla de modo general:
http://enavas.blogspot.com.es/2013/05/en-el-articulo-httpenavas.html

Estas entradas van a ser muy útiles para nosotros porque nos van a permitir cosas como restaurar el portátil sin necesidad de tener red o crear una nueva imagen del sistema y almacenarla en el mismo portátil.

Bueno, pues además de clonezilla, hay otra herramienta muy interesante que merece la pena añadir a nuestros portátiles: UDPcast.

UDPcast es una herramienta de transferencia de archivos que permite enviar datos de forma simultánea desde un equipo a varios destinatarios en una red local. Imaginad lo útil que puede ser ésto:
  • Podremos copiar un archivo o conjunto de archivos de forma simultánea a todos los equipos a la vez.
  • O podremos copiar particiones de un equipo a una serie de máquinas a la vez.
En este artículo vamos a ver cómo montar UDPcast en la partición de arranque de nuestros portátiles.

Partimos de que el portátil tiene una partición /dev/sda1 donde se encuentra el /boot y queremos montar UDPcast en esa misma partición.

Iniciamos el equipo, y creamos un directorio para udpcast en el directorio /boot:
# mkdir /boot/udpcast

Nos situamos dentro del directorio:
# cd /boot/udpcast

Descargamos el kernel:
# wget http://udpcast.linux.lu/current/linux

Descargamos el initrd:
# wget http://udpcast.linux.lu/current/initrd

Editamos el archivo /etc/grub.d/40_custom y le añadimos la siguiente entrada de grub:
menuentry "Udpcast" {
   set root=(hd0,1)
   linux /udpcast/linux
   initrd /udpcast/initrd
}
Como ya teníamos montado antes clonezilla, nos quedaría más o menos así:

/etc/grub.d/40_custom
#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.

menuentry "Clonar sistema (/dev/sda1, /dev/sda2) sin modificar home (/dev/sda6)" {
   set root=(hd0,3)
   linux /livehd/vmlinuz boot=live config noswap nolocales edd=on nomodeset noprompt ocs_live_run=\"ocs-live-restore\" ocs_live_extra_param=\" -c -k -p poweroff restoreparts miniportatil sda1 sda2\" keyboard-layouts=\"NONE\" ocs_live_batch=\"yes\" locales=\"es_ES.UTF-8\" vga=788 ip=frommedia nosplash live-media-path=/livehd bootfrom=/dev/sda3 
   initrd /livehd/initrd.img
}

menuentry "Clonezilla general" {
   set root=(hd0,3)
   linux /livehd/vmlinuz boot=live config noswap nolocales edd=on nomodeset ocs_live_run=\"ocs-live-general\" ocs_live_extra_param=\"\" keyboard-layouts=\"\" ocs_live_batch=\"no\" locales=\"\" vga=788 ip=frommedia nosplash live-media-path=/livehd bootfrom=/dev/sda3 
   initrd /livehd/initrd.img
}

menuentry "Udpcast" {
   set root=(hd0,1)
   linux /udpcast/linux
   initrd /udpcast/initrd
}

Por último, hacemos un update-grub2 para regenerar el archivo /boot/grub/grub.cfg:
# update-grub2

Con ésto, ya tendríamos montado UDPcast en nuestro disco duro.

En otro artículo os mostraré cómo usar udpcast para transferir archivos y clonar particiones.

miércoles, 22 de mayo de 2013

Apagar automáticamente thinclients al apagar, reiniciar o cerrar sesión en el servidor LTSP

Aprovechando que recientemente me han preguntado sobre el tema, voy a escribir esta entrada en la que os voy a mostrar un script muy interesante que creé allá por el año 2011 para apagar los thinclients cuando un usuario apaga el servidor LTSP, lo reinicia o cierra la sesión.

Uno de los problemas de LTSP (Linux Terminal Server Project) es que confía en que el usuario apague los terminales, antes de apagar el servidor, y si no lo hace, los terminales quedarán bloqueados y habrá que apagarlos pulsando el botón de apagado de cada uno de ellos o bajando los diferenciales y/o magnetotérmicos para cortar la corriente. 

Lo primero puede llegar a ser realmente pesado, sobre todo si tienes cada equipo en un cajón cerrado. Lo segundo no es muy recomendable.

Este script está al alcance de todos los administradores, puesto que en su día subí a desarrollo un módulo puppet para montarlo en los servidores de terminales del centro. En cualquier caso, por si alguien más lo quiere, cuelgo aquí también el módulo:
A continuación podéis ver el init.pp del módulo que lo instala vía puppet:

class apagado-terminales {

   file { 
      "/usr/sbin/apagaterminales.sh" :
      source => "puppet://puppetinstituto/apagado-terminales/apagaterminales.sh",
      owner => root, group => root, mode => 750
   }

   file {
      "/opt/ltsp/i386/root/.ssh" :
      ensure => directory, owner => root,  group => root, mode => 700,
   }

   file { "/root/.ssh/id_rsa.pub":
           ensure => file, owner => "root", group => "root", mode => "644",
   }

   file {
      "/root/.ssh/known_hosts" :
      ensure => file, owner => root,  group => root, mode => 644,
   }

   exec { "/usr/bin/ssh-keygen -q -t rsa -N '' -f /root/.ssh/id_rsa":
        unless => "/usr/bin/test -f /root/.ssh/id_rsa",
        notify => Exec["copy-publickey"]
   }

   exec { "copy-publickey":
        command => "/bin/cat /root/.ssh/id_rsa.pub >> /opt/ltsp/i386/root/.ssh/authorized_keys",
 require => [File["/root/.ssh/id_rsa.pub"], File["/opt/ltsp/i386/root/.ssh"]],
        unless => '/bin/grep "$fqdn" /opt/ltsp/i386/root/.ssh/authorized_keys 2>/dev/null',
        notify => Exec["update-image"]
   }

   exec { "update-image":
        command => "/usr/sbin/ltsp-update-image --arch i386",
        path => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        refreshonly => true
       }

   exec { '/bin/sed -i -e "s/exit 0/\/usr\/sbin\/apagaterminales.sh \&\n\nexit 0/g" /etc/gdm3/PostSession/Default':
        unless => '/bin/grep "apagaterminales" /etc/gdm3/PostSession/Default 2>/dev/null'
   }

   file {
      "/etc/init.d/halt-terminales" :
      source => "puppet://puppetinstituto/apagado-terminales/halt-terminales",
      owner => root, group => root, mode => 750
   }

   exec { "/bin/ln -sf /etc/init.d/halt-terminales /etc/rc0.d/K01aapaga-terminales":
      unless => "/usr/bin/test -L /etc/rc0.d/K01aapaga-terminales"
   }

   exec { "/bin/ln -sf /etc/init.d/halt-terminales /etc/rc6.d/K01aapaga-terminales":
      unless => "/usr/bin/test -L /etc/rc6.d/K01aapaga-terminales"
   }

}

Si os fijáis, el módulo es muy completito:
  • Crea un par de claves pública/privada, copia la clave pública al usuario root del chroot de los terminales y regenera la imagen para los terminales (usamos nbd).
  • Copia el script apagaterminales.sh al directorio /usr/sbin del servidor de terminales.
  • Coloca un script de apagado de los terminales en /etc/init.d/halt-terminales y crea los enlaces correspondientes en /etc/rc0.d y /etc/rc6.d para realizar el procedimiento de apagado cuando el usuario apague el servidor o lo reinicie.
  • Y, además, modifica el archivo /etc/gdm3/PostSession/Default para apagar también los terminales cuando el usuario cierre sesión.
Por otra parte, aquí tenéis el script que realiza el apagado de los terminales /usr/sbin/apagaterminales.sh:
#!/bin/bash
# Esteban M. Navas
# IES Valle del Jerte - Plasencia
# 03/02/2011
# Última modificación: 27/11/2013

# apagaterminales.sh -> Apaga los terminales de un aula
# El script hace uso de avahi-browse y ssh-keyscan para cumplir con su función.
# Está pensado para ejecutar el comando de apagado tan sólo sobre las máquinas que se detecten encendidas
# pero al mismo tiempo, va construyendo una lista con las ips de las máquinas que se van detectando.
# Hace uso de ssh-keyscan para obtener las claves rsa de los terminales encendidos y añadirlas al fichero 
# /root/.ssh/known_hosts del servidor de terminales.
# Borra los temporales de los usuarios que iniciaron sesión en los terminales y mata sus procesos

# Detectamos los terminales encendidos, tal y como está definido en ldap
avahi-browse -trpk -d local _workstation._tcp 2>/dev/null | grep 192.168.0. | grep -v '_pro\|\-pro'| cut -d";" -f8 > /tmp/terminalesUp

# Obtenemos las claves rsa de los terminales encendidos
ssh-keyscan -t rsa -f /tmp/terminalesUp > /tmp/rsaterminalesUp

# Añadimos las claves rsa de los terminales encendidos al fichero known_host de root del servidor de terminales
sort -o /root/.ssh/known_hosts -m /tmp/rsaterminalesUp /root/.ssh/known_hosts
sort -o /root/.ssh/known_hosts -u /root/.ssh/known_hosts

# Apagamos los terminales 
while read IP
do
   ssh root@$IP -a /sbin/poweroff -fp &
done < /tmp/terminalesUp

# Obtenemos la lista de usuarios que han iniciado sesión en terminales
w | grep '192.168.0' > /tmp/userstoclean

# Borramos temporales y matamos procesos de aquellos usuarios que hayan iniciado sesión en un terminal
while read SESION ; do

   USUARIO=`echo $SESION | cut -f1 -d" "`

   # Borramos los temporales creados en /tmp al iniciar sesión el usuario 
   find /tmp -not -user root -user $USUARIO -exec rm -r {} \; 2>/dev/null

   # Matamos todos los procesos del usuario
   pkill -9 -u $USUARIO
done < /tmp/userstoclean

rm /tmp/userstoclean

Está super-comentado para que cualquiera que lo lea entienda lo que hace.

Si lo leéis detenidamente, veréis que es un script muy potente:
  • Detecta los terminales que hay encendidos en el momento de ejecutar el script.
  • Obtiene las claves rsa de dichos terminales para que, a la hora de ejecutar las conexiones ssh, no se quede esperando respuesta por parte del usuario, y, además, va construyendo la lista de terminales conocidos en cada ejecución, evitando que haya claves repetidas en el archivo known_hosts
  • Apaga los terminales rápidamente.
  • Y, además, hace limpieza borrando los archivos temporales que se crean en el directorio /tmp del servidor de terminales por cada usuario que inicia sesión en un terminal. Esto es importante.
Y, por último, podéis ver el script de inicio normalizado /etc/init.d/halt-terminales:

#! /bin/sh
### BEGIN INIT INFO
# Provides:          halt-terminales
# Required-Start:
# Required-Stop:
# Default-Start:
# Default-Stop:      0 6
# Short-Description: Execute the reboot command.
# Description:
### END INIT INFO

PATH=/sbin:/usr/sbin:/bin:/usr/bin

. /lib/lsb/init-functions

do_stop () {
 # Apagamos los terminales
 /usr/sbin/apagaterminales.sh &
}

case "$1" in
  start)
 # No-op
 ;;
  restart|reload|force-reload)
 echo "Error: argument '$1' not supported" >&2
 exit 3
 ;;
  stop)
 do_stop
 ;;
  *)
 echo "Usage: $0 start|stop" >&2
 exit 3
 ;;
esac

Establecer un modelo personalizado de resolución de pantalla

El otro día, después de actualizar mi equipo a Wheezy, me llevé la sorpresa de que la máxima resolución que podía aplicar a mi monitor era 1024x768. Y con ésto, tanto los textos como los iconos aparecían enormes y en la ventana de navegador tenía que estar desplazando las barras para ver todo el ancho de pantalla.

Por lo que se ve, el driver ati radeon, no detectaba más allá de los 1024x768 de forma automática. 

root@miservidor:# xrandr
Screen 0: minimum 320 x 200, current 1024 x 768, maximum 8192 x 8192
VGA-0 connected 1024x768+0+0 (normal left inverted right x axis y axis) 0mm x 0mm
   1024x768       60.0 *+
   800x600        60.3     56.2  
   848x480        60.0  
   640x480        59.9  
S-video disconnected (normal left inverted right x axis y axis)
HDMI-0 disconnected (normal left inverted right x axis y axis)
DVI-0 disconnected (normal left inverted right x axis y axis)

Como aquello no me convencía decidí buscar alguna manera de cambiarlo y lo que hice fue lo siguiente: Arranqué una live de Backtrack y me fijé en que a una resolución de 1360x768 la pantalla se veía bien y ya no tenía el problema que comentaba antes.

Paré el servidor gráfico y generé un archivo de configuración para Xorg:
# Xorg -configure

Una vez ejecutado el comando anterior, copié el archivo de configuración generado al directorio /etc/X11:
# cp /root/xorg.conf.new /etc/X11/xorg.conf

A continuación generé un "modeline" personalizado con una resolución de 1360x768 y un refresco de 60Hz para mi monitor:
# root@miservidor:# gtf 1360 768 60

  # 1360x768 @ 60.00 Hz (GTF) hsync: 47.70 kHz; pclk: 84.72 MHz
  Modeline "1360x768_60.00"  84.72  1360 1424 1568 1776  768 769 772 795  -HSync +Vsync

Y se lo añadí a la sección que define el monitor en el fichero /etc/X11/xorg.conf:
Section "Monitor"
        Identifier   "Monitor0"
        VendorName   "Monitor Vendor"
        ModelName    "Monitor Model"
        # 1360x768 @ 60.00 Hz (GTF) hsync: 47.70 kHz; pclk: 84.72 MHz
        Modeline     "1360x768" 84.72 1360 1424 1568 1776 768 769 772 795 -HSync +Vsync
        Option       "DPMS"
EndSection

Por último, añadí la nueva resolución a la subsección "Display" de la sección "Screen" del fichero /etc/X11/xorg.conf
Section "Screen"
 Identifier "Screen0"
 Device     "Card0"
 Monitor    "Monitor0"
 SubSection "Display"
  Viewport   0 0
  Depth     1
  Modes     "1360x768" "1024x768" "800x600" "848x480" "640x480"
 EndSubSection
 SubSection "Display"
  Viewport   0 0
  Depth     4
  Modes     "1360x768" "1024x768" "800x600" "848x480" "640x480"
 EndSubSection
 SubSection "Display"
  Viewport   0 0
  Depth     8
  Modes     "1360x768" "1024x768" "800x600" "848x480" "640x480"
 EndSubSection
 SubSection "Display"
  Viewport   0 0
  Depth     15
  Modes     "1360x768" "1024x768" "800x600" "848x480" "640x480"
 EndSubSection
 SubSection "Display"
  Viewport   0 0
  Depth     16
  Modes     "1360x768" "1024x768" "800x600" "848x480" "640x480"
 EndSubSection
 SubSection "Display"
  Viewport   0 0
  Depth     24
  Modes     "1360x768" "1024x768" "800x600" "848x480" "640x480"
 EndSubSection
EndSection

Y reinicié las X para aplicar los cambios.

Si ahora ejecutamos xrandr, podremos comprobar que tenemos la nueva resolución soportada:
root@miservidor:# xrandr
Screen 0: minimum 320 x 200, current 1360 x 768, maximum 8192 x 8192
VGA-0 connected 1360x768+0+0 (normal left inverted right x axis y axis) 0mm x 0mm
   1360x768       60.0*+
   1024x768       60.0  
   800x600        60.3     56.2  
   848x480        60.0  
   640x480        59.9  
S-video disconnected (normal left inverted right x axis y axis)
HDMI-0 disconnected (normal left inverted right x axis y axis)
DVI-0 disconnected (normal left inverted right x axis y axis)

viernes, 17 de mayo de 2013

Añadir una opción a grub para autorestaurar el sistema de un portátil

En el artículo http://enavas.blogspot.com.es/2013/05/montar-clonezilla-live-en-el-disco-duro.html vimos cómo montar clonezilla live en la partición /dev/sda3 de nuestros portátiles, aprovechando que está vacía y no se usa para nada. 

Además, añadimos una entrada al menú de grub2 para arrancar clonezilla desde el menú de arranque y comenté que podíamos crear una entrada más de autorestauración de forma que restaurase tan sólo las particiones que contienen el sistema: sda1 y sda2 y no tocasen la partición sda6, que contiene el home del usuario.

Basándonos en la configuración que ya hicimos en el artículo del que hablamos, tan sólo tendríamos que añadir una nueva entrada de menú al archivo /etc/grub.d/40_custom, como os muestro a continuación:

/etc/grub.d/40_custom

#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.
# Esteban M. Navas Martín
# 17/05/2013

menuentry "Clonar sistema (/dev/sda1, /dev/sda2) sin modificar la partición home (/dev/sda6)" {
   set root=(hd0,3)
   linux /livehd/vmlinuz boot=live config noswap nolocales edd=on nomodeset noprompt ocs_live_run=\"ocs-live-restore\" ocs_live_extra_param=\" -c -k -p true restoreparts miniportatil sda1 sda2\" keyboard-layouts=\"NONE\" ocs_live_batch=\"yes\" locales=\"es_ES.UTF-8\" vga=788 ip=frommedia nosplash live-media-path=/livehd bootfrom=/dev/sda3 
   initrd /livehd/initrd.img
}

menuentry "Clonezilla general" {
   set root=(hd0,3)
   linux /livehd/vmlinuz boot=live config noswap nolocales edd=on nomodeset ocs_live_run=\"ocs-live-general\" ocs_live_extra_param=\"\" keyboard-layouts=\"\" ocs_live_batch=\"no\" locales=\"\" vga=788 ip=frommedia nosplash live-media-path=/livehd bootfrom=/dev/sda3 
   initrd /livehd/initrd.img
}

Una vez modificado el archivo /etc/grub.d/40_custom,  hacemos un:
# update-grub2

Por último, lo único que quedaría por hacer sería copiar la imagen de clonación a la partición /dev/sda3 y ponerle el siguiente nombre: "miniportatil", si no queremos modificar la entrada de grub.

Problema al montar el directorio de imagen de clonezilla

Éste es un problema que me ha surgido en estos días y me ha traído de cabeza. Para mí es un bug que se da en una determinada situación, pero no he encontrado documentación concreta sobre ello ni la forma de controlarlo.


Se trata de lo siguiente: Si tenemos instalado clonezilla en el disco duro del ordenador y arrancamos con un disco duro externo o pendrive de clonezilla que lo tenga también instalado, al utilizar la opción "skip" para montar el directorio de imagen de clonezilla /home/partimag, no nos va a permitir elegir el directorio /home/partimag que queremos usar (el interno o el externo) y va a montar el primero que detecte.

Utilizo el parámetro live-media-path=/live-hd para tener clonezilla y drbl en el disco duro externo. Después de muchas pruebas, he descubierto que el problema se soluciona llamando de forma diferente al directorio definido con live-media-path en el disco duro interno y el externo. Por ejemplo:
  • live-media-path=/live-hd para el disco duro externo
  • live-media-path=/livehd para el disco duro interno
El caso es que tenga diferente nombre, porque de otro modo, no va a detectar el /home/partimag de uno de los dos discos duros.

jueves, 16 de mayo de 2013

Particiones FAT32: There are differences between boot sector and its backup

En ocasiones, hacemos un fsck a una partición FAT32 y obtenemos un error como éste: "There are differences between boot sector and its backup"

Por ejemplo:

# fsck /dev/sdb1

En este caso, fsck nos ofrece tres posibilidades:

1) Copy original to backup
2) Copy backup to original
3) No action

Y da igual la opción que seleccionemos (copiar desde el original al backup o copiar desde el backup al original) porque nos va a decir:

Leaving file system unchanged.

Si queremos hacer una copia del sector de arranque desde el original al backup o desde el backup al original, tendremos que ejecutar fsck con el parámetro -r:

# fsck -r /dev/sdb1

Prey: Software libre para localizar tu portátil o smartphone

Localiza tu portátil o tu móvil en caso de robo | Bitelia

Instalar paquetes que requieren respuesta del usuario de forma desatendida

A veces queremos instalar un paquete que requiere respuestas por parte del usuario para su instalación, pero queremos que la instalación se realice de forma desatendida. 

Una forma de solucionar este problema es usar preseed, es decir: preestablecer las respuestas en un archivo, det tal manera que al realizar la instalación, el sistema no pregunte al usuario.

Vamos a ver cómo podemos conseguirlo con un ejemplo:

Imaginemos que queremos instalar el paquete ocsinventory-agent de forma desatendida en una serie de clientes, sabiendo que este paquete pregunta al usuario qué método va a usar para inventariar el cliente (local o http), y, en caso de que se elija http, también preguntará la IP del servidor de inventariado.

Lo primero que necesitamos tener instalado es el paquete debconf-utils. Así que, si no lo tenemos instalado aún, lo instalamos:

# apt-get install debconf-utils

Una vez que tenemos las herramientas, instalamos el paquete en cuestión (en el ejemplo: ocsinventory-agent) normalmente:

# apt-get install ocsinventory-agent

Nos hará las preguntas de configuración. Las respondemos con los datos que queramos configurar.

Una vez instalado, ejecutamos el comando debconf-get-selections, de manera que filtremos las preguntas y respuestas del paquete que acabamos de instalar y las almacenemos en un fichero.

Siguiendo con el ejemplo:

# debconf-get-selections | grep ocsinventory-agent > ocsinventory-agent.seed

Si ahora quisiéramos instalar el paquete ocsinventory-agent en un cliente, sin que nos hiciera las preguntas, no tendríamos más que ejecutar los siguientes comandos:

# debconf-set-selections ocsinventory-agent.seed && apt-get -y install ocsinventory-agent 

Y eso es todo. Sencillo, ¿verdad?

miércoles, 15 de mayo de 2013

Paquetes de firefox 21.0 para instalar en las máquinas de los IES

A continuación dejo dos enlaces para descargar los paquetes de 32 y 64 bits creados "de forma rápida" para instalar firefox 21.0 en el directorio /opt/firefox/ de las máquinas del instituto. 

Importante: Estos paquetes tan sólo colocan firefox en /opt/firefox/. No cambian el enlace de /usr/bin/iceweasel a /opt/firefox/firefox para que se siga pudiendo usar iceweasel como navegador por defecto. 

Para realizar el cambio de iceweasel a firefox o firefox a iceweasel, tengo dos tareas puppet:
  • activa-firefox 
  • activa-iceweasel 
De este modo, si quiero que los portátiles, los servidores ltsp o los workstation usen firefox, les pongo la tarea activa-firefox y si quiero que usen iceweasel, les pongo la tarea activa-iceweasel.

martes, 14 de mayo de 2013

Script para detectar los equipos de una red con el puerto ssh abierto

A continuación dejo un script tremendamente útil que escribí, no hace mucho tiempo, para obtener las direcciones IP's de los hosts con el puerto ssh estándar abierto detectados en una red. 

Este script hace un escaneo con nmap y almacena la lista ordenada de ips en un fichero: /var/log/sshservers.log

#!/bin/bash

RED="172.19.144.0/24"
PUERTO=22

nmap -p $PUERTO $RED | grep -B 3 "open" | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' | sort | uniq > /var/log/sshservers.log

echo Listo!
echo "Examina el fichero /var/log/sshservers.log para ver las IPs de los hosts de la red $RED con el puerto $PUERTO abierto"

Si os fijáis, el script tiene definidas dos variables: Una para la red y otra para el puerto. De este modo, podemos personalizarlo para escanear otra red u otro puerto.

lunes, 13 de mayo de 2013

Script para detectar máquinas encendidas en una red local

A veces necesitamos detectar qué máquinas están encendidas en nuestra red local y hacerlo desde un script. Para ello podemos usar muchas herramientas. Una de las que utilizo habitualmente es fping

fping está disponible en los repositorios de Debian. De manera, que si queremos usarlo, no tenemos más que instalarlo con apt-get, por ejemplo:

# apt-get -y install fping

A continuación muestro un ejemplo de script que escanea mi red y me almacena un archivo (/var/log/escaneo.log) con la lista de ips de las máquinas que se encuentran encendidas en el momento de ejecutarlo.

#!/bin/bash

RED="172.19.144.0/23"
#RED="172.19.144.1 172.19.144.50"

fping -g $RED 2>/dev/null | grep alive | cut -f1 -d" " 1> /var/log/escaneo.log

echo Listo!
Como podéis ver en el script, a fping podemos indicarle:
  • Un rango de red mediante la sintaxis ip/máscara. Por ejemplo: 172.19.144.0/23
  • Un intervalo de máquinas. Por ejemplo: 172.19.144.1 172.19.144.50. Esto haría un fping a las máquinas con IP entre la 1 y la 50 de la subred 172.19.144

domingo, 12 de mayo de 2013

Instalar ROM JELLYBLAST v3 en Galaxy Mini/Pop Plus - GT-S5570I

Hace mucho tiempo que tenía ganas de cambiarle la stock rom al pequeñín, pero no encontraba el momento ni el tiempo necesario. Así que ayer por la mañana le dediqué un ratito y le instalé la JELLYBLAST V3
La verdad es que no he tenido mucho tiempo de probarla pero lo que he visto me ha gustado mucho: Una rom fluida y con un aspecto agradable. 
Vamos a ver a continuación el proceso de instalación. No obstante, para una información completa acerca de esta ROM, os recomiendo visitar su espacio en xda-developers:
Como siempre, recordar que esta ROM es para el Samsung Galaxy Mini/Pop Plus GT-S5570I. No es para el GT-S5570. Aunque pudieran parecer el mismo dispositivo, tienen un hardware diferente.

Lo primero e imprescindible para flashear cualquier dispositivo con una nueva ROM es tenerlo rooteado. Si aún no lo habéis rooteado, podéis hacerlo siguiendo las  instrucciones del siguiente post:
http://enavas.blogspot.com.es/2012/09/rootear-galaxy-minipop-plus-gt-s5570i.html

Partiendo de que tenemos nuestro dispositivo rooteado, lo encendemos, lo conectamos a nuestro ordenador mediante usb y le copiamos tres cosas en la raiz de la tarjeta SD:
Una vez que tenemos todo copiado, lo desconectamos y apagamos.

Estando apagado, pulsamos simultáneamente las teclas Vol. Up+Power+Home para entrar en el modo recovery, como se muestra en la siguiente imagen:

Al entrar en el modo recovery, se nos mostrará un menú con 4 opciones:
  • reboot system now
  • apply update from sdcard
  • wipe data/factory reset
  • wipe cache partition
Usaremos las teclas de volumen para desplazarnos por el menú hacia arriba o hacia abajo y la tecla Home para elegir una opción.

Seleccionamos apply update from sdcard. Al seleccionar esta opción, se nos mostrará el contenido de la SD card. 

Seleccionamos el archivo CWM_GT-S5570i.zip, que nos va a permitir cargar el Clockworkmod Recovery y ya estaremos dentro de él:


Como podemos ver en la imagen anterior, tenemos 8 opciones:
  • reboot system now
  • apply update.zip
  • wipe data / reset
  • wipe cache partition
  • install zip from sd
  • backup and restore
  • mounts and storage
  • advanced
Os recomiendo, antes de nada, seleccionar la opción "backup and restore" para hacer un backup del sistema. Al seleccionar esta opción se nos mostrarán tres opciones:
  • Backup
  • Restore
  • Advanced Restore
Elegid Backup y haréis un backup de vuestra Nandroid.

Bueno, una vez hecho el backup, volvemos al menú principal, pulsando el botón de retroceso que hay a la derecha del botón Home.

Estando en el menú principal, seleccionamos wipe data / reset.

Cuando termine el proceso anterior, hacemos un wipe cache partition.

A continuación, seleccionamos la opción advanced en el menú principal para entrar en el menú avanzado y hacemos un Wipe Dalvik Cache.

Una vez hechos los tres "Wipes", volvemos al menú principal y seleccionamos la opción "install zip from sd" Se nos mostrará un menú con 4 opciones.

Elegimos "choose zip from sdcard".Se nos mostrará el contenido de la tarjeta SD. 

Elegimos el archivo que contiene la ROM con la que vamos a flashear nuestro dispositivo: S5570i-JBlastv303.signed.zip

Seleccionamos "yes" para confirmar que queremos instalar la ROM y comenzará el proceso de flasheo.

Una vez terminado, reiniciamos nuestro teléfono. Como nos indican en la web, el primer inicio tardará un poquito. No os preocupéis porque es normal. Esperad a que termine de realizarse el escaner de medios y dejadlo que inicie normalmente.

Una vez que nuestro teléfono haya arrancado, tendremos que volver a entrar en Clockworkmod Recovery para instalar el kernel COR PLENUS.

Entrar en Clockworkmod Recovery una vez que tenemos la rom JELLYBLAST ya es muy sencillo. Mantenemos pulsado el botón de apagado y se nos mostrará un menú de opciones. Si elegimos la que dice "Clockwork Mod", se reiniciará el teléfono y entrará directamente en el Recovery.

Una vez que estemos de nuevo en el Clockworkmod Recovery, desde el menú principal seleccionamos la opción "install zip from sd" Se nos mostrará un menú con 4 opciones.

Elegimos "choose zip from sdcard".Se nos mostrará el contenido de la tarjeta SD. 

Elegimos el archivo que contiene el kernel que queremos montar en nuestro dispositivo: CorPlenusv2.02-randomboot.zip

Y lo instalamos.

martes, 7 de mayo de 2013

Actualizar de Debian Squeeze a Debian Wheezy

Ahora que Debian Wheezy ya es la rama estable de Debian, podemos actualizar nuestro Squeeze de la siguiente manera:

Hacemos un upgrade de forma que nuestro Squeeze se encuentre completamente actualizado:
# apt-get update && apt-get -y upgrade && apt-get -y dist-upgrade

Hacemos una copia de nuestro sources.list, por si pudiéramos necesitarlo:
# cp /etc/apt/sources.list /etc/apt/sources.list.squeeze

Creamos un sources.list con los repositorios de Wheezy:
echo "deb http://ftp.de.debian.org/debian wheezy main contrib non-free\ndeb-src http://ftp.de.debian.org/debian wheezy main contrib non-free\ndeb http://ftp.de.debian.org/debian wheezy-updates main contrib non-free\ndeb http://ftp.de.debian.org/debian-security wheezy/updates main contrib non-free" > /etc/apt/sources.list

Por último, actualizamos nuestro sistema a Wheezy:
# apt-get update && apt-get -y upgrade && apt-get -y dist-upgrade

viernes, 3 de mayo de 2013

Montar clonezilla live en el disco duro de nuestros portátiles

Con la última imagen que se montó en los portátiles de los centros el disco duro tiene las siguientes particiones:
  • /dev/sda1 -> Contiene el sistema de arranque: /boot
  • /dev/sda2 -> Contiene el sistema raiz: /
  • /dev/sda3 -> Tiene el mismo tamaño que la partición /dev/sda2. Está vacía.
  • /dev/sda4 -> Es la partición extendida
  • /dev/sda5 -> Es el área de swap.
  • /dev/sda6 -> Contiene el home del usuario
Aprovechando que la partición sda3 está vacía, podemos montar clonezilla live en ella, guardar allí una imagen de restauración del portátil  y crear una entrada de grub para autorestaurarlo cuando haya algún problema que nos lleve demasiado tiempo solucionar.

Además, podemos crear la entrada de autorestauración a de forma que restaure tan sólo las particiones necesarias: sda1 y sda2. De este modo conseguimos dos cosas:
  • Reducir el tiempo de restauración del portátil.
  • Evitar que el usuario pierda los archivos almacenados en su home (que se encuentran en /dev/sda6) cada vez que restauremos el sistema.
Vamos a ver cómo hacerlo, suponiendo que estamos preparando un portátil modelo y no queremos arrancar su sistema operativo:
  • Arrancamos el portátil con un pendrive donde tengamos montado clonezilla live y, en lugar de seleccionar la opción "Start_Clonezilla", elegimos "Enter_Shell":

  • Una vez que tengamos un shell, nos convertimos en usuario administrador y montamos la partición /dev/sda3 en /mnt:
    # sudo -i
    # mount /dev/sda3 /mnt 
    
  • A continuación descargamos el fichero zip de clonezilla live. Por ejemplo, para descargar la última versión disponible a día de hoy (03/05/2013):
    # wget --trust-server-name http://sourceforge.net/projects/clonezilla/files/clonezilla_live_stable/2.1.1-25/clonezilla-live-2.1.1-25-i686-pae.zip/download 
    
  • Una vez descargado, lo descomprimimos directamente en /mnt (es decir, en nuestra sda3):
    # unzip clonezilla-live-*.zip -d /mnt
  • A continuación renombramos el directorio "live" que ya tenemos en /mnt y desmontamos /dev/sda3:
    # cd /mnt
    # mv live live-hd
    # umount /mnt
    
  • Lo siguiente que tengo que hacer es crear una entrada de grub. Como el sistema raiz está en la partición /dev/sda2, el boot en la partición /dev/sda1, y he arrancado con un sistema live, voy a montar todo y hago un chroot:
    
    # mount /dev/sda2 /mnt
    # mount /dev/sda1 /mnt/boot
    # mount --bind /dev /mnt/dev
    # mount --bind /proc /mnt/proc
    # mount --bind /sys /mnt/sys
    # chroot /mnt 
    
  • Bien, pues ahora que ya tengo el sistema del portátil montado en el chroot, voy  a crear una entrada de grub para clonezilla. Como en los portátiles tenemos instalado grub2, editamos el archivo /etc/grub.d/40_custom y añadimos las opciones que crean la entrada de menú:
    menuentry "Clonezilla" {
       set root=(hd0,3)
       linux /live-hd/vmlinuz boot=live live-config noswap nolocales edd=on nomodeset ocs_live_run=\"ocs-live-general\" ocs_live_extra_param=\"\" keyboard-layouts=\"\" ocs_live_batch=\"no\" locales=\"\" vga=788 ip=frommedia nosplash live-media-path=/live-hd bootfrom=/dev/sda3 toram=filesystem.squashfs
       initrd /live-hd/initrd.img
    } 
    
    Fijaos en que con "set root=(hd0,3)" estoy indicando que clonezilla está en el primer disco (hd0) y en la tercera partición. 
  • Una vez creado el archivo de configuración,  tendremos que hacer un "update-grub2" para crear el archivo de configuración grub.cfg
    # update-grub2
  • Y, por último, salir del chroot y desmontar:
    # exit
    # umount /mnt/sys
    # umount /mnt/proc
    # umount /mnt/dev
    # umount /mnt/boot
    # umount /mnt