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

viernes, 19 de diciembre de 2014

Cómo hacer funcionar jkiwi en amd64

Hace poco tuve que instalar la aplicación jkiwi en varias aulas para los ciclos formativos de peluquería y estética. En los Debian con arquitectura i386 no hubo mucho problema: bajé el paquete .deb de su página y la instalé con esta clase puppet:

class instala_jkiwi {

$version="0.9.5"
$paquete="jkiwi_${version}_ubuntu.deb"

file {"/var/cache/$paquete":
owner => root, group => root, mode => 755,
source => "puppet:///instala_jkiwi/$paquete",
notify => Exec["instala_jkiwi"]
}
exec { "instala_jkiwi":
path => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
command => "dpkg -i --force-confnew  --force-overwrite $paquete; apt-get -f -y install ",
cwd => "/var/cache",
unless => "dpkg -l | grep jkiwi | grep $version | grep ^ii",
require => File["/var/cache/$paquete"],
}

file {"/var/home/usuario/Desktop/jkiwi.desktop":
owner => usuario, group => usuario, mode => 755,
source => "puppet:///instala_jkiwi/jkiwi.desktop",
}
}

Cuando lo instalé en los Debian con arquitectura amd64 no hubo problemas hasta la hora de ejecutarlo. Al hacer doble click no hacía nada y al abrirlo desde terminal me daba el error:

java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
at utils.GtkStockIconSWT.createImage(GtkStockIconSWT.java:120)

viernes, 12 de diciembre de 2014

Copiar un mismo fichero a múltiples ubicaciones en Linux (y, de regalo, en Windows).

Cuando tenemos los homes de nuestros usuarios alojados en un servidor NFS frecuentemente nos encontramos con que tenemos que aplicar una configuración concreta a todos ellos. En Linux eso suele ser tan sencillo como copiar un fichero a una ruta concreta dentro del home. En mi caso me he visto en la necesidad de copiar un fichero mimeTypes.rdf dentro de la configuracion Firefox de cada usuario de mi red.

El problema es que la configuración Firefox no está dentro de una ruta fija en el home, sino que está dentro de .mozilla/firefox/<perfil>.default/mimeTypes.rdf, siendo <perfil> una ristra de números y letras que identifica el perfil del usuario.

¿Hay manera de copiar el mimeTypes.rdf independientemente de cual sera el nombre del directorio de perfil?. Pues si, con:

find /home -name 'mimeTypes.rdf' -print -exec cp -f /root/mimeTypes.rdf {} \;

Con esto buscamos todos los mimeTypes.rdf que hay en todos nuestros homes y los sobrescribimos con el que hay en /root/mimeTypes.rdf.

Si quisiéramos poner un acceso directo en todos los escritorios (independientemente de que el acceso directo existiese previamente o no) haríamos:

find /home -name 'Desktop' -print -exec cp -f /root/Rayuela.desktop {} \;

Ojo, asumimos que el escritorio está en la carpeta Desktop.

Bueno, pues hecho esto en los Linux quería hacerlo también en mis Windows. El problema es que los "homes" en los Windows están en las máquinas locales, y que no parece que se pueda hacer mediante código y tengamos que ir copiando cuenta por cuenta. Pues no, para mi sorpresa resulta que se puede hacer así:

for /f "tokens=*" %a  in ('dir /b/s "c:\documents and settings\mimetypes.rdf"') do copy /Y c:\ficheros\mimetypes.rdf  "%a"

Comentando:

  • Asumimos que todas las cuentas de Windows están en el directorio c:\documents and settings\*
  • El fichero origen está en c:\ficheros\mimetypes.rdf
  • El comando 'dir /b/s "c:\documents and settings\mimetypes.rdf"' es el meollo: busca dentro de "c:\documents and settings" todas las apariciones de mimetypes.rdf y devuelve su ruta completa.
  • Si metemos el código anterior dentro de un fichero .BAT la variable "%a" debe ser sustituida por "%%a" en sus dos apariciones. Cosas de los batch scripts.

Bueno, pues ha sido una sorpresa que el intérprete de comandos de Windows pueda hacer esto. ¡Larga vida a la línea de comandos!, dejemos el ratón y el copiar y pegar cual día de la marmota para los usuarios productivos.

viernes, 5 de diciembre de 2014

Montaje de un servidor WPKG

Para mantener actualizado el software de los Windows utilizo una herramienta llamada wpkg. Podría utilizar puppet como hacemos en los Linux, pero IMHO:

  1. Está muy verde.
  2. Se basa en ruby y mis Windows no están para esos trotes.

Wpkg permite instalar/actualizar/desinstalar programas y mantener algunas configuraciones aunque sea de forma rudimentaria. El esquema de funcionamiento en que se basa en wpkg es el siguiente:

  • Tenemos un servicio llamado WPKG Service que se ejecuta en cada arranque del ordenador.
  • Tenemos una carpeta compartida desde un Linux por samba, donde está el script principal wpkg.js (que es un completísimo Windows Script que hace todo el trabajo duro), la configuración con las órdenes a aplicar en un conjunto de ficheros .xml y los ejecutables y scripts de instalación y configuración que queremos aplicar a nuestros Windows.
  • El servicio ejecuta el script wpkg.js, que interpreta los .xml y aplica lo que en ellos dice sobre el PC donde se ejecuta.

Vamos a ver todos los pasos necesarios para configurarlo:

viernes, 28 de noviembre de 2014

Montar un punto de acceso en Debian Wheezy con ath5k y una tarjeta AirPlus DWL-G520 Wireless (Parte 2 de 2)

Bueno, pues en la anterior entrada teníamos que nuestra tarjeta D-Link AirPlus DWL-G520 [168c:0013] no era compatible con hostapd usando el driver estándar ath5k. A punto de tirar la toalla me acordé de los viejos drivers madwifi, que antaño soportaban las tarjetas con chip Atheros AR5XXX e incluían soporte para, dicho de forma políticamente correcta, monitorizar la seguridad de las redes inalámbricas. Parece ser que desde 2009 esos drivers ya no se desarrollan, pero no perdía nada con intentarlo.

La primera prueba que hago es descargar la última versión, descomprimiéndola sobre /root y compilando desde dentro de su directorio con:

make clean
make

vaya, pues con esto veo que salen muchos errores de compilación. La respuesta sencilla: este código fuente está abandonado y no va con kernels nuevos. Afortunadamente buscando un poco más encontré que un heroico resistente llamado Pavel Roskin ha ido adaptando el código fuente para que siga funcionando en nuevos kernel.

viernes, 21 de noviembre de 2014

Montar un punto de acceso en Debian Wheezy con ath5k y una tarjeta AirPlus DWL-G520 Wireless (Parte 1 de 2)

En los IES de Extremadura normalmente montamos nuestros puntos de acceso para los portátiles de los alumnos en los servidores de aula con tarjetas D-Link DWA-556 Xtreme N, que tienen esta salida lspci:

05:00.0 Network controller [0280]: Atheros Communications Inc. AR5008 Wireless Network Adapter [168c:0024] (rev 01)
Subsystem: D-Link System Inc Device [1186:3a70]
Flags: bus master, fast devsel, latency 0, IRQ 19
Memory at fe9f0000 (64-bit, non-prefetchable) [size=64K]
Capabilities: [40] Power Management version 2
Capabilities: [50] MSI: Enable- Count=1/1 Maskable- 64bit-
Capabilities: [60] Express Legacy Endpoint, MSI 00
Capabilities: [90] MSI-X: Enable- Count=1 Masked-
Capabilities: [100] Advanced Error Reporting
Capabilities: [140] Virtual Channel
Kernel driver in use: ath9k

estas tarjetas están soportadas por hostapd y se pueden configurar sin problema según se explica en esta entrada del blog.

El reto se me presentó al intentar montar un punto de acceso con una tarjeta PCI Dlink DWL-G520, ya que tenía varias ociosas en el almacen. Su salida lspci es:

viernes, 14 de noviembre de 2014

Configuración básica de un punto de acceso con hostapd

hostapd es un excelente software que permite convertir un Linux en un punto de acceso wifi totalmente configurable. La dificultad que le encuentro es que el fichero de configuración /etc/hostapd/hostapd.conf tiene un formato un poco farragoso y me cuesta un montón recordar todas las configuraciones posibles. Vamos a ver la configuración de los principales parámetros con distintos escenarios que será muy útil para hacer pruebas. Empecemos por lo básico:

#/etc/hostapd/hostapd.conf
driver=nl80211
ssid=MiWifi
interface=wlan0
bridge=br0 

Comentemos cada parámetro:

driver: driver a usar por el demonio hostapd para comunicarse con el kernel. Normalmente es nl80211, que soporta muchas tarjetas de red, pero hay otros mas antiguos para casos específicos: hostap, madwifi y prism54.

Ojo: muchas versiones de hostapd sólo vienen preparadas para usar el driver nl80211 y si queremos usar otro (porque la tarjeta de red que tengamos no está soportada por nl80211) hay que recompilar el hostapd (junto con el driver madwifi, por ejemplo) para activarlo.

ssid: SSID de la red wifi que se va a crear desde el punto de acceso.

interface: nombre de la tarjeta de red wifi (normalmente wlanX o athX).

bridge: si la tarjeta de red tiene un bridge con una tarjeta ethernet, debemos indicarlo añadiendo bridgle=brX, siendo brX el nombre de la tarjeta virtual creada por el bridge, con un /etc/network/interfaces parecido a:

#/etc/network/interfaces
iface eth0 inet manual
iface wlan0 inet manual
iface br0 inet static
bridge_maxwait 0
bridge_stp off
bridge_ports eth0 wlan0
address 192.168.0.254
netmask 255.255.255.0
broadcast 192.168.0.255

viernes, 7 de noviembre de 2014

Controlar nuestro SAI con nut (Parte 1)

En nuestra querida Extremadura se nos va mas de lo deseado la  corriente eléctrica (y eso que sólo consumimos el 25% de lo que generamos: en casa de herrero, cuchillo de palo) y es imprescindible un SAI para tener protegidos los servidores, el switch troncal y el router de salida a Internet. Y si el SAI lo controlamos desde uno de los servidores, mejor que mejor, pues así podremos estar avisados y llevar un registro de todo lo que pasa.
Antes de nada, hacer una distinción que no conocía y que me trajo muchos quebraderos de cabeza. Ladies and gentlemen: hay dos/tres clases de SAI.
  • Pasivo u offline: en este SAI la corriente entra de fuera y se bifurca en dos líneas paralelas, una que va a las salidas del SAI y otra que va a la batería. Cuando hay un corte de corriente la línea directa que va a la salida pierde la potencia y la batería tiene que activarse y empezar a suministrar energía. Este proceso tarda unos milisegundos llamado "tiempo de transferencia" y genera una onda cuadrada. Si el ordenador que hay conectado a la salida es demasiado sensible (por ejemplo, un servidor HP que tengo) a estas variaciones de la señal, se pondrá en modo standby e interrumpirá su funcionamiento normal. Es decir, que el SAI no servirá de nada y hasta que me di cuenta de esto estuve comiéndome el coco pensando que la fuente de alimentación del servidor era defectuosa.
  • Activo u online: en este SAI la corriente entra de fuera, pasa a la batería y luego a la salida. Es decir, la salida siempre está recibiendo energía de la batería. Si hay un corte no pasa nada: la batería sigue suministrando energía como antes sin que haya ningún tipo de distorsión. Estos SAIs son mas caros, pero no van a darnos problemas con ningún tipo de servidor.
  • Line interactive (añadido 23/11/2015): es un sistema intermedio entre los dos anteriores, basado en utilizar la batería para regular rápidamente las variaciones de tensión.
Prosigamos. Una vez montada la parte eléctrica del SAI y viendo que funciona, tenemos que enchufarlo por el cable USB  al PC que lo va a controlar. Una vez enchufado hacemos lsusb para saber como se identifica. En mi caso la salida es:
Bus 005 Device 024: ID 06da:0003 Phoenixtec Power Co., Ltd 1300VA UPS
Esto debemos anotarlo para buscar luego en Google el driver de nuestro SAI. Yo he buscado "06da:0003 nut driver" en Google, obteniendo varios enlaces con el referencias al driver nut a usar. En unos hablaban del megatec_usb y en otros del blazer_usb. Me decanté por el segundo y acerté.
Ahora procederemos a instalar los paquetes necesarios para el control: nut, nut-cgi, nut-client y nut-server. Nut es un sistema cliente-servidor, formado por un servidor (upsd-upsdrvctl) y uno o varios clientes (upsmon). Esto permite que el SAI sea monitorizado desde un ordenador al que está conectado por cable usb o serie, pero los resultados de esa monitorización estén disponibles en varios equipos (ya que normalmente un SAI suministra energía a varias máquinas). Nosotros vamos a usar un esquema simple en que solo tenemos un servidor y un cliente, alojados en el mismo PC y él se ocupa de todo.
Una vez instalados los paquetes, vamos a configurarlos. Empezamos editando /etc/nut/ups.conf:
[salicru]
driver = blazer_usb
desc = "SAI Salicru"
port = auto
vendorid = 06da
productid = 0003
bus = "005"
Comentemos:
  • [salicru]: nombre que vamos a dar al SAI para manejarlo luego.
  • desc: descripción del SAI.
  • driver: driver a usar.
  • port: puerto a usar, normalmente "auto" es suficiente. En el caso de SAIs conectados por el puerto serie podríamos tener que poner /dev/ttySX
  • vendorid, productid: los identificadores USB del SAI, mostrados con el lsusb.
  • bus: el bus USB donde va conectado el SAI, mostrado con el lsusb.
Siguiente fichero: /etc/nut/upsd.conf
ACL localhost 127.0.0.1/32
ACL local_network 172.19.231.0/24
ACL all 0.0.0.0/0

ACCEPT monitor localhost
ACCEPT local_network
REJECT all all
Aquí ponemos la red de nuestro centro (marcado en rojo). Simplemente es para decir desde que parte de la red va a permitir nut que se hagan conexiones para controlar el estado del SAI.

Nota 23/11/2015: bueno, pues resulta que esta configuración está deprecated(=viejuna). Ahora la nueva sintaxis es esta descrita aquí. Basicamente con
LISTEN ip [puerto] 
indicamos a través de su IP por cual interface de red/puerto se aceptarán peticiones, en nuestro caso sería:
LISTEN 127.0.0.1
LISTEN 172.19.231.X

Siguiente fichero, /etc/nut/upsd.users:
[admin]
password = pwd_admin
allowfrom = localhost local_network
actions = SET
instcmds = ALL

[control]
password = pwd_control
allowfrom = localhost local_network
upsmon master
Son los usuarios para acceder remotamente al proceso servidor que controla el SAI desde los clientes. Lo dejamos tal cual está aquí.

Otro fichero más, /etc/nut/upsmon.conf:
MONITOR salicru@localhost 1 control pwd_control master
RUN_AS_USER nut
MINSUPPLIES 1
SHUTDOWNCMD "/root/scripts/apagar_servidores.sh"
POLLFREQ 5
POLLFREQALERT 5
HOSTSYNC 15
DEADTIME 15
POWERDOWNFLAG /etc/killpower

NOTIFYCMD "/sbin/upssched"

NOTIFYMSG ONLINE "UPS: Normal state"
NOTIFYMSG ONBATT "UPS: On battery"
NOTIFYMSG LOWBATT "UPS: Battery low"
NOTIFYMSG FSD "UPS: Starting shutdown"
NOTIFYMSG COMMOK "UPS: Communication restored"
NOTIFYMSG COMMBAD "UPS: Communication lose"
NOTIFYMSG SHUTDOWN "UPS: Shutting down"
NOTIFYMSG REPLBATT "UPS: Replace battery"

NOTIFYFLAG ONLINE SYSLOG+WALL+EXEC
NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC
NOTIFYFLAG LOWBATT SYSLOG+WALL+EXEC
NOTIFYFLAG FSD SYSLOG+WALL+EXEC
NOTIFYFLAG COMMOK SYSLOG+WALL+EXEC
NOTIFYFLAG COMMBAD SYSLOG+WALL+EXEC
NOTIFYFLAG SHUTDOWN SYSLOG+WALL+EXEC
NOTIFYFLAG REPLBATT SYSLOG+WALL+EXEC

RBWARNTIME 43200
NOCOMMWARNTIME 300
FINALDELAY 0

Siguiente fichero, /etc/nut/upsset.conf:
# Network UPS Tools - upsset.conf sample file
deny from all
allow from 172.19.231.0
Aqui va el rango de direcciones de red que van a poder acceder a la página web que muestra el estado del SAI. En nuestro caso, toda nuestra red, que cada cual ponga aquí lo que estime oportuno.
Siguiente fichero, /etc/nut/hosts.conf:
# Network UPS Tools: example hosts.conf
#
# This file is used to control the CGI programs.  If you have not
# installed them, you may safely ignore or delete this file.
#
# -----------------------------------------------------------------------
#
# upsstats will use the list of MONITOR entries when displaying the
# default template (upsstats.html).  The "FOREACHUPS" directive in the
# template will use this file to find systems running upsd.
#
# upsstats and upsimage also use this file to determine if a host may be
# monitored.  This keeps evil people from using your system to annoy
# others with unintended queries.
#
# upsset presents a list of systems that may be viewed and controlled
# using this file.
#
# -----------------------------------------------------------------------
#
# Usage: list systems running upsd that you want to monitor
#
# MONITOR  ""
#
# Examples:
#
# MONITOR myups@localhost "Local UPS"
# MONITOR su2200@10.64.1.1 "Finance department"
# MONITOR matrix@shs-server.example.edu "Sierra High School data room #1"
MONITOR salicru@localhost "SAI Salicru IES Virgen de Guadalupe
Aquí va el nombre del SAI (o los SAIs) que será monitorizado y mostrado en el interfaz web de nut.

Siguiente fichero, /etc/nut/nut.conf:
# Network UPS Tools:  nut.conf
#
##############################################################################
# General section
##############################################################################
# The MODE determines which part of the NUT is to be started, and which
# configuration files must be modified.
#
# This file try to standardize the various files being found in the field, like
# /etc/default/nut on Debian based systems, /etc/sysconfig/ups on RedHat based
# systems, ... Distribution's init script should source this file to see which
# component(s) has to be started.
#
# The values of MODE can be:
# - none: NUT is not configured, or use the Integrated Power Management, or use
#   some external system to startup NUT components. So nothing is to be started.
# - standalone: This mode address a local only configuration, with 1 UPS
#   protecting the local system. This implies to start the 3 NUT layers (driver,
#   upsd and upsmon) and the matching configuration files. This mode can also
#   address UPS redundancy.
# - netserver: same as for the standalone configuration, but also need
#   some more network access controls (firewall, tcp-wrappers) and possibly a
#   specific LISTEN directive in upsd.conf.
#   Since this MODE is opened to the network, a special care should be applied
#   to security concerns.
# - netclient: this mode only requires upsmon.

MODE=standalone
# set upsd specific options. use "man upsd" for more info
UPSD_OPTIONS=""
# set upsmon specific options. use "man upsmon" for more info
UPSMON_OPTIONS=""
La variable MODE=standalone indica que tenemos un solo SAI y que es controlado por el PC al que está conectado localmente por el puerto USB.
Siguiente fichero, /etc/nut/upssched.conf:
# Network UPS Tools - upssched.conf

CMDSCRIPT  /root/scripts/avisoups.sh

##Hay que crear la ruta /var/run/nut/upssched/ si no existe con propietario nut:nut
#PIPEFN /var/run/nut/upssched/upssched.pipe
#LOCKFN /var/run/nut/upssched/upssched.lock
#Añadido 18/12/2015: por algún extraño motivo, la ruta 
#/var/run/nut/upssched/ es borrada periódicamente por el sistema con lo cual
#upssched deja de funcionar. La solución mas cómoda es usar /tmp/ para almacenar 
#ambos ficheros:
PIPEFN /tmp/upssched.pipe
LOCKFN /tmp/upssched.lock

# Si hay corte de corriente, se lanza un timer que esperará 300 segundos (5 minutos)
# antes de apagar
AT ONBATT * START-TIMER  ups-on-battery-shutdown  300
# Si vuelve la corriente, se cancela el timer
AT ONLINE * CANCEL-TIMER  ups-on-battery-shutdown

# Si hay corte de corriente, se lanza un timer que esperará 15 segundos
# antes de notificarlo

AT ONBATT * START-TIMER ups-on-battery 15
AT ONLINE * CANCEL-TIMER ups-on-battery

#En los siguientes eventos, llama al script de notificacion para que lo procese.
AT ONLINE * EXECUTE ups-back-on-line
AT REPLBATT * EXECUTE ups-change_battery
AT LOWBATT * EXECUTE ups-low-battery
AT COMMOK * EXECUTE ups-comunication-ok
AT COMMBAD * EXECUTE ups-comunication-bad
Nota 18/12/2015: como se puede ver en el listado anterior, he cambiado

PIPEFN /var/run/nut/upssched/upssched.pipe
LOCKFN /var/run/nut/upssched/upssched.lock

por

PIPEFN /tmp/upssched.pipe
LOCKFN /tmp/upssched.lock

ya que la ruta /var/run/nut/upssched/ es borrada periódicamente por el sistema de forma misteriosa, inhabilitando upssched. Usando tmp ya no habrá problema ya que esa ruta existe siempre y puede escribir cualquier proceso en ella.
Aquí empieza lo bueno, expliquemos:
  • CMDSCRIPT: ruta al script se ejecuta al saltar un evento del SAI, en nuestro caso /root/scripts/avisoups.sh.
  • PIPEFN, LOCKFN: rutas a ficheros creados por el servicio nut. Los quedamos tal como están, asegurándonos de que existe la carpeta /var/run/nut/upssched/ con propietario nut:nut
  • AT ONBATT * START-TIMER  ups-on-battery-shutdown  300: indicamos que cuando empiece a funcionar la batería (es decir, haya un corte de corriente) se define un temporizador de 300 segundos, al cabo del cual se dispara un evento ups-on-battery-shutdown.
  • AT ONLINE * CANCEL-TIMER  ups-on-battery-shutdown: si vuelve la corriente, se cancela el temporizador anterior.
  • AT ONBATT * START-TIMER ups-on-battery 15: ídem, pero damos un timeout de 15 segundos.
  • AT ONLINE * EXECUTE ups-back-on-line : cuando el estado del SAI cambie a online se genera un evento ups-back-online. Ídem para el resto de eventos del SAI.
Cuando sucede uno de los eventos controlados en el fichero anterior, se llama al script /root/scripts/avisoups.sh pásandole como parámetro el nombre del evento en cuestión, que recogerá en $1
Contenido de /root/scripts/avisoups.sh:
#!/bin/bash

source mail.sh

MESSAGE_MAIL=""
EVENT_TYPE=$1
APAGADO=0
FECHA=$(date)

case "$EVENT_TYPE" in
    "ups-on-battery-shutdown")
        MESSAGE_MAIL="UPS on battery: shutdown now"
        APAGADO=1
        ;;
    "ups-on-battery")
        MESSAGE_MAIL="UPS on battery: warning"
        ;;
    "ups-comunication-bad")
        MESSAGE_MAIL="Communications with UPS lost"
        ;;
    "ups-change_battery")
        MESSAGE_MAIL="UPS battery needs to be replaced"
        ;;
    "ups-back-on-line")
        MESSAGE_MAIL="UPS on line power"
        ;;
    "ups-low-battery")
        MESSAGE_MAIL="UPS battery is low"
        ;;
    "ups-comunication-ok")
        MESSAGE_MAIL="Communications with UPS established"
        ;;
esac

mailSend  "$FECHA => $MESSAGE_MAIL"  "[UPS] Event $EVENT_TYPE de SAI Virgen de Guadalupe:"
echo "$FECHA => SAI: $MESSAGE_MAIL" >> /var/log/sai.log

if [ $APAGADO = "1" ]
then
    sleep 30
    /root/scripts/apagar_servidores.sh
fi
Como vemos, recoge el evento, construye un mensaje de correo y lo envia con la funcion mailSend. Adicionalmente, lo registra en /var/log/sai.log, para permitir su posterior consulta.
Destacar que si se ha disparado el evento "ups-on-battery-shutdown" es indicativo de que lleva 5 minutos cortada la corriente y para evitar males mayores ordenamos un apagado ordenado de los servidores a través del script /root/scripts/apagar_servidores.
En /root/scripts/mail.sh tenemos la función mailsend, que ya hemos usado en otras entradas del blog. Hay que configurar este comando con el usuario, contraseña y destinatario pertinentes:
function mailSend() {

    mailsend -smtp smtp.gmail.com \
        -port 587 \
        -starttls -auth \
        -user micuenta@gmail.com \
        -pass mipassword \
        -f micuenta@gmail.com \
        -t micuenta@gmail.com \
        -sub "$1" -M "$2"
}
El script de apagado de servidores, /root/scripts/apagar_servidores.sh es:
#!/bin/bash

source mail.sh

FECHA=$(date)
MESSAGE_MAIL="Apagando servidores ahora mismo desde el script /root/scripts/apagar_servidores.sh."

mailSend  "$FECHA => $MESSAGE_MAIL" "Aviso Servidor Virgen de Guadalupe"
echo "$FECHA => $MESSAGE_MAIL" >> /var/log/sai.log

ssh root@servidor "/sbin/shutdown -h +0"
sleep 1
ssh root@ldap "/sbin/shutdown -h +0"
sleep 1
/sbin/shutdown -h +0
En esta caso apagamos los servidores "servidor", "ldap" y el propio servidor donde está conectado el SAI. Hay que tener en cuenta que para poder ejecutar remotamente los comandos de apagado con ssh sin tener que introducir la contraseña debemos haber establecido una relación de confianza entre nuestros servidores.
Bueno, con todo esto ya podemos iniciar los servicios:
/etc/init.d/nut-server restart
/etc/init.d/ups-monitor restart
Y verificar que funcionan con:
upsc salicru
Cambiar "salicru" por el nombre que le hayamos puesto al SAI en /etc/nut/ups.conf. La salida será algo como:
battery.charge: 100
battery.voltage: 54.60
battery.voltage.high: 52.00
battery.voltage.low: 41.60
battery.voltage.nominal: 48.0
device.type: ups
driver.name: blazer_usb
driver.parameter.bus: 005
driver.parameter.pollinterval: 2
driver.parameter.port: auto
driver.parameter.productid: 0003
driver.parameter.vendorid: 06da
driver.version: 2.6.4
driver.version.internal: 0.08
input.current.nominal: 6.0
input.frequency: 50.0
input.frequency.nominal: 50
input.voltage: 226.6
input.voltage.fault: 226.6
input.voltage.nominal: 230
output.voltage: 226.6
ups.beeper.status: enabled
ups.delay.shutdown: 30
ups.delay.start: 180
ups.load: 19
ups.productid: 0003
ups.status: OL
ups.temperature: 52.5
ups.type: offline / line interactive
ups.vendorid: 06da
Otros comandos del paquete nut que no he usado nunca, pero ahí están:
  • upscmd: permite mandar comandos al SAI, si es programable.
  • upsrw: leer/cambiar variables de un SAI programable.
  • upsd, upslog, upsdrvctl, upsmon, upssched: son comandos internos usados por los demonios, un usuario normal no suele invocarlos
Por último, podemos acceder via web al estado del SAI, con una URL como: http://servidor-nut/cgi-bin/nut/upsstats.cgi?host=salicru@localhost, cambiando host=salicru@localhost por el nombre que le hayamos puesto al SAI en /etc/nut/ups.conf, el resultado será similar a:

Bueno, con esto tendremos bajo control nuestro SAI y protegidos nuestros servidores. Además llevaremos un registro de las caídas de tensión, para poder reclamar a Iberdrola, X-DDD.
Hasta la semana que viene, sean buenos con los lusers.

viernes, 31 de octubre de 2014

Force brute attack a un lápiz de la pizarra Interwrite (Part One)

Ya me quejaba en esta entrada de los lápices de la pizarra Interwrite. Bueno, pues aprovechando que tenía uno "averiado" me decidí a desmontarlo para ver si se podía hacer algo o al menos satisfacía mi curiosidad de cómo funcionaba. En esta entrada veremos como destrozar un lápiz de la Interwrite para ver sus tripas y entender como está montado.

lunes, 27 de octubre de 2014

Punto de acceso D-Link DAP-1360 y muchos clientes wifi.

En el instituto compramos hace tiempo un par de puntos de acceso D-Link DAP-1360 modelo B1 para que se conectasen entre 15 y 20 portátiles en un aula. Al poco tiempo empezaron las quejas de los usuarios de que la conexión se caía y se quedaban sin red, llegando al punto en que había que reiniciar el punto de acceso y/o los equipos para volver a conectar.

Lo primero que hice fue probar pacientemente con todo tipo de combinaciones permitidas con el firmware:

  • wifi N, wifi N+G, wifi N+G+B.
  • cifrados WEP, WPA, TKIP, AES, sin cifrado.
  • con y sin filtro de MAC.
  • distintos canales.
  • Short GI a ON y a OFF, lo que quiera que signifique eso.

viernes, 24 de octubre de 2014

Sistema de clonado remoto (parte 3 de 3)

Bueno, ya tenemos nuestro sistema PXE que arranca por red SystemRescueCD y Clonezilla. Ya solo faltan dos cosas para hacerlo todo como prometí en la primera entrada.

Primero, como entrar remotamente al SystemRescue una vez arrancado. Esa es fácil:

ssh -X root@ip-de-la-maquina-arrancada-por-pxe

¿Y la contraseña?. Pues la indicada en el parámetro rootpass del append del pxelinux.cfg/default. Entramos y ya desde allí podemos abrir clonezilla, hacer fsck o utilizar remotamente cualquier utilidad de las que trae nuestro CD.

martes, 21 de octubre de 2014

Sé lo que hicistéis la última sesión...

En algunos momentos nos interesa registrar quién esta sentado en el ordenador y que está haciendo. Para llevar a cabo esto he estado trabajando en la idea de hacer un script que se ejecute en el arranque del sistema y, cada cierto tiempo, haga una captura con la webcam y del escritorio, fusione ambas imágenes en una sola y la guarde en un directorio. Esas imágenes podremos consultarlas luego o bien procesarlas en el momento, enviándolas por correo electrónico con mailsend o subiéndolas a algún servidor.

El resultado buscado debe ser tal que así:

Vamos a ver los distintos pasos que he dado.

viernes, 17 de octubre de 2014

Sistema de clonado remoto (parte 2 de 3)

Bueno, ya tenemos nuestro servidor PXE en marcha, ahora vamos a añadirle más cosas para darle vidilla. En Internet hay multitud de manuales y herramientas para añadir a un arranque por PXE: el SystemRescueCD, el Clonezilla, otros CD de rescate, instalaciones de red de sistemas operativos, el PartedMagic, antivirus (como Avira, por ejemplo), imágenes de disquetes con utilidades e incluso WinPE con una versión reducida de Windows XP.

En nuestro caso sólo queremos SystemRescueCD y Clonezilla. En principio habría que poner una opción de menú para cada uno de ellos, pero en su día me ocupé de fusionar ambos en una sola imagen de CD que será la que usemos para tener nuestra navaja suiza por PXE.

lunes, 13 de octubre de 2014

Como entrar por ssh a un equipo que está detrás de un router.

Muchas veces queremos entrar por ssh a un equipo de casa o del trabajo y resulta que está detrás de un router, con el que nos damos de narices. Adicionalmente, el equipo tendrá una IP correspondiente a una IP privada de la red propia de nuestra instalación y no habrá posibilidad de conectar con él directamente.

Veremos ahora como solucionar esto con dos posibles escenarios:

1) Cuando tenemos la capacidad de configurar el router para que redirija las peticiones ssh hacia nuestro PC. Por ejemplo, el router ADSL de casa.

2) Cuando no podemos tocar el router, ya que está fuera de nuestro alcance y/o permisos. Por ejemplo, el router nuestro centro de trabajo o estudios.

Si nuestro caso es la unión de ambos, es decir, queremos acceder desde casa  (tras nuestro router ADSL) al trabajo (tras nuestro router corporativo), tendremos que llevar a cabo tanto los pasos del caso 1 como del caso 2.

1) Hacer ssh cuando podemos configurar el router.

Lo primero es tener servicio ssh instalado y funcionando correctamente según estas instrucciones:

El truco para saltar el router y llegar hasta nuestro PC está en configurar las reglas NAT del mismo para que redirija el tráfico ssh hacia el PC, que tendrá una IP fija dentro de nuestra red doméstica. Es lo que popularmente se conoce como "abrir puertos". Los detalles de esta configuración dependen mucho de la marca del router que tengamos en casa, pero Internet está llena de manuales sobre como abrir los puertos (normalmente los de bittorrent y amule) para cada router del mercado. Para adaptarlos a ssh simplemente hay que sustituir el puerto seleccionado al configurarlo por el puerto usado por nuestro servidor ssh (normalmente, el 22 o el 443, que es el que uso yo ya que muchos router corporativos tienen capado el puerto 22). Por ejemplo, para el famoso Livebox de Orange.

Otro problema que se nos presenta es ¿cuál es la IP del router de mi casa?. Normalmente será una IP dinámica que cambiará cada cierto tiempo o reinicio del mismo. Para soslayar ese problema existe NoIP, que te asocia un dominio gratuito del tipo nombre.noip.me a la dirección pública de tu router.

Una vez te has dado de alta (el servicio de NoIP se mantendrá gratuitamente para tí, siempre que una vez al mes lo reactives pulsando al enlace de activación en el recordatorio que te mandan por correo) y has elegido tu dominio (el sufijo siempre será noip.me si elegimos la opción gratuita) tienes que instalarte en tu PC el programa cliente disponible en la propia web de NoIP, que actualizará tu IP en el registro DNS de noip cada vez que te conectes. Si tienes un router ADSL lo suficientemente moderno (por ejemplo, el Livebox de Orange) el propio router tiene una opción en su interface de administración web para configurar esto sin necesidad de instalar nada en tu PC. Una vez dado de alta y configurado el ciente noip, instalado el servicio ssh y abierto el puerto pertinente del router, si haces:

ping dominio-de-mi-casa.noip.com

veras que tu router responde, y con:

ssh -p 443 usuario@dominio-de-mi-casa.noip.com

conectamos por ssh a nuestra máquina de casa (nótese que de ahora en adelante usaré siempre el puerto 443 para ssh).

NOTA: Esto anterior no funciona con router Livebox de Orange cuando lo hacemos dentro de la propia red doméstica. Por algún arcano motivo al enrutar el tráfico hace algún tipo de embrollo que no te permite conectar por ssh a tu IP pública. Yo lo que hago para probar es usar la conexión de datos del móvil y utilizar la apk de android Connectbot para ver si conecto por ssh desde fuera con el PC de casa.

2) Hacer ssh cuando no podemos configurar el router.

Ahora imaginemos que además queremos conectar al PC del trabajo por ssh de igual forma a como lo hemos hecho, en el paso anterior. Configuramos el servidor ssh, obtenemos la IP pública del router del trabajo, y.... ¿cómo abrimos los puertos del router?. Normalmente dicho router no lo controlamos nosotros ya que estamos dentro de una red corporativa y tenemos sus firewall en medio. Desde luego, si les pedimos a los encargados de la seguridad de la red que nos abran los puertos seguramente nos van a mandar a hacer puñetas.

¿Hay solución?. Si, hacer un "túnel inverso", en el que la conexión ssh va al revés: desde el destino al origen. Estrictamente hablando es el PC del trabajo el que te hace ssh a ti, y luego tú te "enganchas" a la conexión creada. Digamos que el PC del trabajo te "llama" por ssh a un sitio fijo (por ejemplo, el PC de casa), tu PC descuelga y ya tienes conexión ssh con él. Aquí viene bien explicado el proceso:

En resumen:

pc-trabajo # ssh -R -p 443  10101:localhost:22 usuario@dominio-de-mi-casa.noip.me -N   

esto conecta el PC del trabajo con el de casa, abriendo el túnel. Básicamente dice: "conéctate a dominio-de-mi-casa.noip.me por el puerto 443 y abre allí un túnel en el puerto 10101 y conéctalo con el puerto 22 de éste ordenador", ahí es nada. Al introducir esta orden nos pide la contraseña del usuario "usuario"  en el PC de casa y una vez metida se queda esperando a que se abra el otro extremo del túnel. En el PC de casa haremos:

pc-casa # ssh -p 10101 root@localhost  -C -X

y con eso conectamos con el PC del trabajo, ya que el puerto 10101 en el PC de casa es el extremo local del túnel abierto, estando en el otro extremo el puerto 22 del PC del trabajo con su demonio ssh esperando pacientemente tras él. Nos pide la contraseña de root allí (si ese es el usuario con el que queremos entrar) y una vez metida se inicia la sesión ssh.

Nótese como en el PC del trabajo asumo que el puerto donde está escuchando ssh es el 22, no 443 como en el PC de casa. Esto dependerá de nuestro caso particular.

Como hemos visto, cuando el PC del trabajo intenta conectar con el de casa para abrir el túnel inverso, nos pide la contraseña. Para evitar esto y hacer la llamada automática sin tener que teclear la contraseña cada vez, debemos establecer una relación de confianza entre el PC del trabajo y el PC de casa, de tal forma que se pueda hacer ssh de uno a otro sin que nos pida contraseña. Para ello, desde el PC del trabajo hacemos:

pc-trabajo # ssh-keygen
pc-trabajo # ssh-copy-id -p 443 usuario@dominio-de-mi-casa.noip.com

Esto genera Nos pedirá la contraseña una vez y ya está. Las próximas veces que hagamos:

pc-trabajo # ssh -p 443 usuario@dominio-de-mi-casa.noip.com

o

pc-trabajo # ssh -R -p 443 10101:localhost:22 usuario@dominio-de-mi-casa.noip.me -N   

desde el PC del trabajo se iniciará sesión en el de casa sin pedir contraseña.

El problema de este interesante método es que alguien debe estar en el otro extremo para iniciar la "llamada", o bien debemos ir primero al trabajo, abrir el túnel inverso y luego a casa, contestando la llamada y estableciendo la conexión ssh. Si no disponemos de un becario a tiempo completo en el PC del trabajo para avisarle por whatsapp de que inicie el túnel inverso, ¿cómo se puede automatizar esto para que la llamada se haga sola?. Pues si: con autossh.

Autossh permite crear un túnel ssh persistente: inicia una conexión inversa ssh y la mantiene contra viento y marea, reconectando de nuevo ante cualquier desconexión de la misma. Al caer la conexión, hay un pequeño intervalo de tiempo en la que no está activa hasta que autossh la reconecta, pero en general siempre que haya red entre los dos extremos estará funcional el túnel.

Primero instalamos el paquete autossh, luego y creamos un directorio llamado /etc/tunnel (esta ubicación es arbitraria, cada cual puede ponerlo donde quiera) para poner allí dos ficheros:

  • id_rsa: la clave privada ssh del usuario que abre el túnel en nuestro pc del trabajo (en mi caso, root). Esta clave privada está en /root/.ssh/id_rsa y debemos copiarla en /etc/tunnel y dejarla con permisos 600, para que sólo sea accesible por el root. Ojo con las claves privadas ssh.
  • tunnel.sh: el script que abre el túnel, que vemos a continuación:
#!/bin/bash
set +e
SSH_OPTIONS=" -i /etc/tunnel/id_rsa"
CREDENCIALES="usuario@dominio-de-mi-casa.noip.me"
PUERTO="443"
# Always assume initial connection will be successful
export AUTOSSH_GATETIME=0
# Disable echo service, relying on SSH exiting itself
export AUTOSSH_PORT=0
autossh -p $PUERTO -vv -- $SSH_OPTIONS -o 'ControlPath none' -R 10101:localhost:22 $CREDENCIALES -N > /var/user_sshlog.out 2> /var/user_ssh_error.out &   

Para conseguir que autossh se inicie al encender el PC lo invocamos añadiendo ésto rc.local, antes de la línea "exit 0":

/etc/tunnel/tunnel.sh > /var/user_tunnel.log 2>&1

Para que se ejecute el script y se establezca el túnel habría que reiniciar el PC del trabajo, aunque podemos lanzarlo manualmente mientras que hacemos pruebas.

Luego, desde el pc de casa entramos como ya hemos explicado:

pc-casa# ssh -p 10101 root@localhost  -C -X

MUY IMPORTANTE: con este método, el PC del trabajo debe estar siempre encendido y con el túnel inverso abierto, ofreciendo disponibilidad 24x7. Para que la conexión del túnel sea estable y no se produzcan timeout cuando lleva un tiempo sin usarse y para permitir conexiones X (para abrir aplicaciones gráficas remotas) hay que tocar un poco las configuraciones en el pc de casa:

En /etc/ssh/sshd_config añadir:

#Metido para las conexiones X
X11Forwarding yes
X11UseLocalhost yes
#Metido para el tunel inverso
ClientAliveInterval 30
ClientAliveCountMax 99999
GatewayPorts yes

Crear ~/.ssh/config (en el home del usuario al que conectamos, no en el usuario root) y añadir:

#Para el tunel inverso
Host *
Protocol 2
TCPKeepAlive yes
ServerAliveInterval 60
ForwardX11 Yes
ForwardX11Trusted yes

Por ultimo, reiniciamos el servicio ssh en el PC local.

pc-casa# service ssh restart

Pasado un tiempo (unos minutos a lo sumo) se iniciará el túnel desde el pc del trabajo y ya podremos entrar en él desde casa. Al final veremos la luz al final del túnel... y allí estará el demonio ssh.

viernes, 10 de octubre de 2014

Sistema de clonado remoto (parte 1 de 3)

Muchas veces tengo que clonar un equipo con Clonezilla o simplemente ejecutar un fsck a uno de sus discos corruptos desde un SystemRescueCD y no encuentro el momento en que esté el aula libre para hacerlo tranquilamente. También sucede a veces que el equipo está en otro edificio y tengo que desplazarme hasta allí para realizar todo el proceso, perdiendo más tiempo entre paseos y esperas de lo que tardo luego en hacerlo. Lo ideal sería poder realizarlo desde mi puesto, mientras tengo otras ventanas abiertas y voy trabajando a la vez en varias cosas. Vamos a ver como conseguirlo.
 
Una forma sencilla de hacerlo sería tener un IPKVM  por equipo. El problema es que cuestan 600 euros o más y nosotros somos un país en quiebra, así que vamos a desechar esta idea. Nuestro reto es hacer que, sin presencia física, un equipo dentro de una red accesible por nosotros se encienda y arranque un SystemRescueCD-Clonezilla perfectamente funcional e independiente del sistema que tenga el PC en el disco duro, al que podremos conectarnos por ssh para realizar nuestra intervención.
 

viernes, 3 de octubre de 2014

Interwrite Device Manager y los $HOME inaccesibles.

El problema.

Mi amiga y compañera Cristina nos comentó que había visto en los logs de algunos ordenadores de aulas unos extraños mensajes acerca un acceso no autorizado a "/home/<usuario>". Posteriormente se había dado cuenta de que sólo sucedía en los equipos que tenían una pizarra digital Interwrite conectada, pizarra que nos ha dado muchos problemas de calibración desde siempre, ya que parecía que olvidaba los datos de calibración entre reinicio y reinicio. Había que aclarar dicho misterio.

sábado, 20 de septiembre de 2014

Como encoger un PDF escaneado

Es una irritante chorrada, pero siempre me pasa. Escaneo sin fijarme algún documento para enviar por correo y cuando lo voy a adjuntar resulta que pesa 40 megas. Hasta ahora lo que hacía era escanear de nuevo a menor resolución o extraer las imágenes del pdf, reducir la calidad y volver a meterlas dentro con las utilidades convert (del paquete imagemagick) y pdftk.
 
Pero ya no vuelve a pasarme más. El otro día descubrí que con el venerable Ghostscript se puede reducir el tamaño y mantener una buena calidad en el PDF.
 
Primero instalamos los paquetes ghostscript y gsfonts si no lo estaban previamente. Una vez hecho esto, aquí va el script:
 
#!/bin/bash

if [ $# -ne 2 ]
then
  echo "Uso correcto: `basename $0` pdf-origen pdf-destino"
  exit 1
fi
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dNOPAUSE -dQUIET -dBATCH -sOutputFile=$2 $1

 
Con esto pude convertir un PDF de 35M en uno de 1.5M sin perdida apreciable de calidad. Si queremos reducirlo aún más, de tal forma que solo sea para verlo en pantalla pero no para imprimir el comando sería:
 
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen -dNOPAUSE -dQUIET -dBATCH -sOutputFile=$2 $1
 
Y ya está listo para enviar....

domingo, 7 de septiembre de 2014

Ver la TDT en Linux con una tarjeta TDT Medion-Creatix CTX917

Bueno, se acabó el veranito, hagámosle un homenaje con la canción Summer Time de la divertida serie Historias Corrientes:

Espero que podáis quitárosla de la cabeza. Bueno, vamos al lío.

En la época de la burbuja, cuando eramos ricos y el interbancario de Frankfurt confiaba en nosotros, era una gozada bajar a la calle la mañana del día de Reyes. No era difícil encontrar ordenadores, monitores y otros aparatejos en la basura, tirados por haber sido sustituidos por flamantes equipos nuevos. Tengo varios equipos montados y funcionando a día de hoy con los deshechos de aquel tiempo tan feliz.

Ahora la cosa está mas puñetera, aún así de vez en cuando llega a mis manos un equipo que el usuario ya no quiere y siempre se puede aprovechar algo. En un PC para desguace que me dieron me encontré una tarjeta de TV un poco rara. Mirando en Internet vi que soportaba DVB-T y por tanto serviría para ver nuestra estupenda TDT española. Tengo un PC para los niños en el pueblo para un saloncito que no tiene TV, así que pensé en ponerla allí.

Naturalmente, el PC tiene un Linux, y ahí empezó la parte divertida. La tarjeta creo que venía en un PC Medion de esos que venden los Lidl y los ALDI y es esta: Creatix CTX917, con chipset Medion 7134. El identificador PCI es 1131:7134.

El lspci me decía:

 03:01.0 Multimedia controller [0480]: Philips Semiconductors SAA7134/SAA7135HL Video Broadcast Decoder [1131:7134] (rev 01)
   Subsystem: Hyperparallel Technologies Device [1210:0001]
   Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
   Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR+ INTx-
   Latency: 64
   Interrupt: pin A routed to IRQ 16
   Region 0: Memory at febff000 (32-bit, non-prefetchable) [size=1K]
   Capabilities: <access denied>
   Kernel driver in use: saa7134
   Kernel modules: saa7134

Por supuesto había drivers para Windows, pero eso no me interesa. El Linux la reconocía y cargaba el módulo saa7134 para manejarla, pero no iba la TDT. Despues de forear, investigar y hacer varias pruebas logré hacerla funcionar. Estas son las instrucciones:

1) Instalar los paquetes

apt-get install linux-firmware linux-firmware-non-free dvb-utils

2) Editar /etc/modules y añadir

saa7134-dvb

3) Crear el fichero /etc/modprobe.d/saa7134 con el siguiente contenido:

options saa7134 card=12 alsa=1
install saa7134 /sbin/modprobe --ignore-install saa7134; /sbin/modprobe saa7134-dvb ; /sbin/modprobe tuner ; /sbin/modprobe tda9887

Los parámetros card=12 alsa=1 son los realmente importantes, ya que dicen al driver que tarjeta tenemos. Además se fuerza a cargar saa7134-dvb en lugar de saa7134, que sería para TV analógica.

Reiniciamos y ya se nos cargan los módulos correctos. Ahora lo primero que haremos será buscar los canales y guardarlos en el sitio adecuado:

mkdir -p ~/.mplayer
scan /usr/share/dvb/dvb-t/es-Carceres  > ~/.mplayer/channels.conf

En /usr/share/dvb/dvb-t/* están los ficheros de frecuencias para los diferentes sitios, en mi caso es es-Carceres (realmente debería ser es-Caceres, pero alguien metió la pata al poner el nombre del fichero).

Una vez tenemos el driver, para ver la TDT hay varias opciones, habría que instalar el paquete correspondiente en cada caso:

  • VLC: es el mas simple y me funciona bien para el uso que le doy. Se ejecuta con (he creado un acceso directo en el escritorio con este comando):

    vlc .mplayer/channels.conf

Para cambiar de canal selecciono Ver->playlist
Para grabar la emisión seecciono Ver->Controles avanzados. Entonces me aparece un botón rojo de grabacion junto a los controles de reproducción, aunque no he probado que tal graba.

  • me-tv: puede importar los canales del channels.conf de vlc, pero no detecta todos. No es muy estable.
  • kaffeine. Hay que seleccionar es-carceres y terrestrial para sintonizar. Si dice que no detecta el dispositivo de video, reiniciar el ordenador. Al hacer el autoescaneo detecta bien todos los canales, incluso los HD. Una vez configurado, se ven muy bien y permite grabar programas. Es un poco lento en los cambios de canal, pero funciona. Lo descarté porque excedía lo que yo necesitaba.

Por detrás la tarjeta tiene solamente el conector de cable coaxial de la antena y el conector S-VIDEO/RCA, ya que no tiene salidas de audio ni conector para mando a distancia. En la placa integrada tiene 3 conectores de 4 pines, que son:

  • blanco    audio-in
  • rojo      audio-out
  • yellow    video-in

En mi caso no ha hecho falta conectarlos a ningún sitio.

Por último, faltaba la antena. En la habitación no hay toma de antena y después de salirme gratis la tarjeta no iba a comprarme una antena de TDT portátil, pudiendo hacer una casera con un cable coaxial sobrante segun este tutorial.

Y ya está, con esta instalación tan lonchafinista ya tenemos televisión en el PC.

Aaaadiós.

domingo, 27 de julio de 2014

Configuracion NAT-DHCP para aulas mixtas de Linux-Windows

Un escenario con el que me encuentro frecuentemente es un aula en el que el ordenador del profesor tiene dos tarjetas de red. Con una de ellas tiene conexión con la red general y con la otra da conexión a una red privada con los ordenadores de los alumnos.

Para que esto funcione, el ordenador del profesor tiene que tener configurado el NAT y un servicio DHCP para ofrecer IP y conectividad a los ordenadores de los alumnos. La cosa se complica cuando tanto el ordenador de profesor como el de alumnos tienen arranque dual y queremos que todo funcione indistintamente tanto Windows como en Linux, independientemente de lo que tenga arrancado cada ordenador de la estancia.

El esquema que he usado es el siguiente:

  • En el profesor, el interfaz que conecta con la red del centro tiene configuración de red dinámica, recibe todo por DHCP, tanto en windows como en Linux.
  • En el profesor, el interfaz que conecta con la red privada del aula tiene configuracion IP fija, con IP 192.168.0.254, máscara 255.255.255.0 y el resto de parámetros sin definir.
  • Los ordenadores de los alumnos son fáciles de configurar: simplemente los dejamos que cojan la configuración de red por DHCP, tanto en Windows como en Linux y ya es suficiente. Recibirán direcciones fijas en función de su MAC en el rango 192.168.0.201-225 (son 25 pc). Debemos recopilar sus MACs en una lista antes de empezar la configuración.

viernes, 25 de julio de 2014

Bono social de Iberdrola para familias numerosas

Este post no va de Linux (ni de Windows :-), pero como me ha costado tanto que Iberdrola me mande los impresos para solicitar el bono social para familias numerosas y no tengo otro blog, pues lo pongo aquí y santas pascuas. Ni el correo bonosocial@iberdrola.es, ni el teléfono han funcionando, al final tuve que hacerlo por twitter y eso es una ofensa para un anti-redes sociales como yo.
 
El documento pinta tal que así:

Descárgalo aquí.

miércoles, 23 de julio de 2014

Actualizo Windows XP a SP3 y me dejan de funcionar las impresoras compartidas desde CUPS: me dicen que están desconectadas.

Tengo varias impresoras compartidas con CUPS desde mis Linux y configuradas en diversos Windows XP como impresoras de red con rutas del estilo:

http://spro-o04:631/printers/COLOR_SALAPROFESORES

Pues no que voy y actualizo el Windows XP de SP2 a SP3 y me dejan de funcionar las impresoras: aparecen como desconectadas. Mando trabajos y se quedan encolados en el Windows sin que éste llegue a conectar con el servidor CUPS del Linux. Lo primero que hago es borrar la impresora y volver a crearla. Bien, funciona. No, cuando reinicio deja de funcionar otra vez.

¿Qué está pasando?. No lo sé, pero aquí encuentro la solución. Los pasos son:

  • Entrar en regedit.
  • Ir a la clave de registro:

HKLM\System\CurrentControlSet\Control\Print\Printers\<nombre de impresora>

  • Allí, cambiar el valor de Attributes a 0X00000A50 hex o 2640 decimal.
  • Reiniciar el servicio de impresión (net stop spooler y net start spooler) o el PC.

Y ya no se vuelven a poner offline de motu propio. Aquí se explican el valor de los atributos activados con este truquito: Network, Local, DoCompleteFirst y EnableBIDI. Estos parámetros no se pueden configurar con el entorno gráfico, deben configurarse desde regedit.

Cuando esto pasa en Linux es imperdonable. Si pasa en Windows es "no sós vos, soy yo".

martes, 22 de julio de 2014

Configurar una impresora Olivetti P200 en Linux

Hace tiempo me encasquetaron la tarea de hacer funcionar una impresora USB Olivetti JobJet P200 en Linux. Ni que decir tiene que funcionaba perfectamente en Windows. El CUPS seleccionaba en la autodetección unos drivers que no funcionaban y en OpenPrinting ni siquiera aparecía. En estos días tengo que actualizar el PC donde está y he recordado como lo hice.

Tras varias pruebas fallidas con los escasos drivers para Olivetti que tiene CUPS, recordé haber leído que muchas impresoras de inyección de marcas diversas son en realidad impresoras HP 500 con la piel cambiada. Entonces me puse a probar drivers de HP Deskjet 500 hasta que di con el adecuado, que imprimía correctamente en blanco y negro y a color.

En concreto el driver es el cdj500 del modelo HP-DeskJet_500C, dentro de la colección de drivers de foomatic. Tan sólo tendríamos que buscar y seleccionar dicho driver en CUPS dentro de la lista de drivers de HP.

Si queremos dar de alta la impresora desde linea de comandos sería (la URI incluye el número de serie, habría que encontrar la URI adecuada para nuestra impresora mirando como la autodetecta CUPS):

 foomatic-configure -s cups -p "HP-DeskJet_500C" -n "OLIVETTI_P200" -N "Impresora color" -c "usb://Olivetti/Job_Jet%20P200?serial=MY31R1C1BV81" -d "cdj500"
 lpadmin -p "OLIVETTI_P200" -o PageSize=A4
 /etc/init.d/cups restart

Y ya la tenemos funcionando.

jueves, 17 de julio de 2014

No dejes para mañana lo que puedas ejecutar hoy....

El otro día tenía  que lanzar un proceso muy largo en un PC (en concreto, buscar los ficheros de mas de 100MB en una máquina concreta) y quedaba poco rato para irme a casa. Tenía varias opciones:

  1. Ejecutarlo por ssh en mi PC y dejarlo encendido hasta el día siguiente. Un poco exagerado dejar mi PC encendido sólo para eso, ¿no?.
  2. Ejecutarlo en la consola física del PC destino y dejarla abierta con la sesión del usuario root. No es una buena práctica eso de dejar sesiones de root abiertas en un PC cualquiera.
  3. Meterlo en un script y lanzarlo con el comando nohup, que permite lanzar un programa que se ejecutará aun cuando cortemos la conexión ssh. El problema su salida a pantalla se pierde en el limbo y habría que usar un fichero donde volcar la salida para ver el resultado mas tarde.
  4. Usar la utilidad screen, que me descubrió mi compañero Carlos Martín y que fué por la que me decanté y que voy a contar ahora.

domingo, 13 de julio de 2014

Cazando al servidor DHCP intruso

De repente a veces nos encontramos con que los equipos de nuestra red empiezan a recibir direcciones IP que no son de nuestro rango. La causa es que tenemos algún dispositivo en la red que está sirviendo IPs en concurrencia con nuestro servicio DHCP "oficial". Los rangos típicos son 192.168.X.X o 10.0.X.X. Vamos a ver como localizarlo y neutralizarlo.

viernes, 11 de julio de 2014

Monitorizar una impresora de red con snmpwalk

En todos los sitios donde he trabajado había una o varias "impresoras críticas", esto es, una impresora comunitaria usada por todo tipo de usuarios y que era sistemáticamente maltratada, sobreexplotada y humillada. Muchas veces esa impresora presenta un problema y nadie se ocupa de resolverlo o avisar de él, con lo cual la cosa suele pasar a mayores y el culpable es el informático, claro está.
 
Si es una impresora de red y tiene opción para activar el SNMP (esto se hace entrando en la página web de configuración de la impresora  o bien con el menú del panel de estado) , podremos acceder a su árbol MIB y obtener información sobre su estado desde un programa externo. Es el método usado por suites como Nagios, que es demasiado compleja para lo que queremos hacer nosotros.
 

miércoles, 9 de julio de 2014

Mover perfiles de usuarios Windows a otra unidad de disco

Esta va de Windows: en Linux es muy fácil cambiar de sitio un perfil de usuario cuando el disco o partición donde está ya no da más de sí. Simplemente tenemos que cambiar la ruta de su home en el fichero /etc/passwd y mover el home preservando los permisos y propietarios de los archivos a la nueva ubicación y ya está. En Windows XP es un pelín mas complicado, pero como veremos también se puede hacer.

Para ello uso un script hecho con la potente herramienta de scripting kix32 y la excelente utilidad de copiado Robocopy. Debemos descargar ambos programas y ponerlos en algun directorio del path de nuestro sistema, por ejemplo en c:\windows\system32.

martes, 8 de julio de 2014

Impresoras duplicadas en CUPS

Un problema bastante desconcertante que me ocurría a veces es que las impresoras conectadas por USB me aparecían dos veces en la lista de impresoras y en /etc/cups/printers.conf, como si CUPS  pensase que eran impresoras distintas, aun cuando su DeviceURI era igual. Este problema se hacía mas frecuente cuando cambiaba el nombre de la impresora y ponía uno a mi gusto, en lugar de el que le había dado CUPS en la autodetección, o cuando usaba el filtro tea4cups para controlar los trabajos enviados a las cola de impresión. 

Como utilizo tea4cups para llevar una contabilidad de las páginas impresas, el que las impresoras apareciesen duplicadas me originaba un problema a la hora de recopilar los datos, además de desconcertar al usuario a la hora de imprimir.

Mi compañero Ubaldo me puso en la pista de como resolver el problema. En el paquete system-config-printer-udev están los scripts encargados de manejar las impresoras USB detectadas por udev. En concreto el script /lib/udev/udev-add-printer es el que se encarga de añadir a CUPS una nueva impresora cuando es detectada por primera vez. Estaba claro que algo fallaba ahí y que había que retocar el código del script para evitar que se duplicase. Afortunadamente el script estaba en python.

El script retocado queda así (pongo en rojo las líneas añadidas por mí):

 #!/usr/bin/python  
 ## udev-add-printer  
 ## Copyright (C) 2009, 2010 Red Hat, Inc.  
 ## Author: Tim Waugh <twaugh@redhat.com>  
 ## This program is free software; you can redistribute it and/or modify  
 ## it under the terms of the GNU General Public License as published by  
 ## the Free Software Foundation; either version 2 of the License, or  
 ## (at your option) any later version.  
 ## This program is distributed in the hope that it will be useful,  
 ## but WITHOUT ANY WARRANTY; without even the implied warranty of  
 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the  
 ## GNU General Public License for more details.  
 ## You should have received a copy of the GNU General Public License  
 ## along with this program; if not, write to the Free Software  
 ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
 import cups  
 import cupshelpers  
 import dbus  
 import os  
 import sys  
 import traceback  
 from syslog import *  
 MFG_BLACKLIST=[  
   "graphtec",  
   ]  
 def create_queue (c, printers, name, device_uri, ppdname, info, installer):  
   # Make sure the name is unique.  
   namel = unicode (name.lower ())  
   unique = False  
   suffix = 1  
   while not unique:  
     unique = True  
     for printer in printers.values ():  
       if (not printer.discovered and  
         ((suffix == 1 and printer.name.lower () == namel) or  
          (suffix > 1 and  
          printer.name.lower () == namel + "-" + str (suffix)))):  
         unique = False  
         break  
     if not unique:  
       suffix += 1  
       if suffix == 100:  
         break  
   if suffix > 1:  
     name += "-" + str (suffix)  
   c.addPrinter (name,  
          device=device_uri,  
          ppdname=ppdname,  
          info=info,  
          location=os.uname ()[1])  
   if not installer:  
     # There is no session applet running to deal with installing  
     # drivers so there is a good chance that this queue won't work  
     # right now. If that's the case, delete it. The user can  
     # reconnect the printer when they log in, and everything will  
     # be set up correctly for them at that point.  
     try:  
       ppdfile = c.getPPD (name)  
       ppd = cups.PPD (ppdfile)  
       os.unlink (ppdfile)  
       (pkgs, exes) = cupshelpers.missingPackagesAndExecutables (ppd)  
       if pkgs or exes:  
         # There are filters missing. Delete the queue.  
         syslog (LOG_ERROR, "PPD %s requires %s" % (ppdname,  
                               repr ((pkgs, exes))))  
         syslog (LOG_ERROR, "Deleting non-functional queue")  
         c.deletePrinter (name)  
         name = None  
     except cups.IPPError, (e, m):  
       pass  
     except RuntimeError:  
       pass  
   if name:  
     cupshelpers.activateNewPrinter (c, name)  
   return name  
 def add_queue (device_id, device_uris, fax_basename=False):  
   """  
   Create a CUPS queue.  
   device_id: the IEEE 1284 Device ID of the device to add a queue for.  
   device_uris: device URIs, best first, for this device  
   fax_basename: False if this is not a fax queue, else name prefix  
   """  
   id_dict = cupshelpers.parseDeviceID (device_id)  
   if id_dict["MFG"].lower () in MFG_BLACKLIST:  
     syslog (LOG_DEBUG, "Ignoring blacklisted manufacturer %s", id_dict["MFG"])  
     return  
   syslog (LOG_DEBUG, "add_queue: URIs=%s" % device_uris)  
   installer = None  
   if fax_basename != False:  
     notification = None  
   else:  
     try:  
       bus = dbus.SystemBus ()  
       obj = bus.get_object ("com.redhat.NewPrinterNotification",  
                  "/com/redhat/NewPrinterNotification")  
       notification = dbus.Interface (obj,  
                       "com.redhat.NewPrinterNotification")  
       notification.GetReady ()  
     except dbus.DBusException, e:  
       syslog (LOG_DEBUG, "D-Bus method call failed: %s" % e)  
       notification = None  
     try:  
       obj = bus.get_object ("com.redhat.PrinterDriversInstaller",  
                  "/com/redhat/PrinterDriversInstaller")  
       installer = dbus.Interface (obj,  
                     "com.redhat.PrinterDriversInstaller")  
     except dbus.DBusException, e:  
       syslog (LOG_DEBUG, "Failed to get D-Bus object for "  
           "PrinterDriversInstaller: %s" % e)  
   id_dict = cupshelpers.parseDeviceID (device_id)  
   if installer:  
     cmd = id_dict["CMD"]  
     if cmd:  
       cmd = reduce (lambda x, y: x + ',' + y, cmd)  
     else:  
       cmd = ""  
     try:  
       installer.InstallDrivers (id_dict["MFG"], id_dict["MDL"], cmd,  
                    timeout=3600)  
     except dbus.DBusException, e:  
       syslog (LOG_DEBUG, "Failed to install drivers: %s" % repr (e))  
   c = cups.Connection ()  
   ppds = cupshelpers.ppds.PPDs (c.getPPDs ())  
   (status, ppdname) = ppds.getPPDNameFromDeviceID (id_dict["MFG"],  
                            id_dict["MDL"],  
                            id_dict["DES"],  
                            id_dict["CMD"],  
                            device_uris[0])  
   syslog (LOG_DEBUG, "PPD: %s; Status: %d" % (ppdname, status))  
   if status == 0:  
     # Think of a name for it.  
     name = id_dict["MDL"]  
     name = name.replace (" ", "-")  
     name = name.replace ("/", "-")  
     name = name.replace ("#", "-")  
     if fax_basename != False:  
       name = fax_basename + "-" + name  
     printers = cupshelpers.getPrinters (c)  
     #Comprobamos si ya existe un dispositivo con esa URI igual  
     #o precedida por tea4cups  
     uri=device_uris[0].lower()  
     ya_existe=False  
     for printer in printers.values ():  
       device_uri=printer.device_uri.lower()  
       if device_uri == "tea4cups://" + uri or device_uri == uri :   
         ya_existe=True  
         break  
     if ya_existe:   
       syslog (LOG_DEBUG, "Alta abortada, URI Repetido: %s" % device_uri)   
       return  
     #Fin de la comprobacion      
     uniquename = create_queue (c, printers, name, device_uris[0], ppdname,  
                   "%s %s" % (id_dict["MFG"], id_dict["MDL"]),  
                   installer)  
     if uniquename != None and fax_basename == False:  
       # Look for a corresponding fax queue. We can only  
       # identify these by looking for device URIs that are the  
       # same as this one but with a different scheme. If we  
       # find one whose scheme ends in "fax", use that as a fax  
       # queue. Note that the HPLIP backends do follow this  
       # pattern (hp and hpfax).  
       used_uris = map (lambda x: x.device_uri, printers.values ())  
       for uri in device_uris[1:]:  
         if uri.find (":") == -1:  
           continue  
         (scheme, rest) = uri.split (":", 1)  
         if scheme.endswith ("fax"):  
           # Now see if the non-scheme parts of the URI match  
           # any of the URIs we were given.  
           for each_uri in device_uris:  
             if each_uri == uri:  
               continue  
             (s, device_uri_rest) = each_uri.split (":", 1)  
             if rest == device_uri_rest:  
               # This one matches. Check there is not  
               # already a queue using this URI.  
               if uri in used_uris:  
                 break  
               try:  
                 devices = c.getDevices(include_schemes=[scheme])  
               except TypeError:  
                 # include_schemes requires pycups 1.9.46  
                 devices = c.getDevices ()  
               device_dict = devices.get (uri)  
               if device_dict == None:  
                 break  
               add_queue (device_dict.get ("device-id", ""),  
                     [uri], fax_basename=uniquename)  
   else:  
     # Not an exact match.  
     uniquename = device_uris[0]  
   if uniquename != None and notification:  
     try:  
       cmd = id_dict["CMD"]  
       if cmd:  
         cmd = reduce (lambda x, y: x + ',' + y, cmd)  
       else:  
         cmd = ""  
       notification.NewPrinter (status, uniquename, id_dict["MFG"],  
                    id_dict["MDL"], id_dict["DES"], cmd)  
     except dbus.DBusException, e:  
       syslog (LOG_DEBUG, "D-Bus method call failed: %s" % e)  
 if len (sys.argv) < 3:  
   print "Syntax: %s {Device ID} {Device URI} [other device URIs...]"  
   sys.exit (1)  
 openlog ("udev-add-printer", 0, LOG_LPR)  
 try:  
   add_queue (sys.argv[1], sys.argv[2:])  
 except SystemExit, e:  
   sys.exit (e)  
 except:  
   (type, value, tb) = sys.exc_info ()  
   tblast = traceback.extract_tb (tb, limit=None)  
   if len (tblast):  
     tblast = tblast[:len (tblast) - 1]  
   for line in traceback.format_tb (tb):  
     syslog (LOG_ERR, line.strip ())  
   extxt = traceback.format_exception_only (type, value)  
   syslog (LOG_ERR, extxt[0].strip ())  

Básicamente lo que hago es comprobar que el DeviceURI de la impresora no existe ya en la lista de impresoras previas, teniendo en cuenta que puede o no tener el prefijo del filtro "tea4cups://". Con esto estaremos a salvo de esas colas de impresión fantasma y tendremos la cola de impresión ajustada a la realidad.

A otra cosa, mariposa....


miércoles, 2 de julio de 2014

Monitorizar la conexión de teclados y ratones.

En un entorno con cientos de maquinas Linux y con usuarios que cambian constantemente es útil tener controlado algo tan trivial como la conexión de teclados y ratones para adelantarnos a las probables incidencias y localizar a los usuarios "graciosetes". Con este script consigo tenerlos controlados y programar un aviso ante cualquier evento de desconexión que acontezca.

El truco está en husmear en /proc/bus/input/devices y buscar allí la presencia del ratón y el teclado. Como la casuística de dispositivos de entrada y la manera en que se identifican es enorme, puede que nos encontremos con excepciones a aplicar, tal como se puede ver en el código del script en el caso de teclados de marcas Sweex y RML, que son los rara avis que yo me he encontrado. En ese caso bastará con adaptar el grep de búsqueda a las circunstancias particulares de cada caso.

El script en cuestión es:

 #!/bin/bash
 #Script: seguimiento_km
 maquina=$(hostname -s)
#Detección raton #En teclados Sweex USB, aparece mouse en devices, aun cuando no haya ratón #conectado. Con el filtro grep -v kbd eliminamos esas lineas, para que solo #coja las corresponden a un ratón real. raton=$(cat /proc/bus/input/devices | grep -i mouse | grep -v kbd | wc -l)
#Detección teclado #En teclados RML, la cadena es "keykoard" en lugar de "keyboard" teclado=$(cat /proc/bus/input/devices | grep -i key[bk]oard | wc -l)
if [ $raton -ne 0 ] then raton="SI" else raton="NO" fi if [ $teclado -ne 0 ] then teclado="SI" else teclado="NO" fi echo "Maquina $maquina. Teclado: $teclado. Ratón: $raton."

Tal como está el script tan solo muestra en pantalla el resultado. Lo ideal sería un aviso por otro medio mas cómodo, pero eso ya depende de la infraestructura de avisos que quiera montar cada cual. En mi caso hago una llamada a una aplicación web mediante wget:

 peticion="http://url/aplicacion/web?maquina=$maquina&raton=$raton&teclado=$teclado"
 actualiza=$(wget -q -O - $peticion 2>/dev/null)

Y mi aplicación web se encarga de procesar los datos (en mi caso guardar un log de los diversos chequeos) y avisarme si es necesario. Este es el método usado en la aplicación controlies, con la cual tengo el honor de colaborar.

Otra opción podría ser enviar un mensaje de correo si cualquiera de los dos periféricos no es detectado. Una forma sencilla de hacerlo es con mailsend, que nos permite mandar correos a través de la cuenta de gmail (o cualquier otra cuenta que soporte smtp) sin tener que configurar nada especial en nuestra máquina:

 mailsend -to destinatario@gmail.com
      -from micorreo@gmail.com
      -ssl -smtp smtp.gmail.com -port 465
      -sub "Aviso de teclado/ratón"
      -M "Maquina $maquina. Teclado: $teclado. Ratón: $raton."
      +cc +bc -q -auth -user "micuenta" -pass "password"

Por último, debemos decidir cuando ejecutar el script de chequeo:

  • Podemos hacerlo en el arranque del sistema, llamando al script en /etc/init.d como un servicio a arrancar en el nivel 2
 cp /path/to/seguimiento_km /etc/init.d/seguimiento_km
 /usr/sbin/update-rc.d seguimiento_km start 05 2 .
  • O desde una línea que comienze con @reboot en el crontab.
 echo "@reboot root /path/to/seguimiento_km" >> /etc/crontab
  • Y otra opción es monitorizarlo cada cierto tiempo mediante una línea en el crontab con los minutos de intervalo (en el ejemplo, 10):
 echo "*/10 * * * * root /path/to/seguimiento_km" >> /etc/crontab

Y ya está. Hasta la próxima...