Publicación Celestinet y videotutoriales

5 de mayo de 2013

Por la fecha de la publicación del último artículo, hace casi dos años que no publico nada en él. Y no es porque no haya realizado nada interesante, más bien todo lo contrario. Ha habido una gran cantidad de cambios en mi vida y uno de ellos ha sido el cambio de trabajo. Sí, soy un culo inquieto que valora por encima de la “seguridad” el disfrutar cada vez más de mi trabajo. Es más, estoy firmemente convencido de que se produce la paradoja de que la seguridad es mucho más insegura que arriesgar y dirigirte a lo que te apasiona. Sólo haciendo lo que te gusta, eres capaz de invertir la energía y la cantidad de horas necesarias para convertirte en un gran profesional: no existen atajos y el camino es duro.

En mi nuevo trabajo estoy realizando cosas realmente interesantes y que en otra ocasión espero poderte contar. Dada la naturaleza del proyecto, casi con toda seguridad podré hacerlo. Mientras tanto, entre las muchas cosas que he estado realizando estos dos años y que te puedo mostrar son este par de proyectos:

Celestinet
Celestinet es un software que permite realizar conexiones tcp entre servicios que se encuentren “aislados” detrás de algún firewall o bien no sean direccionables por las máquinas que desean tener acceso. Para su labor, permite la publicación de servicios y el establecimiento de túneles, permitiendo la conexión transparente de cualquier servicio que use el protocolo tcp (quizás en algún futuro amplíe la funcionalidad para que admita también udp, pero de momento no está disponible).
Pero una imagen vale más que mil palabras, y si además la imagen lleva un audio explicándolo mucho mejor:






Por supuesto el software es libre y con licencia gpl: Celestinet.tar.gz

Videotutoriales
Realicé un par de videotutoriales sobre administración de sistemas, uno de Openldap (Videotutorial LDAP) y otro de MIT Kerberos (Videotutorial Kerberos).
Espero que te gusten ;)

Por el momento, y como diría Bugs Bunny: eso… eso… eso es todo amigos.

Regreso al pasado a través de mi Spectrum

15 de mayo de 2011

Tengo en mi lista de “algún día” aprender ensamblador del Spectrum, pero… ¿por qué narices alguien va a querer hacer algo así en el año 2011?, ¡es de locos!. Reconozco que puede parecer una locura, pero… ¿acaso no está loco el que colecciona mariposas o el que lee libros de aventuras o el aficionado al fútbol que dice alterado “el árbitro nos ha robado el partido” cuando hace décadas que no ha pegado ni una sola patada a un balón?

Mi contacto con la informática empezó creo que sobre los 8 años, no recuerdo muy bien la edad que tenía, pero sí recuerdo bien cuando desembalamos el ordenador e improvisamos un escritorio sobre la mesa del salón con una pequeña tele que teníamos en el cuarto (electrodomésticos nos sobraban, ya que mi padre tenía una pequeña tienda en aquella época, ahora que pienso… quizá mi afición por los “cacharros” venga de entonces). Junto con el ordenador mi padre trajo un par de juegos de los que empezaba por aquel entonces a vender en la tienda y que venían en cinta. Uno de ellos era por supuesto de fútbol, se trataba del Match Day. Me llamó mucho la atención que para jugar había que “cargar” el juego y que aunque no tenía una apariencia como la de las recreativas de 25 pesetas ¡era muy divertido!. Pero aquel LOAD “” que había que poner para cargar el juego era todo un misterio para mi…
Viendo mi interés por aquel pequeño ordenador, ese mismo verano mis padres me apuntaron a un cursillo para aprender a usarlo para algo más que jugar. En aquella academia me enseñaron lo que era el Basic: el primer verano desde un Commodore 64, un Amstrad CPC el segundo y un PC XT en el tercero. Lamentablemente aquella academia cerró y tuve que seguir aprendiendo por mi cuenta.
Por aquel entonces mis padres nos sorprendieron con otro nuevo aparatito para jugar, la Sega Master System I. Los impresionantes gráficos que tenía y la velocidad con la que cargaba los juegos hizo sombra a mi querido Spectrum.
Aun así la programación seguía llamándome la atención, aprendía lo que podía con libros de la biblioteca y las revistas Microhobby que ocasionalmente compraba. Pero aunque tenía muchos amigos con Spectrums, nadie más hacía sus propios programas y jamás pude conseguir el software con el que poder ensamblar programas a código máquina.
Al final fue lo que comenzó la historia, otra nueva sorpresa de mis padres con un flamante 486, la que puso el punto y final a mi Spectrum.

No se si esta melancolía es por la crisis de los 30, pero tengo esa espinita clavada. Por eso quiero darme el gustazo de aprender lo que no llegué a hacer por las circunstancias de la época.

Mi primer paso y el primer inconveniente ha sido la elección de emulador, me ha gustado especialmente FUSE ya que dispone de un debugger y un visualizador de la memoria. Pero no se encuentra empaquetado para Ubuntu Lucid 10.04, por ello he usado los fuentes existentes para Debian realizados por Alberto Garcia, los he empaquetado y los he dejado aquí para su descarga por si a alguien le es útil. Si hago algo interesante lo iré posteando.

Salud y larga vida al Spectrum!

Script para la creación de nuevos proyectos Zend Framework

14 de mayo de 2011

Si ya has hecho algún proyecto con este Framework seguro que ya conoces la herramienta Zend_Tool. Esta herramienta te habrá ayudado bien mediante la línea de comandos o bien integrada en Netbeans a generar el código y estructura inicial de tus aplicaciones.

Como ya habrás comprobado, hay que hacer una serie de retoques si deseamos que nuestra aplicación sea modular y que use layouts (que serán la mayoría). No es un asunto complejo pero sí es un poco coñazo, además como es algo que se hace de uvas a peras, se suelen cometer errores y perder tiempo absurdamente.

Por eso hoy voy a compartir contigo este script que se encargará de crear de una manera sencilla una aplicación modular. Es un poco guarro pero funciona ;) . Para usarlo simplemente edita y modifícalo a tu gusto para que incluya tu nombre de aplicación, parámetros de base de datos, módulos, controladores, librerías, namespaces …

Espero que te sirva de ayuda ;)

Un pequeño hack para la extensión ssh2 de php

10 de abril de 2011

En el proyecto en el que estoy trabajando hago uso de la extensión ssh2 para php que se trata de un wrapper de la conocida libssh2. Como la mayoría de estas extensiones, se encuentra en el repositorio PECL y puede ser instalada mediante PEAR o usar el correspondiente paquete de tu distribución (en el caso de Ubuntu y Debian se llama libssh2-php).
Esta librería permite a tus aplicaciones php hacer prácticamente de todo lo que la conocida librería permite: conexiones mediante claves, passwords, copias con scp, operaciones con sftp, creación de túneles, ejecución de comandos remotos e incluso proporcionarte una shell interactiva.

Está realmente genial, el problema con el que me encontré es que no me permitía hacer algo aparentemente muy simple: obtener la condición de salida de los comandos ejecutados remotamente. Si bien puede llegar a hacerse ejecutando: comando ; echo $? y parsear la última línea para obtener el dato, no era una opción válida en el contexto de la aplicación que estoy desarrollando.
Me pareció realmente extraño que no fuese posible obtener esta información, por lo que consulté la documentación de la librería libssh2 y evidentemente existía una función llamada libssh2_channel_get_exit_status que nos devolvía el valor. El problema entonces era que el wrapper no implementaba esta función así que decidí echarle un vistazo a ver si era factible meterle mano. En otras ocasiones sí que había tenido que compilar alguna extensión PECL pero nunca había puesto mis zarpas encima de ninguna. Decidí darme una oportunidad y si en menos de una hora no lo había resuelto cambiaría de estrategia.

Afortunadamente el código estaba bastante bien y con la información que obtuve ojeando el libro Extending and Embedding PHP a través de mi suscripción a O’Really (que curiosamente se trata de la misma autora de la extensión) pude deducir más o menos cómo incluir la funcionalidad que deseaba y en menos de una hora conseguí mi objetivo. Para ello incluí el siguiente código en el ssh2_fopen_wrappers.c:

static int php_ssh2_channel_get_exit_status(php_stream *stream)
{
	php_ssh2_channel_data *abstract = (php_ssh2_channel_data*)stream->abstract;

	libssh2_channel_close(abstract->channel);
	return libssh2_channel_get_exit_status(abstract->channel);
}

PHP_FUNCTION(ssh2_get_exit_status)
{
	php_ssh2_channel_data *data;
	php_stream *parent;
	zval *zparent;
	int exit_status;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zparent) == FAILURE) {
		RETURN_FALSE;
	}

	php_stream_from_zval(parent, &zparent);

	if (parent->ops != &php_ssh2_channel_stream_ops) {
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Provided stream is not of type " PHP_SSH2_CHANNEL_STREAM_NAME);
		RETURN_FALSE;
	}

	exit_status = php_ssh2_channel_get_exit_status(parent);
	RETVAL_LONG(exit_status);
	return;
}
 

He dejado el código con la extensión parcheada aquí, y puedes instalarlo de la siguiente forma:

apt-get install php5-dev libssh2-1-dev
tar zxvf libssh2-php.tar.gz
cd ssh2-0.11.2
phpize
./confiure
make
make install
echo "extension=ssh2.so" > /etc/php5/conf.d/ssh2.ini

Para usarla, aquí un pequeño trozo de código usando claves rsa de ejemplo:

<?php

$con = ssh2_connect("192.168.0.1", 22, array('hostkey'=>'ssh-rsa'));
$connSuccess = ssh2_auth_pubkey_file($con, "usuario", "mykeyrsa.pub", "mykey");
if(!$connSuccess) die("Error de conexion");
echo "Conexión realizada\n";

$stream = ssh2_exec($con, "exit 15");
$errorStream = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR);

stream_set_blocking( $stream, true );
stream_set_blocking( $errorStream, true );

while($line = fgets($stream)) {
	flush();
	echo $line."\n";
}
$exitStatus = ssh2_get_exit_status($stream);

echo "El exit status: $exitStatus\n";

fclose($stream);
fclose($errorStream);

Espero que te sirva de utilidad ;)

Instalaciones desatendidas de office 2007, conversor y openoffice

1 de abril de 2011

Como ya comenté en entradas anteriores, es de suma utilidad tener automatizadas las instalaciones de los programas de modo que:

  • homogeneicemos las configuraciones
  • no cometamos errores
  • ahorremos tiempo

Recientemente modifiqué la personalización de mi script de instalación de Microsoft Office 2007 con el que hago instalaciones desatendidas. Por ello describo rápidamente el proceso de personalización. De propina también adjunto cómo instalar el plugin para abrir los documentos del nuevo pseudostandar con versiones anteriores de la suite y, cómo no, la instalación de OpenOffice en perfecta convivencia.

Instalación de Microsoft Office 2007

El proceso es muy sencillo:

  • En nuestra máquina de pruebas, abriremos una shell, nos situaremos en el directorio del instalador y ejecutaremos:
setup /admin
  • Personalizaremos la instalación a nuestro gusto (código de licencia, lenguajes, programas a instalar, etc) y guardaremos la personalización en el mismo directorio del instalación, por ejemplo CUSTOM.MSP.
  • Para ejecutar el instalador con el archivo de respuesta generado, simplemente ejecutaremos:
setup /adminfile CUSTOM.MSP

También es de utilidad integrar el último service pack junto al instalador. Para ello simplemente lo bajaremos y lo extraeremos en el directorio Updates del instalador. Para ello podremos usar el mismo 7-zip o bien desde una shell (nos situaremos en el directorio donde esté el sp) ejecutando:

office2007sp2-kb953195-fullfile-es-es.exe /extract:c:\pathinstalador\Updates

Nota: Si omitimos el path en el parámetro extract, nos preguntará donde extraer.

Instalación de plugin de documentos Microsoft Office 2007 para versiones anteriores de Microsoft Office

Si en los equipos tienes instalado alguna versión anterior de Microsoft Office y prefieres instalar el plugin para que pueda abrir los documentos de este nuevo falso estandar en lugar de instalar las nuevas versiones (que lo único que les aporta a la mayoría de los usuarios es confusión):

  • Bájate el O12Conv.msi
  • Ejecuta:
  • msiexec /passive /i O12Conv.msi /l* instalacion.log ALLUSERS=1 PRODUCTLANGUAGE=3082 USERNAME=Username COMPANYNAME=Company ACTION=INSTALL
    

Instalación OpenOffice 3.3

Si tenemos ya instalado Microsoft Office conviene hacer una instalación un poco especial de OpenOffice, deshabilitando la asociación de .doc, etc y eliminando el cargador de inicio de openoffice.

  • Descarga el exe con el instalador.
  • Descomprímelo con 7-zip
  • Ejecuta:
  • msiexec /passive /norestart /i openoffice33.msi COMPANYNAME="Company" USERNAME="Username" REGISTER_NO_MSO_TYPES=1 ADDLOCAL=ALL REMOVE=gm_o_Quickstart ALLUSERS=1
    

Para instalar language packs con diccionarios y demás procedemos del mismo modo, pero ejecutamos:

msiexec /passive /norestart /i openoffice33.msi ALLUSERS=1

Como siempre, no hay nada como leer la documentación oficial:
http://wiki.services.openoffice.org/wiki/Documentation/How_Tos/Automatic_Installation_on_Windows

Obviamente, para que todo esto sea útil, crearemos nuestros scripts para que monten las unidades de red necesarias, se ejecuten con runas si se necesitara, y de este modo no estar como un puto mono dándole al siguiente, siguiente. Espero te sea de utilidad ;)

Configuración de servidor ssh para túneles

14 de marzo de 2011

A menudo nos es necesario conectar con equipos que están detrás de un NAT y no podemos/queremos redireccionar ningún puerto en el router. Para ello OpenSSH nos permite una solución muy sencilla y ampliamente conocida que consiste en realizar un túnel que hará posible la conexión entre los equipos. Para que la comunicación pueda establecerse deberá ser el equipo al que deseamos conectarnos el que iniciará una conexión por ssh a nuestra máquina indicando el puerto local y el puerto remoto que harán de extremos del túnel. Una vez establecido, simplemente conectaremos en nuestra máquina a través de nuestro extremo del túnel y OpenSSH hará la magia.

Como se puede fácilmente deducir, será necesario disponer de una cuenta en nuestra máquina y proporcionar las credenciales indicadas al otro extremo para que inicie conexión. Esto en muchos casos puede suponer un problema, ya que estamos dando un acceso shell completo a nuestra máquina, acceso mediante sftp, etc. También puede ser necesario automatizar scripts en máquinas que no estén bajo nuestro exclusivo control.
Así que si vamos a usar túneles muy a menudo es mejor dejar todo algo más arregladito…

La configuración que propongo (es para Ubuntu Server 10.04, aunque seguramente funcionará también en Debian sin problemas) trata de correr un ssh en un puerto distinto a nuestro ssh corriente, al que sólo nuestro usuario dedicado podrá conectarse mediante keys rsa. Además a este usuario dedicado se le asignará una shell completamente capada.

Instalación de shell para realizar los túneles

Para ello usaremos una shell capada y que nos viene de perlas para esto: http://www.mariovaldez.net/software/sleepshell/

$ wget http://www.mariovaldez.net/software/sleepshell/files/sleepshell_0.0.2.tar.gz
$ tar zxvf sleepshell_0.0.2.tar.gz
$ cd sleepshell
$ gcc -O2 -g sleepshell.c -o sleepshell
$ strip sleepshell
$ sudo cp sleepshell /usr/local/bin

Creación del usuario

Crearemos un usuario para los túneles y le vincularemos la shell:

$ sudo useradd -d /home/tunnel -m tunnel
$ sudo usermod -s /usr/local/bin/sleepshell tunnel

Configuración del servicio

Crearemos nuestro /etc/ssh/sshd_config-tunnel

Port 2022
Protocol 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
UsePrivilegeSeparation yes
KeyRegenerationInterval 3600
ServerKeyBits 768
SyslogFacility AUTH
LogLevel INFO
LoginGraceTime 120
PermitRootLogin no
StrictModes yes
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile	%h/.ssh/authorized_keys
IgnoreRhosts yes
RhostsRSAAuthentication no
HostbasedAuthentication no
PermitEmptyPasswords no
ChallengeResponseAuthentication no
PasswordAuthentication no
X11Forwarding no
X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
AcceptEnv LANG LC_*
UsePAM yes
PidFile /var/run/sshd-tunnel.pid
AllowUsers tunnel

Un /etc/default/ssh-tunnel

SSHD_OPTS="-f /etc/ssh/sshd_config-tunnel"

Y un /etc/init.d/ssh-tunnel

#! /bin/sh

### BEGIN INIT INFO
# Provides:		sshd
# Required-Start:	$remote_fs $syslog
# Required-Stop:	$remote_fs $syslog
# Default-Start:	2 3 4 5
# Default-Stop:
# Short-Description:	OpenBSD Secure Shell server
### END INIT INFO

set -e

# /etc/init.d/ssh: start and stop the OpenBSD "secure shell(tm)" daemon

test -x /usr/sbin/sshd || exit 0
( /usr/sbin/sshd -\? 2>&1 | grep -q OpenSSH ) 2>/dev/null || exit 0

umask 022

export SSHD_OOM_ADJUST=-17
if test -f /etc/default/ssh-tunnel; then
    . /etc/default/ssh-tunnel
fi

# Are we in a virtual environment that doesn't support modifying
# /proc/self/oom_adj?
if grep -q 'envID:.*[1-9]' /proc/self/status; then
    unset SSHD_OOM_ADJUST
fi

. /lib/lsb/init-functions

if [ -n "$2" ]; then
    SSHD_OPTS="$SSHD_OPTS $2"
fi

# Are we running from init?
run_by_init() {
    ([ "$previous" ] && [ "$runlevel" ]) || [ "$runlevel" = S ]
}

check_for_no_start() {
    # forget it if we're trying to start, and /etc/ssh/sshd_not_to_be_run exists
    if [ -e /etc/ssh/sshd_not_to_be_run ]; then
	if [ "$1" = log_end_msg ]; then
	    log_end_msg 0
	fi
	if ! run_by_init; then
	    log_action_msg "OpenBSD Secure Shell server not in use (/etc/ssh/sshd_not_to_be_run)"
	fi
	exit 0
    fi
}

check_dev_null() {
    if [ ! -c /dev/null ]; then
	if [ "$1" = log_end_msg ]; then
	    log_end_msg 1 || true
	fi
	if ! run_by_init; then
	    log_action_msg "/dev/null is not a character device!"
	fi
	exit 1
    fi
}

check_privsep_dir() {
    # Create the PrivSep empty dir if necessary
    if [ ! -d /var/run/sshd ]; then
	mkdir /var/run/sshd
	chmod 0755 /var/run/sshd
    fi
}

check_config() {
    if [ ! -e /etc/ssh/sshd_not_to_be_run ]; then
	/usr/sbin/sshd $SSHD_OPTS -t || exit 1
    fi
}

export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"

case "$1" in
  start)
	check_privsep_dir
	check_for_no_start
	check_dev_null
	log_daemon_msg "Starting OpenBSD Secure Shell server" "sshd"
	if start-stop-daemon --start --quiet --oknodo --pidfile /var/run/sshd-tunnel.pid --exec /usr/sbin/sshd -- $SSHD_OPTS; then
	    log_end_msg 0
	else
	    log_end_msg 1
	fi
	;;
  stop)
	log_daemon_msg "Stopping OpenBSD Secure Shell server" "sshd"
	if start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/sshd-tunnel.pid; then
	    log_end_msg 0
	else
	    log_end_msg 1
	fi
	;;

  reload|force-reload)
	check_for_no_start
	check_config
	log_daemon_msg "Reloading OpenBSD Secure Shell server's configuration" "sshd"
	if start-stop-daemon --stop --signal 1 --quiet --oknodo --pidfile /var/run/sshd-tunnel.pid --exec /usr/sbin/sshd; then
	    log_end_msg 0
	else
	    log_end_msg 1
	fi
	;;

  restart)
	check_privsep_dir
	check_config
	log_daemon_msg "Restarting OpenBSD Secure Shell server" "sshd"
	start-stop-daemon --stop --quiet --oknodo --retry 30 --pidfile /var/run/sshd-tunnel.pid
	check_for_no_start log_end_msg
	check_dev_null log_end_msg
	if start-stop-daemon --start --quiet --oknodo --pidfile /var/run/sshd-tunnel.pid --exec /usr/sbin/sshd -- $SSHD_OPTS; then
	    log_end_msg 0
	else
	    log_end_msg 1
	fi
	;;

  try-restart)
	check_privsep_dir
	check_config
	log_daemon_msg "Restarting OpenBSD Secure Shell server" "sshd"
	set +e
	start-stop-daemon --stop --quiet --retry 30 --pidfile /var/run/sshd-tunnel.pid
	RET="$?"
	set -e
	case $RET in
	    0)
		# old daemon stopped
		check_for_no_start log_end_msg
		check_dev_null log_end_msg
		if start-stop-daemon --start --quiet --oknodo --pidfile /var/run/sshd-tunnel.pid --exec /usr/sbin/sshd -- $SSHD_OPTS; then
		    log_end_msg 0
		else
		    log_end_msg 1
		fi
		;;
	    1)
		# daemon not running
		log_progress_msg "(not running)"
		log_end_msg 0
		;;
	    *)
		# failed to stop
		log_progress_msg "(failed to stop)"
		log_end_msg 1
		;;
	esac
	;;

  status)
	status_of_proc -p /var/run/sshd-tunnel.pid /usr/sbin/sshd sshd && exit 0 || exit $?
	;;

  *)
	log_action_msg "Usage: /etc/init.d/ssh {start|stop|reload|force-reload|restart|try-restart|status}"
	exit 1
esac

exit 0

Un simple /etc/init.d/ssh-tunnel start iniciará el servicio para el túnel.

Creación de las keys de conexión

Con esto ya tenemos listo el servicio, para empezar a funcionar, deberemos crear las keys RSA para usar el túnel con el usuario tunnel y asignársela en su authorized keys:

$ echo "./tunnelkey" | ssh-keygen -t rsa
$ sudo mkdir -p /home/tunnel/.ssh
$ sudo chown tunnel:root /home/tunnel/.ssh
$ sudo cp tunnelkey.pub /home/tunnel/.ssh/authorized_keys
$ sudo chown root:tunnel /home/tunnel/.ssh/authorized_keys
$ sudo chmod 640 /home/tunnel/.ssh/authorized_keys

Conectando el túnel

Para conectar al túnel, usando la clave privada simplemente haremos

(remoto) $ ssh -i tunnelkey -N -R 10069:localhost:22 tunnel@nuestramaquina.com -p 2022
(local) $ ssh usuario@localhost -p 10069

Puede ser de suma utilidad desvincular el proceso de la shell:

(remoto) $ nohup /usr/bin/ssh -i tunnelkey -N -R 10069:localhost:22 tunnel@nuestramaquina.com -p 2022 < /dev/null >> /tmp/sshnohup.out 2>&1 &

Dejo como ejercicio al lector programar un at que reconecte el túnel si está caído . Hasta la próxima y espero que te sirva de ayuda ;)

Forzando la reinstalación de drivers en Windows XP

14 de febrero de 2011

Recientemente he tenido problemas con un equipo en el cual se instalaron unos drivers que no eran los apropiados y hacían que el dispositivo no funcionase correctamente (aunque windows los daba por buenos al coincidir los identificadores hardware). A pesar de intentar actualizar el driver de la manera tradicional, desinstalar y volver a instalar, e incluso eliminar físicamente los ficheros del driver, no conseguía que los cogiera de la nueva ubicación. Al parecer el sistema seguía dando preferencia al inf viejo y buscaba ficheros que poseía el anterior driver. Como no es la primera vez que me ocurre y he perdido bastante tiempo solucionándolo, documento aquí el proceso para no perder tanto tiempo la próxima vez que me ocurra (y si te ocurre a ti, ya sabes cómo solucionarlo ;) ).

  • En primer lugar nos vamos a las propiedades del dispositivo -> Detalles -> Servicio y anotamos el nombre del servicio.
  • Nos vamos a la clave del registro HKLM\Software\Microsoft\Windows\CurrentVersion\DevicePath y eliminamos la carpeta que apunte a los viejos drivers.
  • Desinstalamos el dispositivo.
  • Abrimos una shell, nos vamos a c:\windows\inf y ejecutamos:

for %a in (oem*.inf) do find /i “nombre servicio apuntado” %a >> c:\kk.txt

  • Echamos un vistazo con notepad a c:\kk.txt y vemos cual es el oem*.inf responsable del driver, y nos lo pulimos junto a su correspondiente fichero pnf.
  • Le damos de nuevo a detectar nuevo hardware e indicamos el path a los drivers adecuados.

Nota: sería posible encontrar también el driver usando el identificador hardware como fuente de búsqueda.

Nota: para eliminar físicamente todos los ficheros del driver, en el paso uno anotaríamos los ficheros que usa el driver (controlador -> detalles del controlador) y, después de haber desinstalado el dispositivo, eliminaríamos aquellos ficheros del driver que no pertenezcan a Microsoft.

Nota: en windows vista/7 el nombre del fichero inf aparece directamente en las propiedades del driver, por lo que no es necesario buscar la cadena a mano.

Fuente original:
http://winhlp.com/node/199

Liberado LGDeploy Framework 0.1

5 de enero de 2011

Como ya apunté en la entrada anterior, estaba creando un software gestión centralizada de arranques, tareas de mantenimiento y despliegues de sistemas que pudiera usarse en escenarios tan dispares como un datacenter o un aula informática. Gracias a unas recientes vacaciones y a estos días festivos, he podido centrarme en su desarrollo y ofrecer la descarga de la versión 0.1 amparada bajo la licencia GNU AGPLv3.

Para mostrar su funcionamiento y sus posibilidades, me ha parecido interesante grabar a modo de documentación inicial unos screencasts en los que muestro la herramienta, hago uso de ella y realizo la instalación. Tal vez pasado Enero disponga de tiempo para crear una web con screenshots, documentación adicional y seguimiento de bugs, pero hasta entonces, esto es lo que hay.

En este primer screencast hago una pequeña presentación en la que explico las opciones y funcionalidades del software. Está en dos partes (cosas de Youtube):





En este segundo screencast expongo un caso de uso de despliegue de un sistema windows xp personalizado a un grupo de máquinas usando para ello los scripts de Ceutdeploy.


En este tercer screencast (primero en orden cronológico), muestro el sencillo proceso de instalación:


No está de más recordar que esta versión es una 0.1, por lo que es probable que tenga muchos bugs por solucionar. Por ello y hasta que no haya subido la aplicación a google code o a algún sistema que permita el seguimiento de bugs, me lo puedes enviar al correo y pasado Enero me pondré manos a la obra.

Nada más, tan solo espero que el software pueda servirte de alguna utilidad y que los Reyes Magos traigan a tus sistemas el orden y la paz que te mereces ;) .

Creado módulo FTSWebServer para la generación dinámica pxelinux.cfg

30 de noviembre de 2010

Probablemente ya conozcas el proyecto SYSLINUX, un cargador de arranque muy configurable y modular, que ofrece distintas utilidades en función de dónde queramos realizar su instalación: ISOLINUX (cdrom), EXTLINUX (partición ext2/3) y PXELINUX (arranque por red pxe). Como ya existe muchísima información al respecto, comentaré muy brevemente el funcionamiento de este último.

Básicamente necesitas dos cosas: un servidor dhcp y un servidor tftp. Por un lado se configurará el dhcp con las opciones adecuadas y por otro, bastará con almacenar en la raíz del tftp los binarios de pxelinux y sus módulos (aptegetea syslinux y copia los archivos de /usr/lib/syslinux/). A partir de este momento, cuando nuestra máquina realice un arranque por red, ejecutará el pxelinux.0 que irá a buscar en el directorio pxelinux.cfg del raíz tftp varios ficheros: en primer lugar comprobará si existe un fichero de configuración cuyo nombre es su mac (precedida por 01-) y en caso de no encontrarlo, continuará probando con su ip, subredes (codificadas en hexadecimal) y finalmente buscará un fichero default. Una vez obtenido, el cargador lo interpretará y cederá la ejecución al módulo o sistema operativo que corresponda.

Como vemos, es un mecanismo muy sencillo a la vez que potente, ya que podemos asignar arranques por máquina (o redes) personalizados de manera centralizada. Esto nos permitirá desde seleccionar el sistema operativo en el que arrancará la máquina hasta realizar backups completos, reparaciones del sistema, tareas de mantenimiento o despliegues de sistemas operativos de manera remota (e incluso automatizada).

Ahora bien, en su sencillez también radica su principal debilidad ¿qué ocurre si son cientos de hosts y distintos servidores tftp?, ¿sincronizamos o regeneramos?, ¿cómo puedo saber si se ha producido un arranque?, ¿cómo puedo introducir cierta lógica en la generación de la configuración basada en el momento en que se produce el arranque?…
Afortunadamente, y en respuesta a estos problemas el proyecto Gosa propuso una sencilla solución que además hizo modular para que se pudieran aprovechar otros proyectos. Y así lo hiceron FAI, LTSP y OPSI (y ahora yo ;) )

La solución viene en forma de un servicio “suplicante” llamado FTS. Su funcionamiento es sencillo. Básicamente monta un sistema virtual FUSE sobre el directorio pxelinux.cfg servido por el tftp, de modo que de forma transparente al servicio tftp, le provee de los ficheros solicitados. De este modo, cada solicitud de apertura de fichero al sistema fuse, se traduce en una petición que este suplicante realiza a un tercer servicio, como puede ser un ldap o un webservice.

Estuve mirando los módulos y ninguno hacía lo más sencillo: traducir la petición en una llamada a una url que pudieramos configurar y a la que le pasáramos por parámetro la dirección mac. Por ello, creé este simple modulito el perl (fts está escrito en este lenguaje). Básicamente hará lo siguiente:
CLIENTE (pxelinux.0) -> petición tftp 00-01-02-03-04-05-07 -> SERVIDOR TFTP -> fileopen(00-01-02-03-04-05-06) -> FTS -> petición web http://servidor/pxe.php?mac=01-01-02-03-04-05-07 -> SERVIDOR WEB

Casi me ha costado más escribir este post que programarlo. Ahí va el código:

package FTSWebServer;

# Autor: Luis Guillén Civera
# Fecha: 2010/11/19

use Exporter;
@ISA = ("Exporter");

use strict;
use warnings;

use Switch;
use LWP::Simple;

sub get_module_info {
  return "Web Server provider";
};

my $protocol;
my $admin;
my $password;
my $port;
my $server;
my $script;

my $cfg_defaults = {
  'protocol'  => [ \$protocol,  'http' ],
  'admin'  => [ \$admin,  '' ],
  'password'  => [ \$password,  '' ],
  'port'  => [ \$port,  '80' ],
  'server' => [ \$server, 'localhost' ],
  'script' => [ \$script, 'prueba.php?mac=' ]
};

sub get_config_sections {
  return $cfg_defaults;
}

sub get_pxe_config {
	my ($filename) = shift || return undef;

	my $base_url;
	if($admin) {
		$base_url = "$protocol://$admin:$password\@$server:$port/$script";
	} else {
		$base_url = "$protocol://$server:$port/$script";
	}

	my $web_url=$base_url.$filename;

	my $file_content=&LWP::Simple::get($web_url);

	&main::daemon_log("Getting $web_url...\n");
	if(!defined $file_content) {
		&main::daemon_log("Warning: url doesn't exist $web_url\n");
		return 1;
	}

	$main::filesystem->{'root'}->{'content'}->{$filename}->{'type'}='file';
	$main::filesystem->{'root'}->{'content'}->{$filename}->{'content'}=$file_content;

	return 0;
}

1;

¿Cómo lo instalamos y configuramos? muy fácil, basta aptegetear fts, libwww-perl y libcrypt-ssleay-perl (si deseamos https) (son paquetes de Ubuntu 10.04), copiamos el módulo con nombre FTSWebServer.pm en /usr/lib/fts/modules y configuraremos el /etc/fts/fts.conf del siguiente modo:

  1. comentar las opciones de ldap
  2. configurar pxelinux_cfg y pxelinux_cfg_static (mirar la documentación de fts. Básicamente es un directorio “real” paralelo en el que el servicio mirará en caso de no encontrarse disponible)
  3. agregar una sección:
    [FTSWebServer]
    protocol = http
    port = 80
    server = localhost
    script = pxe.php?mac=
    

Bastará entonces con relanzar el servicio o si se quiere lanzar en primer plano para ver las peticiones, usar el comando

# fts -c /etc/fts/fts.conf -f -s -v

Con un poco de imaginación puede verse la potencia de esta herramienta. Así lo vi yo y por ello actualmente estoy escribiendo un sistema simple de gestión de arranques y tareas centralizado para gestionar clusters y redes de workstations que espero tener listo en breves y publicar en unas semanas.

Scripts de configuración de una estación de trabajo con Ubuntu

17 de noviembre de 2010

Llevo usando sistemas GNU/Linux desde hace ya más de una década. Fue allá por el 96 cuando calló en mis manos mi primera distribución de GNU/Linux, un Slackware 96. Posteriormente fueron pasando Eurielec Linux, Red Hat, Suse, Debian y actualmente Ubuntu (también tuve otras como Gentoo, Lycoris y Mandrake aunque no duraron mucho en mis equipos). Desde entonces ha la llovido mucho, y aquel sistema operativo que parecía creado por aficionados, se ha convertido, junto con muchos otros proyectos libres exitosos (Apache, MySQL,…), en una robustísima plataforma tecnológica libre sobre la que asentarse y crear productos y servicios innovadores. Google, Facebook, Twitter o Amazon así lo han hecho (y opino que de no haber dispuesto de una plataforma así, simplemente por el aspecto económico, hubieran sido inviables desde un principio). Sin embargo, en otros segmentos del mercado en los que existía ya una cierta inercia (por llamar de un modo al monopolio existente), como los escritorios personales y empresariales, GNU/Linux ocupa un marginal 1%.

A pesar de esto, creo firmemente que la distribución que actualmente uso, Ubuntu, también está lista para el segmento de las estaciones de trabajo (tal vez comente en otro post porqué creo que es así). Por ello, y ante una reciente demanda en mi trabajo sobre la posibilidad de su instalación a algunos usuarios (a pesar de no poder ofrecer soporte institucional oficial, ni de tener la infraestructura adecuada), he confeccionado un sistema base de lo que sería una estación de trabajo. Para ello, en lugar de crear un live cd y rebautizar una nueva distribución (algo que se la pone dura a los políticos), he creado una serie de scripts parametrizables e independientes que se han de ejecutar tras una instalación limpia.

Para usarlos simplemente hay que bajarse el paquete y descomprimirlo sobre /usr/local (aunque puede ser en cualquier sitio), configurar los ficheros de configuración de etc (cada script usa su propio fichero) y lanzarlos independientemente o ejecutar el setup_workstation.sh que los ejecuta en el orden adecuado.

Voy a ofrecer un resumen de lo que hace cada uno:

Instalación del software base: install_base.sh

  • Configura apt en función de lo que se tiene en el directorio templates (de este modo puedes poner tus propios sources)
  • Configura el unattended-uptrades (ver directorio templates)
  • Actualiza la distribución
  • Instala software restringido como flash, fuentes ms, wine1.2 y software adicional como thunderbird.
  • Borra algunas ideas felices de Mark Shuttleworth como el cliente de UbuntuOne y el menú me (no son funcionales y no funciona con thunderbird)
  • Agrega repositorio de partners e instala el java de sun y el acroread (ojo, acroread no funciona con 64 bits y usuarios mapeados)
  • Software de medibuntu con codecs y reproducción de dvds

Configuración del servicio SSH: config_ssh.sh

  • Instala el ssh
  • configura para que sólo se puedan validar los usuarios del grupo admin y root (esto es práctico sobre todo si mapeamos posteriormente usuarios con winbind)
  • Agrega la key rsa especificada en el fichero de configuración al usuario root si existe (NO habilita la password de root)

Configuración de la red Windows: config_windows_networing.sh

En el estado actual, este script está preparado para un entorno con un dominio Windows NT4 y, según los parámetros de los ficheros de configuración, se puede configurar la estación de trabajo integrada con el dominio o no. En un futuro agregaré funcionalidad para integrarla en un Active Directory (tengo que desplegar la infraestructura en el “laboratorio” de mi casa).

Como comentaba, actualmente ofrece dos configuraciones en función del modo de seguridad que coinciden con el parámetro de Samba:

Modos de seguridad

  • Security: USER. Ofrece configuración de la estación como miembro de un grupo de trabajo. No agregará la máquina al dominio y los usuarios deberán ser necesariamente locales y darse de alta a mano.
  • Security: DOMAIN.
    • Une la máquina al dominio y la configura mediante la utilidad auth-client-config de ubuntu (hace los cambios pertinientes en nsswitch.conf y pam.d con un profile que he creado para esta situación) de modo la validación de sus recursos sean contra el dominio y los usuarios del mismo podrán logearse en ella.
    • Configura pam_group de modo que si se utiliza gdm, formen parte de los grupos plugdev, audio, video…
    • Configura winbind con caché para que pueda validar los usuarios incluso cuando no hay conexión de red con el servidor (ej. portátiles)

Configuración de wins

Se proporcionan tres configuraciones:

  • nowins: no se usa servicio wins para la resolución de nombres.
  • dhcp: la configuración se obtiene por dhcp. En este caso incluye un nuevo dispatcher para NetworkManager que he creado, ya que no usa los hooks de dhclient.
  • static: se le ofrece en otro parámetro las direcciones de los servidores wins.

En los casos de dhcp y static, configura también nsswitch para que haga resolución a nivel de sistema también por wins.

Evidentemente todo esto depende de las necesidades y a gusto del administrador. Habrá algunos que querrán tener la máquina en el dominio para compartir recursos, pero sin embargo no admitir inicio de sesión interactivo, mapear usuarios o grupos del dominio a locales, etc.
Una recomendación:
Si se emplea un único dominio (sin confianzas) es recomendable usar el backend rid para que el mapeo de usuarios se realice de igual modo en todas las máquinas.

Configuración del firewall: config_ufw.sh

  • Configura las reglas especificadas en la función set_ufw_rules definida en su correspondiente fichero de configuración
  • En el ejemplo pongo unas direcciones ips máquinas de administradores y asigno permisos para poder conectar por ssh y por vnc. También habilito el acceso a samba a las redes locales.

Configuración del login gráfico: config_gdm.sh

  • Configuro el gdm con el wallpaper especificado en su fichero de configuración y ofrece un login sin mostrar usuarios.

Configuración de los perfiles de usuarios

Esto va a gusto del consumidor, he dejado varias opciones:

  • usar sabayon (sin emplear ldap), en la que el usuario deberá crear sus perfiles y asignarlos a los distintos grupos. Hay que implementar la función getSabayonProfile en el fichero de configuración para que descargue nuestros perfiles.
  • ejecución en el primer inicio de sesión de cada usuario del script config_user_profile.sh, incluyéndolo al inicio del .profile del skel. En este caso he puesto un ejemplo:
    • deshabilita la extensión xdamage cuando se activa el escritorio remoto (necesario para muchos drivers)
    • crea diversos accesos a la red tomados del fichero de configuración (modifícalo a tu gusto para que cree los recursos adecuados en función de su pertenencia a grupos ;) ) (otra opción interesante sería usar pam_mount para montar automáticamente los recursos con las credenciales proporcionadas por los usuarios en el login)
    • configura el wallpaper
    • configura la página de inicio del firefox
  • otras no implementadas: como usar pam_exec para que se ejecute al iniciar sesión o sustituir directamente el skel por uno ya personalizado.

¡Espero que con esto ya no tengas escusas para migrar tus estaciones de trabajo a Ubuntu!