"Después del juego es antes del juego"
Sepp Herberger

miércoles, 16 de mayo de 2018

Captura de la pantalla de los alumnos (II)


En el anterior artículo vimos como capturar una imagen de las escritorios de los thinclients en un servidor de aula.

En el presente veremos como capturar las pantallas de pc normales (portátiles o pc de sobremesa). Aunque visualmente no hay diferencia, el reto es ahora es distinto ya que en este escenario los escritorios a capturar corren en pc remotos cuyas sesiones se ejecutan físicamente fuera del ordenador del profesor. En los thinclients todo eran tareas realizadas dentro del propio servidor de aula.

Para esta entrada asumimos que todos los pc de alumnos están dentro de una VLAN privada del aula, con direccionamiento 192.168.0.X.

La idea del proceso es:

  • En los PC de los alumnos hay un script que al ejecutarse hace una captura del escritorio y manda la pantalla al PC del profesor por algún medio.
  • En el PC del profesor hay un script que rastrea el aula en busca de PC de alumnos encendidos y ejecuta remotamente el script anterior en paralelo sin que haya petición de contraseña.
  • Todas las imágenes recopiladas se reunen en un único directorio y se abren para que el profesor pueda verlas.

En primer lugar, ¿cómo hacemos que el desde el pc del profesor se pueda ejecutar algo en los pc de los alumnos sin pedir contraseña?... pues con una relación de confianza. Esto puede automatizarse para que una vez generada la clave pública se distribuya mediante puppet a todos los pc de alumnos usando el recurso ssh_authorized_key.

En segundo lugar, ¿cómo hacemos para ejecutar un comando a la vez en varias máquinas desde el pc del profesor?...pues hay múltiples alternativas. En nuestros centros tenemos la suite "utilaula", desarrollada por nuestro compañero Ricardo, que incluye el script ejecutaenhosts:
ejecutaenhosts -p comando
y que ejecuta el comando indicado en paralelo en todos los pc de alumnos que encuentra dentro del aula en el espacio 192.168.0.X. Al final de esta entrada muestro una versión reducida de este script, pero cada cual puede usar la técnica que desee de las enumeradas en el enlace anterior.

En tercer lugar ¿cómo enviamos la imagen capturada al pc del profesor?. Evalué varias alternativas: copiarlas por scp desde el pc del profesor, enviarlas por tftp desde los pc de los alumnos, enviarlas por netcat ...al final la más simple que encontré es usar una carpeta samba para que los clientes dejen los ficheros y después recogerlos el profesor. Es una técnica que ya tengo montada en mi IES para otros scripts y siempre me ha funcionado bastante bien.

1. Script de captura en los pc de los alumnos.

Vamos primero a ver el script de captura que pondremos en todos los pc de los alumnos:
# cat /usr/bin/captura-escritorio
#!/bin/bash

directorio=$1
pc=$(hostname)
user=$(who | grep "(:0)" | head -1 | cut -f1 -d" ")
if [ -n "$user" ]
then
          su $user -c "DISPLAY=:0 import -window root /tmp/$user-$pc.jpg"
          cd /tmp
          smbclient -N //172.X.Y.Z/almacen -c "cd $directorio; put $user-$pc.jpg"
fi
exit 0 

Comentemos:
  • Toma un parámetro de entrada que será el directorio donde se dejará la imagen capturada del escritorio usando smbclient para subir el fichero a la carpeta remota.
  • La captura se hace de una forma similar a como se hacia en la entrada pasada, con su $user -c "DISPLAY=:0 import -window root /tmp/$user-$pc.jpg".
  • Envía la captura a una carpeta compartida por samba llamada "almacen" en el servidor 172.X.Y.Z, tal como describimos aquí.

2. Scripts en el pc del profesor.

A continuación vemos el programa que ordena la ejecución del script anterior en todos los pc de alumnos, que irá en sudoers ya que se ejecutará como root (esto también sucedió en la parte I de esta serie de entradas).
# cat /etc/sudoers
....
....
%teachers ALL = (ALL) NOPASSWD: /usr/bin/captura-escritorio-alumnos
....
....

El script que lanza la ejecución remota:
# cat /usr/bin/captura-escritorio-alumnos
#!/bin/bash
directorio=$1
/sbin/ejecutaenhosts -p "/usr/bin/captura-escritorio $directorio" 
exit 0

Comentemos:
  • De nuevo toma un parámetro de entrada que será el directorio dentro de "almacen" donde los clientes dejarán la imagen de captura.
  • Usa ejecutaenhosts para lanzar el comando en paralelo en todos los alumnos conectados dentro de la red privada del aula. Como dijimos antes, ejecutaenhosts es un script nuestro de los centros, pero se puede usar cualquier otro método.
Por último, el script que ejecutará el profesor y que lanza todo el proceso:
# cat /usr/bin/captura-escritorio-todos
#!/bin/bash

directorio=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 12 | head -n 1)
smbclient -N //172.X.Y.Z/almacen -c "mkdir $directorio"

pc=$(hostname)
fecha=$(date +%Y-%m-%d)
hora=$(date +%H:%M:%S)
destino="$HOME/capturas/$pc/$fecha/$hora"
rm -rf "$destino"
mkdir -p "$destino"

sudo /usr/bin/captura-escritorio-alumnos $directorio

cd "$destino"
smbclient -N //172.X.Y.Z/almacen -c "cd $id; prompt off; mget *; del *;cd ..;rd $id"

thunar "$destino" &

exit 0

Comentemos:
  • El nombre del directorio donde guardar las imágenes dentro de //172.X.Y.Z/almacen lo formamos con 12 caracteres aleatorios y lo creamos remotamente.
  • Creamos una carpeta local en el home del profesor con el pc, la fecha y la hora de la captura.
  • Llamamos al script de captura mediante sudo. Cuando acaba recogemos todas las capturas de "almacen", las metemos en la carpeta local, borramos la carpeta remota y abrimos "thunar" para mostrarlas al profesor
Como vemos, el resultado final es el mismo que en la entrada anterior, solo que la forma de conseguirlo es bastante distinta dada la diferente arquitectura de funcionamiento del aula.

Se aconseja poner al profesor un fichero .desktop en el escritorio para ejecutar "captura-escritorio-todos".

3. Ejecución en paralelo.

Pongo una versión light de ejecutaenhosts para que lo adaptes a tus necesidades si no lo tienes. Necesitamos que, tal como hemos comentado, la clave pública ssh haya sido repartida previamente a los alumnos para evitar que se pida la contraseña con cada ssh.
# cat /sbin/ejecutaenhosts
#!/bin/bash

if [ "$1" \= "-p" ] ; then 
   enparalelo="yes"
   shift
fi
#Busca los hosts conectados en la vlan en el rango 200-253
listahosts=$(nmap -oG - --system-dns  -sP 192.168.0.200-253 | grep -v '^#' | tr -d '()' | sed 's/.local//' | awk '{print $3 ";" $2}' | sort)
if [ -z "$listahosts" ]; then
  echo "No se ha encontrado ninguna maquina conectada"
  exit 0
fi

for hostip in $listahosts 
do
  host=$(echo $hostip | cut -d";" -f1)
  ip=$(echo $hostip | cut -d";" -f2)
  
  ssh -o StrictHostKeyChecking=no -o ConnectTimeout=9 -o ServerAliveCountMax=2 -o ServerAliveInterval=15 root@$ip $* > /dev/null 2>&1 &
done

echo -n "Esperando a que terminen los procesos "
for job in $(jobs -p)
do
     echo -n "."
     wait $job
done
echo -e "\n"
echo "Hecho!"
exit 0

Y con esto ya estamos, solo nos queda un caso más para tener cerrada la serie.

Nos vamos con la música a otra parte:


No hay comentarios:

Publicar un comentario