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

miércoles, 18 de mayo de 2016

Quitar acentos, eñes, etc del nombre de una serie de ficheros.

En mi centro tengo un proceso automático que sube un directorio completo de ficheros a un servidor ftp externo usado para publicación web. Ese servidor web no está muy afinado por su administrador en cuanto a codificación y tiene un problema con los ficheros que tienen en su nombre eñes, acentos y demás hierbas, por lo que para ahorrarme dolores de cabeza prefiero que no suba ningún fichero con esos caracteres en su nombre.

Aunque tengo a los usuarios que crean esos ficheros avisados para que tengan cuidado, es imposible evitar que se les cuele algo, por lo que lo mejor es usar un script que renombre esos ficheros antes de subirlos mediante la herramienta lftp.

Utilizo este código del blog de mi compañero Esteban, quedando así:

find /home/Publicaciones/ -type f -mmin +1 -print0 | while IFS= read -r -d '' -r f
do
  nuevo=$(echo "$f" |   sed  'y/áÁàÀãÃâÂéÉêÊíÍóÓõÕôÔúÚñÑçǪº/aAaAaAaAeEeEiIoOoOoOuUnNcCao/')
  test  "$f" != "$nuevo" &&  (echo "Corrigiendo $f" ; mv "$f" "$nuevo")
done

De esta manera me deshago de todo tipo de carácter que pueda causar problemas recorriendo el directorio /media/Publicaciones. Si el fichero experimenta cambios después de pasar por el sed lo renombro con "mv".

lunes, 16 de mayo de 2016

La conjura de los necios (V): "Parole, parole, parole"

Veamos una reunión de la Comisión de Educación, Empleo y Deportes del 13 de mayo del 2016:



El orden del día era:

COMPARECENCIA, ANTE COMISIÓN, A PETICIÓN DE LOS MIEMBROS DE LA CÁMARA (INF2C-32). De la Consejera de Educación y Empleo, o persona en quien delegue, a los efectos de informar ante la Comisión de Educación, Empleo y Deportes sobre la participación de Coordinadores TIC y Administradores Informáticos en el proceso de informatización de los centros de enseñanza no universitaria sostenidos con fondos públicos. Formulada por el Grupo Parlamentario PODEMOS Extremadura de conformidad con lo previsto en el artículo 202 del Reglamento de la Cámara. R.E. nº 4.270

Los políticos hablan, yo me voy a centrar en puntualizar varios hechos:

Minuto 7:50: el Secretario General (SG) afirma que todo el contrato de equipamiento era de fondos directos FEDER que expiraban a finales de 2015. Eso no es del todo cierto. Al menos dos lotes son contratos hechos por Red.es, los correspondientes a las impresoras de inyección no demandadas por nadie (1 millón de euros), y aunque su financiación sea también europea, no tengo elementos para afirmar o negar que tuviesen tales límites temporales:


Minuto 9:15: en ese momento no, pero ahora si sabemos que hubo una comisión secreta de expertos TIC, con reuniones secretas y deliberaciones, de momento, secretas, que han sido elevadas a la Consejería para su valoración.

Minuto 10:15: los administradores informáticos no hemos tenido, a día 16 de mayo, ni un solo curso de formación sobre el equipamiento TIC recibido. Los CPR están impulsando lentamente seminarios que son autogestionados en contenido y desarrollo por nosotros mismos, sin participación ni apoyo del Servicio TIC.

Minuto 21:10: no son impresoras 3D, son impresoras A3. No se han pedido muchas impresoras por que eran "para 10 años". Se han recibido por lo general entre 5-10 veces mas impresoras de las pedidas. En cambio otras cosas mas necesarias solicitadas en su día, como PC para servicios comunes, no se ha recibido ninguno.

Minuto 23:00: que a mi me conste, ningún CPR ha organizado sesiones informativas para administradores informáticos. A mi intentaron colarme en una reunión sobre pizarras digitales, pero vetaron mi presencia ya que solo era para docentes-TICs.

Minuto 31:00: no contar con un colectivo o enviar material innecesario no es una generalización. Que algo suceda de forma general no quiere decir que se esté generalizando al decirlo. Se generaliza cuando el hecho es anecdótico y se eleva a universal.

Minuto 33:50: el anterior Gobierno empezó a socavar el uso del SW Libre, pero el actual ha seguido en esa senda y la ha ampliado desde Educación a Sanidad. Eso es algo evidente.

Minuto 35:20: el foro CoorTIC se usa cada vez mas....para quejarse, no para encontrar soluciones. Es nuestro muro de las lamentaciones privado, sin un Yahveh al otro lado para leer los papelitos con nuestras quejas.

Minuto 37:20: en infolabs no hay 3 o 4 asuntos pendientes en aulas. No, hay varios problemas técnicos y de material que afectan a todos los centros de manera general y sin solución satisfactoria a día de hoy. En el foro CoorTIC están enumerados. De igual manera que hay asuntos pendientes de resolver en casí todos los lotes.

Minuto 37:42: es falso que las impresoras no usadas se retiraron en su momento. Siguen amontonadas ocupando espacio en los centros. No me consta que se haya recogido ninguna impresora excepto alguna que fue rechazada en el momento de la entrega.

Minuto 39:00: todavía falta por entregar material a los centros, no está todo repartido ni montando en los términos del contrato.

Y eso es lo que hay, todo lo demás:



Salud.


sábado, 14 de mayo de 2016

VirtualBoxing Windows (Parte I)

Bueno, pues aunque la Junta de Extremadura apuesta por Linux, a nosotros nos está obligando a dejar también abierto el acceso Windows en determinadas máquinas de los IES, haga falta o no. El año próximo apostará por la comida sana en los comedores escolares y en consecuencia habrá cubos de pollo KFC junto al menú normal. Libeggggtad de elección ante todo.

Como a nadie de los que deciden se le ocurrió que para administrar un número considerable de puestos Windows y no morir en el intento hace falta un Windows Server, directorio activo y mas herramientas de ese estilo, me veo con que tengo que encontrar una manera cómoda de administrar este tinglado intentando que:

1) Los datos de cada usuario puedan ser guardados en un almacenamiento privado y ubicuo dentro de la red del centro. Los tenemos malacostumbrados con nuestro NFS de Linux a esa facilidad de uso y no van a llevar bien volver a los 90 en materia de almacenamiento de datos.

2) Los Windows se estropean o se contagian de virus con una facilidad pasmosa en un sitio donde se comparten los puestos. Debo garantizar una forma rápida y de coste cero de recuperación de Windows a un estado previo.

3) Muchas veces, con un par de días (o minutos) de antelación te piden instalar un software concreto en una serie de puestos, siendo imposible encontrar un hueco para entrar en el aula y prepararlos todos.

Tras darle una docena de vueltas he llegado a la conclusión de que la mejor solución que se me ocurre es:

1) Ejecutar los Windows en una máquina virtual VirtualBox desde una sesión Linux. Eso permite restaurar un Windows rápidamente a un estado previo o distribuir una imagen nueva con software adicional (simplemente es copiar un fichero .VDI conteniendo el disco duro). Esa distribución se pude hacer incluso por la noche y la restauración de imágenes es inmediata.

2) La máquina virtual será definida a nivel de máquina física, en el directorio /opt. Todos los usuarios que hagan login en la máquina física compartirán maquina virtual, no es operativo que cada usuario tenga una máquina virtual en su home como sería el funcionamiento por defecto de VirtualBox.

Para acceder a ella pondremos un icono con un acceso directo en el panel XFCE, de tal manera que no se llega a ver nunca el entorno VirtualBox completo: pinchas y se abre una ventana que carga un Windows. Adjunto captura con el icono para lanzar Windows desde el panel (el icono azul con la ventanita, que poco original):


3) Puesto que antes de llegar a la máquina virtual el usuario tiene que acceder al Linux con sus credenciales, éste tiene acceso a su $HOME del servidor NFS. Lo que voy a hacer es antes de abrir la máquina virtual mapear el $HOME del usuario sobre la unidad E: del Windows (joder, 2016 y todavía con letras de unidad como el CP/M en los años 70). De esta forma, cuando el usuario de la máquina virtual Windows guarde cosas en la unidad E: lo estará haciendo en un sitio seguro externo a la máquina: su carpeta NFS del servidor central.

Bueno, pues una vez establecidos los principios vamos a lo divertido: manos a la obra, que hay que producir riqueza mas rápido que los políticos producen deuda.

Paso 1) Establecer /opt/... para guardar las máquinas vitruales, usando para ello el fichero /etc/environment ya que permite definir variables globales para todo el sistema, que queda:
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
VBOX_USER_HOME="/opt/VirtualBox VMs/VirtualBox"
Debemos reiniciar el sistema para que esto se aplique.

Paso 2) Abrimos VirtualBox y creamos la maquina virtual con un nombre WinX, instalamos en ella Windows, lo activamos con su clave de licencia legal y ponemos todo el software que sea necesario. Al final dentro de /opt debe quedar algo parecido a esta estructura (el run_vbox lo vemos ahora en un rato):
/opt/VirtualBox\ VMs/
    run_vbox
    VirtualBox
        compreg.dat
        selectorwindow.log
        VBoxGuestAdditions_4.3.36.iso
        vbox-ssl-cacertificate.crt
        VBoxSVC.log
        VirtualBox.xml
        VirtualBox.xml-prev
        xpti.dat
    Win10
        Logs
        Win10.vbox
        Win10.vbox-prev
        Win10.vdi
Recoordemos que en Wind10.vdi se encuentra el disco duro de la máquina virtual y será el fichero del que hagamos copias para restaurar el sistema y distribuyamos cuando hayamos añadido algo nuevo al sistema que contiene.

Paso 3) Creamos un script que lanzará de forma automática la máquina virtual con un click, para que el usuario no tenga que hacerlo a través de VirtualBox
# cat /opt/VirtualBox\ VMs/run_vbox
#!/bin/bash

#Poniendo esto  /etc/environment
#export VBOX_USER_HOME="/mnt/VirtualBox VMs/VirtualBox"
#en el arranque lo tendremos para todos los usuarios. Maquinas virtuales en local.

machine="Win10"

running=$(VBoxManage list runningvms | grep $machine)
if  [ -n "$running" ]
then
    zenity --error --text "La máquina $machine ya está funcionando"  
else
   #Si cierran la ventana a lo bruto se hace un shutdown de la máquina. Esto al .vbox de la máquina
   #    <extradataitem name="GUI/LastCloseAction" value="Shutdown"/>
   #o bien con VBoxManage...
   VBoxManage setextradata $machine "GUI/LastCloseAction" "Shutdown"

   #Automontamos la carpeta $HOME en el Windows con el nombre "compartido" en la primera unidad libre (E: normalmente).
   VBoxManage sharedfolder add "$machine" --name "compartido" --hostpath "$HOME" --automount

   #Lanzamos la máquina
   VirtualBox --startvm $machine
fi
Paso 4) Creamos un fichero .desktop para el script anterior:
# cat /usr/share/applications/winx.desktop
[Desktop Entry]
Version=1.0
Name=Windows 8
Comment=Windows 8
Exec="/opt/VirtualBox VMs/run_vbox" 
Terminal=false
Icon=/usr/share/icons/hicolor/win8.png
Type=Application
Categories=Categories=X-XFCE;GTK;Utility;
MimeType=text/html;text/xml;application/xhtml_xml;image/webp;x-scheme-handler/http;x-scheme-handler/https;x-scheme-handler/ftp;
X-Ayatana-Desktop-Shortcuts=NewWindow;NewIncognito
El icono /usr/share/icons/hicolor/win8.png sería este:

Paso 5) Para colocar el enlace en el panel XFCE y que esté fijo y visible para que todos los usuarios lo tengan a la vista para lanzar el Windows en el momento en que lo deseen utilizo el método descrito en esta entrada:

El fichero con el xfce4-panel.xml quedaría mas o menos (en negrita lo destacable):
<?xml version="1.0" encoding="UTF-8"?>
<channel name="xfce4-panel" version="1.0" unlocked="root">
<property name="panels" type="uint" value="1">
<property name="panel-0" type="empty">
<property name="position" type="string" value="p=8;x=840;y=945"/>
<property name="length" type="uint" value="100"/>
<property name="position-locked" type="bool" value="true"/>
<property name="plugin-ids" type="array">
<value type="int" value="1"/>
<value type="int" value="8"/>
<value type="int" value="9"/>
<value type="int" value="11"/>
<value type="int" value="12"/>
<value type="int" value="13"/>
<value type="int" value="10"/>
<value type="int" value="2"/>
<value type="int" value="3"/>
<value type="int" value="4"/>
<value type="int" value="5"/>
<value type="int" value="6"/>
<value type="int" value="7"/>
</property>
<property name="background-alpha" type="uint" value="80"/>
<property name="background-style" type="uint" value="2"/>
<property name="background-color" type="empty"/>
<property name="background-image" type="string" value="/usr/share/images/PanelWin7.png"/>
<property name="size" type="uint" value="36"/>
<property name="autohide" type="bool" value="false"/>
<property name="length-adjust" type="bool" value="true"/>
<property name="span-monitors" type="bool" value="false"/>
<property name="enter-opacity" type="uint" value="100"/>
<property name="leave-opacity" type="uint" value="100"/>
<property name="mode" type="uint" value="0"/>
<property name="nrows" type="uint" value="1"/>
<property name="disable-struts" type="bool" value="false"/>
</property>
</property>
<property name="plugins" type="empty">
<property name="plugin-1" type="string" value="whiskermenu"/>
<property name="plugin-2" type="string" value="tasklist">
<property name="flat-buttons" type="bool" value="true"/>
</property>
<property name="plugin-3" type="string" value="separator">
<property name="style" type="uint" value="0"/>
<property name="expand" type="bool" value="true"/>
</property>
<property name="plugin-4" type="string" value="systray">
<property name="show-frame" type="bool" value="false"/>
<property name="size-max" type="uint" value="22"/>
<property name="names-visible" type="array">
<value type="string" value="blueman-applet"/>
<value type="string" value="miniaplicación gestor de la red"/>
<value type="string" value="ibus panel"/>
</property>
</property>
<property name="plugin-5" type="string" value="indicator">
<property name="blacklist" type="array">
<value type="string" value="com.canonical.indicator.keyboard"/>
<value type="string" value="com.canonical.indicator.session"/>
<value type="string" value="com.canonical.indicator.datetime"/>
<value type="string" value="libappmenu.so"/>
</property>
<property name="known-indicators" type="array">
<value type="string" value="libapplication.so"/>
<value type="string" value="com.canonical.indicator.power"/>
<value type="string" value="com.canonical.indicator.messages"/>
<value type="string" value="com.canonical.indicator.sound"/>
<value type="string" value="libprintersmenu.so"/>
<value type="string" value="com.canonical.indicator.keyboard"/>
<value type="string" value="com.canonical.indicator.session"/>
<value type="string" value="com.canonical.indicator.bluetooth"/>
<value type="string" value="com.canonical.indicator.datetime"/>
</property>
</property>
<property name="plugin-6" type="string" value="separator">
<property name="style" type="uint" value="0"/>
<property name="expand" type="bool" value="false"/>
</property>
<property name="plugin-7" type="string" value="clock">
<property name="digital-format" type="string" value="%d %b, %H:%M"/>
<property name="mode" type="uint" value="2"/>
</property>
<property name="plugin-8" type="string" value="showdesktop"/>
<property name="plugin-9" type="string" value="places">
<property name="blacklist" type="empty"/>
<property name="known-indicators" type="empty"/>
</property>
<property name="plugin-11" type="string" value="launcher">
<property name="items" type="array">
<value type="string" value="google-chrome.desktop"/>
</property>
</property>
<property name="plugin-12" type="string" value="launcher">
<property name="items" type="array">
<value type="string" value="rayuela.desktop"/>
</property>
</property>
<property name="plugin-13" type="string" value="launcher">
<property name="items" type="array">
<value type="string" value="winx.desktop"/>
</property>
</property>
<property name="plugin-10" type="string" value="actions">
<property name="items" type="array">
<value type="string" value="-lock-screen"/>
<value type="string" value="-switch-user"/>
<value type="string" value="+separator"/>
<value type="string" value="-suspend"/>
<value type="string" value="-hibernate"/>
<value type="string" value="-separator"/>
<value type="string" value="-shutdown"/>
<value type="string" value="-restart"/>
<value type="string" value="-separator"/>
<value type="string" value="+logout"/>
<value type="string" value="-logout-dialog"/>
</property>
<property name="appearance" type="uint" value="0"/>
<property name="invert-orientation" type="bool" value="false"/>
<property name="ask-confirmation" type="bool" value="true"/>
</property>
</property>
<property name="configver" type="int" value="2"/>
</channel>
Paso 6) Con todo ya montado, he hecho vídeo en el que abrimos el Windows y jugamos con el un rato, creando ficheros sobre el $HOME del usuario que está ejecutando todo. Eso garantiza que esos icheros estarán ubicuos en cualquier ordenador de la red y no se quedarán enclaustrados dentro de la máquina virtual Windows. Enlace al vídeo (reproducelo en HD para ver bien los detalles) https://drive.google.com/open?id=0B8np4HndYC-lMmZxWlRSZndIRVE.



Una cuestión interesante es el tema de las licencias. Cada máquina virtual debe tener la licencia correcta, pero si nos dedicamos a copiar VDI de una máquina física a otra, todo va con la misma licencia. ¿Como se soluciona esto?. Sencillo:

  • Aquí contamos como extraer la licencia del Windows que nos viene de serie en cada máquina fisica. Por supuesto, también podemos tener los números de licencia si los hemos comprado por otra vía.
  • Aquí nos cuentan como con un sencillo script .vbs que viene de serie podemos cambiar el código de licencia de un Windows y activarlo fácilmente.

Como colofón me dejo un par de notas que con vías interesantes para explorar en el futuro:
  • Crear un usuario o sesión que abra un VirtualBox a pantalla completa, sin entorno de escritorio gráfico. Todo el escritorio para Windows, pero un Linux por debajo.
  • Encontrar como hacer un mapeo para acceder a los pendrives pinchados en la máquina física.

Con esto podemos decir que todos nuestros usuarios tendrán acceso a Windows en las máquinas donde adoptemos este modelo, les haga falta o no. Ya pueden respirar tranquilas nuestras autoridades.

Dos funciones puppet para instalar paquetes debian.

Muchas veces queremos instalar un paquete en nuestro Linux controlado por puppet y resulta que este paquete no está dentro de los repositorios ya que no es un paquete "oficial", por lo que no podemos usar el recurso package.

En ese caso, la tarea puppet debe llevar el fichero .deb hasta la máquina cliente y luego instalarlo, usando varios "exec" de puppet encadenados. Esto con el tiempo es tan frecuente que he decidido hacer un par de funciones para implementarlo y poder usarlo de forma cómoda.

Vamos allá, el primer define lo he llamado "instala_paquete_local", que coge el paquete ".deb" del directorio "files" del módulo desde donde se invoca la función. En los parámetros decimos el nombre del paquete, su versión y el .deb que lo contiene y la función se encarga de copiar el paquete al cliente e instalarlo si no estaba ya instalado.

root@servidor:/etc/puppet/defines# cat instala_paquete_local.pp 

#Coge un paquete .deb del directorio files del modulo desde donde se llama el define y se instala en el equipo si no está.
# $title = nombre del paquete
# $version = versión del paquete
# $paquete = nombre completo del paquete

#Ejemplo uso dentro de un módulo de /etc/puppet/modules/nombre-modulo/manifests/init.pp:
#   instala_paquete_local {"brother-udev-rule-type1":
#       version=>"1.0.0-1",
#       paquete=>"brother-udev-rule-type1-1.0.0-1.all.deb",
#   }
#El fichero brother-udev-rule-type1-1.0.0-1.all.deb estaría en /etc/puppet/modules/nombre-modulo/files/


define instala_paquete_local($version,$paquete) {

       #$caller_module_name es una builtin variable que identifica el modulo llamante del define

       file {"descarga_$title":
                path => "/var/cache/$paquete",
                owner => root, group => root, mode => 644,
               source => "puppet:///modules/$caller_module_name/$paquete",
                notify => Exec["instala_$title"]
       }
      
       exec { "instala_$title":
              path => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
              command => "lsof /var/lib/dpkg/lock || (dpkg -i --force-architecture /var/cache/$paquete; apt-get -y -f install)",
              refreshonly => true,
              unless => "dpkg -l |grep $title | grep $version | grep ^ii",
              require => File["descarga_$title"]
       }

}
El segundo define lo he llamado "instala_paquete_web", ya que descarga el paquete ".deb" de una URL que le indicamos como parámetro, siendo el resto de parámetros iguales al caso anterior.
 root@servidor:/etc/puppet/defines# cat instala_paquete_web.pp 
#Descarga un paquete desde una URL web y lo instala si no está instalado en el equipo.
# $title = nombre del paquete
# $version = versión del paquete
# $url = url de descarga

#Ejemplo uso dentro de un módulo de /etc/puppet/modules/nombre-modulo/manifests/init.pp:
#   instala_paquete_web {"brother-udev-rule-type1":
#       version=>"1.0.0-1",
#       url=>"http://servicor-web/ficheros/puppet/brother-udev-rule-type1-1.0.0-1.all.deb",
#   }


define instala_paquete_web($version,$url) {

       exec { "descarga_$title":
           path => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
           command => "wget -q $url -O /var/cache/$title.deb",
           unless => "dpkg -l | grep $title | grep $version | grep ^ii",
           notify => Exec["instala_$title"]
       }

       exec { "instala_$title":
              path => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
              command => "lsof /var/lib/dpkg/lock || (dpkg -i --force-architecture /var/cache/$title.deb; apt-get -y -f install)",
              unless => "dpkg -l |grep $title | grep $version | grep ^ii",
              refreshonly => true,
              require => Exec["descarga_$title"]
       }

}

Unos cuantos comentarios:

1) Las dos funciones: junto con el resto de funciones que ya tengamos, estarán /etc/puppet/defines/... del servidor puppet.
2) Si tenemos pkgsync en los clientes no olvidar poner el paquete instalado en el mayhave del cliente.
3) El "lsof /var/lib/dpkg/lock" sirve para comprobar que no está en marcha ningún proceso sobre el sistema de paquetes, asegurando así que la instalación se realiza sin errores.

Bueno, pues a instalar, a instalar, que el mundo se va a acabar.

sábado, 7 de mayo de 2016

Saltar los límites en shell restringidos inyectando comandos Unix

Muchos routers wifi y dispositivos similares tienen un Linux dentro al que podemos acceder por ssh o por telnet, pero una vez allí vemos que tienen un shell o un busybox restringido, que solo deja ejecutar algunos comandos Unix.

Buscando otras cosas sobre un router ADSL Nucomm llegué aquí en donde nos cuentan como saltarnos esa limitación. La idea es inyectar comandos shell de forma parecida a como se puede inyectar SQL en un formulario que no está bien protegido. Por ejemplo, si el comando pwd está permitido pero el comando cat no, podemos intentar:
# pwd & cat /etc/passwd
o bien
# pwd ; cat /etc/passwd
Con sorpresa veremos que ambos comandos se ejecutan (concurrentemente en el primer caso y en serie en el segundo, da igual), de tal forma que tenemos acceso al fichero /etc/passwd del router.

La causa seguramente es que el analizador sintáctico de esa shell limitada es tan cutre que solo comprueba el primer comando introducido para filtrarlo, dando paso al resto sin analizarlo.

Un truco interesante que me apunto para otros router, switch y sistemas embebidos parecidos.

Y con esta pildorita vuelvo a la madriguera, que el trabajo nos tiene muuuuuuy atareados.

lunes, 25 de abril de 2016

Printer Wars II: Resetear contador de consumibles OKI B45XX.

Bueno, pues ahora vamos a por una OKI B4525/B45XX. La encontramos en la basura sin tóner pero con un tambor al que todavía le quedaba bastante vida útil, así que compré un cartucho de tóner reciclado de 6000 copias.

Por lo visto había que resetear los datos de contabilidad de consumibles, así que me puse a buscar por todo el menú de su panel táctil sin éxito. Parece ser que OKI no quiere que nadie resetee fácilmente sus impresoras y no tiene la información muy visible.

Afortunadamente en este foro daban la pista, primero hay que entrar en "modo admin":

  • Tecla down (flecha abajo), tecla "*" y tecla "#".
  • El menú cambia y muestra un menú oculto : ahora es "SOS1", "SOS2", ... o algo similar, dependiendo del idioma.
  • Entramos en SOS1, aparece un número de 8 bits, por ejemplo "00100001".
  • Cambiamos el primer bit a "1", quedando algo así como "10100001". Volvemos al menú inicial.
  • Reiniciamos la impresora apagando y volviendo a encender.

Una vez reiniciada ya estamos en modo admin, lo cual nos da una serie de funcionalidades para resetear, borrar y hacer muchas más cosas con la impresora. Esas funcionalidades las encontré en la página 23 y sucesivas de este manual de servicio. Adjunto capturas de pantalla:


A mi me interesaba resetear los contadores de consumibles, en ese caso la opción es entrar en Menú (pulsando la tecla de bajar,por ejemplo)-> pulsar "#" -> pulsar "4". Bueno, pues nada, no se resetea nada. Y no es que esté mal el manual, el resto de opciones si funciona, simplemente sucede que OKI no deja que se reseteen esos datos ni siquiera con el "modo admin", aunque el manual de servicio sugiera que es posible.

¿Y como se resetean entonces?. Pues comprando aparte una "tarjeta de reseteo" que se supone solo fabrica OKI y distribuye con sus tóner "originales", aunque se pueden encontrar tarjetas clónicas en AliExpress:


Y en esas estoy, compuesto y sin tóner. ¿Compro la tarjeta al lejano oriente?. Ya veremos.

Adelantando un post que tengo en la recámara, lanzo la siguiente pregunta: Señor OKI, ¿usted qué fabrica? ¿impresoras? ¿cartuchos de tóner? ¿tarjetas chip?. Sepan que han perdido un cliente por su forma estrambótica de controlar el mercado de consumibles. Yo pensaba que eran una empresa seria y resulta que no.

sábado, 23 de abril de 2016

Recopilar mediante puppet de forma masiva las claves de licencia de Windows 7/8/10.

Si en nuestra base de equipos instalados tenemos un buen número de instalaciones duales de Ubuntu+Windows no viene mal poder recopilar las claves de licencia de todos ellos. Es importante tener un inventario de licencias actualizado, así que vamos a ver como hacerlo de forma automática usando un facter de puppet.

La clave de licencia se almacena en una tabla de la BIOS del equipo y se puede mostrar con el comando:
~# hexdump -s 56 -e '"MSDM key: " /29 "%s\n"' /sys/firmware/acpi/tables/MSDM
Con un facter de puppet tendremos el sistema ideal para recoger el dato de forma automatizada:
~# cat /usr/lib/ruby/vendor_ruby/facter/windows_key.rb

# Archivo /usr/lib/ruby/vendor_ruby/facter/windows_key.rb
# Se utiliza para obtener, si es posible, la licencia del windows de la máquina donde se ejecuta.
# 

if File.exist?('/sys/firmware/acpi/tables/MSDM') and key = Facter::Util::Resolution.exec(%Q(hexdump -s 56 -e '/29 "%s"' /sys/firmware/acpi/tables/MSDM))
   Facter.add("WINDOWSKEY") do
            setcode { key }
   end
end

####
Para distribuirlo a todos los clientes usamos esta regla puppet desde una clase que llamaremos "nombre_clase":
.....
#Facter puppet para sacar la clave de Windows OEM de siatics/infolabs y (por probar) portatiles HP

file {"/usr/lib/ruby/vendor_ruby/facter/windows_key.rb":
                                owner => root, group => root, mode => 644,
                                source => "puppet:///modules/nombre_clase/windows_key.rb",
}
.....
Una vez distribuida a todos los clientes, obtendremos en cada cliente la clave con:
 ~# facter windowskey
7WNG2-PXY6F-XXXXX-YYYYY-ZZZZZ
Y, lo mas importante, todos los facter se guardan en el servidor puppet, en los ficheros de facts con formato yaml. De esta forma tendremos centralizado en un sitio todas las claves de licencia recopiladas:
~# grep -ir windowskey /var/lib/puppet/yaml/facts/* 
pc-o23.vguadalupe.yaml:    windowskey: "7WNG2-PXY6F-XXXXX-YYYYY-ZZZZZ"
..........................
Como guinda al pastel solo falta desvelar como recopilar las licencias de nuestros Linux:



lunes, 18 de abril de 2016

Printer Wars I: Re-Animator

Empiezo una serie de posts sobre aventuras y desventuras con impresoras variadas. La primera es mi Epson DX3800, una impresora de inyección que tiene varias características avanzadísimas:

  • Gasta tinta de color incluso cuando imprimes solo en blanco y negro.
  • Si se gasta un cartucho de tinta de color hay que reponerlo sí o sí, aunque solo quieras imprimir en "grayscale".
  • Tiene en la parte baja de sus entrañas una esponja increíble que absorbe todos los mililitros de tinta que no es capaz de hacer llegar al papel. Hay un dineral en tinta perdido para siempre allí abajo.

Tras una época sin usar, me encontré con que ya no imprimía. Puse cartuchos nuevos y tampoco: se habían "secado los inyectores", taponándose con tinta seca. El problema es que todavía tenía varios cartuchos sin abrir y no me parecía razonable tirarlos, así que empecé a buscar una solución. Y encontré ésta:



Parece broma, pero si bombeas dentro del cabezal y extraes lo que te arrastre la succión (coloreado con la tinta correspondiente) varias veces, dejando a continuación secar todo un par de días al poner el cartucho la impresora imprime de nuevo.

Como en la película Re-Animator necesitamos un líquido para hacer revivir los inyectores; en mi caso el líquido que ha funcionado ha sido el Cristasol de toda la vida (nada de marcas blancas), rebajado con un poco de agua:


Las otras herramientas usadas han sido un par de jeringas grandotas: una con un tubo de goma que me ha dejado el profesor de Tecnología y otra una jeringa de repostería comprada en una tienda de chinos (la impresionante aguja no sirve de nada en esta tarea, la uso para meter miedo a los niños). Lo mas sencillo para no dejarlo todo empantanado es que el tubo se acople lo mejor posible al "pitoche" del inyector y así poder bombear metiendo y sacando líquido varias veces con ayuda del vacío.


Detalle de los inyectores:


No se ve bien, pero los "pitoches" de los inyectores tienen unos agujeritos en su superficio que es por dónde entra la tinta del cartucho hacia abajo. Seguramente esos agujeritos son los que se taponan con la tinta seca y al meter el cristasol a presión se disuelve todo.

Después del tratamiento, dejé secar la impresora un par de días y puse los cartuchos. Y ¡voilá! imprimiendo de nuevo a la perfección. Toma ya, Epson.

Epílogo I: aun así no todo ha sido feliz. Los rodillos no siempre cogían el papel (era un problema que ya tenía de antes) así que desmonté toda la impresora siguiendo el "Service Manual" para echar un vistazo y limpiar un poco. Al final del todo, en la parte mas profunda encontré entre los rodillos un trozo de mina de lápiz naranja (#!@@!"&) ... la quité, limpié los rodillos con alcohol y los sometí un par de pasadas con lija de grano grueso:



Monté todo de nuevo sin que me sobrara un tornillo y ¡ajá!, ya coge todo el papel sin problema.

Epílogo II: Epson me odia por alargar la vida de sus trastos. Al apagar la impresora y volverla a encender ha empezado a dar error de fallo general (todos los led se ponen a parpadear compulsivamente). Una de cada diez veces se enciende bien, la cual aprovecharé para imprimir hasta agotar los cartuchos y luego procederé a desmontarla para piezas.

Me encantaría desmontar la parte de escáner y seguir usándo eso sin el resto de impresora, pero me huelo que va a ser imposible. Malditos capitalistas, con esta impresora tan poco aprovechable Mark Watney hubiera muerto en Marte.

jueves, 14 de abril de 2016

Configurando la VGA en los HP ProDesk 600 G2 SFF (Parte I)

Los equipos que hemos recibido para los laboratorios de informática son HP ProDesk 600 G2 SFF. Aunque en la licitación se supone que los equipos deberían ser compatibles 100% con Ubuntu y venir preparados para ello, lo cierto es que hemos tenido que resolver varias "features" por nuestra parte para hacerlos funcionales, estables y sin cuelgues.

Estos equipos traen 2 tarjetas VGA:
00:02.0 8086:1912 VGA compatible controller: Intel Corporation Sky Lake Integrated Graphics (rev 06) 
01:00.0 10de:1287 VGA compatible controller: NVIDIA Corporation GK208 [GeForce GT 730] (rev a1)  
La tarjeta Intel está en la placa y la nVidia está pinchada en un bus.

En el aspecto gráfico hemos tenido 2 problemas:

  • Si encendemos el PC conectado por una salida DisplayPort al monitor (un HP ProDisplay P232) con éste apagado, al encender el monitor a posteriori resulta que permanece "fundido en negro" y no hay manera de ver nada, aunque el PC sea accesible por ssh.
  • El uso o la simple presencia del driver xorg y/o el módulo del kernel "nouveau" provoca cuelgues aleatorios, en los que la pantalla se apaga y el equipo no es accesible por ssh.

Vamos a ver como resolver estos problemillas.

1) Solución al monitor que no muestra imagen al encenderse a posteriori.

Como este problema no aparecía con cables VGA estaba a punto de tirar la toalla y conectar todos los PC con cable VGA, pero afortunadamente mi compañero Francis Paniagua dió con la solución:

"He estado buscando información y he leído que desactivando DDC/CI Support en el propio monitor funcionaba ... pero nada, me he puesto a hacer mas pruebas y entrando en la configuración del monitor en "Input Control": desactivando "Auto Switch Input" (poner a valor Off) y poniendo "DP Hot-Plug Detection" a Always Active, sí funciona."

Pues nada, nos toca ir monitor a monitor haciendo esto, lástima de no tener un alumno castigado y aburrido para ayudarnos.

2) Solución 1 a los problemas provocados por el driver/módulo nouveau.

Esta consiste en instalar el driver propietario de nvidia, que anula el nouveau y usar la tarjeta nvidia para conectar la pantalla. Para ello me guié en este enlace.

En esta solución, usada para el PC del profesor, quiero además que el monitor esté conectado a la salida DisplayPort y tener un cañon de video con la imagen del principal clonada en la salida DVI/VGA. Veamos los pasos:

1) Asegurarnos de que no se carga el módulo nouveau del kernel, metemos este fichero y reiniciamos:
# cat /etc/modprobe.d/nvidia-installer-disable-nouveau.conf 
# generated by nvidia-installer
blacklist nouveau
options nouveau modeset=0
2) Paramos el lightdm desde consola.
# service lightdm stop
3) Entramos en consola y ejecutamos el fichero:
# ./NVIDIA-Linux-x86_64-361.28.run
que hemos descargado de la página de drivers de nvidia y hecho ejecutable con "chmod +x". Si se queja por algo le decimos que si una y otra vez, lo importante es que continúe. Después de quejarse por todo llegamos al final y resulta que lo ha instalado. nVidia debería contratar a otra gente para hacer los instaladores: los que tiene ahora parecen una gincana.

4) Ajuste de resolución para cañón y pantalla:

Hemos dicho que queremos tener clonados monitor (salida DIRECTPORT) y cañon de vídeo (salida DVI). Si no es tu caso, olvida este apartado o adáptalo a tus circunstancias. Por experiencia puedo decir que lo mas sencillo es crear un script de inicio que use xrandr.
# cat /usr/bin/resolucion_infolab_nvidia 

#!/bin/bash

test -e  $HOME/.config/xfce4/xfconf/xfce-perchannel-xml/displays.xml  &&  rm  $HOME/.config/xfce4/xfconf/xfce-perchannel-xml/displays.xml

DVI=$(xrandr | grep " connected" | grep DVI | cut -d" " -f1)
DIRECTPORT=$(xrandr | grep " connected" | grep DP | cut -d" " -f1)

xrandr --output $DIRECTPORT --mode 1440x900 --pos 0x0 --rotate normal \
       --output $DVI --mode 1024x768 --pos 0x0 --rotate normal \
       --same-as $DIRECTPORT --scale-from 1440x900

exit 0
Que ejecutamos con:
# cat /etc/xdg/autostart/Resolucion.desktop 

#!/usr/bin/env xdg-open

[Desktop Entry]
Version=1.0
Type=Application
Terminal=false
Icon[zh_CN]=
Exec=/usr/bin/resolucion_infolab_nvidia
Name[zh_CN]=Resolución
Name=Resolución
Icon=/usr/share/icons/gmusicbrowser.png 
En plan maniático además añadimos un xorg.conf hecho a medida para la nvidia con la herramienta nvidia-settings que instala el driver propietario::
# cat /etc/X11/xorg.conf 

# nvidia-settings: X configuration file generated by nvidia-settings
# nvidia-settings:  version 361.28  (buildmeister@swio-display-x64-rhel04-04)  Wed Feb  3 16:26:48 PST 2016

Section "ServerLayout"
    Identifier     "Layout0"
    Screen      0  "Screen0" 0 0
    InputDevice    "Keyboard0" "CoreKeyboard"
    InputDevice    "Mouse0" "CorePointer"
    Option         "Xinerama" "0"
EndSection

Section "Files"
EndSection

Section "InputDevice"
    # generated from default
    Identifier     "Mouse0"
    Driver         "mouse"
    Option         "Protocol" "auto"
    Option         "Device" "/dev/psaux"
    Option         "Emulate3Buttons" "no"
    Option         "ZAxisMapping" "4 5"
EndSection

Section "InputDevice"
    # generated from default
    Identifier     "Keyboard0"
    Driver         "kbd"
EndSection

Section "Monitor"
    # HorizSync source: edid, VertRefresh source: edid
    Identifier     "Monitor0"
    VendorName     "Unknown"
    ModelName      "HP P232"
    HorizSync       24.0 - 80.0
    VertRefresh     50.0 - 60.0
    Option         "DPMS"
EndSection

Section "Device"
    Identifier     "Device0"
    Driver         "nvidia"
    VendorName     "NVIDIA Corporation"
    BoardName      "GeForce GT 730" 
    Option         "TwinViewOrientation" "Clone"
    Option         "TwinView"

EndSection

Section "Screen"
    Identifier     "Screen0"
    Device         "Device0"
    Monitor        "Monitor0"
    DefaultDepth    24
    Option         "Stereo" "0"
    Option         "nvidiaXineramaInfoOrder" "DFP-2"
    Option         "metamodes" "DP-1: 1440x900 +0+0, DVI-I-0: 1024x768 +0+0"
    Option         "SLI" "Off"
    Option         "MultiGPU" "Off"
    Option         "BaseMosaic" "off"
    SubSection     "Display"
        Depth       24
    EndSubSection
EndSection
Y ya como buen dobleplusparanoico he desactivado la tarjeta VGA intel (la que viene en la placa) en la BIOS del PC, de tal forma que al hacer "lspci | grep -i vga" sale solo la nVidia.

Con esto tenemos un sistema muy estable que no nos dará problemas.

3) Solución 2 a los problemas provocados por el driver/módulo nouveau.

Esta es la solución opuesta: ignorar la tarjeta nvidia y usar la Intel embebida en la placa base. Es la solución empleada para los PC de los alumnos, a los que conecto el monitor por el puerto Display Port 1 de esta tarjeta (que sorpresivamente tiene 3 salidas: 2 DisplayPort y 1 VGA).

Como son muchos PC lo he automatizado con estos recursos puppet:
# cat /etc/puppet/modules/infolab_ajustes/manifests/init.pp 

import "/etc/puppet/defines/*.pp"

class infolab_ajustes {

        ......
        ......

        #Los alumnos van con la tarjeta VGA intel, desactivamos nvidia y nouveau para evitar cuelgues innecesarios
        file {"/etc/modprobe.d/disable-nouveau.conf":
               owner => root , group => root , mode => 644 ,
               source => "puppet:///modules/infolab_ajustes/disable-nouveau.conf",
        }
        #Añade a rc.local (si no está ya) el código que desactiva en el arranque la tarjeta VGA nvidia
        add_line_above { desactiva_nvdia_vga_infolab:
              file=> "/etc/rc.local",
              line=> 'bus=$(lspci | grep "VGA compatible controller: NVIDIA" | cut -d" " -f1) ; test -n $bus && echo 1 > "/sys/bus/pci/devices/0000:$bus/remove"',
              search=> "VGA compatible controller: NVIDIA",
              above=> "^exit 0$"
        }
        #Desactivamos el DPMS en las X.
        file {"/usr/share/X11/xorg.conf.d/10-monitor.conf":
               owner => root , group => root , mode => 644 ,
               source => "puppet:///modules/infolab_ajustes/10-monitor.conf",

        ......
        ......

}
El fichero que quita el módulo nouveau:
# cat /etc/puppet/modules/infolab_ajustes/files/disable-nouveau.conf 
# generated by nvidia-installer
blacklist nouveau
options nouveau modeset=0
El que desactiva DPMS en la salida DP1 (adáptalo a tu caso):
# cat /etc/puppet/modules/infolab_ajustes/files/10-monitor.conf 
Section "Monitor"
 #Los monitores están en la salida DP1. Eso se averigua con xrandr si quieres adaptarlo a otro caso.
 Identifier "DP1"  
 Option "DPMS" "false"
EndSection

Section "ServerLayout"
 Identifier "ServerLayout0"
 Option "StandbyTime" "0"
 Option "SuspendTime" "0"
 Option "OffTime"  "0"
 Option "BlankTime"   "0"
EndSection

Y el rc.local que vaporiza la tarjeta VGA nvidia de los PC de los alumnos debe quedar:
# cat /etc/rc.local
#!/bin/sh -e
#
# rc.local
#
............
bus=$(lspci | grep "VGA compatible controller: NVIDIA" | cut -d" " -f1) ; test -n $bus && echo 1 >  "/sys/bus/pci/devices/0000:$bus/remove"
............

exit 0

Y con esto tenemos estables los PC de los alumnos. Vaya trabajito nos ha costado llegar aquí...

martes, 5 de abril de 2016

Configurando el sonido los HP ProDesk 600 G2/G1 SFF con Ubuntu

Bueno, nos han llegado 2 modelos de HP ProDesk 600: el G1 SFF y el G2 SFF. Ambos tienen tarjetas de sonido analógicas en placa y en la tarjeta gráfica HDMI. Vamos a ver como:

1) Vaporizar las tarjetas de sonido HDMI.

El HP ProDesk 600 G2 SFF (el que usamos en los laboratorios de informática) tiene:
 # lspci de las tarjetas de sonido:
00:1f.3 Audio device: Intel Corporation Sunrise Point-H HD Audio (rev 31)
01:00.0 VGA compatible controller: NVIDIA Corporation GK208 [GeForce GT 730] (rev a1)
01:00.1 Audio device: NVIDIA Corporation GK208 HDMI/DP Audio Controller (rev a1)

# cat /proc/asound/cards
 0 [PCH            ]: HDA-Intel - HDA Intel PCH
                      HDA Intel PCH at 0xbc440000 irq 131
 1 [NVidia         ]: HDA-Intel - HDA NVidia
                      HDA NVidia at 0xbc000000 irq 17

El HP ProDesk 600 G1 SFF (el que usamos con las pizarras digitales) tiene:
 # lspci de las tarjetas de sonido:
00:03.0 Audio device: Intel Corporation Xeon E3-1200 v3/4th Gen Core Processor HD Audio Controller (rev 06)
00:1b.0 Audio device: Intel Corporation 8 Series/C220 Series Chipset High Definition Audio Controller (rev 04)
01:00.0 VGA compatible controller: NVIDIA Corporation GT218 [GeForce 210] (rev a2)
01:00.1 Audio device: VIDIA Corporation High Definition Audio Controller (rev a1)

# cat /proc/asound/cards 
 0 [HDMI           ]: HDA-Intel - HDA Intel HDMI
                      HDA Intel HDMI at 0xf7b34000 irq 36
 1 [PCH            ]: HDA-Intel - HDA Intel PCH
                      HDA Intel PCH at 0xf7b30000 irq 34
 2 [NVidia         ]: HDA-Intel - HDA NVidia

Está muy bien eso de tener varias tarjetas de sonido en PC... si eres de los que te gustan tener varias tarjetas de sonido en el PC. Yo, que solo tengo dos oídos, me conformo con una y por una vez y sin que sirva de precedente estoy de acuerdo con la mayoría: mejor una tarjeta de sonido y que el audio salga por el conector jack, lo simple es bello. Nada mas horrible que abrir el control de sonido y encontrarse con varias tarjetas y controles de volumen si lo único que quieres es escuchar a Metallica un rato.

Ya hicimos esto antes y lo contamos aqui. Veamos ahora como hacerlo para estos dos modelos de PC, usando una tarea puppet que añade el código en cuestión al arranque en rc.local:

En el HP ProDesk 600 G2 SFF:
#============================================================================================================================
#Añade a rc.local (si no está ya) el código que desactiva en el arranque la tarjeta de audio HDMI de la tarjeta gráfica

add_line_above { desactiva_audio_hdmi_siatic:
              file=> "/etc/rc.local",
              line=> 'bus=$(lspci | grep "Audio device: NVIDIA Corporation" | cut -d" " -f1) ; test -n $bus && echo 1 > "/sys/bus/pci/devices/0000:$bus/remove"',
              search=> "NVIDIA Corporation",
              above=> "^exit 0$"
}
Para HP ProDesk 600 G1 SFF:
#============================================================================================================================
#Añade a rc.local (si no está ya) el código que desactiva en el arranque la tarjeta de audio HDMI de la tarjeta gráfica
add_line_above { desactiva_audio_hdmi_infolab:
              file=> "/etc/rc.local",
              line=> 'bus=$(lspci | grep "Audio device: NVIDIA Corporation GK208" | cut -d" " -f1) ; test -n $bus && echo 1 > "/sys/bus/pci/devices/0000:$bus/remove"',
              search=> "GK208",
              above=> "^exit 0$"
}
Con esto el audio HDMI desaparece el PC y no se carga el driver ni el control PulseAudio, quedando solamente la tarjeta de sonido analógico, mas o menos así:
# cat /proc/asound/cards
 0 [PCH            ]: HDA-Intel - HDA Intel PCH
                      HDA Intel PCH at 0xbc440000 irq 131

2) Fijar la tarjeta de sonido analógica

Otra cuestión que me pasaba con los HP ProDesk 600 G2 SFF es el driver la tarjeta de sonido analógica fallaba aleatoriamente durante el arranque, impidiendo manejarla desde el control de sonido. Es decir, salía esto:
# cat /proc/asound/cards
 1 [NVidia         ]: HDA-Intel - HDA NVidia
                      HDA NVidia at 0xbc000000 irq 17
Como se puede ver, la "0 [PCH ]: HDA-Intel - HDA Intel PCH" no estaba. Como consecuencia no salía sonido por el jack y nuestros altavoces analógicos permanecían enmudecidos.

Tras investigar un poco vi que cuando el driver fallaba esta línea aparecía en el syslog:
# dmesg | grep i915
[   10.966853] snd_hda_intel 0000:00:1f.3:
failed to add i915_bpo component master (-19)
Buscando encontré este enlace en el cual vienen a decir que la solución es actualizar al driver ALSA mas moderno que puedas encontrar. Eso se cuenta en esta página. Son dos pasos:

Uno: Instalar dkms con "apt-get install dkms" para permitir recompilar drivers al actualizar el kernel.
Dos: Bajar e instalar la última versión del driver alsa para mi sistema operativo concreto, que a fecha de hoy está en este enlace. Los comandos son:
# wget https://launchpad.net/~ubuntu-audio-dev/+archive/ubuntu/alsa-daily/+files/oem-audio-hda-daily-lts-vivid-dkms_0.201603231016~ubuntu14.04.1_all.deb
# dpkg -i oem-audio-hda-daily-lts-vivid-dkms_0.201603231016~ubuntu14.04.1_all.deb
# apt-get -f install
# ...
# dpkg -l | grep oem-audio-hda
ii  oem-audio-hda-daily-lts-vivid-dkms 0.201603231016~ubuntu14.04.1    

Tras esto reiniciamos y el driver de la tarjeta analógica siempre estará cargado.

Y con esto acabamos por hoy, de todas maneras seguiremos hablando de estos equipos y los problemas que dan con Ubuntu pese a que el contrato exigía que se entregasen totalmente compatibles. La empresa ganadora se piensa que si instalas y arrancas sin problemas ya va todo bien.... en fin, como siempre me recuerda Noo-Noo, mi Roomba:



Ampliación 21/09/2016: me comenta mi compañero Ismael que el enlace al driver ya no va, que hay que buscar en Internet "oem-audio-hda-daily-dkms" y luego descargar el paquete mas adecuado para nuestra versión. Otro compañero, Francis, da la solución definitiva: instalar mediante un PPA el paquete, asi siempre estará actualizado.
# add-apt-repository ppa:ubuntu-audio-dev/alsa-daily
# apt-get update
# apt-get install oem-audio-hda-daily-lts-vivid-dkms
¡Gracias, compañeros!.