Happy new year

A todos los lectores de puppetlinux
PuppetLinux - 2013

Leer más

Lo mejor de 2012: PuppetLinux

Para ir cerrando el año, os dejo un listado de los post más leídos de este año que va a terminar. Para el año 2013, intentaré aumentar la calidad de los post, pero sin perder la dinámica que caracteriza este blog.
  • Alertas Zabbix a Twitter
    ¿Usas Zabbix para monitorizar y tener alertas de tus sistemas? En este pequeño post se escenifica cómo hacer para enviar todas las alertas a Twitter y así poder leerlas de manera sencilla, por ejemplo desde nuestro smartphone.
  • Cómo agregar un repositorio a RedHat
    Pequeño ejemplo de cómo agregar un repositorio nuevo a nuestra distribución Red Hat/CentOS.
  • Liberar memoria en Google Chrome
    El navegador de Google fue sin dudarla el gran beneficiado de este año, aumentando significativamente si presencia en la red. Este pequeño truco indica cómo hacer para liberar memoria de forma muy sencilla del navegador, si usas un gran número de pestañas o lleva varios días abierto.
  • Manejar repositorios RedHat
    Si enseñamos cómo agregar un repositorio a nuestro sistema Red Hat/CentOS también tendremos que saber cómo manejar los repositorios disponibles.
  • Autenticación en linux vía USB
    Quieres usar un pendrive para iniciar sesión y proteger tus datos de forma muy sencilla. Léelo y mira cómo se hace!
  • Cluster MySQL (master-master vs. master-slave)
    En estes dos post se hace paso a paso el montaje de un sistema MySQL distribuido. Si tienes un sistema importante, quizás te interese saber cómo aumentar la disponibilidad de la base de datos.

La entrada Lo mejor de 2012: PuppetLinux la puedes leer en Puppet Linux.
Leer más

Control de sesiones Zimbra desde Zabbix


Zimbra ofrece muy buenas herramientas para extraer, tanto desde el interfaz gráfico como desde línea de comandos, información y estado de toda la actividad. Si deseamos tener un perfecto control de nuestros sistemas, de cuanta más información dispongamos, mejor que mejor. Aunque siempre hay que tener un balanceo entre la información recadada, la procesada y el tiempo de cada una.
Sin embargo, con información fácil de extraer siempre es útil tenerla presente y éste es el caso de las sesiones activas y las cuentas que tiene Zimbra. Con la ejecución de un simple comando, zmsoap -z -t admin DumpSessionsRequest, podemos obtener información interesante del uso de nuestro servidor Zimbra.
shell> zmsoap -z -t admin DumpSessionsRequest
<DumpSessionsResponse activeSessions="21" xmlns="urn:zimbraAdmin">
  <soap activeAccounts="4" activeSessions="8"/>
  <imap activeAccounts="7" activeSessions="13"/>
</DumpSessionsResponse>

Como podemos observar, tenenemos el número de sesiones activas en Zimbra en el momento de la ejecución, por lo que si lo ejecutamos periódicamente podemos obtener unas buenas estadísticas del uso del sistema de correo a lo largo del tiempo, lo que ayudaría a prevenir problemas o a dar respuesta a problemas encontrados. Como de lo que estamos hablando es de monitorización, estamos hablando de Zabbix! En el foro de Zabbix, stefaan dejó un script que hacía lo mismo, así que simplemente lo vamos a adaptar para nuestros intereses y propósitos.
#!/usr/bin/perl

use XML::Simple;
use Data::Dumper;

my $num_args = $#ARGV + 1;
if ($num_args != 1) {
   print "Usage: zabbix_sessions <Accounts|Sessions>\n";
   exit;
} else {
   $parm = $ARGV[0];
   $xml = new XML::Simple;
   $xmldata = `/bin/su -c 'zmsoap -z -t admin DumpSessionsRequest' \
               - zimbra`;
   $data = $xml->XMLin($xmldata);
   if ($parm eq "sessions") {
      if($data->{activeSessions} eq ""){
         print "0";
      } else {
         print $data->{activeSessions};
      }
   }
   
   if ($parm eq "soapaccounts") {
      if($data->{soap}{activeAccounts} eq ""){
         print "0";
      } else {
         print $data->{soap}{activeAccounts};
      }
   }
   
   if ($parm eq "soapsessions") {
      if($data->{soap}{activeSessions} eq ""){
         print "0";
      } else {
         print $data->{soap}{activeSessions};
      }
   }
   
   if ($parm eq "imapaccounts") {
      if($data->{imap}{activeAccounts} eq ""){
         print "0";
      } else {
         print $data->{imap}{activeAccounts};
      }
   }
   
   if ($parm eq "imapsessions") {
      if($data->{imap}{activeSessions} eq ""){
         print "0";
      } else {
         print $data->{imap}{activeSessions};
      }
   }
}
Como siempre, necesitamos darle permisos a dicho script para que el usuario zabbix lo pueda ejecutar y también modificar el fichero de configuración del agente, para crear una nueva key, en este caso zimbra.users.
zabbix ALL= NOPASSWD: /usr/local/bin/zabbix_sessions
Y en el agente, creamos la nueva key,
UserParameter=zimbra.users[*], /usr/bin/sudo /usr/local/bin/zabbix_sessions $1

Los parámetros que acepta son: sessions, soapaccounts, soapsessions, imapaccounts e imapsessions. Ya sólo nos queda crear los item's de monitorización.
Como el valor que se almacena es de tipo numérico, si es necesario crear un trigger para algún valor en concreto será muy simple de hacer.
Leer más

Backup de la configuración en Cisco

Si hace unos días intentaba explicar cómo realizar un backup automático de un router Enterasys desde una shell en Linux, hoy toca seguir profundizando en elementos de red, en este caso en router's Cisco, éstos quizás más conocidos y habituales en muchos entornos de trabajo.
En este caso, vamos a ver cómo se realiza un backup completo de la configuración del router, para más adelante poder automatizarlo. Aunque en una serie de pequeños post a modo de chuletas Cisco y los comandos en IOS ya se ha comentado, aquí vamos a ver cómo realizar de forma completa, no solamente citando el comando.
Partimos de un switch Cisco y de un servidor tftp montado en la misma red de acceso y desde el modo de configuración observamos el comando write-memory que no hace otra cosa que volcar todo el contenido de la memoria a un fichero que se deposita en el sistema raíz del equipo.
Router(config-archive)# ?
Archive configuration commands:
  ...
  write-memory  Enable automatic backup generation during write memory
Por lo tanto, entrando en modo de configuración, accedemos al path sobre el que deseamos hacer la copia y volcamos todo el contenido de la configuración en el fichero. Por defecto creará un nombre que será el nombre del router y la fecha de creación.
R0# conf t
Enter configuration commands, one per line.  End with CNTL/Z.
R0(config)#archive
R0(config-archive)#path disk0:R0
R0(config-archive)#write-memory
R0(config-archive)#end
Si en vez de dejarlo en el mismo equipo lo que nos interesa es sacar una copia, únicamente habrá que indicar otro path, en este caso un path remoto, vía tftp, tal como sigue.
R0(config-archive)# path tftp://10.10.10.10/R0/
Ahora escribirá el contenido de la memoria en el servidor remoto, quedándonos así con una copia de la configuración del equipo.
Más vale prevenir... que luego volver a configurar ;-)
Leer más

MySQL multimaster: trucos

Si ya habéis leído el post sobre cómo montar un sistema MySQL con dos nodos activos, podréis ver que esa configuración presenta varias deficiencias. Una de las más notorias y que además es casi fijo que os suceda es un fallo a la hora de sincronizar datos si éstos tienen un campo que sea un ID autoincremental.
En una arquitectura master - slave, como sólo se escribe en uno de los nodos, no hay problema, pero en master - master, cada vez que se escriba el auto-incremental se va a aumentar en uno, pudiendo colisionar cuando lleguen los datos del otro nodo. Y si la tabla está diseñada para que no puedan existir datos con ID's duplicados, ya tenemos el lío montado!
Por suerte, MySQL tiene tiene una solución para este problema, que no es otra que indicarle a un nodo que emplee los autoincrementales pares y al otro nodo los impares. De esta forma, cuando se sincronicen los datos, siempre serán correctos y nunca habrá ID's replicados. Para lograr esto, simplemente en el fichero de configuración (/etc/my.cnf) de cada uno de los nodos tendremos que tener lo siguiente,
  • M1: Números pares
    auto_increment_increment = 2
    auto_increment_offset    = 1
    
  • M2: Números impares
    auto_increment_increment = 2
    auto_increment_offset    = 2
    
Lógicamente si aun aplicación es la encargada de realizar los insert's habrá que controlar en función del servidor destino el ID que deba escribir, evitando siempre escribir duplicados para que sea así posible la sincronización de los datos.
Leer más

MySQL Active -- Active (multimaster)

Hace unos días hablamos aquí de cómo poder montar una arquitectura master - slave en MySQL y los beneficios de la misma. Hoy vamos a ver cómo crear un sistema en MySQL master - master (o multimaster) y los beneficios del mismo.
En la gran mayoría de los casos, un sistema master - slave será lo ideal y ofrecerá una buena estabilidad entre rendimiento y fiabilidad. En este caso, lo que se favorece es un gran número de lecturas, frente a un número considerablemente bajo de escrituras. Por el contrario, la nueva acquitectura master - master, lo que favorecerá será a un gran número de escrituras, frente a un número normal o bajo de lecturas. Se escribe más de lo que se lee, de ahí que nos interese dividir los servidores de escritura.
Montar un sistema master - master realmente es configurar en ambos sentidos un sistema master - slave. El Master-1 será el slave del Master-2 y viceversa. Todo lo que se escriba en Master-2 será replicado automática a Master-1 y todo lo que se escriba en Master-1 será replicado automática a Master-2.
Los datos de los que partimos serán:
  • M1 -- 192.168.0.33 -- id: 1
  • M2 -- 192.168.0.35 -- id: 2
En ambos nodos se cuenta con una versión 5.5.x de MySQL previamente instalada, por lo que únicamente explicaremos el proceso de replicación. Puesto que prácticamente lo que se haga en el primer nodo lo tendremos que ejecutar en el segundo, simplemente haremos un cambio del prompt de MySQL, para saber en qué equipo estamos en cada momento.
  1. Configuramos los servidores
    Aquí únicamente tendremos que configurar el fichero de configuración de MySQL (/etc/my.cfg) de ambos nodos. La configuración es similar a la de la arquitectura master-slave, pero como salvedad en este caso únicamente haremos réplica máster-máster de una base de datos.
    log-bin          = mysql-bin
    binlog-do-db     = BD_master
    binlog-ignore-db = mysql
    binlog-ignore-db = test
    server-id        = 1
    
    Y aplicamos la misma configuración para M2, salvo por el server-id.
    log-bin          = mysql-bin
    binlog-do-db     = BD_master
    binlog-ignore-db = mysql
    binlog-ignore-db = test
    server-id        = 2
    
  2. Reiniciamos el servicio MySQL
    M1@shell> service mysqld restart
    
    En ambos nodos...
    M2@shell> service mysqld restart
    
  3. Creamos un backup de los datos
    El equipo M1 es el que contiene los datos de origen, así que serán los que empleemos para crear el clúster. Por lo tanto, haremos un backup de los mismos,
    M1@shell> mysqldump -u root -p --master-data=2 > all.sql
    
  4. Posición del log para replicación
    Y al igual que sucede al crear un slave, necesitamos saber en qué punto del binary log estamos situados, para indicar que será a partir de ese punto desde donde deba comenzar a replicar. Para eso, simplemente desde el servidor M1, ejecutamos:
    mysql@M1> SHOW MASTER STATUS;
    +------------------+----------+--------------+------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +------------------+----------+--------------+------------------+
    | mysql-bin.000001 |       98 |              |                  | 
    +------------------+----------+--------------+------------------+
    
    1 row in set (0.00 sec)
    
  5. Importamos los datos en M2
    Importamos los datos que sacamos del servidor M1 al servidor M2 para partir de los mismos datos de origen. Previamente a este importado, tendremos que pasar el fichero all.sql de M1 a M2.
    mysql@M2> SOURCE /home/javier/all.sql
    
  6. Creamos el usuario de replicación
    Puesto que ambos nodos se replican el uno del otro, tendremos que crear un usuario en cada uno de los servidores.
    mysql@M1> GRANT REPLICATION SLAVE, REPLICATION CLIENT 
           -> ON *.* 
           -> TO remote_user@'192.168.0.35' 
           -> IDENTIFIED BY 'remote_user_passwd';
    
    Lo mismo para el segundo master.
    mysql@M2> GRANT REPLICATION SLAVE, REPLICATION CLIENT 
           -> ON *.* 
           -> TO remote_user@'192.168.0.33' 
           -> IDENTIFIED BY 'remote_user_passwd';
    
  7. Configuramos la replicación de datos
    mysql@M1> CHANGE MASTER TO MASTER_HOST='192.168.0.35',
           -> MASTER_USER = 'remote_user',
           -> MASTER_PASSWORD = 'remote_user_passwd',
           -> MASTER_LOG_FILE = 'mysql-bin.000001 ',
           -> MASTER_LOG_POS = 98;
    
    mysql@M2> CHANGE MASTER TO MASTER_HOST='192.168.0.33',
           -> MASTER_USER = 'remote_user',
           -> MASTER_PASSWORD = 'remote_user_passwd',
           -> MASTER_LOG_FILE = 'mysql-bin.000001 ',
           -> MASTER_LOG_POS = 98;
    
  8. Arrancamos los procesos slave's en ambos nodos
    mysql@M1> START SLAVE;
    
    mysql@M2> START SLAVE;
    
Y con esto ya tenemos un sistema de MySQL activo - activo, o lo que es lo mismo un slave de cada uno de los master's.
Leer más

Debian, distro padre


Aunque este gráfico suele estar muy presente en todos los blog y se habla muy a menudo, recientemente lo volví a ver en futurist.se y la verdad es que quedé sorprendido de la cantidad de distribuciones que salieron de Debian. No es por decir que es la mejor, ni de lejos, pero si se puede afirmar que es la distro padre de la gran mayoría.
Os dejo el enlace a la original y la comparación.

Leer más

Zabbix trigger report

Supongo que no seré el único que muchas veces está trabajando con Zabbix y necesita tener rápidamente un listado de todos los equipos afectados por un determinado trigger. Recientemente desarrollé un pequeño módulo que se agrega a la pestaña Reports de Zabbix y que ofrece un listado de todos aquellos triggers que están activos y una dirección de correo a la que enviar el listado. Si estás trabajando y alguien te pregunta ¿qué equipos tienen la carga alta? Ahora la respuesta será muy sencilla: "Te lo paso por mail".
Si te interesa lo puedes descargar desde aquí y tras copiarlo a tu directorio raíz con el nombre trigger_report.php ya sólo necesitas editar el fichero include/menu.inc.php y agregar estas líneas dentro del array de reports.
array(
   'url' => 'trigger_report.php',
   'label' => _('Trigger reports'),
   'user_type' => USER_TYPE_SUPER_ADMIN
)
El resultado es el que se muestra en la imagen lateral, en la que sólo salen aquellos trigger's que están activos. A continuación nos pide un mail al que enviar los resultados. Tras darle a enviar, haciendo uso de la API de zabbix, se enviará el listado de los equipos afectados por el trigger que se ha seleccionado.




Leer más

OpenSSH, permitir acceso por usuarios/grupos

En el post anterior hablamos de cómo poder bloquear el acceso ssh a un equipo mediante las directivas DenyUsers y DenyGroups. Ahora toca hablar de cómo poder permitir el acceso a un equipo por ssh, para lo que existen las directivas AllowUsers y AllowGroups.
Antes de nada, hay que aclarar que por defecto, si no se emplea ninguna directiva, TODOS los usuarios del sistema pueden acceder por ssh al equipo, pero que en caso de que alguna de las directivas de acceso estén habilitadas, sólo lo podrán hacer aquellos que la cumplan.
Entonces... ¿para qué sirven las directivas Allow*?
Pues bien, sirven para tener un mayor control de usuarios que pueden acceder siempre que el número de estos vaya a ser menor que el número de usuarios que no, sino, tendría más sentidos usar las vistas anteriormente.
Al igual que para Deny*, también tenemos control de usuarios y grupos.
  • AllowUsers
    AllowUsers user1 user2
    
  • AllowGroups
    AllowGroups grupo_acceso_ssh
    
Nota: No está permitido usar UID's o GID's para especificar a los usuarios.
Leer más

Extraño fallo al actualizar Ubuntu


Aunque eEste es un curioso fallo que me pasó cuando estaba actualizando una estación de trabajo con Ubuntu 12.04. Aunque el fallo no tenía gran sentido, lo comento a continuación por si a alguien más le sucede que pueda ver cómo yo lo solucioné.

shell> apt-get dist-upgrade
Leyendo lista de paquetes... Hecho
...
Preconfigurando paquetes ...
(Leyendo la base de datos ... 266542 ficheros o directorios instalados actualmente.)
Desempaquetando linux-headers-3.5.0-13 (de .../linux-headers-3.5.0-13_3.5.0-13.13_all.deb) ...
dpkg-deb (subproceso): datos: error interno de lectura de gzip `: data error'
dpkg-deb: error: el subproceso  devolvió el código de salida de error 2
dpkg: error al procesar /var/cache/apt/archives/linux-headers-3.5.0-13_3.5.0-13.13_all.deb (--unpack): el subproceso dpkg-deb --fsys-tarfile devolvió el código de salida de error 2
No se escribió ningún informe «apport» porque ya se ha alcanzado el valor de «MaxReports»
                                                                           ...
Se encontraron errores al procesar:
 /var/cache/apt/archives/linux-headers-3.5.0-13_3.5.0-13.13_all.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)
Al realizar un upgrade del sistema, éste intenta instalar el paquete linux-headers-3.5.0-13_3.5.0-13.13_all.deb, pero terminada dando un fallo que impide su instalación, dejando el sistema de paquetes "tocado".
Lo primero que se me ocurre es forzar la instalación de los paquetes, para ver si ésto soluciona el problema.
shell> apt-get install -f
...
Los paquetes indicados a continuación se instalaron de forma automática y ya no son necesarios.
  linux-headers-3.2.0-23 linux-headers-3.2.0-24 linux-headers-3.2.0-24-generic linux-headers-3.2.0-23-generic-pae linux-headers-3.2.0-24-generic-pae
  linux-headers-3.2.0-23-generic
Utilice «apt-get autoremove» para eliminarlos.
Se instalarán los siguientes paquetes extras:
  linux-headers-3.5.0-13
Se instalarán los siguientes paquetes NUEVOS:
  linux-headers-3.5.0-13
0 actualizados, 1 se instalarán, 0 para eliminar y 1 no actualizados.
20 no instalados del todo o eliminados.
Se necesita descargar 0 B/12,2 MB de archivos.
Se utilizarán 58,7 MB de espacio de disco adicional después de esta operación.
¿Desea continuar [S/n]? 
(Leyendo la base de datos ... 266542 ficheros o directorios instalados actualmente.)
Desempaquetando linux-headers-3.5.0-13 (de .../linux-headers-3.5.0-13_3.5.0-13.13_all.deb) ...
dpkg-deb (subproceso): datos: error interno de lectura de gzip `: data error'
dpkg-deb: error: el subproceso  devolvió el código de salida de error 2
dpkg: error al procesar /var/cache/apt/archives/linux-headers-3.5.0-13_3.5.0-13.13_all.deb (--unpack):
 el subproceso dpkg-deb --fsys-tarfile devolvió el código de salida de error 2
Se encontraron errores al procesar:
 /var/cache/apt/archives/linux-headers-3.5.0-13_3.5.0-13.13_all.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)
Aunque obtenemos el mismo fallo al intentar instalar el paquete. Así que vamos a optar por desinstalarlo  ya que además son las cabeceras de una versión del kernel que no estaba siendo usada.
shell> apt-get remove --purge linux-headers-3.5.0-13
Leyendo lista de paquetes... Hecho
Creando árbol de dependencias       
Leyendo la información de estado... Hecho
El paquete linux-headers-3.5.0-13 no está instalado, no se eliminará
Tal vez quiera ejecutar «apt-get -f install» para corregirlo:
Los siguientes paquetes tienen dependencias incumplidas:
 linux-headers-3.5.0-13-generic : Depende: linux-headers-3.5.0-13 pero no va a instalarse
E: Dependencias incumplidas. Intente «apt-get -f install» sin paquetes (o especifique una solución).
Nuevamente no nos lo permite hacer y nos indica que la forma solucionarla es una que ya probamos con anterioridad y no funcionó.
La solución encontrada viene de la mano de dpkg y es la siguiente.
shell> dpkg --remove --force-remove-reinstreq linux-headers-3.5.0-13-generic
(Leyendo la base de datos ... 266541 ficheros o directorios instalados actualmente.)
Desinstalando linux-headers-3.5.0-13-generic ...
shell> apt-get clean
Tras ello, volvemos a intentar instalar todos los paquetes que tengamos pendientes y parece que ya todo está correcto.
shell> apt-get install -f
Leyendo lista de paquetes... Hecho
Creando árbol de dependencias       
Leyendo la información de estado... Hecho
Corrigiendo dependencias... Listo
Los paquetes indicados a continuación se instalaron de forma automática y ya no son necesarios.
  linux-headers-3.2.0-23 linux-headers-3.2.0-24 linux-headers-3.2.0-24-generic linux-headers-3.2.0-23-generic-pae linux-headers-3.2.0-24-generic-pae
  linux-headers-3.2.0-23-generic
Utilice «apt-get autoremove» para eliminarlos.
Se instalarán los siguientes paquetes extras:
  linux-headers-3.5.0-13 linux-headers-3.5.0-13-generic
Se instalarán los siguientes paquetes NUEVOS:
  linux-headers-3.5.0-13 linux-headers-3.5.0-13-generic
0 actualizados, 2 se instalarán, 0 para eliminar y 0 no actualizados.
20 no instalados del todo o eliminados.
Necesito descargar 13,2 MB de archivos.
Se utilizarán 69,9 MB de espacio de disco adicional después de esta operación.
¿Desea continuar [S/n]? 
Des:1 http://ppa.launchpad.net/xorg-edgers/ppa/ubuntu/ precise/main linux-headers-3.5.0-13 all 3.5.0-13.13 [12,2 MB]
Des:2 http://ppa.launchpad.net/xorg-edgers/ppa/ubuntu/ precise/main linux-headers-3.5.0-13-generic i386 3.5.0-13.13 [1.010 kB]
Descargados 13,2 MB en 3seg. (3.743 kB/s)             
(Leyendo la base de datos ... 257690 ficheros o directorios instalados actualmente.)
Desempaquetando linux-headers-3.5.0-13 (de .../linux-headers-3.5.0-13_3.5.0-13.13_all.deb) ...
Seleccionando paquete linux-headers-3.5.0-13-generic previamente no seleccionado
Desempaquetando linux-headers-3.5.0-13-generic (de .../linux-headers-3.5.0-13-generic_3.5.0-13.13_i386.deb) ...
Configurando libllvm3.1 (3.1-1~precise1) ...
Configurando libgl1-mesa-dri (9.0~git20120901+9.0.6886da78-0ubuntu0ricotz2~precise) ...
Configurando libxatracker1 (9.0~git20120901+9.0.6886da78-0ubuntu0ricotz2~precise) ...
Configurando linux-image-3.5.0-13-generic (3.5.0-13.13) ...
Running depmod.
update-initramfs: deferring update (hook will be called later)
Examining /etc/kernel/postinst.d.
run-parts: executing /etc/kernel/postinst.d/initramfs-tools 3.5.0-13-generic /boot/vmlinuz-3.5.0-13-generic
update-initramfs: Generating /boot/initrd.img-3.5.0-13-generic
run-parts: executing /etc/kernel/postinst.d/pm-utils 3.5.0-13-generic /boot/vmlinuz-3.5.0-13-generic
run-parts: executing /etc/kernel/postinst.d/update-notifier 3.5.0-13-generic /boot/vmlinuz-3.5.0-13-generic
run-parts: executing /etc/kernel/postinst.d/zz-update-grub 3.5.0-13-generic /boot/vmlinuz-3.5.0-13-generic
Generating grub.cfg ...
Found linux image: /boot/vmlinuz-3.5.0-13-generic
Found initrd image: /boot/initrd.img-3.5.0-13-generic
Found linux image: /boot/vmlinuz-3.2.0-24-generic
Found initrd image: /boot/initrd.img-3.2.0-24-generic
Found linux image: /boot/vmlinuz-3.2.0-23-generic
Found initrd image: /boot/initrd.img-3.2.0-23-generic
Found memtest86+ image: /boot/memtest86+.bin
done
Configurando libhpmud0 (3.12.2-1ubuntu3.1) ...
Configurando libsane-hpaio (3.12.2-1ubuntu3.1) ...
Configurando hplip-data (3.12.2-1ubuntu3.1) ...
Configurando printer-driver-hpcups (3.12.2-1ubuntu3.1) ...
Configurando hplip (3.12.2-1ubuntu3.1) ...
Creating/updating hplip user account...
Configurando printer-driver-postscript-hp (3.12.2-1ubuntu3.1) ...
Configurando libcrystalhd3 (1:0.0~git20110715.fdd2f19-4.1) ...
Configurando linux-headers-3.5.0-13 (3.5.0-13.13) ...
Configurando linux-headers-3.5.0-13-generic (3.5.0-13.13) ...
Configurando linux-headers-generic (3.5.0.13.13) ...
Configurando linux-image-extra-3.5.0-13-generic (3.5.0-13.13) ...
Running depmod.
update-initramfs: deferring update (hook will be called later)
Examining /etc/kernel/postinst.d.
run-parts: executing /etc/kernel/postinst.d/initramfs-tools 3.5.0-13-generic /boot/vmlinuz-3.5.0-13-generic
update-initramfs: Generating /boot/initrd.img-3.5.0-13-generic
run-parts: executing /etc/kernel/postinst.d/pm-utils 3.5.0-13-generic /boot/vmlinuz-3.5.0-13-generic
run-parts: executing /etc/kernel/postinst.d/update-notifier 3.5.0-13-generic /boot/vmlinuz-3.5.0-13-generic
run-parts: executing /etc/kernel/postinst.d/zz-update-grub 3.5.0-13-generic /boot/vmlinuz-3.5.0-13-generic
Generating grub.cfg ...
Found linux image: /boot/vmlinuz-3.5.0-13-generic
Found initrd image: /boot/initrd.img-3.5.0-13-generic
Found linux image: /boot/vmlinuz-3.2.0-24-generic
Found initrd image: /boot/initrd.img-3.2.0-24-generic
Found linux image: /boot/vmlinuz-3.2.0-23-generic
Found initrd image: /boot/initrd.img-3.2.0-23-generic
Found memtest86+ image: /boot/memtest86+.bin
done
Configurando linux-image-generic (3.5.0.13.13) ...
Configurando postfix (2.9.3-2~12.04.3) ...

Postfix configuration was not changed.  If you need to make changes, edit
/etc/postfix/main.cf (and others) as needed.  To view Postfix configuration
values, see postconf(1).

After modifying main.cf, be sure to run '/etc/init.d/postfix reload'.

Running newaliases
 * Stopping Postfix Mail Transport Agent postfix          [ OK ] 
 * Starting Postfix Mail Transport Agent postfix          [ OK ] 
Configurando printer-driver-hpijs (3.12.2-1ubuntu3.1) ...
Configurando vlc-nox (2.0.3-0ubuntu0.12.04.1) ...
Configurando vlc-plugin-notify (2.0.3-0ubuntu0.12.04.1) ...
Configurando vlc (2.0.3-0ubuntu0.12.04.1) ...
Configurando vlc-plugin-pulse (2.0.3-0ubuntu0.12.04.1) ...
Procesando disparadores para libc-bin ...
ldconfig deferred processing now taking place
Leer más

Apache, Prefork vs. Worker

Apache es el servidor web por excelencia. Es uno de los más conocidos y sin dudarlo el más usado a nivel de software libre. Este servidor tiene dos formas completamente diferentes de trabajar y de gestionar las conexiones y los hilos. Una es Prefork y otra es Worker. Por defecto, la instalación de Apache, especialmente si lo empleas con módulos php usa la primera, por que la considera más eficiente, pero depende de para qué y de la cantidad de visitas que vayas a tener, emplear uno u otra puede mejorar mucho el rendimiento de tu sistema.
A continuación vamos a mostrar las diferencias entre una y otra, para que así quede más claro y la decisión de usar una u otra sea más fácil de tomar.
MPM PreforkMPM Worker
Activado por defecto en Apache.
No está habilitado por defecto y para activarlo es necesario alterar la configuración de Apache.
El manejo de las peticiones es muy similar a cómo lo hacía la versión 1.3.

Mucho más fácil de usar con instalaciones de php, lo que lo hace más estable y seguro.
El manejo de páginas en php se le hace más complicado.
Maneja cada petición que se realiza de forma completamente independiente. Un proceso de Apache para cada cliente.
Al finalizar con un cliente el thread atiende a otro (MaxRequestsPerChild).
Presenta un modo de funcionamiento multiproceso-multihilo.
Un proceso puede desplegar varios hilos lo que facilita la respuesta a un gran número de clientes.
Tiene un número máximo de clientes a atender simultáneamente (max_clients).
No tiene un límite pre-establecido de clientes.
Necesita más recursos de CPU y memoria.
Necesita muchos menos recursos de CPU y de memoria, lo que ofrece una mejor escalabilidad.

Algunos módulos, especialmente de php, pueden no funcionar correctamente. Si se habilita hay que comprobar el correcto funcionamiento de éstos.
Es ideal para emplear con páginas dinámicas y pocas conexiones concurrentes.
Se usa para una elevada concurrencia de usuarios sobre páginas más o menos estáticas.
El empleo de uno u otro no es simplemente un cambio en la configuración, sino que el servidor Apache debe venir con uno u otro compilado (o emplear un módulo diferente para cada uno). Si te interesa saber qué MPM emplear tu Apache,
shell> apachectl -V
Server version:               Apache/2.2.16 (Debian)
Server built:                 Sep 13 2012 02:54:14
Server's Module Magic Number: 20051115:24
Server loaded:                APR 1.4.2, APR-Util 1.3.9
Compiled using:               APR 1.4.2, APR-Util 1.3.9
Architecture:                 64-bit
Server MPM:                   Prefork
  threaded:                   no
    forked:                   yes (variable process count)
...
shell> apache2 -l
Compiled in modules:
  core.c
  mod_log_config.c
  mod_logio.c
  prefork.c
  http_core.c
  mod_so.c
La configuración por defecto de Apache para ambos módulos es la siguiente (en debian).
<ifmodule mpm_prefork_module>
    StartServers          5
    MinSpareServers       5
    MaxSpareServers      10
    MaxClients          150
    MaxRequestsPerChild   0
</ifmodule>

<ifmodule mpm_worker_module>
    StartServers          2
    MinSpareThreads      25
    MaxSpareThreads      75
    ThreadLimit          64
    ThreadsPerChild      25
    MaxClients          150
    MaxRequestsPerChild   0
</ifmodule>
donde,
  • StartServers
    Número de procesos que arrancan al iniciar el servicio.
  • MinSpareServers
    Número de procesos iniciales en iddle que esperan una petición.
  • MaxSpareServers
    Número máximo de procesos en iddle esperando una petición.
  • MaxRequestsPerChild
    Número máximo de respuestas por hijo.
    Cuando un hijo excede este valor es automáticamente destruido y si es necesario un nuevo proceso ocupa su lugar. Esto favorece el reciclaje de memoria, ya que al destruir el hijo también de limpian los archivos dinámicos que se han generado. Por lo tanto, favorece el uso y mantenimiento de la RAM.
Algo también importante a la hora de optimizar nuestro servidor Apache son las conexiones persistentes y el comportamiento de las mismas. Esto se configura en las siguientes variables,
  • KeepAlive
    Activa o desactiva las conexiones persistentes. Si las permitimos una misma conexión TCP puede realizar múltiples peticiones sin cerrar dicha conexión.
  • MaxKeepAliveRequests
    Representa el número máximo de peticiones permitidas en una misma conexión.
  • KeepAliveTimeOut
    Representa el tiempo máximo (en segundos) que una conexión permanecerá a la espera de nuevas peticiones. Si no se cerrará.

La entrada Apache, Prefork vs. Worker la puedes leer en Puppet Linux.
Leer más

MySQL: Tipos de datos

Nunca os ha pasado que tenéis que crear algún campo en una base de datos MySQL y no sabéis qué tipo de datos ponerle. Aquí os dejo una pequeña chuleta con todos los tipos de datos que MySQL soporta y que será muy útil a la hora de definir mejor los campos.
Ahorrarás espacio y ayudarás al motor de base de datos a ir más fluido.
Más información: MySQL.com.
Tipo
Descripción
CHARAlmacenan un carácter o una cadena de caracteres de 0 hasta 255
VARCHARAlmacenan una cadena de caracteres variables de 0 a 255
TINYINTAlmacena un valor entero pequeño de 0 a 255 o de -128 a 127
BIT
BOOL
BOOLEAN
Son sinónimos de TINYINT(3)
SMALLINTAlmacena un entero corto entre -32768 y 32767
En caso de no tener un signo de 0 a 65535
MEDIUMINTAlmacena un entero de tamaño medio entre -83888608 y 8388607 o entre 0 y 16777215 sin signo.
INT
INTEGER
Contiene un entero de tamaño normal entre -2147483648 y 2147483647 o entre 0 y 4294967295 sin signo
BIGINTContiene un entero grande entre -9223372036854775808 y 922337203685477807 con signo o de 0 a 18446744073709551615 sin signo
FLOATGuarda un número de coma flotante
Opcionalmente puede acompañarse (al tipo flota sin los paréntesis) de la palabra PRECISION que le indica la precisión decimal que se desea, que puede llegar hasta 24 para precisión sencilla y de 25 a 53 para una precisión doble
En caso de especificarse el modificador UNSIGNED los valores negativos no son permitidos.
DOUBLEContiene un número de coma flotante de precisión normal
Si se define UNSIGNED, los valores negativos no son permitidos.
DOUBLE PRECISION REALSinónimos de DOUBLE (10)
DECIMALGuarda un número de coma flotante sin empaquetar, lo que implica que da número es un caracter (CHAR)
DEC
NUMERIC
FIXED
Son todos sinónimos de DECIMAL
DATEAlmacena un valor de fecha
Los rangos permitidos son desde '1000-01-01' y '9999-12-31'
El formato de fecha presentado es: 'AAAA-MM-DD'
DATETIMEAlmacena un valor de fecha +  hora
Los rangos permitidos, desde '1000-01-01 00:00:00' hasta '9999-12-31 23:59:59'
El formato es del tipo 'AAAA-MM-DD HH:MM:SS'
TIMESTAMPEs un valor temporal que va desde '1970-01-01 00:00:00' hasta el año 2037
TIMEAlmacena valores de tipo hora, pero entre dos eventos, de ahí que pueda superar el rango de las 24 horas y ser incluso negativo
Los rangos permitidos, '-838:59:59' a '838:59:59'
TINYBLOB
TINYTEXT
Almacena valores de tipo BLOB o TEXT con una longitud de hasta 255 caracteres
BLOX TEXTAlmacena valores de tipo BLOB o TEXT con una longitud de hasta 65535 caracteres
MEDIUMBLOB
MEDIUMTEXT
Almacena valores de tipo BLOB o TEXT con una longitud de hasta 16777215 caracteres
LONGBLOB
LONGTEXT
Almacena valores de tipo BLOB o TEXT con una longitud de hasta 4294967298 caracteres
ENUMAlmacena un enumerado con un máximo de 65535 valores diferentes
SETAlmacena un conjunto con un máximo de miembros de 64
Leer más

Qubes OS, aprovechando xen en el escritorio

Hace años cuando comencé a investigar sobre los sistemas de virtualización y más concretamente sobre Xen. Una de las cosas más prometedoras que tenía era la posibilidad de independizar completamente una instancia de las otras, es decir, una máquina del resto. Esto ofrece como era de esperar una gran independencia. El mismo hardware, pero máquinas diferentes, por lo que si una se veía afectada, la otra seguiría estando bien. Las posibilidades eran muchas y muy diferentes, pero los requisitos también eran bastantes.
Sin embargo, hoy descubrí un nuevo proyecto, Qubes OS, que es un sistema operativo basado en GNU/Linux con los parches de Xen y que hace justamente lo descrito con anterioridad, aprovechando todas sus características.

Como los propios creados del sistema lo denominan, Qubes OS es "un sistema operativo diseñado para la seguridad".
Qubes is an open source operating system designed to provide strong security for desktop computing.
El método que ofrece para determinar que cada entorno es lo más seguro posible es la independencia que Xen ofrece para cada una de las máquinas que arranca (5 tipos por defecto) y que todas son accesibles y manejables desde un entorno gráfico.
  • random
    Máquina con datos volátiles para instalaciones y páginas en las que no confiemos al 100%. No almacena ningún tipo de información sensible.
  • social
    Máquina para uso de aplicaciones y acceso a páginas frecuentes. Sí almacena información sensible.
  • shopping
    Dominio virtual pensado para la realización de compras on-line y comercio electrónico.
  • bank
    Máquina con máxima seguridad. Sólo permite navegación HTTPS.
  • corporate
    Máquina que sólo dispone de un cliente VPN para conectarse a la red de la compañía y trabajar remotamente.
Como todo, aunque cada uno de los dominio virtuales esté 100% independiente del otro, el factor humano sigue jugando en contra de la seguridad de los datos que están ahí, lo que sí, es que se consigue una instalación con varias máquinas con diferentes perfiles.
Quizás en próximas versiones incluya una instalación de Windows (previo pago de licencia).
Más información, en su web oficial.
Leer más

exiftool, extract image metadata

Hace tiempo que tenía pendiente de terminar de escribir este post sobre metadatos. Si necesitas saber algo de alguien, actualmente los metadatos de los archivos a los que tengas acceso te pueden ayudar. Ya hace tiempo escribí un pequeño post sobre cómo obtener los metadatos de ficheros pdf de forma muy simple (a golpe de comando). Hoy vamos a ver cómo hacer lo mismo con una imagen y cómo aprovechar y extraer todo el jugo que esta valiosa información nos ofrece.
Lo primero de todo es instalar la herramienta que vamos a emplear. En nuestro caso será exiftool. En sistemas de base Debian la podéis encontrar disponible en los repositorios.
shell> apt-get install libimage-exiftool-perl
Una vez instalada ya sólo queda usarla. El único requisito, tener acceso a la imagen que os interese analizar. En mi caso me bajé una imagen de internet de la que se puede observar lo siguiente,
shell> exiftool imagen_4.jpg
ExifTool Version Number         : 8.15
File Name                       : imagen_4.jpg
Directory                       : .
File Size                       : 34 kB
File Modification Date/Time     : 2012:12:14 16:08:19+01:00
File Permissions                : rw-r--r--
File Type                       : JPEG
MIME Type                       : image/jpeg
JFIF Version                    : 1.02
Resolution Unit                 : None
X Resolution                    : 1
Y Resolution                    : 1
Comment                         : *
Profile CMM Type                : lcms
Profile Version                 : 2.1.0
Profile Class                   : Display Device Profile
Color Space Data                : RGB
Profile Connection Space        : XYZ
Profile Date Time               : 2012:01:25 03:41:57
Profile File Signature          : acsp
Primary Platform                : Apple Computer Inc.
CMM Flags                       : Not Embedded, Independent
Device Manufacturer             : 
Device Model                    : 
Device Attributes               : Reflective, Glossy, Positive, Color
Rendering Intent                : Perceptual
Connection Space Illuminant     : 0.9642 1 0.82491
Profile Creator                 : lcms
Profile ID                      : 0
Profile Description             : c2
Profile Copyright               : FB
Media White Point               : 0.9642 1 0.82491
Media Black Point               : 0.01205 0.0125 0.01031
Red Matrix Column               : 0.43607 0.22249 0.01392
Green Matrix Column             : 0.38515 0.71687 0.09708
Blue Matrix Column              : 0.14307 0.06061 0.7141
Image Width                     : 600
Image Height                    : 450
Encoding Process                : Progressive DCT, Huffman coding
Bits Per Sample                 : 8
Color Components                : 3
Y Cb Cr Sub Sampling            : YCbCr4:2:0 (2 2)
Image Size                      : 600x450

Aquí podemos ver información de la imagen y una de las cosas que más destaca es fue realizada con un equipo de Apple. Viendo la foto, se supone que con un iPhone. Otra de las cosas que llama la atención es la fecha y la hora en la que se tomó la foto, que también están perfectamente registradas. Sin embargo no se observa ningún dato más interesante. En este otro ejemplo tenemos lo siguiente:

shell> exiftool -a imagen_5.jpg
...
Exif Byte Order                 : Little-endian (Intel, II)
Make                            : google
Camera Model Name               : Nexus S
Orientation                     : Rotate 90 CW
Software                        : JZO54K
...
Flash                           : No Flash
...
Image Size                      : 2560x1920
...
Aquí ya tenemos más información, como el dispositivo exacto con el que se sacó. En este caso mi Nexus S dejando huella. Sin embargo aquí todavía no hay datos 100% intenresantes, como puede ser la localización de la fotografía. Así que vamos a alguna red social y veamos lo que se puede obtener de ahí,
shell> exiftool -c "%d %d %.8f" imagen_9.jpg
...
GPS Version ID                  : 2.2.0.0
GPS Latitude                    : 48 25 11.90280000
GPS Longitude Ref               : East
GPS Longitude                   : 7 25 22.11240000 E
Image Size                      : 269x188
GPS Position                    : 48 25 11.90280000, 7 25 22.11240000 E
Para facilitar el trabajo, yo le doy un formato de salida a la posición (opción -c "%d %d %.8F") que ya GoogleMaps entenderá. Esta fotografía sí tiene datos de interés, como es su localización exacta. Si el valor del campo GPS Position lo buscamos directamente en GoogleMaps, veremos la zona en la que se sacó la foto. Ahora que ya sabéis lo que se puede obtener de una foto, es vuestra decisión compartir la posición o no.
Por cierto, si no os interesa descargar las imágenes sino que el proceso sea más continuo, se puede enlazar exiftool con wget, para que después de descarga la imagen automáticamente la escanee.
shell> wget -qO - http://www.../imagen_1.jpg | exiftool -fast -
Leer más

Control de colas de correo desde Zabbix

Hoy vamos a ver cómo podemos controlar las colas de correo de Zimbra (y en general de postfix) desde nuestra herramienta de monitorización.
Antes de comenzar, vamos a hacer una breve introducción a qshape, una utilidad nativa de postfix que permite controlar la antigüedad de los correos. Dicho de otra forma, nos permite saber cuánto tiempo lleva un correo en una cola. Todos sabemos que ne postfix hay 4 colas principales, active, deferred, hold e incoming. Si hacemos uso qshape podremos saber exactamente cuanto correo hay en cada cola. Veamos un ejemplo.
shell> qshape deferred
              T  5 10 20 40 80 160 320 640 1280 1280+
       TOTAL  3  0  0  0  1  0   0   0   0    0     2
    yahoo.es  1  0  0  0  1  0   0   0   0    0     0
 hotmial.com  1  0  0  0  0  0   0   0   0    0     1
    gmail.es  1  0  0  0  0  0   0   0   0    0     1
Como podéis observar, se le pasa como parámetro la cola que nos interesa y nos devuelve la cantidad de mail's que hay en ella. La primera columna representa el nombre del destino, que como se puede observar suelen ser nombres mal escritos. La segunda columna, representada como una T, representa el total de los mail's en cola y el resto de columnas lo mismo pero por minutos.

Para poder graficar y controlar estos valores, primero necesitamos tener un pequeño script que nos los devuelva. Así que aquí os dejo el que yo hice (no muy currado).
#!/usr/bin/perl
#
# Usage: zabbix_qshape <queue> <time>
# <queue>: active, deferred, hold, incoming
# <time>: T (all), 5,10,20,40,80,160,320,640,1280,1280+
# Returns the number of messages in <queue> for <minutes>

use strict;

my $num_args = $#ARGV + 1;
if ($num_args != 2) {
   print "Usage: zabbix_qshape <queue> <time>\n";
   exit;
} else {
   my $queue = @ARGV[0];
   my $time = @ARGV[1];
   my %tindex = ('T' => 2,
      '5' => 3,
      '10' => 4,
      '20' => 5,
      '40' => 6,
      '80' => 7,
     '160' => 8,
     '320' => 9,
     '640' => 10,
    '1280' => 11,
   '1280+' => 12);
   my $index=$tindex{$time};
   if(!$index) {
      print "Usage: zabbix_qshape <queue> <time>\n";
      exit;
   }
   my $command = "sudo /opt/zimbra/postfix/sbin/qshape.pl $queue \
                 | grep TOTAL \
                 | awk {'print \$$index'}";
   my $sal = qx@$command@;
   chomp($sal);
   print "$sal\n";
}
Con este pequeño script al pasarle una cola y un tiempo, nos devuelve el número de mail's que están en dicha cola. De forma más gráfica,
shell> perl /usr/local/bin/zabbix_qshape deferred T
3
Así que ahora sólo queda crear un nuevo item que se encargue de monitorizarlo. Puesto que queda más limpio, soy de los que prefiere emplear el UserParameter del fichero de configuración, creando ahí una nueva key_ que se encargue de controlar esto. Puesto que le vamos a pasar 2 parámetros, vamos a crearla con opciones.
UserParameter=zimbra.queue[*], /usr/local/bin/zabbix_qshape $1 $2
Ahora ya sólo queda crear los items que deseamos monitorizar, tal que así:
Name                    : Zimbra monitor: $1
Type                    : Zabbix agent
Key                     : zimbra.queue[deferred, T]
Type of information     : numeric (unsigned)
Data type               : Decimal
Update interval (in sec): 300
Applications            : Zimbra
De la forma que la hemos creado, tenemos una única key_ a la que le podemos pasar como parámetros la cola y el tiempo y lógicamente, mostrarlos como parte del nombre. En el ejemplo anterior la key_ creada es para la cola deferred. Para monitorizar el resto de colas, las key's a crear serán:
zimbra.queue[active, T]
zimbra.queue[hold, T]
zimbra.queue[incoming, T]
Sólo para terminar, un detalle importante es el empleo de sudo en el comando. Algunos ya os habréis dado cuenta, pero para los que no, simplemente deciros que antes de que esto funcione debemos de añadir la siguiente línea al fichero /etc/sudoers.
zabbix  ALL=NOPASSWD: /opt/zimbra/postfix/sbin/qshape.pl
Como nota adicional decir que el comando qshape de zimbra está localizado bajo /opt/zimbra/bin/qshape, pero como todo el sistema Zimbra está preparado para ser ejecutado con el usuario zimbra. Sin embargo, la instalación de postfix ofrece también dicho comando, localizado /opt/zimbra/postfix/sbin/qshape.pl al que sí le podemos añadir fácilmente permisos con sudo para el usuario zabbix.
Leer más

Windows como escritorio de Linux


Para todos aquellos que solemos usar GNU/Linux estamos muy felices con él, pero siempre hay veces que es necesario tener un Windows a mano. No por que nosotros queramos, sino por que hay veces que se hace estrictamente necesario, bien por una aplicación que no hay versión para Linux, un fichero de office ;-), etc. También se puede dar el caso de un ordenador compartido en el que tras el login se puede iniciar una sesión Windows o Linux.
Ahora imaginémonos que todo el control de usuarios/contraseñas se las dejamos al sistema base (GNU/Linux) y el interfaz gráfico pues a elección de la persona que inicie. Así alguien podría decidir en un momento arrancar con KDE y en otro con WindowsXP. Esta opción daría una gran ventaja, ya que presentaría el equipo Windows como un escritorio más de inicio de sesión.

Por lo tanto, la idea es realizar una pequeña instalación de una máquina con VirtualBox, en nuestro caso y por que nos interesa, con Windows XP y luego agregarla como una opción más en el menú de GDM. Así, cuando un usuario decida arrancar con el escritorio Windows, se iniciará una instancia de dicha máquina virtual, la usará como un escritorio más y al finalizar simplemente volverá a la pantalla de login.
Como veremos a continuación, realizar esto es bastante sencillo, por lo que gracias a puppet replicarlo por una red de ordenadores, léase una facultad por ejemplo, sería muy sencillo.
Vamos a comenzar por el principio pues, realizando la instalación de los paquetes que nos hacen falta en nuestra distribución. En este caso, Debian ;-)
shell> apt-get install virtualbox-ose virtualbox-guest-additions
Al finalizar la instalación, simplemente arrancamos VirtualBox e instalamos el sistema que deseemos. En nuestro caso Windows XP. Creamos el disco (a poder ser, de tamaño fijo) y también le permitimos acceso a la red. Al finalizar toda la instalación, cerramos VirtualBox y seguimos configurando lo que nos falta.
Toca ahora añadir en el menú de GDM una nueva entrada con nuestro nuevo escritorio. Para ello creamos un nuevo fichero llamado WindowsXP.desktop bajo /usr/share/xsessions con el siguiente contenido:
[Desktop Entry]
  Encoding=UTF-8
  Name=Windows XP
  Comment=Use esta sesion para ejecutar Windows XP
  Exec=/usr/bin/Windows-XP-GDM
  Icon=
  Type=Application
Tras guardarlo en GDM ya aparecerá una nueva línea que nos permitirá iniciar sesión en el Windows virtual, pero en ningún lado le hemos dicho nada.
Sí, efectivamente el parámetro Exec del fichero WindowsXP.desktop es el que nos da la solución. Tenemos que crear dicho fichero (/usr/bin/Windows-XP-GDM) y el contenido del mismo será,
#!/bin/bash
VBoxSDL -vm WinXP -fullscreen
Simplemente le indicamos que arranque una estancia de una máquina virtual (en este caso WinXP) y a pantalla completa.

Al iniciar el usuario con este "nuevo escritorio" se iniciará la máquina virtual automáticamente y el usuario verá que su escritorio es realmente un Windows. Cuando la apague, automáticamente regresará a la ventana de login.
En breves intentaré dejar un manifiesto puppet que haga automáticamente este proceso para demostrar lo sencillo que sería distribuir sistema en una red de ordenadores.
Y por si alguien se lo está preguntando, gracias a VirtualBox la aceleración hardware ya no es un problema. Tras instalar la máquina virtual, instalamos los drivers (virtualbox-guest-additions) y todo irá muy fluido. Si te atreves a probarlo, comenta tu experiencia!
Leer más

Firmar paquete RPM local

Muy estrechamente relacionado con el tema de crear repositorios locales para RedHat/CentOS, está la necesidad de autenticar dichos repositorios y el contenido de los mismo. Está claro que si el repositorio se sirve vía http, podemos emplear https con un certificado válido para nuestra empresa y así ya tener autenticación de origen de datos, sin embargo no tenemos ninguna garantía de que los paquetes que vamos a instalar estén realmente firmados como es debido. Para ello, cada vez que creemos un paquete que se vaya a subir al repositorio, antes de hacerlo, deberíamos de firmarlo. En este post, vamos a ver cómo conseguirlo.
Primero comenzamos creando una clave gpg para el firmado. Obviamente esta clave es generada localmente, por lo que el certificado no estará aceptado por autoridades externas.
shellgpg --gen-key
gpg (GnuPG) 1.4.10; Copyright (C) 2008 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Por favor seleccione tipo de clave deseado:
  (1) RSA and RSA (default)
  (2) DSA and Elgamal
  (3) DSA (sólo firmar)
  (4) RSA (sólo firmar)
Su elección: 1
las claves RSA pueden tener entre 1024 y 4096 bits de longitud.
¿De qué tamaño quiere la clave? (2048)
El tamaño requerido es de 2048 bits
Por favor, especifique el período de validez de la clave.
  0 = la clave nunca caduca
    = la clave caduca en n días
  w = la clave caduca en n semanas
  m = la clave caduca en n meses
  y = la clave caduca en n años
¿Validez de la clave (0)? 0
La clave nunca caduca
¿Es correcto? (s/n) s
Necesita un identificador de usuario para identificar su clave. El programa
construye el identificador a partir del Nombre Real, Comentario y Dirección
de Correo Electrónico de esta forma:
    "Heinrich Heine (Der Dichter) "
Nombre y apellidos: Javier Terceiro
Dirección de correo electrónico: javier@miempresa.com
Comentario:
Ha seleccionado este ID de usuario:
    "Javier Terceiro "
¿Cambia (N)ombre, (C)omentario, (D)irección o (V)ale/(S)alir? V
Necesita una frase contraseña para proteger su clave secreta.

Es necesario generar muchos bytes aleatorios. Es una buena idea realizar
alguna otra tarea (trabajar en otra ventana/consola, mover el ratón, usar
la red y los discos) durante la generación de números primos. Esto da al
generador de números aleatorios mayor oportunidad de recoger suficiente
entropía.
..+++++......++++++++++
gpg: clave 1C5D59BF marcada como de confianza absoluta
claves pública y secreta creadas y firmadas.

gpg: comprobando base de datos de confianza
gpg: 3 dudosa(s) necesarias, 1 completa(s) necesarias,
modelo de confianza PGP
gpg: nivel: 0  validez: 1  firmada: 0  confianza: 0-, 0q, 0n, 0m, 0f, 1u
pub   2048R/1C5D59BF 2012-05-21
  Huella de clave = 2493 D660 1A83 12F5 0A50  2E71 8A82 1165 1C5D 59BF
uid                  Javier Terceiro 
sub   2048R/25A1D82A 2012-05-21
Una vez tengamos la firma creada, ya estamos preparados para firmar todos los paquetes que vayamos creando. Para ello, vamos a crear el fichero .rpmmacros en la home del usuario que los vaya a firmar. Dicho fichero tendrá el siguiente contenido.
%_signature gpg
%_gpg_name Repository Owner
Y ahora para firmar un paquete nuevo, únicamente hay que ejecutar,
shell> rpm --resign zabbix-server-1.8.12.src.rpm
Enter pass phrase:
Pass phrase is good.
zabbix-server-1.8.12.src.rpm
Y si ahora interesa saber si el fichero está correctamente firmado, simplemente,
shell> rpm -K zabbix-server-1.8.12.src.rpm
zabbix-server-1.8.12.src.rpm: (SHA1) DSA sha1 md5 (GPG) NOT OK (MISSING KEYS: GPG#1C5D59BF)
Como podéis ver algo muy simple de hacer y que te aporta ese extra de seguridad a los paquetes que tú mismo crees y que evitará que ante un ataque se sustituyan por otros infectados.

Leer más

XenSource, curioso fallo en debian (xm new)

Si usas XenSource, la versión libre de Xen integrada en el kernel de GNU/Linux quizás esto te haya pasado, así que aquí tienes la solución.
Para arrancar una máquina virtual se suele emplear el comando "xm start machine", sin embargo si deseas reservar espacio para algunas de las máquinas es buena idea emplear el comando "xm new machine" or decirlo de alguna forma, con el parámetro new, Xen lo que hace es aprovisionar la máquina en el sistema, pero no arrancarla, lo que es necesario hacer por ejemplo si empleamos algún interfaz gráfico de administración de Xen.
Sin embargo en la versión estable de Debian, al llamar a dicho comando se obtiene un fallo de librerías no encontradas,
shell> xm new pentest.cfg 
Unexpected error: 

Please report to xen-devel@lists.xensource.com
Traceback (most recent call last):
  File "/usr/lib/xen-4.0/bin/xm", line 8, in main.main(sys.argv)
  File "/usr/lib/xen-4.0/lib/python/xen/xm/main.py", line 3620, in main_, rc = _run_cmd(cmd, cmd_name, args)
  File "/usr/lib/xen-4.0/lib/python/xen/xm/main.py", line 3644, in _run_cmd return True, cmd(args)
  File "", line 1, in 
  File "/usr/lib/xen-4.0/lib/python/xen/xm/main.py", line 1449, in xm_importcommand cmd = __import__(command, globals(), locals(), 'xen.xm')
  File "/usr/lib/xen-4.0/lib/python/xen/xm/new.py", line 26, in from xen.xm.xenapi_create import *
  File "/usr/lib/xen-4.0/lib/python/xen/xm/xenapi_create.py", line 22, in from xml.parsers.xmlproc import xmlproc, xmlval, xmldtd
ImportError: No module named xmlproc
Para poder solucionarlo, hay que instalar una librería de manejo de xml para python, concretamente la python-lxml (en la versión Squeeze de Debian).
shell> apt-get install python-lxml
Tras dicha instalación, debemos dejar el fichero /usr/lib/xen-4.0/lib/python/xen/xm/xenapi_create.py tal como sigue (comentada la línea 22).
...
# from xml.parsers.xmlproc import xmlproc, xmlval, xmldtd
...
Al volver a ejecutar el comando funcionará correctamente, dejando la máquina aprovisionada en el servidor Xen, pero sin comenzar la ejecución de la misma.
Leer más

Formulario de contacto

Nombre

Correo electrónico *

Mensaje *

Últimos comentarios